agent-relay 2.1.10 → 2.1.12

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 (119) hide show
  1. package/dist/index.cjs +260 -45
  2. package/dist/src/cli/index.d.ts.map +1 -1
  3. package/dist/src/cli/index.js +438 -1
  4. package/dist/src/cli/index.js.map +1 -1
  5. package/package.json +18 -18
  6. package/packages/acp-bridge/README.md +171 -0
  7. package/packages/acp-bridge/dist/acp-agent.d.ts +118 -0
  8. package/packages/acp-bridge/dist/acp-agent.d.ts.map +1 -0
  9. package/packages/acp-bridge/dist/acp-agent.js +713 -0
  10. package/packages/acp-bridge/dist/acp-agent.js.map +1 -0
  11. package/packages/acp-bridge/dist/cli.d.ts +18 -0
  12. package/packages/acp-bridge/dist/cli.d.ts.map +1 -0
  13. package/packages/acp-bridge/dist/cli.js +125 -0
  14. package/packages/acp-bridge/dist/cli.js.map +1 -0
  15. package/packages/acp-bridge/dist/index.d.ts +24 -0
  16. package/packages/acp-bridge/dist/index.d.ts.map +1 -0
  17. package/packages/acp-bridge/dist/index.js +22 -0
  18. package/packages/acp-bridge/dist/index.js.map +1 -0
  19. package/packages/acp-bridge/dist/types.d.ts +144 -0
  20. package/packages/acp-bridge/dist/types.d.ts.map +1 -0
  21. package/packages/acp-bridge/dist/types.js +6 -0
  22. package/packages/acp-bridge/dist/types.js.map +1 -0
  23. package/packages/acp-bridge/package.json +60 -0
  24. package/packages/acp-bridge/src/acp-agent.ts +826 -0
  25. package/packages/acp-bridge/src/cli.ts +137 -0
  26. package/packages/acp-bridge/src/index.ts +34 -0
  27. package/packages/acp-bridge/src/types.ts +142 -0
  28. package/packages/acp-bridge/tsconfig.json +11 -0
  29. package/packages/api-types/package.json +1 -1
  30. package/packages/benchmark/package.json +4 -4
  31. package/packages/bridge/dist/spawner.d.ts +12 -0
  32. package/packages/bridge/dist/spawner.d.ts.map +1 -1
  33. package/packages/bridge/dist/spawner.js +108 -1
  34. package/packages/bridge/dist/spawner.js.map +1 -1
  35. package/packages/bridge/package.json +8 -8
  36. package/packages/bridge/src/spawner.ts +118 -1
  37. package/packages/cli-tester/package.json +1 -1
  38. package/packages/config/package.json +2 -2
  39. package/packages/continuity/package.json +2 -2
  40. package/packages/daemon/dist/server.js +5 -2
  41. package/packages/daemon/dist/server.js.map +1 -1
  42. package/packages/daemon/package.json +12 -12
  43. package/packages/daemon/src/server.ts +5 -2
  44. package/packages/hooks/package.json +4 -4
  45. package/packages/mcp/dist/client.d.ts +29 -1
  46. package/packages/mcp/dist/client.d.ts.map +1 -1
  47. package/packages/mcp/dist/client.js +50 -2
  48. package/packages/mcp/dist/client.js.map +1 -1
  49. package/packages/mcp/dist/file-transport.d.ts +13 -7
  50. package/packages/mcp/dist/file-transport.d.ts.map +1 -1
  51. package/packages/mcp/dist/file-transport.js +16 -9
  52. package/packages/mcp/dist/file-transport.js.map +1 -1
  53. package/packages/mcp/dist/hybrid-client.d.ts +11 -4
  54. package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
  55. package/packages/mcp/dist/hybrid-client.js +13 -5
  56. package/packages/mcp/dist/hybrid-client.js.map +1 -1
  57. package/packages/mcp/dist/index.d.ts +2 -2
  58. package/packages/mcp/dist/index.d.ts.map +1 -1
  59. package/packages/mcp/dist/index.js +5 -1
  60. package/packages/mcp/dist/index.js.map +1 -1
  61. package/packages/mcp/dist/install.d.ts.map +1 -1
  62. package/packages/mcp/dist/install.js +75 -9
  63. package/packages/mcp/dist/install.js.map +1 -1
  64. package/packages/mcp/dist/server.d.ts.map +1 -1
  65. package/packages/mcp/dist/server.js +19 -1
  66. package/packages/mcp/dist/server.js.map +1 -1
  67. package/packages/mcp/dist/tools/index.d.ts +2 -1
  68. package/packages/mcp/dist/tools/index.d.ts.map +1 -1
  69. package/packages/mcp/dist/tools/index.js +2 -1
  70. package/packages/mcp/dist/tools/index.js.map +1 -1
  71. package/packages/mcp/dist/tools/relay-channel.d.ts +26 -0
  72. package/packages/mcp/dist/tools/relay-channel.d.ts.map +1 -1
  73. package/packages/mcp/dist/tools/relay-channel.js +48 -0
  74. package/packages/mcp/dist/tools/relay-channel.js.map +1 -1
  75. package/packages/mcp/dist/tools/relay-connected.d.ts.map +1 -1
  76. package/packages/mcp/dist/tools/relay-connected.js +15 -1
  77. package/packages/mcp/dist/tools/relay-connected.js.map +1 -1
  78. package/packages/mcp/dist/tools/relay-messages.d.ts +32 -0
  79. package/packages/mcp/dist/tools/relay-messages.d.ts.map +1 -0
  80. package/packages/mcp/dist/tools/relay-messages.js +61 -0
  81. package/packages/mcp/dist/tools/relay-messages.js.map +1 -0
  82. package/packages/mcp/dist/tools/relay-who.d.ts.map +1 -1
  83. package/packages/mcp/dist/tools/relay-who.js +17 -2
  84. package/packages/mcp/dist/tools/relay-who.js.map +1 -1
  85. package/packages/mcp/package.json +4 -4
  86. package/packages/mcp/src/client.ts +101 -16
  87. package/packages/mcp/src/file-transport.ts +16 -9
  88. package/packages/mcp/src/hybrid-client.ts +13 -5
  89. package/packages/mcp/src/index.ts +15 -1
  90. package/packages/mcp/src/install.ts +85 -9
  91. package/packages/mcp/src/server.ts +30 -0
  92. package/packages/mcp/src/tools/index.ts +15 -0
  93. package/packages/mcp/src/tools/relay-channel.ts +58 -0
  94. package/packages/mcp/src/tools/relay-connected.ts +16 -1
  95. package/packages/mcp/src/tools/relay-messages.ts +66 -0
  96. package/packages/mcp/src/tools/relay-who.ts +18 -2
  97. package/packages/mcp/tests/client.test.ts +75 -0
  98. package/packages/mcp/tests/tools.test.ts +154 -0
  99. package/packages/memory/package.json +2 -2
  100. package/packages/policy/package.json +2 -2
  101. package/packages/protocol/package.json +1 -1
  102. package/packages/resiliency/package.json +1 -1
  103. package/packages/sdk/package.json +3 -3
  104. package/packages/spawner/package.json +1 -1
  105. package/packages/state/package.json +1 -1
  106. package/packages/storage/package.json +2 -2
  107. package/packages/storage/src/jsonl-adapter.test.ts +4 -3
  108. package/packages/telemetry/package.json +1 -1
  109. package/packages/trajectory/package.json +2 -2
  110. package/packages/user-directory/package.json +2 -2
  111. package/packages/utils/package.json +3 -3
  112. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +5 -0
  113. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
  114. package/packages/wrapper/dist/relay-pty-orchestrator.js +70 -4
  115. package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
  116. package/packages/wrapper/package.json +6 -6
  117. package/packages/wrapper/src/relay-pty-orchestrator.test.ts +7 -1
  118. package/packages/wrapper/src/relay-pty-orchestrator.ts +93 -4
  119. package/relay-snippets/agent-relay-snippet.md +25 -2
