agent-relay-server 0.4.17 → 0.4.19

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 (3) hide show
  1. package/README.md +8 -5
  2. package/package.json +1 -1
  3. package/src/cli.ts +57 -0
package/README.md CHANGED
@@ -326,17 +326,20 @@ agent-relay /pair codex "Debug flaky auth tests"
326
326
  agent-relay pair codex --objective "Debug flaky auth tests"
327
327
  agent-relay pair accept PAIR_ID --agent "$AGENT_RELAY_ID"
328
328
  agent-relay pair send PAIR_ID --from "$AGENT_RELAY_ID" --body "What do you see?"
329
+ agent-relay /message codex "Can you look at that failing action?"
330
+ agent-relay /send-claimable tag:backend "Please claim and fix the failing API test"
329
331
  agent-relay /disconnect
330
332
  agent-relay /status
331
333
  agent-relay /label backend-fixer
332
334
  agent-relay /tags backend tests urgent
333
335
  ```
334
336
 
335
- Inside provider sessions, the Codex skill and Claude plugin context instruct
336
- agents to treat slash-style user messages like `/pair codex`, `/status`,
337
- `/label backend-fixer`, and `/tags backend tests` as relay commands and run the
338
- CLI. The CLI tries to auto-detect the current agent id from provider state; pass
339
- `--from` or `--agent` if you want to be explicit.
337
+ Inside provider sessions, the Codex plugin and Claude plugin ship command
338
+ skills for `/pair`, `/message`, `/send-claimable`, `/disconnect`, `/status`,
339
+ `/label`, and `/tags`. If one of those names collides with another installed
340
+ skill, invoke the provider-prefixed form such as `/agent-relay:pair` or
341
+ `/agent-relay:message`. The CLI tries to auto-detect the current agent id from
342
+ provider state; pass `--from` or `--agent` if you want to be explicit.
340
343
 
341
344
  If the target is already in a pending or active pair, the relay returns
342
345
  `409 Busy`. If a target like `codex` matches multiple available agents, the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-relay-server",
3
- "version": "0.4.17",
3
+ "version": "0.4.19",
4
4
  "description": "Lightweight HTTP message relay for inter-agent communication across machines",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
package/src/cli.ts CHANGED
@@ -26,7 +26,10 @@ Usage:
26
26
  agent-relay setup [--yes] [--dry-run] [--force] [--env-file PATH] [--host HOST] [--port PORT] [--db-path PATH] [--token TOKEN|--no-token]
27
27
  agent-relay daemon <install|uninstall|start|stop|restart|enable|disable|status|logs> [options]
28
28
  agent-relay pair <target|create|status|accept|reject|hangup|send> [options]
29
+ agent-relay message <target> <body> [options]
29
30
  agent-relay /pair <target|accept|reject|send|status> [...]
31
+ agent-relay /message <target> <body>
32
+ agent-relay /send-claimable <target> <body>
30
33
  agent-relay /disconnect [PAIR_ID]
31
34
  agent-relay /status
32
35
  agent-relay /label [LABEL]
@@ -39,6 +42,8 @@ Pair examples:
39
42
  agent-relay pair status
40
43
  agent-relay pair accept PAIR_ID --agent AGENT_ID
41
44
  agent-relay pair send PAIR_ID --from AGENT_ID --body "What do you see?"
45
+ agent-relay /message codex "Can you look at that failing action?"
46
+ agent-relay /send-claimable tag:backend "Please claim and fix the failing API test"
42
47
  agent-relay /disconnect
43
48
  agent-relay /status
44
49
  agent-relay /label backend-fixer
@@ -94,6 +99,10 @@ export async function handleCli(args: string[]): Promise<"start" | "handled"> {
94
99
  await handleSlashOrPairCommand(command, args.slice(1));
95
100
  return "handled";
96
101
  }
102
+ if (command === "message" || command === "send" || command === "/message" || command === "/send" || command === "/send-claimable") {
103
+ await handleMessageCommand(args.slice(1), { claimable: command === "/send-claimable" });
104
+ return "handled";
105
+ }
97
106
  if (command === "/status" || command === "status") {
98
107
  await handleStatusCommand(args.slice(1));
99
108
  return "handled";
@@ -357,6 +366,54 @@ async function handlePairCommand(args: string[]): Promise<void> {
357
366
  }
358
367
  }
359
368
 
369
+ async function handleMessageCommand(args: string[], defaults: { claimable?: boolean } = {}): Promise<void> {
370
+ const target = args[0];
371
+ if (!target || target.startsWith("--")) {
372
+ throw new Error("Usage: agent-relay message <target> <body> [--from AGENT_ID] [--subject TEXT] [--channel NAME] [--reply-to ID] [--claimable]");
373
+ }
374
+
375
+ let from = await detectAgentId();
376
+ let subject: string | undefined;
377
+ let channel: string | undefined;
378
+ let replyTo: number | undefined;
379
+ let idempotencyKey: string | undefined;
380
+ let json = false;
381
+ let claimable = defaults.claimable ?? false;
382
+ const bodyParts: string[] = [];
383
+
384
+ for (let i = 1; i < args.length; i++) {
385
+ const arg = args[i];
386
+ if (arg === "--from" && i + 1 < args.length) from = args[++i];
387
+ else if (arg === "--subject" && i + 1 < args.length) subject = args[++i];
388
+ else if (arg === "--channel" && i + 1 < args.length) channel = args[++i];
389
+ else if (arg === "--reply-to" && i + 1 < args.length) {
390
+ const parsed = Number.parseInt(args[++i]!, 10);
391
+ if (!Number.isFinite(parsed) || parsed <= 0) throw new Error("--reply-to must be a positive message id");
392
+ replyTo = parsed;
393
+ } else if (arg === "--idempotency-key" && i + 1 < args.length) idempotencyKey = args[++i];
394
+ else if (arg === "--claimable") claimable = true;
395
+ else if (arg === "--json") json = true;
396
+ else bodyParts.push(arg!);
397
+ }
398
+
399
+ const body = bodyParts.join(" ").trim();
400
+ if (!from) throw new Error("Could not detect current Agent Relay ID. Pass --from AGENT_ID or set AGENT_RELAY_ID.");
401
+ if (!body) throw new Error("Message body required.");
402
+
403
+ const message = await apiRequest("POST", "/api/messages", {
404
+ from,
405
+ to: target,
406
+ subject,
407
+ channel,
408
+ body,
409
+ replyTo,
410
+ claimable,
411
+ idempotencyKey,
412
+ });
413
+ if (json) console.log(JSON.stringify(message, null, 2));
414
+ else console.log(`${claimable ? "Claimable message" : "Message"} sent: ${(message as any).id} -> ${target}`);
415
+ }
416
+
360
417
  async function handleStatusCommand(args: string[]): Promise<void> {
361
418
  let agentId = await detectAgentId();
362
419
  let json = false;