agent-relay-runner 0.10.19 → 0.10.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +2 -2
  2. package/plugins/claude/.claude-plugin/plugin.json +4 -1
  3. package/plugins/claude/hooks/hooks.json +114 -0
  4. package/plugins/claude/hooks/permission-request.sh +20 -0
  5. package/plugins/claude/hooks/post-compact.sh +5 -0
  6. package/plugins/claude/hooks/pre-compact.sh +5 -0
  7. package/plugins/claude/hooks/relay-status.sh +66 -0
  8. package/plugins/claude/hooks/session-end.sh +16 -3
  9. package/plugins/claude/hooks/session-start.sh +14 -0
  10. package/plugins/claude/hooks/stop-failure.sh +15 -0
  11. package/plugins/claude/hooks/stop.sh +13 -3
  12. package/plugins/claude/hooks/subagent-start.sh +12 -0
  13. package/plugins/claude/hooks/subagent-stop.sh +12 -0
  14. package/plugins/claude/hooks/user-prompt-submit.sh +2 -3
  15. package/plugins/claude/monitors/relay-monitor.ts +16 -4
  16. package/plugins/claude/skills/react/SKILL.md +18 -0
  17. package/plugins/claude/skills/read-message/SKILL.md +24 -0
  18. package/plugins/claude/skills/reply/SKILL.md +7 -3
  19. package/plugins/codex/skills/guide/SKILL.md +15 -0
  20. package/plugins/codex/skills/react/SKILL.md +17 -0
  21. package/plugins/codex/skills/read-message/SKILL.md +23 -0
  22. package/plugins/codex/skills/reply/SKILL.md +6 -2
  23. package/src/adapter.ts +207 -6
  24. package/src/adapters/claude-delivery.ts +108 -0
  25. package/src/adapters/claude.ts +232 -31
  26. package/src/adapters/codex-client.ts +27 -1
  27. package/src/adapters/codex.ts +635 -26
  28. package/src/attachment-cache.ts +190 -0
  29. package/src/claim-tracker.ts +48 -5
  30. package/src/control-server.ts +193 -6
  31. package/src/index.ts +203 -6
  32. package/src/profile-home.ts +82 -0
  33. package/src/profile-projection.ts +146 -0
  34. package/src/relay-instructions.ts +25 -0
  35. package/src/runner.ts +811 -40
  36. package/src/version.ts +39 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-relay-runner",
3
- "version": "0.10.19",
3
+ "version": "0.10.20",
4
4
  "description": "Unified provider lifecycle runner for Agent Relay",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  "directory": "runner"
21
21
  },
22
22
  "dependencies": {
23
- "agent-relay-sdk": "0.2.0"
23
+ "agent-relay-sdk": "0.2.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/bun": "latest",
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "name": "agent-relay-runner",
3
3
  "description": "Thin Agent Relay runner bridge for Claude Code",
4
- "version": "0.10.19"
4
+ "version": "0.10.20",
5
+ "agentRelayContracts": {
6
+ "providerPluginProtocol": 1
7
+ }
5
8
  }
