agent-relay-plugin 0.4.39 → 0.6.1

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "agent-relay",
3
3
  "description": "Client connector for Agent Relay — auto-registers Claude Code sessions as agents and enables inter-agent messaging via a lightweight HTTP message bus",
4
- "version": "0.4.39"
4
+ "version": "0.6.1"
5
5
  }
@@ -26,6 +26,7 @@ fi
26
26
  pid_file="/tmp/agent-relay-poll-${AGENT_ID}.pid"
27
27
  status_file="/tmp/agent-relay-status-${AGENT_ID}.state"
28
28
  delivered_file="/tmp/agent-relay-delivered-${AGENT_ID}.queue"
29
+ cursor_file="/tmp/agent-relay-cursor-${AGENT_ID}.state"
29
30
  project=$(basename "${PWD:-unknown}")
30
31
  if [ -n "$CLAUDE_RIG_NAME" ]; then rig="$CLAUDE_RIG_NAME"
31
32
  elif [ -n "$CLAUDE_CONFIG_DIR" ]; then rig=$(basename "$CLAUDE_CONFIG_DIR")
@@ -44,6 +45,19 @@ fetch_cursor() {
44
45
  esac
45
46
  }
46
47
 
48
+ read_saved_cursor() {
49
+ local cursor
50
+ cursor=$(head -1 "$cursor_file" 2>/dev/null || true)
51
+ case "$cursor" in
52
+ ''|*[!0-9]*) return 1 ;;
53
+ *) printf '%s\n' "$cursor" ;;
54
+ esac
55
+ }
56
+
57
+ save_cursor() {
58
+ printf '%s\n' "$1" > "$cursor_file"
59
+ }
60
+
47
61
  current_status() {
48
62
  local status
49
63
  status=$(head -1 "$status_file" 2>/dev/null || true)
@@ -107,8 +121,10 @@ set_status() {
107
121
  -H 'Content-Type: application/json' -d "{\"status\":\"$1\"}" 2>/dev/null
108
122
  }
109
123
 
110
- # Bootstrap cursor at current max so we only see messages arriving after session start.
111
- since_id=$(fetch_cursor || echo 0)
124
+ # First start bootstraps at current max; restarted monitors resume their saved
125
+ # cursor so messages that arrived during downtime are still delivered.
126
+ since_id=$(read_saved_cursor || fetch_cursor || echo 0)
127
+ save_cursor "$since_id"
112
128
 
113
129
  fail_streak=0
114
130
  marked_ready=false
@@ -132,12 +148,8 @@ while true; do
132
148
  # Agent was pruned — re-register instead of exiting.
133
149
  if [ "$hb_code" = "404" ]; then
134
150
  if re_register; then
135
- if since_id=$(fetch_cursor); then
136
- marked_ready=false
137
- hb_code="200"
138
- else
139
- hb_code="000"
140
- fi
151
+ marked_ready=false
152
+ hb_code="200"
141
153
  else
142
154
  hb_code="000"
143
155
  fi
@@ -194,7 +206,7 @@ while true; do
194
206
  fi
195
207
  fi
196
208
 
197
- if ! line=$(printf '%s' "$msg" | jq -r '(.meta.pairId // "") as $pair | (if $pair != "" then " [pair:\($pair)]" else "" end) as $pairText | (.body | gsub("\r"; "\\r") | gsub("\n"; "\\n")) as $body | if .type == "system" then "⚠ SYSTEM [msg:\(.id)]\($pairText): \($body)" else "[msg:\(.id)]\($pairText) \(.from) → \(.to) | \(.subject // "(no subject)"): \($body)" end') || [ -z "$line" ]; then
209
+ if ! line=$(printf '%s' "$msg" | jq -r '(.payload.pairId // "") as $pair | (if $pair != "" then " [pair:\($pair)]" else "" end) as $pairText | (.body | gsub("\r"; "\\r") | gsub("\n"; "\\n")) as $body | if .kind == "system" or .kind == "control" then "⚠ SYSTEM [msg:\(.id)]\($pairText): \($body)" else "[msg:\(.id)]\($pairText) \(.from) → \(.to) | \(.subject // "(no subject)"): \($body)" end') || [ -z "$line" ]; then
198
210
  echo "warn: failed to format relay message ${mid}" >&2
199
211
  delivery_failed=true
200
212
  continue
@@ -207,6 +219,7 @@ while true; do
207
219
  done < <(echo "$msgs" | jq -c '.[]')
208
220
  if [ "$delivery_failed" = "false" ]; then
209
221
  since_id=$(echo "$msgs" | jq '[.[].id] | max')
222
+ save_cursor "$since_id"
210
223
  fi
211
224
  fi
212
225
 
@@ -38,6 +38,7 @@ fi
38
38
  ar_init_profile "claude" "$rig" "$project"
39
39
 
40
40
  session_key="${CLAUDE_CODE_SESSION_ID:-$PPID}"
41
+ safe_session_key=$(printf '%s' "$session_key" | sed 's/[^A-Za-z0-9_.:-]/_/g')
41
42
  if command -v shasum >/dev/null 2>&1; then
42
43
  short_pid=$(printf '%s' "$session_key" | shasum -a 1 | head -c 6)
43
44
  elif command -v sha1sum >/dev/null 2>&1; then
@@ -66,6 +67,25 @@ if [ -f "$instance_state" ]; then
66
67
  fi
67
68
  printf '%s\n' "$agent_id" > "$instance_state"
68
69
 
70
+ context_dir="${HOME:-/tmp}/.agent-relay/contexts"
71
+ context_path="${context_dir}/${safe_session_key}.json"
72
+ mkdir -p "$context_dir" 2>/dev/null || true
73
+ jq -n \
74
+ --arg agentId "$agent_id" \
75
+ --arg relayUrl "$RELAY_URL" \
76
+ --arg cwd "${PWD:-}" \
77
+ --arg session "$session_key" \
78
+ --arg updatedAt "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
79
+ '{
80
+ version: 1,
81
+ agentId: $agentId,
82
+ provider: "claude",
83
+ relayUrl: $relayUrl,
84
+ cwd: $cwd,
85
+ matchEnv: [{name: "CLAUDE_CODE_SESSION_ID", value: $session}],
86
+ updatedAt: $updatedAt
87
+ }' > "$context_path" 2>/dev/null || true
88
+
69
89
  reg_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "${RELAY_URL}/api/agents" "${auth_header_args[@]}" \