package/dist/index.cjs CHANGED
@@ -3156,13 +3156,13 @@ var init_logger = __esm({
3156
3156
  });
3157
3157
 
3158
3158
  // packages/config/dist/bridge-utils.js
3159
- var import_node_child_process9, import_node_util3, execAsync2;
3159
+ var import_node_child_process10, import_node_util3, execAsync2;
3160
3160
  var init_bridge_utils = __esm({
3161
3161
  "packages/config/dist/bridge-utils.js"() {
3162
3162
  "use strict";
3163
- import_node_child_process9 = require("node:child_process");
3163
+ import_node_child_process10 = require("node:child_process");
3164
3164
  import_node_util3 = require("node:util");
3165
- execAsync2 = (0, import_node_util3.promisify)(import_node_child_process9.exec);
3165
+ execAsync2 = (0, import_node_util3.promisify)(import_node_child_process10.exec);
3166
3166
  }
3167
3167
  });
3168
3168
 
@@ -43148,6 +43148,7 @@ var import_node_net3 = require("node:net");
43148
43148
  var import_node_crypto9 = require("node:crypto");
43149
43149
  var import_node_path11 = require("node:path");
43150
43150
  var import_node_os6 = require("node:os");
43151
+ var import_node_child_process4 = require("node:child_process");
43151
43152
  var import_node_fs8 = require("node:fs");
43152
43153
  var import_node_url2 = require("node:url");
43153
43154
 