@@ -0,0 +1,114 @@
1
+ {
2
+ "hooks": {
3
+ "UserPromptSubmit": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit.sh\"",
9
+ "timeout": 5
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "PermissionRequest": [
15
+ {
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/permission-request.sh\"",
20
+ "timeout": 900
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "Stop": [
26
+ {
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop.sh\"",
31
+ "timeout": 5
32
+ }
33
+ ]
34
+ }
35
+ ],
36
+ "StopFailure": [
37
+ {
38
+ "hooks": [
39
+ {
40
+ "type": "command",
41
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop-failure.sh\"",
42
+ "timeout": 5
43
+ }
44
+ ]
45
+ }
46
+ ],
47
+ "SubagentStart": [
48
+ {
49
+ "hooks": [
50
+ {
51
+ "type": "command",
52
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/subagent-start.sh\"",
53
+ "timeout": 5
54
+ }
55
+ ]
56
+ }
57
+ ],
58
+ "SubagentStop": [
59
+ {
60
+ "hooks": [
61
+ {
62
+ "type": "command",
63
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/subagent-stop.sh\"",
64
+ "timeout": 5
65
+ }
66
+ ]
67
+ }
68
+ ],
69
+ "PreCompact": [
70
+ {
71
+ "hooks": [
72
+ {
73
+ "type": "command",
74
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-compact.sh\"",
75
+ "timeout": 5
76
+ }
77
+ ]
78
+ }
79
+ ],
80
+ "PostCompact": [
81
+ {
82
+ "hooks": [
83
+ {
84
+ "type": "command",
85
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-compact.sh\"",
86
+ "timeout": 5
87
+ }
88
+ ]
89
+ }
90
+ ],
91
+ "SessionStart": [
92
+ {
93
+ "hooks": [
94
+ {
95
+ "type": "command",
96
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh\"",
97
+ "timeout": 5
98
+ }
99
+ ]
100
+ }
101
+ ],
102
+ "SessionEnd": [
103
+ {
104
+ "hooks": [
105
+ {
106
+ "type": "command",
107
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-end.sh\"",
108
+ "timeout": 5
109
+ }
110
+ ]
111
+ }
112
+ ]
113
+ }
114
+ }
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ port="${AGENT_RELAY_RUNNER_PORT:-}"
5
+ if [[ -z "$port" ]]; then
6
+ exit 0
7
+ fi
8
+
9
+ payload="$(cat)"
10
+ response="$(
11
+ printf '%s' "$payload" | curl -fsS \
12
+ --max-time 900 \
13
+ -H 'Content-Type: application/json' \
14
+ --data-binary @- \
15
+ "http://127.0.0.1:${port}/permissions/request" 2>/dev/null || true
16
+ )"
17
+
18
+ if [[ -n "$response" ]]; then
19
+ printf '%s\n' "$response"
20
+ fi
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ relay_post_timeline_status idle provider-turn "" compacted
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ relay_post_timeline_status busy provider-turn "" compacting
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env bash
2
+
3
+ relay_post_status() {
4
+ local status="${1:-}"
5
+ local reason="${2:-}"
6
+ local id="${3:-}"
7
+ local label="${4:-}"
8
+ local role="${5:-}"
9
+ local parent_id="${6:-}"
10
+ local clear_kind="${7:-}"
11
+ local timeline_status="${8:-}"
12
+ local port="${AGENT_RELAY_RUNNER_PORT:-}"
13
+ [ -z "$port" ] && return 0
14
+ [ -z "$status" ] && return 0
15
+ local body="{\"status\":\"$(relay_json_escape "$status")\""
16
+ [ -n "${AGENT_RELAY_PROVIDER_SESSION_ID:-}" ] && body="${body},\"providerSessionId\":\"$(relay_json_escape "$AGENT_RELAY_PROVIDER_SESSION_ID")\""
17
+ [ -n "$reason" ] && body="${body},\"reason\":\"$(relay_json_escape "$reason")\""
18
+ [ -n "$clear_kind" ] && body="${body},\"clear\":[\"$(relay_json_escape "$clear_kind")\"]"
19
+ [ -n "$timeline_status" ] && body="${body},\"timeline\":{\"status\":\"$(relay_json_escape "$timeline_status")\"}"
20
+ [ -n "$id" ] && body="${body},\"id\":\"$(relay_json_escape "$id")\""
21
+ [ -n "$label" ] && body="${body},\"label\":\"$(relay_json_escape "$label")\""
22
+ [ -n "$role" ] && body="${body},\"role\":\"$(relay_json_escape "$role")\""
23
+ [ -n "$parent_id" ] && body="${body},\"parentId\":\"$(relay_json_escape "$parent_id")\""
24
+ body="${body}}"
25
+ curl -fsS -X POST "http://127.0.0.1:${port}/status" \
26
+ -H 'Content-Type: application/json' \
27
+ -d "$body" >/dev/null || true
28
+ }
29
+
30
+ relay_post_status_clearing_subagents() {
31
+ relay_post_status "$1" "${2:-}" "${3:-}" "${4:-}" "${5:-}" "${6:-}" subagent
32
+ }
33
+
34
+ relay_post_timeline_status() {
35
+ relay_post_status "$1" "${2:-provider-turn}" "" "" "" "" "${3:-}" "$4"
36
+ }
37
+
38
+ relay_pending_reply_stop_decision() {
39
+ local port="${AGENT_RELAY_RUNNER_PORT:-}"
40
+ [ -z "$port" ] && return 0
41
+ local response
42
+ response="$(curl -fsS "http://127.0.0.1:${port}/reply-obligations/claude-stop" 2>/dev/null || true)"
43
+ case "$response" in
44
+ *'"decision":"block"'*|*'"decision": "block"'*) ;;
45
+ *) return 0 ;;
46
+ esac
47
+ printf '%s' "$response"
48
+ }
49
+
50
+ relay_json_string_field() {
51
+ local field="${1:-}"
52
+ local input="${2:-}"
53
+ [ -z "$field" ] && return 0
54
+ printf '%s' "$input" | sed -nE 's/.*"'"$field"'"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/p' | head -1
55
+ }
56
+
57
+ relay_json_bool_field() {
58
+ local field="${1:-}"
59
+ local input="${2:-}"
60
+ [ -z "$field" ] && return 0
61
+ printf '%s' "$input" | sed -nE 's/.*"'"$field"'"[[:space:]]*:[[:space:]]*(true|false).*/\1/p' | head -1
62
+ }
63
+
64
+ relay_json_escape() {
65
+ printf '%s' "${1:-}" | sed 's/\\/\\\\/g; s/"/\\"/g'
66
+ }
@@ -1,5 +1,18 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
- port="${AGENT_RELAY_RUNNER_PORT:-}"
4
- [ -z "$port" ] && exit 0
5
- curl -fsS -X POST "http://127.0.0.1:${port}/status" -H 'Content-Type: application/json' -d '{"status":"offline"}' >/dev/null || true
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ payload="$(cat || true)"
6
+ reason="$(relay_json_string_field reason "$payload")"
7
+
8
+ case "$reason" in
9
+ clear)
10
+ relay_post_timeline_status idle provider-turn subagent clearing-context
11
+ ;;
12
+ resume)
13
+ relay_post_status_clearing_subagents idle
14
+ ;;
15
+ logout|prompt_input_exit|bypass_permissions_disabled|other|*)
16
+ relay_post_status_clearing_subagents offline
17
+ ;;
18
+ esac
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ payload="$(cat || true)"
6
+ source_kind="$(relay_json_string_field source "$payload")"
7
+
8
+ case "$source_kind" in
9
+ clear)
10
+ relay_post_timeline_status idle provider-turn subagent context-cleared
11
+ ;;
12
+ *)
13
+ ;;
14
+ esac
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ payload="$(cat || true)"
6
+ error="$(relay_json_string_field error "$payload")"
7
+
8
+ case "$error" in
9
+ authentication_failed|oauth_org_not_allowed|billing_error|model_not_found)
10
+ relay_post_status_clearing_subagents error
11
+ ;;
12
+ *)
13
+ relay_post_status_clearing_subagents idle
14
+ ;;
15
+ esac
@@ -1,5 +1,15 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
- port="${AGENT_RELAY_RUNNER_PORT:-}"
4
- [ -z "$port" ] && exit 0
5
- curl -fsS -X POST "http://127.0.0.1:${port}/status" -H 'Content-Type: application/json' -d '{"status":"idle"}' >/dev/null || true
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+
5
+ payload="$(cat || true)"
6
+ stop_hook_active="$(relay_json_bool_field stop_hook_active "$payload")"
7
+ if [ "$stop_hook_active" != "true" ]; then
8
+ stop_decision="$(relay_pending_reply_stop_decision)"
9
+ if [ -n "$stop_decision" ]; then
10
+ printf '%s\n' "$stop_decision"
11
+ exit 0
12
+ fi
13
+ fi
14
+
15
+ relay_post_status_clearing_subagents idle
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
5
+ # shellcheck source=/dev/null
6
+ source "${PLUGIN_ROOT}/hooks/relay-status.sh"
7
+
8
+ payload="$(cat || true)"
9
+ agent_id="$(relay_json_string_field agent_id "$payload")"
10
+ agent_type="$(relay_json_string_field agent_type "$payload")"
11
+
12
+ relay_post_status busy subagent "${agent_id:-subagent}" "$agent_type" "$agent_type"
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
5
+ # shellcheck source=/dev/null
6
+ source "${PLUGIN_ROOT}/hooks/relay-status.sh"
7
+
8
+ payload="$(cat || true)"
9
+ agent_id="$(relay_json_string_field agent_id "$payload")"
10
+ agent_type="$(relay_json_string_field agent_type "$payload")"
11
+
12
+ relay_post_status idle subagent "${agent_id:-subagent}" "$agent_type" "$agent_type"
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
- port="${AGENT_RELAY_RUNNER_PORT:-}"
4
- [ -z "$port" ] && exit 0
5
- curl -fsS -X POST "http://127.0.0.1:${port}/status" -H 'Content-Type: application/json' -d '{"status":"busy"}' >/dev/null || true
3
+ source "${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/hooks/relay-status.sh"
4
+ relay_post_status busy
@@ -1,16 +1,28 @@
1
+ import type { Message } from "agent-relay-sdk";
2
+ import { claudeProviderMessageText } from "../../../src/adapters/claude-delivery";
3
+ import { CLAUDE_READ_ONLY_RELAY_CONTEXT, CLAUDE_RELAY_CONTEXT } from "../../../src/relay-instructions";
4
+
1
5
  const port = process.env.AGENT_RELAY_RUNNER_PORT;
