agent-relay 2.2.23 → 2.3.0

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 (133) hide show
  1. package/dist/index.cjs +199 -3
  2. package/package.json +64 -21
  3. package/packages/acp-bridge/package.json +2 -2
  4. package/packages/api-types/package.json +1 -1
  5. package/packages/benchmark/package.json +5 -5
  6. package/packages/bridge/package.json +7 -7
  7. package/packages/cli-tester/package.json +1 -1
  8. package/packages/config/package.json +2 -2
  9. package/packages/continuity/package.json +2 -2
  10. package/packages/daemon/dist/cloud-sync.d.ts +13 -1
  11. package/packages/daemon/dist/cloud-sync.d.ts.map +1 -1
  12. package/packages/daemon/dist/cloud-sync.js +169 -5
  13. package/packages/daemon/dist/cloud-sync.js.map +1 -1
  14. package/packages/daemon/dist/server.d.ts +5 -0
  15. package/packages/daemon/dist/server.d.ts.map +1 -1
  16. package/packages/daemon/dist/server.js +50 -0
  17. package/packages/daemon/dist/server.js.map +1 -1
  18. package/packages/daemon/package.json +12 -12
  19. package/packages/daemon/src/cloud-sync.ts +201 -5
  20. package/packages/daemon/src/server.ts +61 -0
  21. package/packages/hooks/package.json +4 -4
  22. package/packages/mcp/package.json +5 -5
  23. package/packages/memory/package.json +2 -2
  24. package/packages/policy/package.json +2 -2
  25. package/packages/protocol/package.json +1 -1
  26. package/packages/resiliency/package.json +1 -1
  27. package/packages/sdk/dist/client.d.ts +1 -1
  28. package/packages/sdk/dist/client.js +2 -2
  29. package/packages/sdk/package.json +3 -3
  30. package/packages/sdk/src/client.ts +2 -2
  31. package/packages/sdk-ts/README.md +65 -0
  32. package/packages/sdk-ts/dist/__tests__/integration.test.d.ts +2 -0
  33. package/packages/sdk-ts/dist/__tests__/integration.test.d.ts.map +1 -0
  34. package/packages/sdk-ts/dist/__tests__/integration.test.js +139 -0
  35. package/packages/sdk-ts/dist/__tests__/integration.test.js.map +1 -0
  36. package/packages/sdk-ts/dist/__tests__/quickstart.test.d.ts +2 -0
  37. package/packages/sdk-ts/dist/__tests__/quickstart.test.d.ts.map +1 -0
  38. package/packages/sdk-ts/dist/__tests__/quickstart.test.js +176 -0
  39. package/packages/sdk-ts/dist/__tests__/quickstart.test.js.map +1 -0
  40. package/packages/sdk-ts/dist/browser.d.ts +16 -0
  41. package/packages/sdk-ts/dist/browser.d.ts.map +1 -0
  42. package/packages/sdk-ts/dist/browser.js +19 -0
  43. package/packages/sdk-ts/dist/browser.js.map +1 -0
  44. package/packages/sdk-ts/dist/client.d.ts +91 -0
  45. package/packages/sdk-ts/dist/client.d.ts.map +1 -0
  46. package/packages/sdk-ts/dist/client.js +360 -0
  47. package/packages/sdk-ts/dist/client.js.map +1 -0
  48. package/packages/sdk-ts/dist/consensus-helpers.d.ts +103 -0
  49. package/packages/sdk-ts/dist/consensus-helpers.d.ts.map +1 -0
  50. package/packages/sdk-ts/dist/consensus-helpers.js +147 -0
  51. package/packages/sdk-ts/dist/consensus-helpers.js.map +1 -0
  52. package/packages/sdk-ts/dist/consensus.d.ts +72 -0
  53. package/packages/sdk-ts/dist/consensus.d.ts.map +1 -0
  54. package/packages/sdk-ts/dist/consensus.js +378 -0
  55. package/packages/sdk-ts/dist/consensus.js.map +1 -0
  56. package/packages/sdk-ts/dist/examples/demo.d.ts +2 -0
  57. package/packages/sdk-ts/dist/examples/demo.d.ts.map +1 -0
  58. package/packages/sdk-ts/dist/examples/demo.js +63 -0
  59. package/packages/sdk-ts/dist/examples/demo.js.map +1 -0
  60. package/packages/sdk-ts/dist/examples/example.d.ts +2 -0
  61. package/packages/sdk-ts/dist/examples/example.d.ts.map +1 -0
  62. package/packages/sdk-ts/dist/examples/example.js +80 -0
  63. package/packages/sdk-ts/dist/examples/example.js.map +1 -0
  64. package/packages/sdk-ts/dist/examples/quickstart.d.ts +2 -0
  65. package/packages/sdk-ts/dist/examples/quickstart.d.ts.map +1 -0
  66. package/packages/sdk-ts/dist/examples/quickstart.js +56 -0
  67. package/packages/sdk-ts/dist/examples/quickstart.js.map +1 -0
  68. package/packages/sdk-ts/dist/examples/ralph-loop.d.ts +2 -0
  69. package/packages/sdk-ts/dist/examples/ralph-loop.d.ts.map +1 -0
  70. package/packages/sdk-ts/dist/examples/ralph-loop.js +281 -0
  71. package/packages/sdk-ts/dist/examples/ralph-loop.js.map +1 -0
  72. package/packages/sdk-ts/dist/index.d.ts +9 -0
  73. package/packages/sdk-ts/dist/index.d.ts.map +1 -0
  74. package/packages/sdk-ts/dist/index.js +9 -0
  75. package/packages/sdk-ts/dist/index.js.map +1 -0
  76. package/packages/sdk-ts/dist/logs.d.ts +47 -0
  77. package/packages/sdk-ts/dist/logs.d.ts.map +1 -0
  78. package/packages/sdk-ts/dist/logs.js +137 -0
  79. package/packages/sdk-ts/dist/logs.js.map +1 -0
  80. package/packages/sdk-ts/dist/protocol.d.ts +249 -0
  81. package/packages/sdk-ts/dist/protocol.d.ts.map +1 -0
  82. package/packages/sdk-ts/dist/protocol.js +2 -0
  83. package/packages/sdk-ts/dist/protocol.js.map +1 -0
  84. package/packages/sdk-ts/dist/pty.d.ts +8 -0
  85. package/packages/sdk-ts/dist/pty.d.ts.map +1 -0
  86. package/packages/sdk-ts/dist/pty.js +14 -0
  87. package/packages/sdk-ts/dist/pty.js.map +1 -0
  88. package/packages/sdk-ts/dist/relay.d.ts +118 -0
  89. package/packages/sdk-ts/dist/relay.d.ts.map +1 -0
  90. package/packages/sdk-ts/dist/relay.js +355 -0
  91. package/packages/sdk-ts/dist/relay.js.map +1 -0
  92. package/packages/sdk-ts/dist/relaycast.d.ts +57 -0
  93. package/packages/sdk-ts/dist/relaycast.d.ts.map +1 -0
  94. package/packages/sdk-ts/dist/relaycast.js +110 -0
  95. package/packages/sdk-ts/dist/relaycast.js.map +1 -0
  96. package/packages/sdk-ts/dist/shadow.d.ts +100 -0
  97. package/packages/sdk-ts/dist/shadow.d.ts.map +1 -0
  98. package/packages/sdk-ts/dist/shadow.js +174 -0
  99. package/packages/sdk-ts/dist/shadow.js.map +1 -0
  100. package/packages/sdk-ts/package.json +75 -0
  101. package/packages/sdk-ts/scripts/bundle-agent-relay.mjs +53 -0
  102. package/packages/sdk-ts/src/__tests__/integration.test.ts +170 -0
  103. package/packages/sdk-ts/src/__tests__/quickstart.test.ts +198 -0
  104. package/packages/sdk-ts/src/browser.ts +57 -0
  105. package/packages/sdk-ts/src/client.ts +491 -0
  106. package/packages/sdk-ts/src/consensus-helpers.ts +253 -0
  107. package/packages/sdk-ts/src/consensus.ts +506 -0
  108. package/packages/sdk-ts/src/examples/demo.ts +88 -0
  109. package/packages/sdk-ts/src/examples/example.ts +91 -0
  110. package/packages/sdk-ts/src/examples/quickstart.ts +72 -0
  111. package/packages/sdk-ts/src/examples/ralph-loop.ts +352 -0
  112. package/packages/sdk-ts/src/examples/sample-prd.json +37 -0
  113. package/packages/sdk-ts/src/index.ts +8 -0
  114. package/packages/sdk-ts/src/logs.ts +163 -0
  115. package/packages/sdk-ts/src/protocol.ts +266 -0
  116. package/packages/sdk-ts/src/pty.ts +16 -0
  117. package/packages/sdk-ts/src/relay.ts +454 -0
  118. package/packages/sdk-ts/src/relaycast.ts +143 -0
  119. package/packages/sdk-ts/src/shadow.ts +230 -0
  120. package/packages/sdk-ts/tsconfig.json +16 -0
  121. package/packages/spawner/package.json +1 -1
  122. package/packages/state/package.json +1 -1
  123. package/packages/storage/package.json +2 -2
  124. package/packages/telemetry/package.json +1 -1
  125. package/packages/trajectory/package.json +2 -2
  126. package/packages/user-directory/package.json +2 -2
  127. package/packages/utils/package.json +3 -3
  128. package/packages/wrapper/dist/client.js +1 -1
  129. package/packages/wrapper/package.json +6 -6
  130. package/packages/wrapper/src/client.test.ts +1 -1
  131. package/packages/wrapper/src/client.ts +1 -1
  132. package/packages/mcp/SPEC.md +0 -1922
  133. package/packages/mcp/STAFFING_PLAN.md +0 -294
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Runnable demo — shows the full AgentRelay message flow with real output.
3
+ * Uses `cat` as a universally-available stand-in for agent CLIs.
4
+ *
5
+ * Run:
6
+ * npm run build && npm run demo
7
+ */
8
+ import { AgentRelay } from "../relay.js";
9
+ const relay = new AgentRelay({ env: process.env });
10
+ // ── Event hooks ─────────────────────────────────────────────────────────────
11
+ relay.onMessageReceived = (message) => {
12
+ console.log(` šŸ“Ø received │ from=${message.from} to=${message.to} text="${message.text}"`);
13
+ };
14
+ relay.onMessageSent = (message) => {
15
+ console.log(` šŸ“¤ sent │ from=${message.from} to=${message.to} text="${message.text}"`);
16
+ };
17
+ relay.onAgentSpawned = (agent) => {
18
+ console.log(` 🟢 spawned │ ${agent.name} (${agent.runtime})`);
19
+ };
20
+ relay.onAgentReleased = (agent) => {
21
+ console.log(` šŸ”“ released │ ${agent.name}`);
22
+ };
23
+ relay.onAgentExited = (agent) => {
24
+ console.log(` ⚪ exited │ ${agent.name}`);
25
+ };
26
+ // ── Spawn agents ────────────────────────────────────────────────────────────
27
+ console.log("\n─── Spawning agents ───\n");
28
+ const [agentA, agentB] = await Promise.all([
29
+ relay.spawnPty({ name: "AgentA", cli: "claude", args: ["--print"], channels: ["general"] }),
30
+ relay.spawnPty({ name: "AgentB", cli: "claude", args: ["--print"], channels: ["general"] }),
31
+ ]);
32
+ // ── Send messages ───────────────────────────────────────────────────────────
33
+ console.log("\n─── Sending messages ───\n");
34
+ const human = relay.human({ name: "System" });
35
+ await human.sendMessage({ to: agentA.name, text: "Hello AgentA, welcome!" });
36
+ await human.sendMessage({ to: agentB.name, text: "Hello AgentB, welcome!" });
37
+ // Agent-to-agent messaging
38
+ await agentA.sendMessage({ to: agentB.name, text: "Hey B, got a task for you" });
39
+ await agentB.sendMessage({ to: agentA.name, text: "On it!" });
40
+ // Threaded conversation
41
+ const thread = await human.sendMessage({ to: agentA.name, text: "Status update?" });
42
+ await agentA.sendMessage({ to: human.name, text: "All good!", threadId: thread.eventId });
43
+ // Priority messages
44
+ await human.sendMessage({ to: agentA.name, text: "Critical alert!", priority: 0 });
45
+ await human.sendMessage({ to: agentB.name, text: "Low priority FYI", priority: 4 });
46
+ // Small delay to let events propagate
47
+ await new Promise((r) => setTimeout(r, 500));
48
+ // ── List agents ─────────────────────────────────────────────────────────────
49
+ console.log("\n─── Active agents ───\n");
50
+ const agents = await relay.listAgents();
51
+ for (const agent of agents) {
52
+ console.log(` • ${agent.name} runtime=${agent.runtime} channels=[${agent.channels}]`);
53
+ }
54
+ // ── Release all ─────────────────────────────────────────────────────────────
55
+ console.log("\n─── Releasing agents ───\n");
56
+ for (const agent of agents) {
57
+ await agent.release();
58
+ }
59
+ await new Promise((r) => setTimeout(r, 300));
60
+ // ── Shutdown ────────────────────────────────────────────────────────────────
61
+ await relay.shutdown();
62
+ console.log("\n─── Done ───\n");
63
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/examples/demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../../src/examples/example.ts"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ import { AgentRelayClient } from "../client.js";
2
+ function parseArgs(raw) {
3
+ if (!raw || raw.trim() === "") {
4
+ return [];
5
+ }
6
+ return raw
7
+ .split(" ")
8
+ .map((part) => part.trim())
9
+ .filter((part) => part.length > 0);
10
+ }
11
+ function now() {
12
+ return new Date().toISOString();
13
+ }
14
+ async function main() {
15
+ const codexCmd = process.env.CODEX_CMD ?? "codex";
16
+ const codexArgs = parseArgs(process.env.CODEX_ARGS);
17
+ const channel = process.env.RELAY_CHANNEL ?? "general";
18
+ const xName = process.env.AGENT_X_NAME ?? "CodexX";
19
+ const oName = process.env.AGENT_O_NAME ?? "CodexO";
20
+ const client = await AgentRelayClient.start({
21
+ channels: [channel],
22
+ });
23
+ const stopLogging = client.onEvent((event) => {
24
+ console.log(`[${now()}] event`, JSON.stringify(event));
25
+ });
26
+ const stopStderrLogging = client.onBrokerStderr((line) => {
27
+ console.log(`[${now()}] broker:stderr ${line}`);
28
+ });
29
+ const cleanup = async () => {
30
+ console.log(`[${now()}] cleaning up agents + broker`);
31
+ try {
32
+ await client.release(xName);
33
+ }
34
+ catch {
35
+ // ignore
36
+ }
37
+ try {
38
+ await client.release(oName);
39
+ }
40
+ catch {
41
+ // ignore
42
+ }
43
+ await client.shutdown();
44
+ stopLogging();
45
+ stopStderrLogging();
46
+ };
47
+ process.on("SIGINT", async () => {
48
+ console.log(`[${now()}] SIGINT received`);
49
+ await cleanup();
50
+ process.exit(0);
51
+ });
52
+ process.on("SIGTERM", async () => {
53
+ console.log(`[${now()}] SIGTERM received`);
54
+ await cleanup();
55
+ process.exit(0);
56
+ });
57
+ console.log(`[${now()}] spawning ${xName} (${codexCmd} ${codexArgs.join(" ")})`);
58
+ await client.spawnPty({
59
+ name: xName,
60
+ cli: codexCmd,
61
+ args: codexArgs,
62
+ channels: [channel],
63
+ });
64
+ console.log(`[${now()}] spawning ${oName} (${codexCmd} ${codexArgs.join(" ")})`);
65
+ await client.spawnPty({
66
+ name: oName,
67
+ cli: codexCmd,
68
+ args: codexArgs,
69
+ channels: [channel],
70
+ });
71
+ console.log(`[${now()}] workers spawned. send kickoff via Relaycast (MCP relay_send) and watch events here (Ctrl+C to stop).`);
72
+ await new Promise(() => {
73
+ // keep process alive while events stream
74
+ });
75
+ }
76
+ main().catch((error) => {
77
+ console.error(`[${now()}] fatal`, error);
78
+ process.exit(1);
79
+ });
80
+ //# sourceMappingURL=example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example.js","sourceRoot":"","sources":["../../src/examples/example.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=quickstart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickstart.d.ts","sourceRoot":"","sources":["../../src/examples/quickstart.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Quickstart — shows the clean AgentRelay facade API.
3
+ *
4
+ * Run:
5
+ * npm run build && npm run quickstart
6
+ *
7
+ * Environment:
8
+ * RELAY_API_KEY — Relaycast workspace key (required)
9
+ * AGENT_RELAY_BIN — path to agent-relay binary (optional)
10
+ */
11
+ import { AgentRelay } from "../relay.js";
12
+ // The Relay is the communication backbone for your agents.
13
+ // Drop it into your codebase and let your agents communicate.
14
+ const relay = new AgentRelay();
15
+ // ── Event hooks ─────────────────────────────────────────────────────────────
16
+ relay.onMessageReceived = (message) => {
17
+ console.log(`message received → from=${message.from} to=${message.to}`);
18
+ };
19
+ relay.onMessageSent = (message) => {
20
+ console.log(`message sent → from=${message.from} to=${message.to}`);
21
+ };
22
+ relay.onAgentSpawned = (agent) => {
23
+ console.log(`agent spawned → ${agent.name} (${agent.runtime})`);
24
+ };
25
+ relay.onAgentReleased = (agent) => {
26
+ console.log(`agent released → ${agent.name}`);
27
+ };
28
+ relay.onAgentExited = (agent) => {
29
+ console.log(`agent exited → ${agent.name}`);
30
+ };
31
+ // ── Create agents with sane defaults, running locally ───────────────────────
32
+ const [codex, claude, gemini] = await Promise.all([
33
+ relay.codex.spawn(),
34
+ relay.claude.spawn(),
35
+ relay.gemini.spawn(),
36
+ ]);
37
+ // ── Configure messaging with custom CLI agents ─────────────────────────────
38
+ const worker1 = await relay.spawnPty({
39
+ name: "Worker1",
40
+ cli: "codex",
41
+ args: ["--model", "gpt-5"],
42
+ channels: ["general"],
43
+ });
44
+ // ── Control messaging from non-agent sources ────────────────────────────────
45
+ const human = relay.human({ name: "System" });
46
+ await human.sendMessage({ to: codex.name, text: "Hello, world!" });
47
+ // ── List agents ─────────────────────────────────────────────────────────────
48
+ const agents = await relay.listAgents();
49
+ for (const agent of agents) {
50
+ console.log(` ${agent.name} runtime=${agent.runtime} channels=[${agent.channels}]`);
51
+ }
52
+ for (const agent of agents) {
53
+ await agent.release();
54
+ }
55
+ await relay.shutdown();
56
+ //# sourceMappingURL=quickstart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickstart.js","sourceRoot":"","sources":["../../src/examples/quickstart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,2DAA2D;AAC3D,8DAA8D;AAC9D,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;AAE/B,+EAA+E;AAE/E,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,EAAE;IACpC,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,KAAK,CAAC,aAAa,GAAG,CAAC,OAAO,EAAE,EAAE;IAChC,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,KAAK,CAAC,cAAc,GAAG,CAAC,KAAK,EAAE,EAAE;IAC/B,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,KAAK,CAAC,eAAe,GAAG,CAAC,KAAK,EAAE,EAAE;IAChC,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,KAAK,CAAC,aAAa,GAAG,CAAC,KAAK,EAAE,EAAE;IAC9B,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;IAChD,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE;IACnB,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE;IACpB,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE;CACrB,CAAC,CAAC;AAEH,8EAA8E;AAE9E,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC;IACnC,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,OAAO;IACZ,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,CAAC,SAAS,CAAC;CACtB,CAAC,CAAC;AAEH,+EAA+E;AAE/E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC9C,MAAM,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;AAEnE,+EAA+E;AAE/E,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;AACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,OAAO,eAAe,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;AACzF,CAAC;AAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;IAC3B,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ralph-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralph-loop.d.ts","sourceRoot":"","sources":["../../src/examples/ralph-loop.ts"],"names":[],"mappings":""}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Ralph Loop — Claude + Codex pair-programming through a PRD.
3
+ *
4
+ * Each iteration spawns TWO agents that work together simultaneously:
5
+ * - Claude (PTY) — the architect. Plans, guides, and reviews.
6
+ * - Codex (PTY, --full-auto) — the builder. Implements the code.
7
+ *
8
+ * Both agents join #general and communicate in real-time:
9
+ * 1. Claude receives the story and posts an implementation plan
10
+ * 2. Codex receives the story + sees Claude's plan on #general
11
+ * 3. As Codex works, Claude can course-correct via the channel
12
+ * 4. When Codex finishes, Claude reviews and posts REVIEW:PASS/FAIL
13
+ * 5. Quality checks run, story marked done or retried with feedback
14
+ *
15
+ * Why two agents instead of one?
16
+ * - Claude reasons about architecture, Codex executes rapidly
17
+ * - They see each other's messages in real-time (not just handoffs)
18
+ * - Fresh eyes on review catch mistakes a single agent misses
19
+ * - Each iteration is doubly effective — thinking + doing in parallel
20
+ *
21
+ * Run:
22
+ * npx tsc && npm run ralph
23
+ *
24
+ * References:
25
+ * https://github.com/snarktank/ralph
26
+ * https://ghuntley.com/ralph/
27
+ */
28
+ import fs from "node:fs";
29
+ import { execSync } from "node:child_process";
30
+ import { AgentRelay } from "../relay.js";
31
+ // ── Configuration ───────────────────────────────────────────────────────────
32
+ const PRD_PATH = process.env.PRD_PATH ?? "prd.json";
33
+ const PROGRESS_PATH = process.env.PROGRESS_PATH ?? "progress.txt";
34
+ const MAX_ITERATIONS = Number(process.env.MAX_ITERATIONS ?? 10);
35
+ const MAX_REVIEW_ROUNDS = Number(process.env.MAX_REVIEW_ROUNDS ?? 2);
36
+ const QUALITY_CMD = process.env.QUALITY_CMD ?? "npm run check";
37
+ /** Max time (ms) to wait for both agents per round before releasing them. */
38
+ const ROUND_TIMEOUT_MS = Number(process.env.ROUND_TIMEOUT_MS ?? 5 * 60 * 1000);
39
+ // ── Helpers ─────────────────────────────────────────────────────────────────
40
+ function loadPrd() {
41
+ return JSON.parse(fs.readFileSync(PRD_PATH, "utf-8"));
42
+ }
43
+ function savePrd(prd) {
44
+ fs.writeFileSync(PRD_PATH, JSON.stringify(prd, null, 2) + "\n");
45
+ }
46
+ function appendProgress(entry) {
47
+ const line = `[${new Date().toISOString()}] ${entry}\n`;
48
+ fs.appendFileSync(PROGRESS_PATH, line);
49
+ }
50
+ function readProgress() {
51
+ return fs.existsSync(PROGRESS_PATH)
52
+ ? fs.readFileSync(PROGRESS_PATH, "utf-8")
53
+ : "";
54
+ }
55
+ function nextStory(prd) {
56
+ return prd.userStories.find((s) => !s.passes);
57
+ }
58
+ function runQualityChecks() {
59
+ try {
60
+ const output = execSync(QUALITY_CMD, { encoding: "utf-8", stdio: "pipe" });
61
+ return { passed: true, output };
62
+ }
63
+ catch (err) {
64
+ const output = err.stdout ?? String(err);
65
+ return { passed: false, output };
66
+ }
67
+ }
68
+ // ── Prompt builders ─────────────────────────────────────────────────────────
69
+ function architectPrompt(story, progress) {
70
+ const criteria = story.acceptanceCriteria.map((c) => ` - ${c}`).join("\n");
71
+ return [
72
+ `## Architect: ${story.title}`,
73
+ ``,
74
+ `You are the architect. A Codex agent ("Builder") is working alongside you.`,
75
+ `You are both on the #general channel and can communicate freely.`,
76
+ ``,
77
+ `### How to communicate`,
78
+ `Use the Relaycast MCP tools to post messages to #general:`,
79
+ `1. Call set_workspace_key with your RELAY_API_KEY env var`,
80
+ `2. Register as an agent using your name`,
81
+ `3. Use post_message to send to the #general channel`,
82
+ ``,
83
+ story.description,
84
+ ``,
85
+ `### Acceptance Criteria`,
86
+ criteria,
87
+ ``,
88
+ `### Previous Learnings`,
89
+ progress || "(first story)",
90
+ ``,
91
+ `### Your job`,
92
+ `1. Post a concise implementation plan to #general (files, changes, edge cases)`,
93
+ `2. Monitor the Builder's progress messages on the channel`,
94
+ `3. Provide guidance if the Builder asks questions or goes off track`,
95
+ `4. When the Builder says it's done, review the git diff`,
96
+ `5. Post exactly "REVIEW:PASS" to #general if all criteria are met`,
97
+ `6. Post exactly "REVIEW:FAIL" followed by feedback to #general if issues remain`,
98
+ ``,
99
+ `IMPORTANT: You MUST use Relaycast MCP tools to post messages. This is how`,
100
+ `the orchestrator knows you're done. Post your plan first, then your verdict.`,
101
+ ].join("\n");
102
+ }
103
+ function builderPrompt(story, progress, reviewFeedback) {
104
+ const criteria = story.acceptanceCriteria.map((c) => ` - ${c}`).join("\n");
105
+ const sections = [
106
+ `## Builder: ${story.title}`,
107
+ ``,
108
+ `You are the builder. A Claude agent ("Architect") is guiding you on #general.`,
109
+ `Read the Architect's plan from the channel and implement it.`,
110
+ ``,
111
+ `### How to communicate`,
112
+ `Use the Relaycast MCP tools to post messages to #general:`,
113
+ `1. Call set_workspace_key with your RELAY_API_KEY env var`,
114
+ `2. Register as an agent using your name`,
115
+ `3. Use post_message to send to the #general channel`,
116
+ ``,
117
+ story.description,
118
+ ``,
119
+ `### Acceptance Criteria`,
120
+ criteria,
121
+ ];
122
+ if (reviewFeedback) {
123
+ sections.push(``, `### Review Feedback (fix these issues first)`, reviewFeedback);
124
+ }
125
+ sections.push(``, `### Previous Learnings`, progress || "(first story)", ``, `### Your job`, `1. Read the Architect's plan from #general`, `2. Implement the changes`, `3. Post progress updates to #general as you work`, `4. When done, post exactly "IMPLEMENTATION COMPLETE" to #general`, ``, `IMPORTANT: You MUST use Relaycast MCP tools to post messages. This is how`, `the orchestrator knows you're done.`);
126
+ return sections.join("\n");
127
+ }
128
+ // ── Main loop ───────────────────────────────────────────────────────────────
129
+ const relay = new AgentRelay({ env: process.env });
130
+ const channelLog = [];
131
+ relay.onMessageReceived = (msg) => {
132
+ channelLog.push(msg);
133
+ console.log(` šŸ’¬ ${msg.from}: "${msg.text.slice(0, 80)}…"`);
134
+ };
135
+ relay.onAgentSpawned = (agent) => console.log(` 🟢 ${agent.name} spawned (${agent.runtime})`);
136
+ relay.onAgentReleased = (agent) => console.log(` šŸ”“ ${agent.name} released`);
137
+ relay.onAgentExited = (agent) => console.log(` ⚪ ${agent.name} exited`);
138
+ relay.onMessageSent = (msg) => console.log(` šŸ“¤ → ${msg.to}: "${msg.text.slice(0, 60)}…"`);
139
+ const prd = loadPrd();
140
+ const orchestrator = relay.human({ name: "Ralph" });
141
+ console.log(`\n══ Ralph Loop (Claude + Codex) ══`);
142
+ console.log(` branch: ${prd.branchName}`);
143
+ console.log(` stories: ${prd.userStories.length}`);
144
+ console.log(` remaining: ${prd.userStories.filter((s) => !s.passes).length}`);
145
+ console.log(` max iterations: ${MAX_ITERATIONS}`);
146
+ console.log(` max review rounds: ${MAX_REVIEW_ROUNDS}\n`);
147
+ let iteration = 0;
148
+ while (iteration < MAX_ITERATIONS) {
149
+ const story = nextStory(prd);
150
+ if (!story)
151
+ break;
152
+ iteration++;
153
+ console.log(`\n── Story ${story.id}: ${story.title} (iteration ${iteration}) ──\n`);
154
+ let reviewFeedback;
155
+ let storyPassed = false;
156
+ for (let round = 0; round < MAX_REVIEW_ROUNDS; round++) {
157
+ const roundLabel = round === 0 ? "initial" : `fix-${round}`;
158
+ const progress = readProgress();
159
+ // ── Spawn both agents concurrently ──────────────────────────────────
160
+ console.log(` ⚔ Spawning Claude (architect) + Codex (builder) — round: ${roundLabel}`);
161
+ const [architect, builder] = await Promise.all([
162
+ relay.claude.spawn({
163
+ name: `Architect-${story.id}-${roundLabel}`,
164
+ channels: ["general"],
165
+ }),
166
+ relay.codex.spawn({
167
+ name: `Builder-${story.id}-${roundLabel}`,
168
+ args: ["--full-auto"],
169
+ channels: ["general"],
170
+ }),
171
+ ]);
172
+ // ── Inject tasks via relay ──────────────────────────────────────────
173
+ // Claude gets the architect prompt first so it can post the plan
174
+ await orchestrator.sendMessage({
175
+ to: architect.name,
176
+ text: architectPrompt(story, progress),
177
+ });
178
+ // Small delay so Claude's plan arrives before Codex starts reading
179
+ await new Promise((r) => setTimeout(r, 2000));
180
+ await orchestrator.sendMessage({
181
+ to: builder.name,
182
+ text: builderPrompt(story, progress, reviewFeedback),
183
+ });
184
+ // ── Wait for agents to finish or detect completion ────────────────────
185
+ // Interactive agents don't exit on their own, so we poll channel
186
+ // messages for completion signals and release them when done.
187
+ console.log(` ā³ Claude + Codex working together on #general…`);
188
+ const startLen = channelLog.length;
189
+ const deadline = Date.now() + ROUND_TIMEOUT_MS;
190
+ let verdict;
191
+ // Poll every 5s for completion signals in channel messages
192
+ while (Date.now() < deadline) {
193
+ const recent = channelLog.slice(startLen);
194
+ // Check if Claude posted a review verdict
195
+ const review = recent.find((m) => m.text.includes("REVIEW:PASS") || m.text.includes("REVIEW:FAIL"));
196
+ if (review) {
197
+ verdict = review.text;
198
+ console.log(` šŸ“‹ Claude posted verdict`);
199
+ break;
200
+ }
201
+ // Check if Codex signaled completion (Claude may still be reviewing)
202
+ const implDone = recent.find((m) => m.text.includes("IMPLEMENTATION COMPLETE"));
203
+ if (implDone) {
204
+ console.log(` šŸ“‹ Codex finished, waiting for Claude's review…`);
205
+ // Give Claude up to 60s more to post a verdict
206
+ const reviewDeadline = Date.now() + 60_000;
207
+ while (Date.now() < reviewDeadline) {
208
+ await new Promise((r) => setTimeout(r, 3000));
209
+ const afterImpl = channelLog.slice(startLen);
210
+ const rv = afterImpl.find((m) => m.text.includes("REVIEW:PASS") || m.text.includes("REVIEW:FAIL"));
211
+ if (rv) {
212
+ verdict = rv.text;
213
+ break;
214
+ }
215
+ }
216
+ break;
217
+ }
218
+ // Check if either agent exited on its own
219
+ const archResult = await architect.waitForExit(0);
220
+ const buildResult = await builder.waitForExit(0);
221
+ if (archResult !== "timeout" && buildResult !== "timeout")
222
+ break;
223
+ await new Promise((r) => setTimeout(r, 5000));
224
+ }
225
+ // Release both agents (they're interactive so won't exit on their own)
226
+ const cleanup = async (agent) => {
227
+ try {
228
+ await agent.release();
229
+ }
230
+ catch { /* already exited */ }
231
+ };
232
+ await Promise.all([cleanup(architect), cleanup(builder)]);
233
+ // ── Quality gate ────────────────────────────────────────────────────
234
+ console.log(` šŸ” running quality checks…`);
235
+ const quality = runQualityChecks();
236
+ if (!quality.passed) {
237
+ appendProgress(`āŒ ${story.id} round=${roundLabel} — quality checks failed`);
238
+ reviewFeedback = `Quality checks failed:\n${quality.output.slice(0, 500)}`;
239
+ console.log(` āŒ quality checks failed\n`);
240
+ continue;
241
+ }
242
+ // ── Check verdict ─────────────────────────────────────────────────────
243
+ if (verdict?.includes("REVIEW:PASS")) {
244
+ storyPassed = true;
245
+ appendProgress(`āœ… ${story.id} — ${story.title} — PASSED (round=${roundLabel})`);
246
+ console.log(` āœ… story passed!\n`);
247
+ break;
248
+ }
249
+ else if (verdict?.includes("REVIEW:FAIL")) {
250
+ const failText = verdict.replace("REVIEW:FAIL", "").trim();
251
+ reviewFeedback = failText;
252
+ appendProgress(`šŸ”„ ${story.id} round=${roundLabel} — review failed: ${reviewFeedback.slice(0, 200)}`);
253
+ console.log(` šŸ”„ review failed, starting new round\n`);
254
+ }
255
+ else {
256
+ // No verdict from Claude — quality passed so accept it
257
+ storyPassed = true;
258
+ appendProgress(`āœ… ${story.id} — ${story.title} — PASSED (quality only, round=${roundLabel})`);
259
+ console.log(` āœ… quality passed (no explicit review verdict)\n`);
260
+ break;
261
+ }
262
+ }
263
+ if (storyPassed) {
264
+ story.passes = true;
265
+ savePrd(prd);
266
+ }
267
+ else {
268
+ appendProgress(`āš ļø ${story.id} — exhausted review rounds, moving on`);
269
+ console.log(` āš ļø exhausted ${MAX_REVIEW_ROUNDS} review rounds for ${story.id}\n`);
270
+ }
271
+ }
272
+ // ── Summary ─────────────────────────────────────────────────────────────────
273
+ const remaining = prd.userStories.filter((s) => !s.passes);
274
+ if (remaining.length === 0) {
275
+ console.log(`\nšŸŽ‰ COMPLETE — all stories pass.`);
276
+ }
277
+ else {
278
+ console.log(`\nāš ļø ${remaining.length} stories remain after ${iteration} iterations.`);
279
+ }
280
+ await relay.shutdown();
281
+ //# sourceMappingURL=ralph-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralph-loop.js","sourceRoot":"","sources":["../../src/examples/ralph-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAA4B,MAAM,aAAa,CAAC;AAiBnE,+EAA+E;AAE/E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,UAAU,CAAC;AACpD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,cAAc,CAAC;AAClE,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;AAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC;AACrE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,eAAe,CAAC;AAC/D,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAE/E,+EAA+E;AAE/E,SAAS,OAAO;IACd,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,OAAO,CAAC,GAAQ;IACvB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;IACxD,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC;QACjC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC;QACzC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,SAAS,CAAC,GAAQ;IACzB,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3E,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QAClE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E,SAAS,eAAe,CAAC,KAAY,EAAE,QAAgB;IACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,OAAO;QACL,iBAAiB,KAAK,CAAC,KAAK,EAAE;QAC9B,EAAE;QACF,4EAA4E;QAC5E,kEAAkE;QAClE,EAAE;QACF,wBAAwB;QACxB,2DAA2D;QAC3D,2DAA2D;QAC3D,yCAAyC;QACzC,qDAAqD;QACrD,EAAE;QACF,KAAK,CAAC,WAAW;QACjB,EAAE;QACF,yBAAyB;QACzB,QAAQ;QACR,EAAE;QACF,wBAAwB;QACxB,QAAQ,IAAI,eAAe;QAC3B,EAAE;QACF,cAAc;QACd,gFAAgF;QAChF,2DAA2D;QAC3D,qEAAqE;QACrE,yDAAyD;QACzD,mEAAmE;QACnE,iFAAiF;QACjF,EAAE;QACF,2EAA2E;QAC3E,8EAA8E;KAC/E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAY,EAAE,QAAgB,EAAE,cAAuB;IAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG;QACf,eAAe,KAAK,CAAC,KAAK,EAAE;QAC5B,EAAE;QACF,+EAA+E;QAC/E,8DAA8D;QAC9D,EAAE;QACF,wBAAwB;QACxB,2DAA2D;QAC3D,2DAA2D;QAC3D,yCAAyC;QACzC,qDAAqD;QACrD,EAAE;QACF,KAAK,CAAC,WAAW;QACjB,EAAE;QACF,yBAAyB;QACzB,QAAQ;KACT,CAAC;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,QAAQ,CAAC,IAAI,CACX,EAAE,EACF,8CAA8C,EAC9C,cAAc,CACf,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,IAAI,CACX,EAAE,EACF,wBAAwB,EACxB,QAAQ,IAAI,eAAe,EAC3B,EAAE,EACF,cAAc,EACd,4CAA4C,EAC5C,0BAA0B,EAC1B,kDAAkD,EAClD,kEAAkE,EAClE,EAAE,EACF,2EAA2E,EAC3E,qCAAqC,CACtC,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAE/E,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAEnD,MAAM,UAAU,GAAc,EAAE,CAAC;AAEjC,KAAK,CAAC,iBAAiB,GAAG,CAAC,GAAG,EAAE,EAAE;IAChC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC,CAAC;AAEF,KAAK,CAAC,cAAc,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;AAC/F,KAAK,CAAC,eAAe,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC;AAC9E,KAAK,CAAC,aAAa,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;AACzE,KAAK,CAAC,aAAa,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAE5F,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AACtB,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAEpD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACnD,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;AACpD,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/E,OAAO,CAAC,GAAG,CAAC,qBAAqB,cAAc,EAAE,CAAC,CAAC;AACnD,OAAO,CAAC,GAAG,CAAC,wBAAwB,iBAAiB,IAAI,CAAC,CAAC;AAE3D,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB,OAAO,SAAS,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK;QAAE,MAAM;IAElB,SAAS,EAAE,CAAC;IACZ,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,KAAK,eAAe,SAAS,QAAQ,CAAC,CAAC;IAEpF,IAAI,cAAkC,CAAC;IACvC,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,iBAAiB,EAAE,KAAK,EAAE,EAAE,CAAC;QACvD,MAAM,UAAU,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAEhC,uEAAuE;QACvE,OAAO,CAAC,GAAG,CAAC,8DAA8D,UAAU,EAAE,CAAC,CAAC;QAExF,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;gBACjB,IAAI,EAAE,aAAa,KAAK,CAAC,EAAE,IAAI,UAAU,EAAE;gBAC3C,QAAQ,EAAE,CAAC,SAAS,CAAC;aACtB,CAAC;YACF,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;gBAChB,IAAI,EAAE,WAAW,KAAK,CAAC,EAAE,IAAI,UAAU,EAAE;gBACzC,IAAI,EAAE,CAAC,aAAa,CAAC;gBACrB,QAAQ,EAAE,CAAC,SAAS,CAAC;aACtB,CAAC;SACH,CAAC,CAAC;QAEH,uEAAuE;QACvE,iEAAiE;QACjE,MAAM,YAAY,CAAC,WAAW,CAAC;YAC7B,EAAE,EAAE,SAAS,CAAC,IAAI;YAClB,IAAI,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC;SACvC,CAAC,CAAC;QAEH,mEAAmE;QACnE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAE9C,MAAM,YAAY,CAAC,WAAW,CAAC;YAC7B,EAAE,EAAE,OAAO,CAAC,IAAI;YAChB,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,cAAc,CAAC;SACrD,CAAC,CAAC;QAEH,yEAAyE;QACzE,iEAAiE;QACjE,8DAA8D;QAC9D,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;QAC/C,IAAI,OAA2B,CAAC;QAEhC,2DAA2D;QAC3D,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAE1C,0CAA0C;YAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CACxE,CAAC;YACF,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;gBAC1C,MAAM;YACR,CAAC;YAED,qEAAqE;YACrE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAChF,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;gBACjE,+CAA+C;gBAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;gBAC3C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;oBACnC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;oBAC9C,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC7C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CACxE,CAAC;oBACF,IAAI,EAAE,EAAE,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC;wBAAC,MAAM;oBAAC,CAAC;gBACvC,CAAC;gBACD,MAAM;YACR,CAAC;YAED,0CAA0C;YAC1C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACjD,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS;gBAAE,MAAM;YAEjE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,uEAAuE;QACvE,MAAM,OAAO,GAAG,KAAK,EAAE,KAAY,EAAE,EAAE;YACrC,IAAI,CAAC;gBAAC,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAC/D,CAAC,CAAC;QACF,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAE1D,uEAAuE;QACvE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QAEnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,cAAc,CAAC,KAAK,KAAK,CAAC,EAAE,UAAU,UAAU,0BAA0B,CAAC,CAAC;YAC5E,cAAc,GAAG,2BAA2B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YAC3E,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QAED,yEAAyE;QACzE,IAAI,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACrC,WAAW,GAAG,IAAI,CAAC;YACnB,cAAc,CAAC,KAAK,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,oBAAoB,UAAU,GAAG,CAAC,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,MAAM;QACR,CAAC;aAAM,IAAI,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3D,cAAc,GAAG,QAAQ,CAAC;YAC1B,cAAc,CACZ,MAAM,KAAK,CAAC,EAAE,UAAU,UAAU,qBAAqB,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACtF,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,WAAW,GAAG,IAAI,CAAC;YACnB,cAAc,CAAC,KAAK,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,kCAAkC,UAAU,GAAG,CAAC,CAAC;YAC9F,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;SAAM,CAAC;QACN,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,uCAAuC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,kBAAkB,iBAAiB,sBAAsB,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AACnD,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,QAAQ,SAAS,CAAC,MAAM,yBAAyB,SAAS,cAAc,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ export * from "./protocol.js";
2
+ export * from "./client.js";
3
+ export * from "./relaycast.js";
4
+ export * from "./pty.js";
5
+ export * from "./relay.js";
6
+ export * from "./logs.js";
7
+ export * from "./consensus.js";
8
+ export * from "./shadow.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ export * from "./protocol.js";
2
+ export * from "./client.js";
3
+ export * from "./relaycast.js";
4
+ export * from "./pty.js";
5
+ export * from "./relay.js";
6
+ export * from "./logs.js";
7
+ export * from "./consensus.js";
8
+ export * from "./shadow.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Log reading utilities for the broker SDK.
3
+ *
4
+ * Reads agent logs from the local filesystem at
5
+ * `.agent-relay/worker-logs/{agent}.log`.
6
+ */
7
+ export interface GetLogsOptions {
8
+ /** Directory containing worker logs. Defaults to `.agent-relay/worker-logs` in cwd. */
9
+ logsDir?: string;
10
+ /** Number of lines to return from the end. Default: 50 */
11
+ lines?: number;
12
+ }
13
+ export interface LogsResult {
14
+ agent: string;
15
+ content: string;
16
+ found: boolean;
17
+ lineCount: number;
18
+ /** Other agents that have log files (populated when `found` is false). */
19
+ availableAgents?: string[];
20
+ }
21
+ /**
22
+ * Get logs for a specific agent.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { getLogs } from "agent-relay/broker";
27
+ *
28
+ * const result = await getLogs("Worker1", { lines: 100 });
29
+ * if (result.found) {
30
+ * console.log(result.content);
31
+ * }
32
+ * ```
33
+ */
34
+ export declare function getLogs(agent: string, options?: GetLogsOptions): Promise<LogsResult>;
35
+ /**
36
+ * List all agents that have log files.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { listLoggedAgents } from "agent-relay/broker";
41
+ *
42
+ * const agents = await listLoggedAgents();
43
+ * console.log("Agents with logs:", agents);
44
+ * ```
45
+ */
46
+ export declare function listLoggedAgents(logsDir?: string): Promise<string[]>;
47
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AA2ED;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAW1E"}