From b37a9d6e8a0353ea88764533fcea25f993782a73 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Wed, 3 Jun 2026 06:36:27 -0400 Subject: [PATCH 1/3] Remove vendored openclaw package; rename MCP server to agent-relay OpenClaw lives in its own repo (AgentWorkforce/agent-relay-openclaw); the copy under packages/openclaw was a stale duplicate re-added after the split and nothing in relay depends on it. Drop it (and its package-lock entries + the CI build step). Also align the customer-facing MCP surface with the binary name: - CLI uninstall now cleans up the `agent-relay` .mcp.json key and the legacy `relaycast` key. - Refresh the orchestrating-agent-relay skill for the v8 `local` CLI surface, relay-only messaging, and the `mcp__agent-relay__*` tools. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../skills/orchestrating-agent-relay/SKILL.md | 413 +-- .../skills/orchestrating-agent-relay/SKILL.md | 388 +-- .github/workflows/package-validation.yml | 5 +- package-lock.json | 379 +-- packages/cli/src/cli/lib/core-maintenance.ts | 28 +- packages/openclaw/README.md | 77 - packages/openclaw/bin/relay-openclaw.mjs | 2 - packages/openclaw/bridge/bridge.mjs | 307 --- packages/openclaw/bridge/spawn-from-env.mjs | 56 - packages/openclaw/package.json | 61 - packages/openclaw/skill/SKILL.md | 707 ----- .../src/__tests__/SPEC-ws-client-testing.md | 199 -- .../src/__tests__/gateway-control.test.ts | 291 -- .../__tests__/gateway-poll-fallback.test.ts | 478 ---- .../src/__tests__/gateway-threads.test.ts | 1164 -------- .../openclaw/src/__tests__/naming.test.ts | 24 - .../src/__tests__/spawn-manager.test.ts | 197 -- .../openclaw/src/__tests__/ws-client.test.ts | 486 ---- packages/openclaw/src/auth/converter.ts | 90 - packages/openclaw/src/cli.ts | 356 --- packages/openclaw/src/config.ts | 500 ---- packages/openclaw/src/control.ts | 100 - packages/openclaw/src/gateway.ts | 2389 ----------------- packages/openclaw/src/identity/contract.ts | 44 - packages/openclaw/src/identity/files.ts | 196 -- packages/openclaw/src/identity/model.ts | 27 - packages/openclaw/src/identity/naming.ts | 6 - packages/openclaw/src/index.ts | 71 - packages/openclaw/src/inject.ts | 78 - packages/openclaw/src/mcp/server.ts | 121 - packages/openclaw/src/mcp/tools.ts | 172 -- .../openclaw/src/runtime/openclaw-config.ts | 66 - packages/openclaw/src/runtime/patch.ts | 103 - packages/openclaw/src/runtime/setup.ts | 130 - packages/openclaw/src/setup.ts | 636 ----- packages/openclaw/src/spawn/docker.ts | 291 -- packages/openclaw/src/spawn/manager.ts | 172 -- packages/openclaw/src/spawn/process.ts | 274 -- packages/openclaw/src/spawn/types.ts | 45 - packages/openclaw/src/types.ts | 101 - packages/openclaw/templates/SOUL.md.template | 34 - packages/openclaw/test/vitest.setup.ts | 1 - packages/openclaw/tsconfig.json | 12 - 43 files changed, 501 insertions(+), 10776 deletions(-) delete mode 100644 packages/openclaw/README.md delete mode 100755 packages/openclaw/bin/relay-openclaw.mjs delete mode 100644 packages/openclaw/bridge/bridge.mjs delete mode 100644 packages/openclaw/bridge/spawn-from-env.mjs delete mode 100644 packages/openclaw/package.json delete mode 100644 packages/openclaw/skill/SKILL.md delete mode 100644 packages/openclaw/src/__tests__/SPEC-ws-client-testing.md delete mode 100644 packages/openclaw/src/__tests__/gateway-control.test.ts delete mode 100644 packages/openclaw/src/__tests__/gateway-poll-fallback.test.ts delete mode 100644 packages/openclaw/src/__tests__/gateway-threads.test.ts delete mode 100644 packages/openclaw/src/__tests__/naming.test.ts delete mode 100644 packages/openclaw/src/__tests__/spawn-manager.test.ts delete mode 100644 packages/openclaw/src/__tests__/ws-client.test.ts delete mode 100644 packages/openclaw/src/auth/converter.ts delete mode 100644 packages/openclaw/src/cli.ts delete mode 100644 packages/openclaw/src/config.ts delete mode 100644 packages/openclaw/src/control.ts delete mode 100644 packages/openclaw/src/gateway.ts delete mode 100644 packages/openclaw/src/identity/contract.ts delete mode 100644 packages/openclaw/src/identity/files.ts delete mode 100644 packages/openclaw/src/identity/model.ts delete mode 100644 packages/openclaw/src/identity/naming.ts delete mode 100644 packages/openclaw/src/index.ts delete mode 100644 packages/openclaw/src/inject.ts delete mode 100644 packages/openclaw/src/mcp/server.ts delete mode 100644 packages/openclaw/src/mcp/tools.ts delete mode 100644 packages/openclaw/src/runtime/openclaw-config.ts delete mode 100644 packages/openclaw/src/runtime/patch.ts delete mode 100644 packages/openclaw/src/runtime/setup.ts delete mode 100644 packages/openclaw/src/setup.ts delete mode 100644 packages/openclaw/src/spawn/docker.ts delete mode 100644 packages/openclaw/src/spawn/manager.ts delete mode 100644 packages/openclaw/src/spawn/process.ts delete mode 100644 packages/openclaw/src/spawn/types.ts delete mode 100644 packages/openclaw/src/types.ts delete mode 100644 packages/openclaw/templates/SOUL.md.template delete mode 100644 packages/openclaw/test/vitest.setup.ts delete mode 100644 packages/openclaw/tsconfig.json diff --git a/.agents/skills/orchestrating-agent-relay/SKILL.md b/.agents/skills/orchestrating-agent-relay/SKILL.md index c05eb7489..af1fc0e9e 100644 --- a/.agents/skills/orchestrating-agent-relay/SKILL.md +++ b/.agents/skills/orchestrating-agent-relay/SKILL.md @@ -3,49 +3,72 @@ name: orchestrating-agent-relay description: The canonical way to run agent-relay - self-bootstrap the broker and autonomously spawn, monitor, and coordinate a team of worker agents without human intervention. Covers infrastructure startup, agent spawning, lifecycle monitoring, CLI-first reading, and team coordination. --- -### Overview +# Orchestrating Agent Relay + +Self-bootstrap agent-relay infrastructure and manage a team of agents autonomously. + +## Overview A headless orchestrator is an agent that: -1. Starts the relay infrastructure itself (`agent-relay up`) -2. Spawns and manages worker agents -3. Monitors agent lifecycle events +1. Starts the relay infrastructure itself (`agent-relay local up`) +2. Spawns and manages worker agents (`agent-relay local agent …`) +3. Monitors agent liveness via the broker (`agent-relay local agent list`) and reads worker replies through relay (`agent-relay message inbox check`) 4. Coordinates work without human intervention -The orchestrator drives the team **from outside** and is **not** a -registered relay agent, so it reads/sends/lists via the `agent-relay` CLI -(MCP `mcp__relaycast__message_*` tools require a registered identity). The -workers it spawns _are_ registered participants — their peer-messaging -reference is the **`using-agent-relay`** skill. +The CLI has two surfaces, and the split is the thing to memorize: -### When to Use +- **`agent-relay local …`** — **lifecycle only**: start/stop the local broker + and spawn/release/list the agents it runs. No token required; it talks to the + local broker via `.agentworkforce/relay/connection.json`. **Never use it to + read or send messages.** +- **`agent-relay message … / channel … / agent …`** — **all messaging goes + through relay** (the Relaycast service at `gateway.relaycast.dev`). These are + **token-gated** (`--token` / `RELAY_AGENT_TOKEN`). Register once for an agent + token (see Step 3), then send and read every coordination message here — or + use the equivalent relay MCP tools (`mcp__agent-relay__*`). -- Agent needs full control over its worker team -- No human available to run `agent-relay up` manually -- Agent should manage agent lifecycle autonomously -- Building self-contained multi-agent systems +**Always go through relay for messaging — never contact the broker directly to +read worker output.** Worker ACKs, replies, and DONE signals arrive as relay +messages: read them with `agent-relay message inbox check` / +`message dm list `, not by tailing the broker. (`local tail` is +a low-level broker/TTY debugging aid only.) -### Quick Reference +The orchestrator drives the team **from outside** but is itself a registered +relay agent — that is what lets it message through relay. The workers it spawns +are registered participants too; their peer-messaging reference is the +**`using-agent-relay`** skill. -| Step | Command/Tool | -| ---------------------------------- | ------------------------------------------------------- | -| Verify installation | `command -v agent-relay` or `npx agent-relay --version` | -| Verify Node runtime if shim fails | `node --version` or fix mise/asdf first | -| Start infrastructure | `agent-relay up --no-dashboard --verbose` | -| Check status | `agent-relay status --wait-for=10` | -| Spawn worker | `agent-relay spawn Worker1 claude "task"` | -| List workers | `agent-relay who` | -| View worker logs | `agent-relay agents:logs Worker1` | -| Send DM to worker | `agent-relay send Worker1 "message"` | -| Post to channel | `agent-relay send '#general' "message"` | -| Read worker DM replies (full text) | `agent-relay replies Worker1` (add `--json` to parse) | -| Read full DM conversation history | `agent-relay history --to Worker1` | -| Release worker | `agent-relay release Worker1` | -| Stop infrastructure | `agent-relay down` | +## When to Use -### Bootstrap Flow +- Agent needs full control over its worker team +- No human available to run `agent-relay local up` manually +- Agent should manage agent lifecycle autonomously +- Building self-contained multi-agent systems -#### Step 0: Verify Installation +## Quick Reference + +| Step | Command/Tool | +| --------------------------------- | ------------------------------------------------------------- | +| Verify installation | `command -v agent-relay` or `npx agent-relay --version` | +| Verify Node runtime if shim fails | `node --version` or fix mise/asdf first | +| Start infrastructure | `agent-relay local up --no-dashboard --verbose` | +| Check broker readiness | `agent-relay local status --wait-for=10` | +| Spawn worker | `agent-relay local agent spawn claude --name Worker1 --task "…"` | +| List workers | `agent-relay local agent list` | +| Resource usage | `agent-relay local metrics` | +| Register for a messaging token | `agent-relay agent register Lead` (sets up `RELAY_AGENT_TOKEN`) | +| DM a worker (via relay) | `agent-relay message dm send Worker1 "…"` | +| Post to a channel (via relay) | `agent-relay message post general "…"` | +| Read a worker's replies (via relay) | `agent-relay message dm list ` | +| Check inbox (via relay) | `agent-relay message inbox check` | +| Debug raw worker output (not messaging) | `agent-relay local tail --agent Worker1` | +| Release worker | `agent-relay local agent release Worker1` | +| Stop infrastructure | `agent-relay local down` | + +## Bootstrap Flow + +### Step 0: Verify Installation ```bash # Check if agent-relay is available @@ -62,131 +85,206 @@ npm install -g agent-relay npx agent-relay --version ``` -#### Step 1: Start Infrastructure +### Step 1: Start Infrastructure + +```bash +# Start the local broker in headless mode +agent-relay local up --no-dashboard --verbose +``` + +Verify broker readiness before spawning any workers: + +```bash +# Polls until the broker reports RUNNING (or times out after 10s) +agent-relay local status --wait-for=10 +``` + +The broker: + +- Provisions a Relaycast workspace when none is configured +- Removes `CLAUDECODE` env var when spawning (fixes nested session error) +- Persists state to `.agentworkforce/relay/` (connection files, etc.) + +When verifying from a source checkout or throwaway git worktree, run these +commands from the project/worktree root. The CLI writes runtime state to +`.agentworkforce/relay/` and may create `.mcp.json`; clean those files after +validation if the worktree should remain clean. Pass `--state-dir ` to +relocate broker state. + +### Step 2: Spawn Workers ```bash -# Starts a detached broker in headless mode and returns after API readiness -agent-relay up --no-dashboard --verbose +# provider is positional; --name defaults to the provider; --channels defaults to "general" +agent-relay local agent spawn claude --name Worker1 --task "Implement the authentication module following the existing patterns" ``` -#### Step 2: Spawn Workers via MCP +MCP equivalent (works once the orchestrator is registered — see Step 3): ```text -mcp__relaycast__agent_add( +mcp__agent-relay__add_agent( name: "Worker1", cli: "claude", task: "Implement the authentication module following the existing patterns" ) ``` -#### Step 3: Monitor and Coordinate - -```bash -# Read Worker1's DM replies (chronological, full text, untruncated) -agent-relay replies Worker1 +### Step 3: Register, then Coordinate Through Relay -# Machine-readable: full text + direction, safe to parse in a loop -agent-relay replies Worker1 --json +Register once for an agent token so every message — sent or read — goes through +relay: -# Send a targeted DM to a specific worker -agent-relay send Worker1 "Also add unit tests" +```bash +# Prints a registration JSON that includes the agent token +agent-relay agent register Lead +# Copy the "token" value from the output: +export RELAY_AGENT_TOKEN= +``` -# Broadcast to all agents on a channel -agent-relay send '#general' "All workers: wrap up current task" +Now do **all** coordination through the `message` group (or the equivalent +`mcp__agent-relay__*` tools): -# List active workers (structured status for polling) -agent-relay who --json +```bash +agent-relay message dm send Worker1 "Also add unit tests" # targeted DM +agent-relay message post general "All workers: wrap up" # channel broadcast (bare name, no #) +agent-relay message dm list # read a worker's replies +agent-relay message inbox check # unread across conversations ``` -#### Step 4: Release Workers +Track which workers are alive with the lifecycle command (not a messaging +channel): -```text -mcp__relaycast__agent_remove(name: "Worker1") +```bash +agent-relay local agent list # pid, status, uptime — JSON, ideal for polling ``` -#### Step 5: Shutdown (optional) +> **Read worker replies through relay, never from the broker.** ACKs, replies, +> and DONE signals are relay messages — read them with `message inbox check` / +> `message dm list`. Do not use `local tail` to "read" worker responses; it +> streams the broker's raw TTY output and is only a low-level debugging aid. +> +> **Messaging requires a registered agent identity.** The `message`, `channel`, +> and `dm` groups (and the `mcp__agent-relay__*` tools) reject unregistered +> callers with `Not registered. Call agent.register first.` Run +> `agent-relay agent register ` and set `RELAY_AGENT_TOKEN` (or pass +> `--token ` per call). + +### Step 4: Release Workers ```bash -agent-relay down +agent-relay local agent release Worker1 +# MCP: mcp__agent-relay__remove_agent(name: "Worker1") ``` -### CLI Commands for Orchestration - -#### Channel vs DM — When to Use Each +### Step 5: Shutdown (optional) ```bash -# WRONG — history (no flags) will not show DM replies from workers -agent-relay history +agent-relay local down +``` -# RIGHT — read a worker's DM replies (full text, chronological) -agent-relay replies Worker1 +## CLI Commands for Orchestration -# Machine-readable: full text + direction, safe to parse in a loop -agent-relay replies Worker1 --json +Two namespaces — keep the split straight. -# Full DM conversation history with a worker (read + unread) -agent-relay history --to Worker1 +### Local broker & agents — lifecycle only (no token) -# Channel evidence (diffs, grep counts, GO/NO-GO) — full text, -# untruncated, chronological; add --json to parse it programmatically -agent-relay history --to '#general' --json +Use these to start/stop the broker and manage the agent processes. **Not for +messaging** — never read or send messages here. + +```bash +agent-relay local up [--no-dashboard] [--verbose] [--no-spawn] [--background] [--state-dir ] +agent-relay local down [--force] [--all] +agent-relay local status [--wait-for ] # broker readiness +agent-relay local metrics [--agent ] # resource usage +agent-relay local agent list # running agents (JSON) +agent-relay local agent spawn --name --task "" [--channels ] [--model ] +agent-relay local agent new … # spawn + attach to its TUI +agent-relay local agent release # graceful stop +agent-relay local agent set-model # switch a running agent's model +agent-relay local agent attach --mode view|drive|passthrough +agent-relay local tail [--agent ] # raw broker/TTY output — DEBUG ONLY, not message reading ``` -#### Spawning and Messaging +### Messaging & registry — always through relay (token-gated) + +Every coordination message goes through relay here. All accept `--token ` +(or `RELAY_AGENT_TOKEN`), `--workspace-key`, and `--base-url`. ```bash -# Spawn a worker -agent-relay spawn Worker1 claude "Implement auth module" +agent-relay agent register # print an agent token, then export RELAY_AGENT_TOKEN +agent-relay agent list [--status ] # workspace agent registry + +agent-relay message post # channel broadcast (bare channel name) +agent-relay message list [--limit ] # channel history +agent-relay message dm send # DM a worker +agent-relay message dm list [--limit ] # read a DM thread +agent-relay message dm send_group # group DM +agent-relay message reply # threaded reply +agent-relay message get_thread # full thread +agent-relay message search [--channel ] [--from ] [--limit ] +agent-relay message inbox check [--limit ] # unread messages +agent-relay message inbox mark_read +agent-relay message reaction add|remove + +agent-relay channel create|list|join|leave|invite|set_topic|archive … +``` -# Send a DM to a specific worker (replies readable via `replies`) -agent-relay send Worker1 "Add unit tests too" +### Channel vs DM — When to Use Each -# Broadcast to all workers via channel -agent-relay send '#general' "Team: wrap up and report status" +**DM** — targeted, private, for responses you need to read back: -# Read Worker1's DM reply -agent-relay replies Worker1 +- `agent-relay message dm send Worker1 "message"` — sends a DM to Worker1 +- `mcp__agent-relay__send_dm(to: "Worker1", text: "...")` — same via MCP +- Read a worker's thread with `agent-relay message dm list ` -# Release when done -agent-relay release Worker1 -``` +**Channel post** — broadcast, visible to all agents on that channel: -#### Monitoring Workers (Essential) +- `agent-relay message post general "message"` — posts to the `general` channel + (bare name — no `#` prefix in the new `message post` command) +- `mcp__agent-relay__post_message(channel: "general", text: "...")` — same via MCP +- Use for coordination messages, status updates, announcements -```bash -# Show currently active agents (structured: pid, uptimeSecs, memoryBytes, -# status) — poll this instead of scraping the worker TTY for health -agent-relay who --json +### Monitoring Workers (Essential) -# View real-time output from a worker (critical for debugging) -agent-relay agents:logs Worker1 +Read worker progress and replies **through relay**; use the broker only for +liveness/health. -# Read DM replies from a specific worker (use --json to parse safely) -agent-relay replies Worker1 --json +```bash +# Worker replies, ACKs, DONE signals — read these through relay +agent-relay message inbox check # unread across conversations +agent-relay message dm list # a specific worker's thread -# View channel message history (channel posts only — not DMs) -agent-relay history --to '#general' --json +# Liveness/health only (lifecycle, not messaging) +agent-relay local agent list # running agents (pid, status, uptime) +agent-relay local metrics # resource usage -# Check overall system status -agent-relay status +# Last resort: raw broker/TTY output for debugging a wedged worker. +# This is NOT how you read a worker's messages. +agent-relay local tail --agent Worker1 ``` -#### Troubleshooting +### Troubleshooting ```bash -# Kill unresponsive worker -agent-relay agents:kill Worker1 +# Gracefully stop an unresponsive worker +agent-relay local agent release Worker1 + +# Reset the broker if it is wedged +agent-relay local down --force # Re-check broker status -agent-relay status +agent-relay local status -# If a worker looks stuck, inspect its logs first -agent-relay agents:logs Worker1 +# If a worker looks stuck, inspect its output first +agent-relay local tail --agent Worker1 ``` -### Orchestrator Instructions Template +**Tip:** Read worker progress through relay (`agent-relay message inbox check`) +and poll `agent-relay local agent list` for liveness. Reach for +`agent-relay local tail` only to debug a wedged worker's raw output. + +## Orchestrator Instructions Template -#### Give your lead agent these instructions: +Give your lead agent these instructions: ```text You are an autonomous orchestrator. Bootstrap the relay infrastructure and manage a team of workers. @@ -197,44 +295,41 @@ If you hit a mise/asdf shim error: verify Node first with `node --version`, then If not found: npm install -g agent-relay ## Step 2: Start Infrastructure -Run: agent-relay up --no-dashboard --verbose -Verify: agent-relay status --wait-for=10 (should show "RUNNING") +Run: agent-relay local up --no-dashboard --verbose +Verify: agent-relay local status --wait-for=10 (should report RUNNING) ## Step 3: Manage Your Team -Spawn workers: - agent-relay spawn Worker1 claude "Task description" +Spawn workers (provider is positional, --name/--task are flags): + agent-relay local agent spawn claude --name Worker1 --task "Task description" -Monitor workers (do this frequently): - agent-relay who # List active workers - agent-relay agents:logs Worker1 # View worker output/progress +Register once so all messaging goes through relay: + agent-relay agent register Lead # prints a token + export RELAY_AGENT_TOKEN= -Send targeted DM instructions: - agent-relay send Worker1 "Additional instructions" +Coordinate ENTIRELY through relay (send and read every message here): + agent-relay message dm send Worker1 "Additional instructions" # targeted DM + agent-relay message post general "All workers: prioritize auth" # broadcast + agent-relay message dm list # read a worker's replies + agent-relay message inbox check # unread across conversations -Broadcast to all workers: - agent-relay send '#general' "All workers: prioritize the auth module" - -Read worker replies (DMs are not visible in plain `history`): - agent-relay replies Worker1 # full text, chronological - agent-relay replies Worker1 --json # parseable: text + direction +Check liveness only (lifecycle, not messaging): + agent-relay local agent list # running workers + status Release when done: - agent-relay release Worker1 + agent-relay local agent release Worker1 ## Protocol -- Workers will ACK when they receive tasks -- Workers will send DONE when complete -- Use `agent-relay agents:logs ` to monitor progress -- Use `agent-relay replies ` to read a worker's DM replies (full text, chronological, persistent); add `--json` to parse -- Use `agent-relay history --to ` for the full DM conversation thread (read + unread) -- Use `agent-relay history --to '#general' --json` to see channel message flow -- Do NOT use `agent-relay history` alone to check worker replies — it only shows channel posts, DM replies are invisible there +- Workers ACK when they receive tasks and send DONE when complete — both arrive as relay messages +- Read replies through relay: `agent-relay message inbox check` / `message dm list ` (requires RELAY_AGENT_TOKEN) +- NEVER read worker responses with `agent-relay local tail` — that is broker-direct raw output, not relay messaging (use it only to debug a wedged worker) +- Poll `agent-relay local agent list` for liveness; do all messaging through the `message`/`channel` groups ``` -### Lifecycle Events +## Lifecycle Events -The broker emits these events (available via SDK subscriptions): +The broker emits these events (available via SDK subscriptions and +`agent-relay local tail`): | Event | When | | ------------------------ | --------------------------- | @@ -244,35 +339,41 @@ The broker emits these events (available via SDK subscriptions): | `agent_exited` | Worker process ended | | `agent_permanently_dead` | Worker failed after retries | -### Common Mistakes - -| Mistake | Fix | -| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `agent-relay: command not found` or mise/asdf shim error | Ensure Node is available first (`node --version`); if a shim is broken, fix the runtime manager, then install/use `agent-relay` | -| "Nested session" error | Broker handles this automatically; if running manually, unset `CLAUDECODE` env var | -| Broker not starting | Try `agent-relay down` first, then `agent-relay up --no-dashboard --verbose` and `agent-relay status --wait-for=10` | -| Broker shows STARTING after `status --wait-for` | The process is alive but the broker API is not ready; inspect logs, retry readiness, or restart with `agent-relay down --force` if it remains stuck | -| Broker shows STOPPED immediately after start | Check `ps aux \| grep agent-relay-broker` and `.agent-relay/connection.json`; if the process is alive but status is STOPPED, rerun status from the project root or pass `--state-dir` | -| Worktree verification leaves git status dirty | Run `agent-relay down --force`, then remove generated `.agent-relay/` and `.mcp.json` from throwaway validation worktrees before committing | -| Spawn fails with `internal reply dropped` | Broker likely is not fully ready yet; wait for readiness, then spawn one worker first | -| Workers not connecting | Ensure broker started; check `agent-relay who` and worker logs | -| Not monitoring workers | Use `agent-relay agents:logs ` frequently to track progress | -| Workers seem stuck | Check logs with `agent-relay agents:logs ` for errors | -| Messages not delivered | Check `agent-relay history --to '#general' --json` for channel messages; use `agent-relay replies --json` for DMs | -| Worker replies not showing in history | Expected — plain `history` only shows channel posts. Use `agent-relay replies ` (full text, chronological) or `agent-relay history --to ` (full thread) to read DM replies | -| Need to see unread DM content | `inbox_check` / `inbox --agent` only return counts or clear on read, and the MCP `message_dm_list` tool requires a registered identity you don't have. Use `agent-relay replies --json` | -| Re-reading already-read replies | `agent-relay replies ` is a persistent view (not unread-only); use `--since