2
6
  if (!port) process.exit(0);
3
7
 
8
+ let firstDelivery = true;
9
+ let deliveryCount = 0;
4
10
  const ws = new WebSocket(`ws://127.0.0.1:${port}/monitor`);
5
11
 
6
12
  ws.onmessage = (event) => {
7
13
  const payload = parsePayload(String(event.data));
8
14
  if (!payload || payload.type !== "message.deliver" || !Array.isArray(payload.messages)) return;
9
- const messages = payload.messages as Array<{ id: number; from: string; subject?: string; body: string }>;
10
- for (const message of messages) {
11
- const subject = message.subject ? `\nSubject: ${message.subject}` : "";
12
- console.log(`Relay message #${message.id} from ${message.from}${subject}\n${message.body}`);
15
+ const messages = payload.messages as Message[];
16
+ deliveryCount += 1;
17
+ if (firstDelivery) {
18
+ console.log(process.env.AGENT_RELAY_APPROVAL === "read-only" ? CLAUDE_READ_ONLY_RELAY_CONTEXT : CLAUDE_RELAY_CONTEXT);
19
+ console.log("");
20
+ firstDelivery = false;
13
21
  }
22
+ console.log(claudeProviderMessageText(messages, {
23
+ deliveryCount,
24
+ readOnly: process.env.AGENT_RELAY_APPROVAL === "read-only",
25
+ }));
14
26
  ws.send(JSON.stringify({
15
27
  type: "message.delivered",
16
28
  deliveryId: typeof payload.deliveryId === "string" ? payload.deliveryId : "",
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: react
3
+ description: Add or remove an Agent Relay reaction on a message. Use for lightweight acknowledgement, approval, thanks, or good-job responses when no text reply is needed.
4
+ argument-hint: "<messageId> <emoji> [--remove]"
5
+ allowed-tools: [Bash]
6
+ ---
7
+
8
+ # Agent Relay React
9
+
10
+ Run:
11
+
12
+ ```bash
13
+ agent-relay /react $ARGUMENTS
14
+ ```
15
+
16
+ Use reactions instead of text when the message only needs lightweight acknowledgement, approval, thanks, or "good job".
17
+
18
+ Do not use reactions when the sender asked a question, gave a new task, reported a bug, or needs a result in text.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: read-message
3
+ description: Fetch a full Agent Relay message by ID, including full body, attachments, metadata, and thread context. Use when a delivered Relay preview is truncated or when the user asks to inspect a relay message.
4
+ argument-hint: "<messageId> [--json|--body]"
5
+ allowed-tools: [Bash]
6
+ ---
7
+
8
+ # Agent Relay Read Message
9
+
10
+ Run:
11
+
12
+ ```bash
13
+ agent-relay get-message $ARGUMENTS
14
+ ```
15
+
16
+ Useful forms:
17
+
18
+ ```bash
19
+ agent-relay get-message 206
20
+ agent-relay get-message 206 --json
21
+ agent-relay get-message 206 --body
22
+ ```
23
+
24
+ Use `--body` when you only need the complete message text. Use `--json` when attachments, metadata, or thread context matter.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: reply
3
- description: Reply to an Agent Relay message by ID. Auto-routes to the sender and inherits channel context — no target needed. Use when the user invokes /reply or asks to reply to a specific relay message.
4
- argument-hint: "<messageId> <message>"
3
+ description: Reply to an Agent Relay message by ID. Auto-routes to the sender and inherits channel context — no target needed. Use when the user invokes /reply or asks to reply to a specific relay message, especially with stdin/file for long replies.
4
+ argument-hint: "<messageId> <message|--stdin|--body-file PATH>"
5
5
  allowed-tools: [Bash]
6
6
  ---
7
7
 
@@ -20,6 +20,10 @@ Examples:
20
20
  ```bash
21
21
  agent-relay /reply 206 "Sounds good, I'll take a look"
22
22
  agent-relay /reply 42 "Done — the fix is in commit abc123"
23
+ agent-relay /reply 42 --stdin < response.md
24
+ agent-relay /reply 42 --body-file response.md
23
25
  ```
24
26
 
25
- Report the sent message id and resolved target briefly.
27
+ Use `--stdin` or `--body-file` for long replies so shell quoting does not mangle the body. Oversized replies are automatically uploaded as an Agent Relay artifact and sent as an attached concise reply.
28
+
29
+ Do not send a separate Relay follow-up that only confirms the reply was sent. The CLI output is enough local confirmation.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: guide
3
+ description: Show the Agent Relay command guide for coding agents. Use when the user invokes /guide or asks how to use Agent Relay messaging, replies, pair sessions, labels, tags, targets, or claimable work.
4
+ argument-hint: ""
5
+ ---
6
+
7
+ # Agent Relay Guide
8
+
9
+ Run:
10
+
11
+ ```bash
12
+ agent-relay /guide
13
+ ```
14
+
15
+ Use this before guessing Relay commands. The guide explains reply, message, pair, status, label, tag, target, and claimable-work commands.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: react
3
+ description: Add or remove an Agent Relay reaction on a message. Use for lightweight acknowledgement, approval, thanks, or good-job responses when no text reply is needed.
4
+ argument-hint: "<messageId> <emoji> [--remove]"
5
+ ---
6
+
7
+ # Agent Relay React
8
+
9
+ Run:
10
+
11
+ ```bash
12
+ agent-relay /react $ARGUMENTS
13
+ ```
14
+
15
+ Use reactions instead of text when the message only needs lightweight acknowledgement, approval, thanks, or "good job".
16
+
17
+ Do not use reactions when the sender asked a question, gave a new task, reported a bug, or needs a result in text.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: read-message
3
+ description: Fetch a full Agent Relay message by ID, including full body, attachments, metadata, and thread context. Use when a delivered Relay preview is truncated or when the user asks to inspect a relay message.
4
+ argument-hint: "<messageId> [--json|--body]"
5
+ ---
6
+
7
+ # Agent Relay Read Message
8
+
9
+ Run:
10
+
11
+ ```bash
12
+ agent-relay get-message $ARGUMENTS
13
+ ```
14
+
15
+ Useful forms:
16
+
17
+ ```bash
18
+ agent-relay get-message 206
19
+ agent-relay get-message 206 --json
20
+ agent-relay get-message 206 --body
21
+ ```
22
+
23
+ Use `--body` when you only need the complete message text. Use `--json` when attachments, metadata, or thread context matter.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: reply
3
- description: Reply to an Agent Relay message by ID. Auto-routes to the sender and inherits channel context, so no target is needed. Use when the user invokes /reply or asks to reply to a specific relay message.
4
- argument-hint: "<messageId> <message>"
3
+ description: Reply to an Agent Relay message by ID. Auto-routes to the sender and inherits channel context, so no target is needed. Use when the user invokes /reply or asks to reply to a specific relay message, especially with stdin/file for long replies.
4
+ argument-hint: "<messageId> <message|--stdin|--body-file PATH>"
5
5
  ---
6
6
 
7
7
  # Agent Relay Reply
@@ -19,6 +19,10 @@ Examples:
19
19
  ```bash
20
20
  agent-relay /reply 206 "Sounds good, I'll take a look"
21
21
  agent-relay /reply 42 "Done; the fix is in commit abc123"
22
+ agent-relay /reply 42 --stdin < response.md
23
+ agent-relay /reply 42 --body-file response.md
22
24
  ```
23
25
 
26
+ Use `--stdin` or `--body-file` for long replies so shell quoting does not mangle the body. Oversized replies are automatically uploaded as an Agent Relay artifact and sent as an attached concise reply.
27
+
24
28
  Report the sent message id and resolved target briefly.