agent-relay-server 0.4.12 → 0.4.14

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.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Agent Relay
2
2
 
3
3
  [![npm: server](https://img.shields.io/npm/v/agent-relay-server?label=server&color=blue)](https://www.npmjs.com/package/agent-relay-server)
4
- [![npm: plugin](https://img.shields.io/npm/v/agent-relay-plugin?label=plugin&color=blue)](https://www.npmjs.com/package/agent-relay-plugin)
4
+ [![npm: plugin](https://img.shields.io/npm/v/agent-relay-plugin?label=claude&color=blue)](https://www.npmjs.com/package/agent-relay-plugin)
5
+ [![npm: codex](https://img.shields.io/npm/v/agent-relay-codex?label=codex&color=blue)](https://www.npmjs.com/package/agent-relay-codex)
6
+ [![npm: client](https://img.shields.io/npm/v/agent-relay-client?label=client&color=blue)](https://www.npmjs.com/package/agent-relay-client)
5
7
  [![License: AGPL-3.0-or-later](https://img.shields.io/badge/license-AGPL--3.0--or--later-green)](LICENSE)
6
8
 
7
9
  A lightweight HTTP message bus that lets AI coding agents talk to each other across sessions, projects, and machines.
8
10
 
9
- Built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code), but the relay server is a plain HTTP API that any agent or script can use.
10
-
11
11
  ![Agent Relay Dashboard](https://raw.githubusercontent.com/edimuj/agent-relay/main/docs/dashboard.png)
12
12
 
13
13
  ## Why
@@ -23,125 +23,22 @@ You're running three Claude Code sessions: one debugging a backend, another writ
23
23
  - **Closed-loop tasks**: external systems can create deduped work items agents
24
24
  claim, progress, resolve, and report back through callbacks
25
25
 
26
- ## Mental Model
27
-
28
- Agent Relay is a small trusted-network message bus. Agents register themselves,
29
- the relay stores their presence and messages in SQLite, and clients route work
30
- by id, label, tag, capability, channel, or claimable task.
31
-
32
- ```mermaid
33
- flowchart LR
34
- subgraph Agents["Claude / Codex Sessions"]
35
- A1["Agent registers"]
36
- A2["Polls / SSE / sidecar"]
37
- A3["Replies"]
38
- A4["Claims work"]
39
- end
40
-
41
- subgraph Relay["Agent Relay"]
42
- R1["Agents table"]
43
- R2["Messages"]
44
- R3["Threads"]
45
- R4["Tasks"]
46
- R5["Events & callbacks"]
47
- end
48
-
49
- subgraph Tools["External Tools"]
50
- T1["Scripts"]
51
- T2["CI"]
52
- T3["Monitoring"]
53
- T4["Support desks"]
54
- end
55
-
56
- A1 -- "POST /api/agents" --> R1
57
- A2 <-- "notifications / polling" --> R2
58
- A3 -- "POST /api/messages" --> R3
59
- A4 -- "POST claim" --> R4
60
- T1 -- "integration event" --> R4
61
- T2 -- "integration event" --> R4
62
- T3 -- "alerts" --> R4
63
- T4 -- "tickets" --> R4
64
- R4 -- "task lifecycle" --> R5
65
- ```
66
-
67
- The relay does not decide what an agent should do. It gives agents a shared
68
- address book, inbox, task queue, and dashboard.
26
+ ## How It Works
69
27
 
70
- ### Agent Identity
71
-
72
- Every running Claude or Codex session registers as an agent. The generated agent
73
- id is the stable address for that session:
74
-
75
- ```text
76
- macmini2-codex-live-agent-relay-019f4c2a
77
28
  ```
78
-
79
- Treat ids as machine-friendly session addresses. For human workflows, use
80
- labels, tags, and capabilities:
81
-
82
- | Field | Example | Use it for | Target syntax |
83
- |-------|---------|------------|---------------|
84
- | `id` | `macmini2-codex-live-agent-relay-019f4c2a` | One exact running session | `macmini2-codex-live-agent-relay-019f4c2a` |
85
- | `label` | `backend fixer` | A human-friendly name you can change from the dashboard | `label:backend fixer` |
86
- | `tag` | `backend`, `macmini2`, `release` | Grouping sessions by project, machine, role, or temporary work | `tag:backend` |
87
- | `capability` | `review`, `ops`, `support` | Routing work to agents that can do a kind of job | `cap:review` |
88
- | `channel` | `alerts`, `support`, `deploy` | Scoping message/task streams so unrelated agents ignore noise | `channel=alerts` |
89
-
90
- Labels are for people. Tags are for grouping. Capabilities are for routing work.
91
- When in doubt, route tasks by capability and use tags/channels to narrow the
92
- audience.
93
-
94
- ### Routing Examples
95
-
96
- ```json
97
- { "to": "macmini2-codex-live-agent-relay-019f4c2a", "body": "Can you check this branch?" }
29
+ ┌──────────────────┐ ┌──────────────────┐
30
+ │ Claude Code │ ┌────────┐ │ Scripts / CI │
31
+ │ Codex │◄───────►│ Relay │◄───────►│ Monitoring │
32
+ │ Any HTTP client │ HTTP │ Server │ HTTP │ Support desks │
33
+ └──────────────────┘ └────────┘ └──────────────────┘
98
34
  ```
99
35
 
100
- Direct messages go to one exact session.
101
-
102
- ```json
103
- { "to": "tag:backend", "body": "Who owns the migration failure?" }
104
- ```
105
-
106
- Tags fan out to every matching agent.
107
-
108
- ```json
109
- { "to": "cap:review", "claimable": true, "body": "Review PR #42" }
110
- ```
111
-
112
- Claimable capability-routed messages act like a tiny work queue: many agents may
113
- see the work, but one agent claims it before acting.
114
-
115
- ```json
116
- {
117
- "target": "cap:ops",
118
- "channel": "alerts",
119
- "dedupeKey": "prod-api:5xx-rate",
120
- "title": "prod-api 5xx rate high"
121
- }
122
- ```
123
-
124
- Integration events create durable tasks. The dedupe key prevents alert storms
125
- from spamming agents with duplicate work.
126
-
127
- ### Message And Task Lifecycle
128
-
129
- Messages and tasks are persisted in SQLite, so server restarts do not erase the
130
- inbox. Agents reconnect, heartbeat, and resume polling from the latest known
131
- message cursor.
36
+ Agent Relay has two parts:
132
37
 
133
- | Concept | What it means |
134
- |---------|---------------|
135
- | Claimable task | A message or integration task that exactly one agent should own. Agents claim it atomically before acting, so duplicate workers do not race on the same work. |
136
- | Read state | Read markers are stored per agent. One agent reading a message does not hide it from another matching agent. |
137
- | Threading | Replies set `replyTo`; the relay keeps the thread chain so the dashboard/API can show the conversation instead of isolated messages. |
138
- | Restart | The server reloads agents, messages, tasks, events, callbacks, and read markers from SQLite. Connected clients reconnect through polling/SSE/sidecars. |
139
- | Offline agents | Agents that stop heartbeating become `offline` after `STALE_TTL_MS`. Their claimed but unfinished work is released so another agent can pick it up. |
140
- | Pruning | Old messages are removed after `RETENTION_DAYS`. Long-offline agents are removed after `OFFLINE_PRUNE_MS`. Built-in/system agents are kept. |
38
+ 1. **The relay server** - a single Bun process with SQLite. Stores agents, messages, tasks, and presence. Exposes a plain HTTP API and a live dashboard.
39
+ 2. **A provider integration** - a plugin or sidecar that auto-registers your AI session as an agent, delivers incoming messages, and manages lifecycle (heartbeat, status, offline cleanup).
141
40
 
142
- For task-like work, prefer `claimable: true` or integration tasks over plain
143
- broadcasts. For long-running work, update task status/progress so humans and
144
- tools can see whether it is claimed, blocked, done, failed, or canceled.
41
+ Pick your provider: install the Claude Code plugin, the Codex connector, or both. The shared config is the same four env vars either way. See the [full mental model](docs/mental-model.md) for routing, identity, and task lifecycle details, or the [provider spec](docs/provider-spec.md) if you want to build your own integration.
145
42
 
146
43
  ## Quick Start
147
44
 
@@ -154,209 +51,76 @@ bunx agent-relay-server@latest
154
51
 
155
52
  Dashboard at `http://localhost:4850`.
156
53
 
157
- Localhost is intentionally frictionless. If you bind the relay to a non-loopback
158
- address, set `AGENT_RELAY_TOKEN` first:
54
+ ### 2. Connect your agents
159
55
 
160
- ```bash
161
- AGENT_RELAY_TOKEN="$(openssl rand -hex 24)" HOST=0.0.0.0 bunx agent-relay-server@latest
162
- ```
163
-
164
- For an always-on local relay, use the setup + daemon commands instead:
165
-
166
- ```bash
167
- bun install -g agent-relay-server@latest
168
- agent-relay setup --yes
169
- agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
170
- ```
171
-
172
- `setup` creates a managed env file with a generated token, loopback bind, and a
173
- durable SQLite path. `daemon install` auto-detects systemd user services on
174
- Linux and LaunchAgents on macOS.
175
-
176
- ### 2. Install the Claude Code plugin
177
-
178
- Requires **Claude Code 2.1.105+** (native plugin monitors).
56
+ **Claude Code** (requires 2.1.105+):
179
57
 
180
58
  ```bash
181
59
  claude plugin marketplace add edimuj/agent-relay
182
60
  claude plugin install agent-relay@agent-relay
183
61
  ```
184
62
 
185
- ### 3. Done. It's autonomous
186
-
187
- There is no step 3. The plugin activates itself: it registers the session as an agent, starts monitoring for messages, and injects messaging capabilities. No user interaction required.
188
-
189
- Open a second Claude Code session and say:
190
-
191
- > "Send a message to the other agent: hey, what are you working on?"
192
-
193
- ## Codex Quick Start
194
-
195
- Codex live support uses the same relay server plus:
196
-
197
- - `codex-relay` launcher
198
- - a `SessionStart` hook
199
- - the live sidecar (`codex/live-sidecar.ts`)
200
-
201
- The installer also adds a Codex plugin skill bundle. That plugin is optional:
202
- it adds in-session guidance, but live agent registration and incoming-message
203
- delivery are handled by the hook + sidecar path.
63
+ **Codex** (requires Bun + Codex CLI):
204
64
 
205
65
  ```bash
206
- # terminal 1: central relay server
207
- bunx agent-relay-server@latest
208
-
209
- # one-time installer
210
- curl -fsSL https://unpkg.com/agent-relay-server@latest/codex/install-codex.sh | bash
211
-
212
- # start Codex with live Agent Relay support after restarting your shell
66
+ curl -fsSL https://unpkg.com/agent-relay-codex@latest/install-codex.sh | bash
67
+ # restart your shell, then:
213
68
  codex-relay
214
69
  ```
215
70
 
216
- `codex-relay` launches `codex app-server`, opens Codex through
217
- `codex --remote`, registers the session as an Agent Relay agent, injects
218
- incoming messages as live turns, and cleans up sidecar processes when Codex
219
- exits.
220
-
221
- The normal hook path attaches to the Codex thread that was just launched. If the
222
- launcher has to use its fallback sidecar because the hook did not report in
223
- time, it starts a new thread by default to avoid surprising cwd-based attachment
224
- to an unrelated loaded session. Use `codex-relay --thread-mode auto` or
225
- `AGENT_RELAY_CODEX_FALLBACK_THREAD_MODE=auto` when you deliberately want the
226
- fallback sidecar to attach to the newest loaded thread for the current cwd.
227
- The lower-level sidecar also defaults to `CODEX_THREAD_MODE=start`; `auto` is an
228
- explicit opt-in because it may deliver relay messages into an already-open Codex
229
- session for the same directory.
230
-
231
- ### Codex approval mode
232
-
233
- Replying to relay messages is usually done with a shell command (`curl` to
234
- `/api/messages`), so Codex may prompt for approval in stricter modes.
235
-
236
- By default, `codex-relay` starts Codex with `--ask-for-approval never --sandbox
237
- workspace-write` so relay replies do not get stuck on approval prompts while
238
- still keeping Codex inside workspace boundaries. If you pass an explicit Codex
239
- runtime mode, `codex-relay`
240
- leaves it alone and forwards it to the sidecar, including `--ask-for-approval`,
241
- `--sandbox`, `--full-auto`, and `--yolo`.
242
-
243
- Useful setups:
244
-
245
- ```bash
246
- # default: no approval prompts, workspace sandbox
247
- codex-relay
248
- ```
249
-
250
- ```bash
251
- # no approval prompts, still sandboxed to workspace boundaries
252
- codex-relay -- --ask-for-approval never --sandbox workspace-write
253
- ```
254
-
255
- ```bash
256
- # trusted private rig only: no approval prompts, no Codex sandbox
257
- codex-relay -- --dangerously-bypass-approvals-and-sandbox
258
- ```
259
-
260
- ```python
261
- # ~/.codex/rules/default.rules
262
- # allow only relay message sends without repeated prompts
263
- prefix_rule(
264
- pattern = ["curl", "-sS", "-X", "POST", "http://127.0.0.1:4850/api/messages"],
265
- decision = "allow",
266
- justification = "Allow local Agent Relay message posts",
267
- )
268
- ```
71
+ Windows: `irm https://unpkg.com/agent-relay-codex@latest/install-codex.ps1 | iex`
269
72
 
270
- Use a remote relay server by setting:
271
-
272
- ```bash
273
- export AGENT_RELAY_URL=http://100.x.y.z:4850
274
- export AGENT_RELAY_TOKEN=your-shared-token
275
- bunx -p agent-relay-server@latest codex-relay
276
- ```
277
-
278
- If you install the package globally, the shorter command works too:
279
-
280
- ```bash
281
- bun install -g agent-relay-server@latest
282
- codex-relay
283
- ```
73
+ ### 3. Done. It's autonomous
284
74
 
285
- On Windows PowerShell:
75
+ There is no step 3. Both integrations activate themselves: register the session as an agent, start monitoring for messages, and inject messaging capabilities. No user interaction required.
286
76
 
287
- ```powershell
288
- irm https://unpkg.com/agent-relay-server@latest/codex/install-codex.ps1 | iex
289
- codex-relay
290
- ```
77
+ Open a second session and say:
291
78
 
292
- The installer always adds `codex-relay` and asks whether plain `codex` should
293
- also route through Agent Relay. If you opt out, `codex` stays unchanged.
294
- Without restarting your shell first, use:
79
+ > "Send a message to the other agent: hey, what are you working on?"
295
80
 
296
- ```bash
297
- bunx -p agent-relay-server@latest codex-relay
298
- ```
81
+ **Going multi-machine?** Set `AGENT_RELAY_TOKEN` on the server and export it on each client machine. The dashboard asks for the token on first load. See [Deployment](#deployment) for details.
299
82
 
300
- Non-interactive alias opt-in:
83
+ ## Configuration
301
84
 
302
- ```bash
303
- curl -fsSL https://unpkg.com/agent-relay-server@latest/codex/install-codex.sh | bash -s -- --alias
304
- ```
85
+ Both integrations share the same four env vars:
305
86
 
306
- ```powershell
307
- $env:AGENT_RELAY_CODEX_ALIAS = "1"; irm https://unpkg.com/agent-relay-server@latest/codex/install-codex.ps1 | iex
308
- ```
309
-
310
- Uninstall Codex support:
311
-
312
- ```bash
313
- agent-relay-codex uninstall
314
- ```
87
+ | Env var | Default | Purpose |
88
+ |---------|---------|---------|
89
+ | `AGENT_RELAY_URL` | `http://localhost:4850` | Relay server URL |
90
+ | `AGENT_RELAY_TOKEN` | unset | Auth token (required for remote relays) |
91
+ | `AGENT_RELAY_CAPS` | `chat` | Comma-separated agent capabilities |
92
+ | `AGENT_RELAY_APPROVAL` | `open` | Approval mode: `open`, `guarded`, `read-only` |
315
93
 
316
- This removes the Codex SessionStart hook, local plugin marketplace files, and
317
- launcher shims. It leaves shell profile PATH edits and runtime logs in place.
94
+ Codex has additional tuning vars documented in [codex/README.md](codex/README.md).
318
95
 
319
- Full managed cleanup:
96
+ Agent IDs are deterministic: `{hostname}-{rig}-{project}-{session-hash}`.
320
97
 
321
- ```bash
322
- agent-relay-codex uninstall --purge
323
- ```
98
+ ## Message Targeting
324
99
 
325
- Purge also removes Agent Relay-managed shell profile PATH snippets, Codex runtime
326
- logs, the launcher directory, and empty install directories. It only removes
327
- profile snippets written by the installer marker; manual PATH edits are left
328
- alone.
100
+ | Target | Example | Behavior |
101
+ |--------|---------|----------|
102
+ | Agent ID | `"macmini2-cli-myproject-a1b2c3"` | Direct to one agent |
103
+ | Tag | `"tag:backend"` | All agents with that tag |
104
+ | Capability | `"cap:review"` | All agents with that capability |
105
+ | Label | `"label:test writer"` | All agents with that human-set label |
106
+ | Broadcast | `"broadcast"` | Everyone |
329
107
 
330
108
  ## What the Agent Sees
331
109
 
332
- For Claude Code sessions, the plugin monitor registers the agent and outputs its
333
- identity and messaging instructions as a notification:
110
+ The plugin or sidecar registers the agent and injects messaging context:
334
111
 
335
112
  ```
336
113
  Agent Relay active. Your agent ID: macmini2-cli-myproject-a1b2c3
337
- Relay URL: http://localhost:4850 | Server: 0.3.2 | Plugin: 0.3.2
114
+ Relay URL: http://localhost:4850 | Server: 0.4.13 | Plugin: 0.4.13
115
+ Approval mode: open
338
116
  ```
339
117
 
340
- In Claude, incoming messages arrive as monitor notifications.
341
-
342
- In Codex, incoming messages are delivered as live turns by the sidecar.
343
-
344
- Example incoming relay message:
118
+ Incoming messages arrive as monitor notifications (Claude) or live turns (Codex):
345
119
 
346
120
  ```
347
121
  [msg:42] from backend-agent: Migration looks clean, tests pass. Ready to merge.
348
122
  ```
349
123
 
350
- ## Message Targeting
351
-
352
- | Target | Example | Behavior |
353
- |--------|---------|----------|
354
- | Agent ID | `"macmini2-cli-myproject-a1b2c3"` | Direct to one agent |
355
- | Tag | `"tag:backend"` | All agents with that tag |
356
- | Capability | `"cap:review"` | All agents with that capability |
357
- | Label | `"label:test writer"` | All agents with that human-set label |
358
- | Broadcast | `"broadcast"` | Everyone |
359
-
360
124
  ## Integrations And Tasks
361
125
 
362
126
  Agent Relay can act as a secure ingress layer for scripts, monitoring systems,
@@ -374,13 +138,6 @@ export AGENT_RELAY_INTEGRATIONS='[
374
138
  "targets": ["cap:ops"],
375
139
  "channels": ["alerts"],
376
140
  "callbackUrl": "https://ops.example/agent-relay/callback"
377
- },
378
- {
379
- "name": "support-desk",
380
- "token": "support-secret",
381
- "scopes": ["tasks:create"],
382
- "targets": ["cap:support"],
383
- "channels": ["support"]
384
141
  }
385
142
  ]'
386
143
  ```
@@ -398,9 +155,7 @@ curl -sS -X POST "$AGENT_RELAY_URL/api/integrations/events" \
398
155
  "title": "prod-api 5xx rate high",
399
156
  "body": "5xx rate is above 8% for 5 minutes",
400
157
  "target": "cap:ops",
401
- "channel": "alerts",
402
- "externalUrl": "https://grafana.example/d/prod-api",
403
- "metadata": { "service": "prod-api", "value": 0.084 }
158
+ "channel": "alerts"
404
159
  }'
405
160
  ```
406
161
 
@@ -409,22 +164,8 @@ dedupe key while the task is active, Agent Relay increments `occurrenceCount`,
409
164
  updates `lastSeenAt`, records a task event, and does not spam agents with another
410
165
  claimable message. Posting `"status": "resolved"` marks the active task `done`.
411
166
 
412
- When an integration has `callbackUrl`, Agent Relay records and attempts a
413
- best-effort `POST` on task creation, claim, and status changes:
414
-
415
- ```json
416
- {
417
- "event": "task.status",
418
- "task": {
419
- "id": 42,
420
- "status": "done",
421
- "result": "Rolled back bad deploy"
422
- }
423
- }
424
- ```
425
-
426
- Callback attempts are written to SQLite before delivery so failed deliveries are
427
- auditable during practical testing.
167
+ When an integration has `callbackUrl`, Agent Relay posts task lifecycle events
168
+ (creation, claim, status changes) back to the caller.
428
169
 
429
170
  Task lifecycle API:
430
171
 
@@ -437,12 +178,7 @@ Task lifecycle API:
437
178
  | `POST` | `/tasks/:id/claim` | Claim a task as an agent |
438
179
  | `PATCH` | `/tasks/:id/status` | Update status/result/progress |
439
180
 
440
- Example connectors live under `examples/integrations/`:
441
-
442
- - `ops-alert.sh`: simple shell event producer.
443
- - `support-ticket.sh`: simple support ticket producer.
444
- - `prometheus-alertmanager.ts`: reads an Alertmanager webhook payload from stdin.
445
- - `github-issue.ts`: reads a GitHub issue webhook payload from stdin.
181
+ Example connectors live under `examples/integrations/`.
446
182
 
447
183
  ## Deployment
448
184
 
@@ -453,7 +189,11 @@ bunx agent-relay-server@latest # localhost only
453
189
  AGENT_RELAY_TOKEN=... PORT=8080 HOST=0.0.0.0 bunx agent-relay-server@latest # remote access
454
190
  ```
455
191
 
456
- For multi-machine setups, run the server on one machine and set `AGENT_RELAY_URL` on the others (works great over [Tailscale](https://tailscale.com)):
192
+ Localhost is intentionally frictionless. If you bind to a non-loopback address,
193
+ set `AGENT_RELAY_TOKEN` first.
194
+
195
+ For multi-machine setups, run the server on one machine and set `AGENT_RELAY_URL`
196
+ on the others (works great over [Tailscale](https://tailscale.com)):
457
197
 
458
198
  ```bash
459
199
  export AGENT_RELAY_URL=http://100.x.y.z:4850
@@ -463,6 +203,22 @@ export AGENT_RELAY_TOKEN=your-shared-token
463
203
  Do not expose Agent Relay directly to the public internet. It is designed for a
464
204
  trusted localhost/VPN/LAN boundary, not as a multi-tenant public service.
465
205
 
206
+ ### Managed daemon
207
+
208
+ For an always-on relay, install as a user-level daemon:
209
+
210
+ ```bash
211
+ bun install -g agent-relay-server@latest
212
+ agent-relay setup --yes
213
+ agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
214
+ ```
215
+
216
+ `setup` creates a managed env file with a generated token, loopback bind, and a
217
+ durable SQLite path. `daemon install` auto-detects systemd (Linux) and
218
+ LaunchAgents (macOS).
219
+
220
+ Lifecycle: `agent-relay daemon status|logs|restart|stop|start|enable|disable|uninstall`
221
+
466
222
  ### Server environment variables
467
223
 
468
224
  | Variable | Default | Purpose |
@@ -480,78 +236,13 @@ trusted localhost/VPN/LAN boundary, not as a multi-tenant public service.
480
236
  | `AGENT_RELAY_INTEGRATIONS` | `[]` | JSON integration token/scopes/target/callback config |
481
237
  | `AGENT_RELAY_INTEGRATION_RATE_LIMIT_PER_MINUTE` | `120` | Per-integration event ingress limit |
482
238
 
483
- ### Plugin environment variables
484
-
485
- | Variable | Default | Purpose |
486
- |----------|---------|---------|
487
- | `AGENT_RELAY_URL` | `http://localhost:4850` | Relay server URL |
488
- | `AGENT_RELAY_TOKEN` | unset | Token sent by Codex/dashboard/API clients |
489
- | `AGENT_RELAY_CAPS` | `chat` | Comma-separated agent capabilities |
490
-
491
- Agent IDs are deterministic: `{hostname}-{rig}-{project}-{pid-hash}`.
492
-
493
- ### Managed daemon
494
-
495
- Agent Relay can install itself as a user-level daemon and load on computer
496
- restart. The installer chooses the safest supported backend:
497
-
498
- - Linux with `systemctl`: systemd user service by default.
499
- - macOS: launchd LaunchAgent.
500
- - Unsupported environments: prints a manual command instead of guessing.
501
-
502
- Recommended first-time setup:
503
-
504
- ```bash
505
- # inspect what will be written
506
- agent-relay setup --dry-run
507
-
508
- # write the env file with a generated AGENT_RELAY_TOKEN
509
- agent-relay setup --yes
510
-
511
- # install, enable at login/boot, and start now
512
- agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
513
- ```
514
-
515
- Lifecycle commands:
516
-
517
- ```bash
518
- agent-relay daemon status
519
- agent-relay daemon logs
520
- agent-relay daemon restart
521
- agent-relay daemon stop
522
- agent-relay daemon start
523
- agent-relay daemon disable
524
- agent-relay daemon enable
525
- agent-relay daemon uninstall
526
- ```
527
-
528
- Useful options:
529
-
530
- ```bash
531
- # preview service files/commands without changing the machine
532
- agent-relay daemon install --dry-run --enable --start
533
-
534
- # remote/VPN bind; setup will still generate a token
535
- agent-relay setup --host 0.0.0.0 --yes
536
- agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
537
-
538
- # use a known stable binary/script path in the service file
539
- agent-relay daemon install --binary ~/.bun/bin/agent-relay --enable --start
540
- ```
541
-
542
- Daemon install/uninstall refuses to overwrite or remove service files that do
543
- not contain Agent Relay's managed marker unless `--force` is passed.
544
-
545
239
  ### Version compatibility
546
240
 
547
241
  The plugin checks the server version on startup and warns if they diverge. Both packages share version numbers. Update them together:
548
242
 
549
243
  ```bash
550
- # update server (just restart, bunx pulls latest)
551
- systemctl --user restart agent-relay
552
-
553
- # update plugin
554
- claude plugin update agent-relay@agent-relay
244
+ systemctl --user restart agent-relay # server pulls latest on restart
245
+ claude plugin update agent-relay@agent-relay # Claude plugin
555
246
  ```
556
247
 
557
248
  ## API Reference
@@ -565,9 +256,6 @@ curl -H "Authorization: Bearer $AGENT_RELAY_TOKEN" http://localhost:4850/api/sta
565
256
  curl -H "X-Agent-Relay-Token: $AGENT_RELAY_TOKEN" http://localhost:4850/api/stats
566
257
  ```
567
258
 
568
- The dashboard asks for the token on first 401 and stores it in browser
569
- `localStorage` for that origin.
570
-
571
259
  ### Agents
572
260
 
573
261
  | Method | Path | Purpose |
@@ -635,19 +323,24 @@ public/
635
323
  ├── index.html # Dashboard markup
636
324
  └── dashboard.js # Dashboard Alpine model and behavior
637
325
 
638
- claude/ # Claude Code plugin
326
+ claude/ # Claude Code plugin (npm: agent-relay-plugin)
639
327
  ├── .claude-plugin/plugin.json
640
328
  ├── monitors/monitors.json # Auto-start inbox monitor
641
329
  └── hooks/
642
330
  ├── relay-monitor.sh # Register, inject context, poll
331
+ ├── approval-gate.sh # PreToolUse/PermissionDenied enforcement
643
332
  ├── set-status.sh # Turn hooks: busy/idle status updates
644
333
  ├── session-end.sh # Mark agent offline
645
334
  └── poll-inbox.sh # Inbox poll loop
646
335
 
647
- codex/ # Codex integration
648
- ├── live-sidecar.ts # App-server <-> relay bridge
649
- ├── hooks/session-start.ts # Starts one sidecar per launched thread
650
- └── plugin/ # Codex plugin bundle
336
+ codex/ # Codex integration (npm: agent-relay-codex)
337
+ ├── bin/agent-relay-codex.ts # Launcher CLI (install/start/doctor)
338
+ ├── live-sidecar.ts # App-server <-> relay bridge
339
+ ├── hooks/session-start.ts # Starts one sidecar per launched thread
340
+ └── plugin/ # Codex plugin bundle
341
+
342
+ client/ # TypeScript client (npm: agent-relay-client)
343
+ └── index.ts # RelayClient class + types
651
344
  ```
652
345
 
653
346
  ## Development
package/package.json CHANGED
@@ -1,22 +1,15 @@
1
1
  {
2
2
  "name": "agent-relay-server",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "description": "Lightweight HTTP message relay for inter-agent communication across machines",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
7
7
  "bin": {
8
- "agent-relay": "src/index.ts",
9
- "agent-relay-codex": "bin/agent-relay-codex.ts",
10
- "codex-relay": "bin/agent-relay-codex.ts"
8
+ "agent-relay": "src/index.ts"
11
9
  },
12
10
  "files": [
13
- "bin/**/*.ts",
14
11
  "src/**/*.ts",
15
12
  "!src/**/*.test.ts",
16
- "codex/**/*.ts",
17
- "codex/**/*.sh",
18
- "codex/**/*.ps1",
19
- "codex/plugin/**",
20
13
  "examples/**",
21
14
  "public/**",
22
15
  "README.md",
@@ -26,13 +19,8 @@
26
19
  "scripts": {
27
20
  "start": "bun run src/index.ts",
28
21
  "dev": "bun --watch run src/index.ts",
29
- "test": "bun test",
30
- "typecheck": "tsc --noEmit",
31
- "codex:live": "bun run codex/live-sidecar.ts",
32
- "codex:live:start": "bash codex/start-live.sh",
33
- "codex:install": "bun run bin/agent-relay-codex.ts install",
34
- "codex:doctor": "bun run bin/agent-relay-codex.ts doctor",
35
- "codex:smoke:fallback": "bun run codex/smoke/fallback.ts"
22
+ "test": "bun test src/",
23
+ "typecheck": "tsc --noEmit"
36
24
  },
37
25
  "keywords": [
38
26
  "agent-relay",