70
90
  -H 'Content-Type: application/json' \
71
91
  -d "$(jq -n \
@@ -88,7 +108,7 @@ fi
88
108
  server_version=$(curl -s "${auth_header_args[@]}" "${RELAY_URL}/api/stats" 2>/dev/null | jq -r '.version // empty' 2>/dev/null)
89
109
  version_warning=""
90
110
  if [ -z "$server_version" ]; then
91
- version_warning="⚠ Server does not report its version — consider updating: bunx agent-relay-server@latest"
111
+ version_warning="⚠ Server does not report its version — consider updating: agent-relay upgrade"
92
112
  elif [ "$PLUGIN_VERSION" = "unknown" ]; then
93
113
  version_warning="⚠ Version mismatch — server ${server_version}, plugin unknown. Restart Claude Code or update the Agent Relay plugin."
94
114
  elif [ "$server_version" != "$PLUGIN_VERSION" ]; then
@@ -128,7 +148,7 @@ To reply to a message (threading):
128
148
  Anti-loop rule: do not auto-reply to pure acknowledgements, "thanks", or "received" messages; acknowledge once, then only send follow-ups when there is new work, a decision, or a deliverable.
129
149
 
130
150
  To send a claimable task (only one agent can claim it):
131
- curl -s -X POST ${RELAY_URL}/api/messages${auth_header_example} -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"cap:review","body":"TASK","claimable":true}'
151
+ curl -s -X POST ${RELAY_URL}/api/messages${auth_header_example} -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"cap:review","kind":"task","body":"TASK","claimable":true,"payload":{"title":"TASK"}}'
132
152
 
133
153
  To claim a task:
134
154
  curl -s -X POST ${RELAY_URL}/api/messages/MSG_ID/claim${auth_header_example} -H 'Content-Type: application/json' -d '{"agentId":"${agent_id}"}'
@@ -20,6 +20,8 @@ if [ -z "$session_key" ]; then
20
20
  exit 0
21
21
  fi
22
22
  instance_state="/tmp/agent-relay-instance-${session_key}.state"
23
+ safe_session_key=$(printf '%s' "$session_key" | sed 's/[^A-Za-z0-9_.:-]/_/g')
24
+ context_path="${HOME:-/tmp}/.agent-relay/contexts/${safe_session_key}.json"
23
25
 
24
26
  if [ -f "$instance_state" ]; then
25
27
  agent_id=$(head -1 "$instance_state" 2>/dev/null)
@@ -40,6 +42,7 @@ if [ -n "${agent_id:-}" ]; then
40
42
  -d '{"status":"offline"}' \
41
43
  > /dev/null 2>&1 &
42
44
  [ -n "$instance_state" ] && [ -f "$instance_state" ] && rm -f "$instance_state"
45
+ [ -f "$context_path" ] && rm -f "$context_path"
43
46
  fi
44
47
 
45
48
  exit 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-relay-plugin",
3
- "version": "0.4.39",
3
+ "version": "0.6.1",
4
4
  "description": "Claude Code plugin for Agent Relay — auto-registers sessions as agents and enables inter-agent messaging",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",