@@ -43502,9 +43503,9 @@ var AgentHealthMonitor = class extends import_events.EventEmitter {
43502
43503
  * Get memory and CPU usage for a process
43503
43504
  */
43504
43505
  async getProcessUsage(pid) {
43505
- const { execSync: execSync10 } = await import("child_process");
43506
+ const { execSync: execSync12 } = await import("child_process");
43506
43507
  try {
43507
- const output = execSync10(`ps -o rss=,pcpu= -p ${pid}`, { encoding: "utf8" }).trim();
43508
+ const output = execSync12(`ps -o rss=,pcpu= -p ${pid}`, { encoding: "utf8" }).trim();
43508
43509
  const [rss, cpu] = output.split(/\s+/);
43509
43510
  return {
43510
43511
  memory: parseInt(rss, 10) * 1024,
@@ -46429,7 +46430,7 @@ var ACTIVITY_VERIFICATION = {
46429
46430
  function hashWorkspaceId(workspaceId) {
46430
46431
  return (0, import_node_crypto9.createHash)("sha256").update(workspaceId).digest("hex").slice(0, 12);
46431
46432
  }
46432
- var RelayPtyOrchestrator = class extends BaseWrapper {
46433
+ var RelayPtyOrchestrator = class _RelayPtyOrchestrator extends BaseWrapper {
46433
46434
  config;
46434
46435
  // Process management
46435
46436
  relayPtyProcess;
@@ -46493,6 +46494,42 @@ var RelayPtyOrchestrator = class extends BaseWrapper {
46493
46494
  cgroupManager;
46494
46495
  hasCgroupSetup = false;
46495
46496
  // Note: sessionEndProcessed and lastSummaryRawContent are inherited from BaseWrapper
46497
+ /**
46498
+ * Gather system diagnostics for debugging SIGKILL/unexpected exits.
46499
+ * Returns a formatted string with memory, process, and system info.
46500
+ */
46501
+ static gatherSigkillDiagnostics(agentName, pid) {
46502
+ const lines = [];
46503
+ try {
46504
+ const free = (0, import_node_os6.freemem)();
46505
+ const total = (0, import_node_os6.totalmem)();
46506
+ const usedPercent = Math.round((1 - free / total) * 100);
46507
+ lines.push(`Memory: ${Math.round(free / 1024 / 1024)}MB free / ${Math.round(total / 1024 / 1024)}MB total (${usedPercent}% used)`);
46508
+ try {
46509
+ const psOutput = (0, import_node_child_process4.execSync)("ps aux | grep -c relay-pty || echo 0", { encoding: "utf-8", timeout: 1e3 }).trim();
46510
+ lines.push(`relay-pty processes: ${psOutput}`);
46511
+ } catch {
46512
+ }
46513
+ try {
46514
+ const dmesgOutput = (0, import_node_child_process4.execSync)('dmesg -T 2>/dev/null | grep -i "killed process" | tail -3 || true', {
46515
+ encoding: "utf-8",
46516
+ timeout: 1e3
46517
+ }).trim();
46518
+ if (dmesgOutput) {
46519
+ lines.push(`Recent OOM kills: ${dmesgOutput.replace(/\n/g, " | ")}`);
46520
+ }
46521
+ } catch {
46522
+ }
46523
+ if (pid) {
46524
+ lines.push(`Killed process PID: ${pid}`);
46525
+ }
46526
+ lines.push(`Agent name: ${agentName}`);
46527
+ lines.push(`Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}`);
46528
+ } catch (err) {
46529
+ lines.push(`Diagnostics error: ${err instanceof Error ? err.message : String(err)}`);
46530
+ }
46531
+ return lines.join("\n ");
46532
+ }
46496
46533
  constructor(config2) {
46497
46534
  super(config2);
46498
46535
  this.config = config2;
@@ -46708,6 +46745,11 @@ var RelayPtyOrchestrator = class extends BaseWrapper {
46708
46745
  if (!binaryPath) {
46709
46746
  throw new Error("relay-pty binary not found. Build with: cd relay-pty && cargo build --release");
46710
46747
  }
46748
+ try {
46749
+ (0, import_node_fs8.accessSync)(binaryPath, import_node_fs8.constants.X_OK);
46750
+ } catch (err) {
46751
+ throw new Error(`relay-pty binary not executable at ${binaryPath}: ${err?.message ?? "permission denied"}. Build with: cd relay-pty && cargo build --release, or ensure the binary has execute permissions.`);
46752
+ }
46711
46753
  this.log(` Using binary: ${binaryPath}`);
46712
46754
  await this.spawnRelayPty(binaryPath);
46713
46755
  await this.connectToSocket();
@@ -46897,6 +46939,13 @@ var RelayPtyOrchestrator = class extends BaseWrapper {
46897
46939
  if (!this.socketConnected) {
46898
46940
  this.earlyExitInfo = { code, signal, stderr: stderrBuffer };
46899
46941
  }
46942
+ if (signal === "SIGKILL" || exitCode === 137) {
46943
+ const diagnostics = _RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, proc.pid);
46944
+ this.logError(` SIGKILL DETECTED - gathering diagnostics:
46945
+ ${diagnostics}`);
46946
+ console.error(`[relay-pty-orchestrator] SIGKILL for ${this.config.name}:
46947
+ ${diagnostics}`);
46948
+ }
46900
46949
  this.running = false;
46901
46950
  const crashContext = this.memoryMonitor.getCrashContext(this.config.name);
46902
46951
  this.memoryMonitor.unregister(this.config.name);
@@ -47318,7 +47367,10 @@ ${line}
47318
47367
  const exitReason = exitInfo.signal ? `signal ${exitInfo.signal}` : `code ${exitInfo.code ?? "unknown"}`;
47319
47368
  const stderrHint = exitInfo.stderr ? `
47320
47369
  stderr: ${exitInfo.stderr.trim().slice(0, 500)}` : "";
47321
- throw new Error(`relay-pty process died early (${exitReason}).${stderrHint}`);
47370
+ const diagnostics = exitInfo.signal === "SIGKILL" || exitInfo.code === 137 ? `
47371
+ Diagnostics (SIGKILL often indicates OOM or resource limits):
47372
+ ${_RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, this.relayPtyProcess?.pid)}` : "";
47373
+ throw new Error(`relay-pty process died early (${exitReason}).${stderrHint}${diagnostics}`);
47322
47374
  }
47323
47375
  throw new Error("relay-pty process died before socket could be created");
47324
47376
  }
@@ -47338,7 +47390,10 @@ ${line}
47338
47390
  const exitReason = exitInfo.signal ? `signal ${exitInfo.signal}` : `code ${exitInfo.code ?? "unknown"}`;
47339
47391
  const stderrHint = exitInfo.stderr ? `
47340
47392
  stderr: ${exitInfo.stderr.trim().slice(0, 500)}` : "";
47341
- throw new Error(`relay-pty process died during socket connection (${exitReason}).${stderrHint}`);
47393
+ const diagnostics = exitInfo.signal === "SIGKILL" || exitInfo.code === 137 ? `
47394
+ Diagnostics (SIGKILL often indicates OOM or resource limits):
47395
+ ${_RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, this.relayPtyProcess?.pid)}` : "";
47396
+ throw new Error(`relay-pty process died during socket connection (${exitReason}).${stderrHint}${diagnostics}`);
47342
47397
  }
47343
47398
  throw new Error(`Failed to connect to socket after ${maxAttempts} attempts`);
47344
47399
  }
@@ -48611,7 +48666,7 @@ var OpenCodeApi = class {
48611
48666
  var openCodeApi = new OpenCodeApi();
48612
48667
 
48613
48668
  // packages/wrapper/dist/opencode-wrapper.js
48614
- var import_node_child_process4 = require("node:child_process");
48669
+ var import_node_child_process5 = require("node:child_process");
48615
48670
  var TASK_INJECTION = {
48616
48671
  /** Maximum retries when injection fails */
48617
48672
  MAX_RETRIES: 3,
@@ -48719,7 +48774,7 @@ var OpenCodeWrapper = class extends BaseWrapper {
48719
48774
  this.running = true;
48720
48775
  await this.client.connect();
48721
48776
  const args = this.config.args ?? [];
48722
- this.process = (0, import_node_child_process4.spawn)(this.config.command, args, {
48777
+ this.process = (0, import_node_child_process5.spawn)(this.config.command, args, {
48723
48778
  cwd: this.config.cwd,
48724
48779
  env: { ...process.env, ...this.config.env },
48725
48780
  stdio: ["pipe", "pipe", "pipe"]
@@ -48797,7 +48852,7 @@ var OpenCodeWrapper = class extends BaseWrapper {
48797
48852
  */
48798
48853
  async startServe() {
48799
48854
  console.log("[OpenCodeWrapper] Auto-starting opencode serve...");
48800
- this.serveProcess = (0, import_node_child_process4.spawn)("opencode", ["serve"], {
48855
+ this.serveProcess = (0, import_node_child_process5.spawn)("opencode", ["serve"], {
48801
48856
  cwd: this.config.cwd,
48802
48857
  env: { ...process.env, ...this.config.env },
48803
48858
  stdio: "ignore",
@@ -55295,26 +55350,26 @@ var Router = class _Router {
55295
55350
  };
55296
55351
 
55297
55352
  // packages/bridge/dist/utils.js
55298
- var import_node_child_process5 = require("node:child_process");
55353
+ var import_node_child_process6 = require("node:child_process");
55299
55354
  var import_node_util = require("node:util");
55300
- var execAsync = (0, import_node_util.promisify)(import_node_child_process5.exec);
55355
+ var execAsync = (0, import_node_util.promisify)(import_node_child_process6.exec);
55301
55356
  function sleep2(ms) {
55302
55357
  return new Promise((resolve5) => setTimeout(resolve5, ms));
55303
55358
  }
55304
55359
 
55305
55360
  // packages/bridge/dist/shadow-cli.js
55306
- var import_node_child_process7 = require("node:child_process");
55361
+ var import_node_child_process8 = require("node:child_process");
55307
55362
  var import_node_util2 = require("node:util");
55308
55363
 
55309
55364
  // packages/utils/dist/command-resolver.js
55310
- var import_node_child_process6 = require("node:child_process");
55365
+ var import_node_child_process7 = require("node:child_process");
55311
55366
  var import_node_fs10 = __toESM(require("node:fs"), 1);
55312
55367
  function resolveCommand(command) {
55313
55368
  if (command.startsWith("/")) {
55314
55369
  return resolveSymlinks(command);
55315
55370
  }
55316
55371
  try {
55317
- const output = (0, import_node_child_process6.execSync)(`which ${command}`, {
55372
+ const output = (0, import_node_child_process7.execSync)(`which ${command}`, {
55318
55373
  encoding: "utf-8",
55319
55374
  stdio: ["pipe", "pipe", "pipe"],
55320
55375
  // Ensure we have a reasonable PATH
@@ -55348,7 +55403,7 @@ function resolveSymlinks(filePath) {
55348
55403
  }
55349
55404
  function commandExists(command) {
55350
55405
  try {
55351
- (0, import_node_child_process6.execSync)(`which ${command}`, {
55406
+ (0, import_node_child_process7.execSync)(`which ${command}`, {
55352
55407
  encoding: "utf-8",
55353
55408
  stdio: ["pipe", "pipe", "pipe"]
55354
55409
  });
@@ -55359,7 +55414,7 @@ function commandExists(command) {
55359
55414
  }
55360
55415
 
55361
55416
  // packages/bridge/dist/shadow-cli.js
55362
- var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process7.execFile);
55417
+ var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process8.execFile);
55363
55418
  function normalizeCli(cli) {
55364
55419
  if (!cli)
55365
55420
  return null;
@@ -55423,13 +55478,13 @@ async function selectShadowCli(primaryCli, options) {
55423
55478
  }
55424
55479
 
55425
55480
  // packages/bridge/dist/cli-resolution.js
55426
- var import_node_child_process8 = require("node:child_process");
55481
+ var import_node_child_process9 = require("node:child_process");
55427
55482
  init_logger();
55428
55483
  var log2 = createLogger2("cli-resolution");
55429
55484
  function commandExists2(cmd) {
55430
55485
  try {
55431
55486
  const whichCmd = process.platform === "win32" ? "where" : "which";
55432
- (0, import_node_child_process8.execSync)(`${whichCmd} ${cmd}`, { stdio: "ignore" });
55487
+ (0, import_node_child_process9.execSync)(`${whichCmd} ${cmd}`, { stdio: "ignore" });
55433
55488
  return true;
55434
55489
  } catch {
55435
55490
  return false;
@@ -55470,7 +55525,7 @@ function resolveCli(rawCommand) {
55470
55525
 
55471
55526
  // packages/bridge/dist/spawner.js
55472
55527
  var import_node_fs14 = __toESM(require("node:fs"), 1);
55473
- var import_node_child_process12 = require("node:child_process");
55528
+ var import_node_child_process13 = require("node:child_process");
55474
55529
  var import_node_path17 = __toESM(require("node:path"), 1);
55475
55530
  var import_node_url3 = require("node:url");
55476
55531
 
@@ -63593,8 +63648,8 @@ var relayStatusSchema = external_exports.object({});
63593
63648
 
63594
63649
  // packages/mcp/dist/tools/relay-logs.js
63595
63650
  var import_node_util4 = require("node:util");
63596
- var import_node_child_process10 = require("node:child_process");
63597
- var execAsync3 = (0, import_node_util4.promisify)(import_node_child_process10.exec);
63651
+ var import_node_child_process11 = require("node:child_process");
63652
+ var execAsync3 = (0, import_node_util4.promisify)(import_node_child_process11.exec);
63598
63653
  var relayLogsSchema = external_exports.object({
63599
63654
  agent: external_exports.string().describe("Name of the agent to get logs for"),
63600
63655
  lines: external_exports.number().optional().default(50).describe("Number of lines to retrieve (default: 50)")
@@ -63661,6 +63716,14 @@ var relayChannelMessageSchema = external_exports.object({
63661
63716
  message: external_exports.string().describe("The message content"),
63662
63717
  thread: external_exports.string().optional().describe("Optional thread ID for threaded conversations")
63663
63718
  });
63719
+ var relayAdminChannelJoinSchema = external_exports.object({
63720
+ channel: external_exports.string().describe("The channel name"),
63721
+ member: external_exports.string().describe("The agent name to add to the channel")
63722
+ });
63723
+ var relayAdminRemoveMemberSchema = external_exports.object({
63724
+ channel: external_exports.string().describe("The channel name"),
63725
+ member: external_exports.string().describe("The agent name to remove from the channel")
63726
+ });
63664
63727
 
63665
63728
  // packages/mcp/dist/tools/relay-shadow.js
63666
63729
  var relayShadowBindSchema = external_exports.object({
@@ -63685,11 +63748,21 @@ var relayVoteSchema = external_exports.object({
63685
63748
  reason: external_exports.string().optional().describe("Optional reason for your vote")
63686
63749
  });
63687
63750
 
63751
+ // packages/mcp/dist/tools/relay-messages.js
63752
+ var relayQueryMessagesSchema = external_exports.object({
63753
+ limit: external_exports.number().optional().describe("Maximum number of messages to return (default: 100)"),
63754
+ since_ts: external_exports.number().optional().describe("Only return messages after this Unix timestamp (ms)"),
63755
+ from: external_exports.string().optional().describe("Filter by sender name"),
63756
+ to: external_exports.string().optional().describe("Filter by recipient name"),
63757
+ thread: external_exports.string().optional().describe("Filter by thread ID"),
63758
+ order: external_exports.enum(["asc", "desc"]).optional().describe("Sort order (default: desc)")
63759
+ });
63760
+
63688
63761
  // packages/mcp/dist/install.js
63689
63762
  var import_node_fs13 = require("node:fs");
63690
63763
  var import_node_path16 = require("node:path");
63691
63764
  var import_node_os9 = require("node:os");
63692
- var import_node_child_process11 = require("node:child_process");
63765
+ var import_node_child_process12 = require("node:child_process");
63693
63766
 
63694
63767
  // node_modules/smol-toml/dist/error.js
63695
63768
  function getLineColFromPtr(string3, ptr) {
@@ -64597,7 +64670,7 @@ function getConfigPaths() {
64597
64670
  }
64598
64671
  function isUsingNvm() {
64599
64672
  try {
64600
- const nodePath = (0, import_node_child_process11.execSync)("which node", { encoding: "utf-8" }).trim();
64673
+ const nodePath = (0, import_node_child_process12.execSync)("which node", { encoding: "utf-8" }).trim();
64601
64674
  return nodePath.includes(".nvm");
64602
64675
  } catch {
64603
64676
  return false;
@@ -64605,14 +64678,14 @@ function isUsingNvm() {
64605
64678
  }
64606
64679
  function getNodePath() {
64607
64680
  try {
64608
- return (0, import_node_child_process11.execSync)("which node", { encoding: "utf-8" }).trim();
64681
+ return (0, import_node_child_process12.execSync)("which node", { encoding: "utf-8" }).trim();
64609
64682
  } catch {
64610
64683
  return null;
64611
64684
  }
64612
64685
  }
64613
64686
  function getGlobalMcpBinPath() {
64614
64687
  try {
64615
- const npmPrefix = (0, import_node_child_process11.execSync)("npm prefix -g", { encoding: "utf-8" }).trim();
64688
+ const npmPrefix = (0, import_node_child_process12.execSync)("npm prefix -g", { encoding: "utf-8" }).trim();
64616
64689
  const binPath = (0, import_node_path16.join)(npmPrefix, "lib", "node_modules", "@agent-relay", "mcp", "dist", "bin.js");
64617
64690
  if ((0, import_node_fs13.existsSync)(binPath)) {
64618
64691
  return binPath;
@@ -64651,8 +64724,59 @@ function getEditorConfig(editorKey) {
64651
64724
  return editors[editorKey];
64652
64725
  }
64653
64726
  function stripJsonComments(content) {
64654
- let result = content.replace(/\/\/.*$/gm, "");
64655
- result = result.replace(/\/\*[\s\S]*?\*\//g, "");
64727
+ let result = "";
64728
+ let inString = false;
64729
+ let inSingleLineComment = false;
64730
+ let inMultiLineComment = false;
64731
+ let i = 0;
64732
+ while (i < content.length) {
64733
+ const char = content[i];
64734
+ const nextChar = content[i + 1];
64735
+ if (!inSingleLineComment && !inMultiLineComment) {
64736
+ if (char === '"' && (i === 0 || content[i - 1] !== "\\")) {
64737
+ inString = !inString;
64738
+ result += char;
64739
+ i++;
64740
+ continue;
64741
+ }
64742
+ if (inString) {
64743
+ result += char;
64744
+ i++;
64745
+ continue;
64746
+ }
64747
+ if (char === "/" && nextChar === "/") {
64748
+ inSingleLineComment = true;
64749
+ i += 2;
64750
+ continue;
64751
+ }
64752
+ if (char === "/" && nextChar === "*") {
64753
+ inMultiLineComment = true;
64754
+ i += 2;
64755
+ continue;
64756
+ }
64757
+ result += char;
64758
+ i++;
64759
+ continue;
64760
+ }
64761
+ if (inSingleLineComment) {
64762
+ if (char === "\n") {
64763
+ inSingleLineComment = false;
64764
+ result += char;
64765
+ }
64766
+ i++;
64767
+ continue;
64768
+ }
64769
+ if (inMultiLineComment) {
64770
+ if (char === "*" && nextChar === "/") {
64771
+ inMultiLineComment = false;
64772
+ i += 2;
64773
+ continue;
64774
+ }
64775
+ i++;
64776
+ continue;
64777
+ }
64778
+ i++;
64779
+ }
64656
64780
  return result;
64657
64781
  }
64658
64782
  function readConfigFile(configPath, format) {
@@ -64750,12 +64874,19 @@ function installForEditor(editorKey, options = {}) {
64750
64874
  const defaultConfig = buildServerConfig();
64751
64875
  const serverConfig = {
64752
64876
  command: options.command || defaultConfig.command,
64753
- args: options.args || [...defaultConfig.args]
64877
+ args: options.args || [...defaultConfig.args],
64878
+ env: options.env ? { ...options.env } : void 0
64754
64879
  };
64755
- if (options.env) {
64756
- serverConfig.env = { ...options.env };
64757
- }
64758
64880
  const isProjectLocal = !options.global && options.projectDir;
64881
+ if (isProjectLocal) {
64882
+ const projectSocket = (0, import_node_path16.join)(options.projectDir, ".agent-relay", "relay.sock");
64883
+ serverConfig.env = {
64884
+ ...serverConfig.env || {},
64885
+ RELAY_SOCKET: serverConfig.env?.RELAY_SOCKET || projectSocket,
64886
+ RELAY_PROJECT: serverConfig.env?.RELAY_PROJECT || options.projectDir,
64887
+ AGENT_RELAY_PROJECT: serverConfig.env?.AGENT_RELAY_PROJECT || options.projectDir
64888
+ };
64889
+ }
64759
64890
  if (isProjectLocal) {
64760
64891
  serverConfig.args = [...serverConfig.args, "--project", options.projectDir];
64761
64892
  }
@@ -65021,6 +65152,12 @@ var AgentSpawner = class _AgentSpawner {
65021
65152
  policyEnforcementEnabled = false;
65022
65153
  onMarkSpawning;
65023
65154
  onClearSpawning;
65155
+ /**
65156
+ * Set of agent names currently being spawned.
65157
+ * Prevents race conditions where concurrent spawn requests for the same agent
65158
+ * could both pass the activeWorkers.has() check before either completes.
65159
+ */
65160
+ spawningAgents = /* @__PURE__ */ new Set();
65024
65161
  constructor(projectRootOrOptions, _tmuxSession, dashboardPort) {
65025
65162
  const options = typeof projectRootOrOptions === "string" ? { projectRoot: projectRootOrOptions, tmuxSession: _tmuxSession, dashboardPort } : projectRootOrOptions;
65026
65163
  const paths = getProjectPaths(options.projectRoot);
@@ -65045,6 +65182,72 @@ var AgentSpawner = class _AgentSpawner {
65045
65182
  });
65046
65183
  log3.info("Policy enforcement enabled");
65047
65184
  }
65185
+ this.cleanupOrphanedWorkers();
65186
+ }
65187
+ /**
65188
+ * Clean up orphaned relay-pty processes from a previous daemon run.
65189
+ * Reads workers.json to find PIDs from the previous session and kills any
65190
+ * that are still running. This ensures a clean slate after daemon restarts.
65191
+ */
65192
+ cleanupOrphanedWorkers() {
65193
+ if (!import_node_fs14.default.existsSync(this.workersPath)) {
65194
+ return;
65195
+ }
65196
+ try {
65197
+ const raw = JSON.parse(import_node_fs14.default.readFileSync(this.workersPath, "utf-8"));
65198
+ const workers = Array.isArray(raw?.workers) ? raw.workers : [];
65199
+ if (workers.length === 0) {
65200
+ return;
65201
+ }
65202
+ log3.info(`Checking for orphaned workers from previous run (${workers.length} entries)`);
65203
+ let orphansKilled = 0;
65204
+ for (const worker of workers) {
65205
+ if (!worker.pid) {
65206
+ continue;
65207
+ }
65208
+ let isRunning = false;
65209
+ try {
65210
+ process.kill(worker.pid, 0);
65211
+ isRunning = true;
65212
+ } catch {
65213
+ }
65214
+ if (isRunning) {
65215
+ try {
65216
+ const psOutput = (0, import_node_child_process13.execSync)(`ps -p ${worker.pid} -o comm= 2>/dev/null || true`, {
65217
+ encoding: "utf-8",
65218
+ timeout: 1e3
65219
+ }).trim();
65220
+ if (psOutput.includes("relay-pty") || psOutput.includes(worker.cli)) {
65221
+ log3.warn(`Killing orphaned worker "${worker.name}" (PID: ${worker.pid})`);
65222
+ try {
65223
+ process.kill(worker.pid, "SIGTERM");
65224
+ } catch {
65225
+ }
65226
+ const pid = worker.pid;
65227
+ setTimeout(() => {
65228
+ try {
65229
+ process.kill(pid, 0);
65230
+ process.kill(pid, "SIGKILL");
65231
+ log3.warn(`Force killed orphaned worker "${worker.name}" (PID: ${pid})`);
65232
+ } catch {
65233
+ }
65234
+ }, 500);
65235
+ orphansKilled++;
65236
+ } else {
65237
+ log3.debug(`PID ${worker.pid} is running but not relay-pty (${psOutput}), skipping`);
65238
+ }
65239
+ } catch (err) {
65240
+ log3.debug(`Could not verify PID ${worker.pid}, skipping: ${err}`);
65241
+ }
65242
+ }
65243
+ }
65244
+ import_node_fs14.default.writeFileSync(this.workersPath, JSON.stringify({ workers: [] }, null, 2));
65245
+ if (orphansKilled > 0) {
65246
+ log3.info(`Cleaned up ${orphansKilled} orphaned worker(s) from previous run`);
65247
+ }
65248
+ } catch (err) {
65249
+ log3.warn(`Failed to clean up orphaned workers: ${err}`);
65250
+ }
65048
65251
  }
65049
65252
  /**
65050
65253
  * Set cloud policy fetcher for workspace-level policies
@@ -65142,7 +65345,7 @@ var AgentSpawner = class _AgentSpawner {
65142
65345
  return null;
65143
65346
  }
65144
65347
  return await new Promise((resolve5) => {
65145
- (0, import_node_child_process12.execFile)(ghPath, ["auth", "token", "--hostname", "github.com"], { timeout: 5e3 }, (err, stdout) => {
65348
+ (0, import_node_child_process13.execFile)(ghPath, ["auth", "token", "--hostname", "github.com"], { timeout: 5e3 }, (err, stdout) => {
65146
65349
  if (err) {
65147
65350
  resolve5(null);
65148
65351
  return;
@@ -65268,6 +65471,13 @@ var AgentSpawner = class _AgentSpawner {
65268
65471
  error: `Agent "${name}" is already running. Use a different name or release the existing agent first.`
65269
65472
  };
65270
65473
  }
65474
+ if (this.spawningAgents.has(name)) {
65475
+ return {
65476
+ success: false,
65477
+ name,
65478
+ error: `Agent "${name}" spawn is already in progress. Wait for it to complete or use a different name.`
65479
+ };
65480
+ }
65271
65481
  if (this.isAgentConnected(name)) {
65272
65482
  return {
65273
65483
  success: false,
@@ -65300,6 +65510,8 @@ var AgentSpawner = class _AgentSpawner {
65300
65510
  log3.debug(`Policy allowed spawn: ${spawnerName} -> ${name} (source: ${decision.policySource})`);
65301
65511
  }
65302
65512
  }
65513
+ this.spawningAgents.add(name);
65514
+ log3.info(`Spawn lock acquired for ${name} (concurrent spawns: ${this.spawningAgents.size})`);
65303
65515
  try {
65304
65516
  const cliParts = cli.split(" ");
65305
65517
  const rawCommandName = cliParts[0];
@@ -65850,6 +66062,9 @@ ${relayInstructions}`;
65850
66062
  error: tracedError.userMessage,
65851
66063
  errorId: tracedError.errorId
65852
66064
  };
66065
+ } finally {
66066
+ this.spawningAgents.delete(name);
66067
+ log3.info(`Spawn lock released for ${name} (remaining: ${this.spawningAgents.size})`);
65853
66068
  }
65854
66069
  }
65855
66070
  /** Role presets for shadow agents */
@@ -71120,7 +71335,7 @@ var SyncQueue = class {
71120
71335
  // packages/utils/dist/git-remote.js
71121
71336
  var fs26 = __toESM(require("node:fs"), 1);
71122
71337
  var path27 = __toESM(require("node:path"), 1);
71123
- var import_node_child_process13 = require("node:child_process");
71338
+ var import_node_child_process14 = require("node:child_process");
71124
71339
  function parseGitRemoteUrl(url) {
71125
71340
  if (!url)
71126
71341
  return null;
@@ -71140,7 +71355,7 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
71140
71355
  if (!fs26.existsSync(gitDir)) {
71141
71356
  return null;
71142
71357
  }
71143
- const result = (0, import_node_child_process13.execSync)(`git remote get-url ${remoteName}`, {
71358
+ const result = (0, import_node_child_process14.execSync)(`git remote get-url ${remoteName}`, {
71144
71359
  cwd: workingDirectory,
71145
71360
  encoding: "utf-8",
71146
71361
  timeout: 5e3,
@@ -73994,7 +74209,7 @@ var Daemon = class _Daemon {
73994
74209
  return this.consensus;
73995
74210
  }
73996
74211
  };
73997
- var isMainModule = import_meta_url === `file://${process.argv[1]}`;
74212
+ var isMainModule = import_meta_url === `file://${process.argv[1]}` && !process.env.AGENT_RELAY_VERSION;
73998
74213
  if (isMainModule) {
73999
74214
  const daemon = new Daemon();
74000
74215
  process.on("SIGINT", async () => {
@@ -74748,15 +74963,15 @@ var Orchestrator = class extends import_events8.EventEmitter {
74748
74963
  */
74749
74964
  getGitInfo(workspacePath) {
74750
74965
  try {
74751
- const { execSync: execSync10 } = require("child_process");
74752
- const branch = execSync10("git branch --show-current", {
74966
+ const { execSync: execSync12 } = require("child_process");
74967
+ const branch = execSync12("git branch --show-current", {
74753
74968
  cwd: workspacePath,
74754
74969
  encoding: "utf8",
74755
74970
  stdio: ["pipe", "pipe", "pipe"]
74756
74971
  }).trim();
74757
74972
  let remote;
74758
74973
  try {
74759
- remote = execSync10("git remote get-url origin", {
74974
+ remote = execSync12("git remote get-url origin", {
74760
74975
  cwd: workspacePath,
74761
74976
  encoding: "utf8",
74762
74977
  stdio: ["pipe", "pipe", "pipe"]
@@ -77240,7 +77455,7 @@ function manageContext(compactor, messages) {
77240
77455
  }
77241
77456
 
77242
77457
  // packages/daemon/dist/cli-auth.js
77243
- var import_node_child_process14 = require("node:child_process");
77458
+ var import_node_child_process15 = require("node:child_process");
77244
77459
  var fs33 = __toESM(require("fs/promises"), 1);
77245
77460
  var os15 = __toESM(require("os"), 1);
77246
77461
  var import_node_path27 = require("node:path");
@@ -77357,7 +77572,7 @@ async function startCLIAuth(provider, options = {}) {
77357
77572
  config2.command,
77358
77573
  ...args
77359
77574
  ];
77360
- const proc = (0, import_node_child_process14.spawn)(relayPtyPath, relayArgs, {
77575
+ const proc = (0, import_node_child_process15.spawn)(relayPtyPath, relayArgs, {
77361
77576
  cwd: process.cwd(),
77362
77577
  env: {
77363
77578
  ...process.env,
@@ -78599,11 +78814,11 @@ var HookRegistry = class {
78599
78814
  };
78600
78815
 
78601
78816
  // packages/trajectory/dist/integration.js
78602
- var import_node_child_process15 = require("node:child_process");
78817
+ var import_node_child_process16 = require("node:child_process");
78603
78818
  async function runTrail2(args) {
78604
78819
  return new Promise((resolve5) => {
78605
78820
  const trajectoryEnv = getTrajectoryEnvVars();
78606
- const proc = (0, import_node_child_process15.spawn)("trail", args, {
78821
+ const proc = (0, import_node_child_process16.spawn)("trail", args, {
78607
78822
  cwd: getProjectPaths().projectRoot,
78608
78823
  env: { ...process.env, ...trajectoryEnv },
78609
78824
  stdio: ["pipe", "pipe", "pipe"]
@@ -78874,7 +79089,7 @@ var TrajectoryIntegration2 = class {
78874
79089
  */
78875
79090
  isTrailInstalledSync() {
78876
79091
  try {
78877
- (0, import_node_child_process15.execSync)("which trail", { stdio: "pipe" });
79092
+ (0, import_node_child_process16.execSync)("which trail", { stdio: "pipe" });
78878
79093
  return true;
78879
79094
  } catch {
78880
79095
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AA8JH;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAqC7H"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AA8VH;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAqC7H"}