agent-relay 2.1.10 → 2.1.11
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/dist/index.cjs +196 -39
- package/dist/src/cli/index.js +43 -0
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +18 -18
- package/packages/api-types/package.json +1 -1
- package/packages/benchmark/package.json +4 -4
- package/packages/bridge/dist/spawner.d.ts +12 -0
- package/packages/bridge/dist/spawner.d.ts.map +1 -1
- package/packages/bridge/dist/spawner.js +108 -1
- package/packages/bridge/dist/spawner.js.map +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/bridge/src/spawner.ts +118 -1
- package/packages/cli-tester/package.json +1 -1
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/dist/server.js +5 -2
- package/packages/daemon/dist/server.js.map +1 -1
- package/packages/daemon/package.json +12 -12
- package/packages/daemon/src/server.ts +5 -2
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/client.d.ts +29 -1
- package/packages/mcp/dist/client.d.ts.map +1 -1
- package/packages/mcp/dist/client.js +40 -0
- package/packages/mcp/dist/client.js.map +1 -1
- package/packages/mcp/dist/file-transport.d.ts +13 -7
- package/packages/mcp/dist/file-transport.d.ts.map +1 -1
- package/packages/mcp/dist/file-transport.js +16 -9
- package/packages/mcp/dist/file-transport.js.map +1 -1
- package/packages/mcp/dist/hybrid-client.d.ts +11 -4
- package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
- package/packages/mcp/dist/hybrid-client.js +13 -5
- package/packages/mcp/dist/hybrid-client.js.map +1 -1
- package/packages/mcp/dist/index.d.ts +2 -2
- package/packages/mcp/dist/index.d.ts.map +1 -1
- package/packages/mcp/dist/index.js +5 -1
- package/packages/mcp/dist/index.js.map +1 -1
- package/packages/mcp/dist/server.d.ts.map +1 -1
- package/packages/mcp/dist/server.js +19 -1
- package/packages/mcp/dist/server.js.map +1 -1
- package/packages/mcp/dist/tools/index.d.ts +2 -1
- package/packages/mcp/dist/tools/index.d.ts.map +1 -1
- package/packages/mcp/dist/tools/index.js +2 -1
- package/packages/mcp/dist/tools/index.js.map +1 -1
- package/packages/mcp/dist/tools/relay-channel.d.ts +26 -0
- package/packages/mcp/dist/tools/relay-channel.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-channel.js +48 -0
- package/packages/mcp/dist/tools/relay-channel.js.map +1 -1
- package/packages/mcp/dist/tools/relay-messages.d.ts +32 -0
- package/packages/mcp/dist/tools/relay-messages.d.ts.map +1 -0
- package/packages/mcp/dist/tools/relay-messages.js +61 -0
- package/packages/mcp/dist/tools/relay-messages.js.map +1 -0
- package/packages/mcp/package.json +4 -4
- package/packages/mcp/src/client.ts +91 -14
- package/packages/mcp/src/file-transport.ts +16 -9
- package/packages/mcp/src/hybrid-client.ts +13 -5
- package/packages/mcp/src/index.ts +15 -1
- package/packages/mcp/src/server.ts +30 -0
- package/packages/mcp/src/tools/index.ts +15 -0
- package/packages/mcp/src/tools/relay-channel.ts +58 -0
- package/packages/mcp/src/tools/relay-messages.ts +66 -0
- package/packages/mcp/tests/client.test.ts +75 -0
- package/packages/mcp/tests/tools.test.ts +154 -0
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/package.json +3 -3
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/storage/src/jsonl-adapter.test.ts +4 -3
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +3 -3
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +5 -0
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.js +70 -4
- package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
- package/packages/wrapper/package.json +6 -6
- package/packages/wrapper/src/relay-pty-orchestrator.test.ts +7 -1
- package/packages/wrapper/src/relay-pty-orchestrator.ts +93 -4
- 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
|
|
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
|
-
|
|
3163
|
+
import_node_child_process10 = require("node:child_process");
|
|
3164
3164
|
import_node_util3 = require("node:util");
|
|
3165
|
-
execAsync2 = (0, import_node_util3.promisify)(
|
|
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:
|
|
43506
|
+
const { execSync: execSync12 } = await import("child_process");
|
|
43506
43507
|
try {
|
|
43507
|
-
const output =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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)(
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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)(
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
63597
|
-
var execAsync3 = (0, import_node_util4.promisify)(
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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;
|
|
@@ -65021,6 +65094,12 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65021
65094
|
policyEnforcementEnabled = false;
|
|
65022
65095
|
onMarkSpawning;
|
|
65023
65096
|
onClearSpawning;
|
|
65097
|
+
/**
|
|
65098
|
+
* Set of agent names currently being spawned.
|
|
65099
|
+
* Prevents race conditions where concurrent spawn requests for the same agent
|
|
65100
|
+
* could both pass the activeWorkers.has() check before either completes.
|
|
65101
|
+
*/
|
|
65102
|
+
spawningAgents = /* @__PURE__ */ new Set();
|
|
65024
65103
|
constructor(projectRootOrOptions, _tmuxSession, dashboardPort) {
|
|
65025
65104
|
const options = typeof projectRootOrOptions === "string" ? { projectRoot: projectRootOrOptions, tmuxSession: _tmuxSession, dashboardPort } : projectRootOrOptions;
|
|
65026
65105
|
const paths = getProjectPaths(options.projectRoot);
|
|
@@ -65045,6 +65124,72 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65045
65124
|
});
|
|
65046
65125
|
log3.info("Policy enforcement enabled");
|
|
65047
65126
|
}
|
|
65127
|
+
this.cleanupOrphanedWorkers();
|
|
65128
|
+
}
|
|
65129
|
+
/**
|
|
65130
|
+
* Clean up orphaned relay-pty processes from a previous daemon run.
|
|
65131
|
+
* Reads workers.json to find PIDs from the previous session and kills any
|
|
65132
|
+
* that are still running. This ensures a clean slate after daemon restarts.
|
|
65133
|
+
*/
|
|
65134
|
+
cleanupOrphanedWorkers() {
|
|
65135
|
+
if (!import_node_fs14.default.existsSync(this.workersPath)) {
|
|
65136
|
+
return;
|
|
65137
|
+
}
|
|
65138
|
+
try {
|
|
65139
|
+
const raw = JSON.parse(import_node_fs14.default.readFileSync(this.workersPath, "utf-8"));
|
|
65140
|
+
const workers = Array.isArray(raw?.workers) ? raw.workers : [];
|
|
65141
|
+
if (workers.length === 0) {
|
|
65142
|
+
return;
|
|
65143
|
+
}
|
|
65144
|
+
log3.info(`Checking for orphaned workers from previous run (${workers.length} entries)`);
|
|
65145
|
+
let orphansKilled = 0;
|
|
65146
|
+
for (const worker of workers) {
|
|
65147
|
+
if (!worker.pid) {
|
|
65148
|
+
continue;
|
|
65149
|
+
}
|
|
65150
|
+
let isRunning = false;
|
|
65151
|
+
try {
|
|
65152
|
+
process.kill(worker.pid, 0);
|
|
65153
|
+
isRunning = true;
|
|
65154
|
+
} catch {
|
|
65155
|
+
}
|
|
65156
|
+
if (isRunning) {
|
|
65157
|
+
try {
|
|
65158
|
+
const psOutput = (0, import_node_child_process13.execSync)(`ps -p ${worker.pid} -o comm= 2>/dev/null || true`, {
|
|
65159
|
+
encoding: "utf-8",
|
|
65160
|
+
timeout: 1e3
|
|
65161
|
+
}).trim();
|
|
65162
|
+
if (psOutput.includes("relay-pty") || psOutput.includes(worker.cli)) {
|
|
65163
|
+
log3.warn(`Killing orphaned worker "${worker.name}" (PID: ${worker.pid})`);
|
|
65164
|
+
try {
|
|
65165
|
+
process.kill(worker.pid, "SIGTERM");
|
|
65166
|
+
} catch {
|
|
65167
|
+
}
|
|
65168
|
+
const pid = worker.pid;
|
|
65169
|
+
setTimeout(() => {
|
|
65170
|
+
try {
|
|
65171
|
+
process.kill(pid, 0);
|
|
65172
|
+
process.kill(pid, "SIGKILL");
|
|
65173
|
+
log3.warn(`Force killed orphaned worker "${worker.name}" (PID: ${pid})`);
|
|
65174
|
+
} catch {
|
|
65175
|
+
}
|
|
65176
|
+
}, 500);
|
|
65177
|
+
orphansKilled++;
|
|
65178
|
+
} else {
|
|
65179
|
+
log3.debug(`PID ${worker.pid} is running but not relay-pty (${psOutput}), skipping`);
|
|
65180
|
+
}
|
|
65181
|
+
} catch (err) {
|
|
65182
|
+
log3.debug(`Could not verify PID ${worker.pid}, skipping: ${err}`);
|
|
65183
|
+
}
|
|
65184
|
+
}
|
|
65185
|
+
}
|
|
65186
|
+
import_node_fs14.default.writeFileSync(this.workersPath, JSON.stringify({ workers: [] }, null, 2));
|
|
65187
|
+
if (orphansKilled > 0) {
|
|
65188
|
+
log3.info(`Cleaned up ${orphansKilled} orphaned worker(s) from previous run`);
|
|
65189
|
+
}
|
|
65190
|
+
} catch (err) {
|
|
65191
|
+
log3.warn(`Failed to clean up orphaned workers: ${err}`);
|
|
65192
|
+
}
|
|
65048
65193
|
}
|
|
65049
65194
|
/**
|
|
65050
65195
|
* Set cloud policy fetcher for workspace-level policies
|
|
@@ -65142,7 +65287,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65142
65287
|
return null;
|
|
65143
65288
|
}
|
|
65144
65289
|
return await new Promise((resolve5) => {
|
|
65145
|
-
(0,
|
|
65290
|
+
(0, import_node_child_process13.execFile)(ghPath, ["auth", "token", "--hostname", "github.com"], { timeout: 5e3 }, (err, stdout) => {
|
|
65146
65291
|
if (err) {
|
|
65147
65292
|
resolve5(null);
|
|
65148
65293
|
return;
|
|
@@ -65268,6 +65413,13 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65268
65413
|
error: `Agent "${name}" is already running. Use a different name or release the existing agent first.`
|
|
65269
65414
|
};
|
|
65270
65415
|
}
|
|
65416
|
+
if (this.spawningAgents.has(name)) {
|
|
65417
|
+
return {
|
|
65418
|
+
success: false,
|
|
65419
|
+
name,
|
|
65420
|
+
error: `Agent "${name}" spawn is already in progress. Wait for it to complete or use a different name.`
|
|
65421
|
+
};
|
|
65422
|
+
}
|
|
65271
65423
|
if (this.isAgentConnected(name)) {
|
|
65272
65424
|
return {
|
|
65273
65425
|
success: false,
|
|
@@ -65300,6 +65452,8 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65300
65452
|
log3.debug(`Policy allowed spawn: ${spawnerName} -> ${name} (source: ${decision.policySource})`);
|
|
65301
65453
|
}
|
|
65302
65454
|
}
|
|
65455
|
+
this.spawningAgents.add(name);
|
|
65456
|
+
log3.info(`Spawn lock acquired for ${name} (concurrent spawns: ${this.spawningAgents.size})`);
|
|
65303
65457
|
try {
|
|
65304
65458
|
const cliParts = cli.split(" ");
|
|
65305
65459
|
const rawCommandName = cliParts[0];
|
|
@@ -65850,6 +66004,9 @@ ${relayInstructions}`;
|
|
|
65850
66004
|
error: tracedError.userMessage,
|
|
65851
66005
|
errorId: tracedError.errorId
|
|
65852
66006
|
};
|
|
66007
|
+
} finally {
|
|
66008
|
+
this.spawningAgents.delete(name);
|
|
66009
|
+
log3.info(`Spawn lock released for ${name} (remaining: ${this.spawningAgents.size})`);
|
|
65853
66010
|
}
|
|
65854
66011
|
}
|
|
65855
66012
|
/** Role presets for shadow agents */
|
|
@@ -71120,7 +71277,7 @@ var SyncQueue = class {
|
|
|
71120
71277
|
// packages/utils/dist/git-remote.js
|
|
71121
71278
|
var fs26 = __toESM(require("node:fs"), 1);
|
|
71122
71279
|
var path27 = __toESM(require("node:path"), 1);
|
|
71123
|
-
var
|
|
71280
|
+
var import_node_child_process14 = require("node:child_process");
|
|
71124
71281
|
function parseGitRemoteUrl(url) {
|
|
71125
71282
|
if (!url)
|
|
71126
71283
|
return null;
|
|
@@ -71140,7 +71297,7 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
|
|
|
71140
71297
|
if (!fs26.existsSync(gitDir)) {
|
|
71141
71298
|
return null;
|
|
71142
71299
|
}
|
|
71143
|
-
const result = (0,
|
|
71300
|
+
const result = (0, import_node_child_process14.execSync)(`git remote get-url ${remoteName}`, {
|
|
71144
71301
|
cwd: workingDirectory,
|
|
71145
71302
|
encoding: "utf-8",
|
|
71146
71303
|
timeout: 5e3,
|
|
@@ -73994,7 +74151,7 @@ var Daemon = class _Daemon {
|
|
|
73994
74151
|
return this.consensus;
|
|
73995
74152
|
}
|
|
73996
74153
|
};
|
|
73997
|
-
var isMainModule = import_meta_url === `file://${process.argv[1]}
|
|
74154
|
+
var isMainModule = import_meta_url === `file://${process.argv[1]}` && !process.env.AGENT_RELAY_VERSION;
|
|
73998
74155
|
if (isMainModule) {
|
|
73999
74156
|
const daemon = new Daemon();
|
|
74000
74157
|
process.on("SIGINT", async () => {
|
|
@@ -74748,15 +74905,15 @@ var Orchestrator = class extends import_events8.EventEmitter {
|
|
|
74748
74905
|
*/
|
|
74749
74906
|
getGitInfo(workspacePath) {
|
|
74750
74907
|
try {
|
|
74751
|
-
const { execSync:
|
|
74752
|
-
const branch =
|
|
74908
|
+
const { execSync: execSync12 } = require("child_process");
|
|
74909
|
+
const branch = execSync12("git branch --show-current", {
|
|
74753
74910
|
cwd: workspacePath,
|
|
74754
74911
|
encoding: "utf8",
|
|
74755
74912
|
stdio: ["pipe", "pipe", "pipe"]
|
|
74756
74913
|
}).trim();
|
|
74757
74914
|
let remote;
|
|
74758
74915
|
try {
|
|
74759
|
-
remote =
|
|
74916
|
+
remote = execSync12("git remote get-url origin", {
|
|
74760
74917
|
cwd: workspacePath,
|
|
74761
74918
|
encoding: "utf8",
|
|
74762
74919
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -77240,7 +77397,7 @@ function manageContext(compactor, messages) {
|
|
|
77240
77397
|
}
|
|
77241
77398
|
|
|
77242
77399
|
// packages/daemon/dist/cli-auth.js
|
|
77243
|
-
var
|
|
77400
|
+
var import_node_child_process15 = require("node:child_process");
|
|
77244
77401
|
var fs33 = __toESM(require("fs/promises"), 1);
|
|
77245
77402
|
var os15 = __toESM(require("os"), 1);
|
|
77246
77403
|
var import_node_path27 = require("node:path");
|
|
@@ -77357,7 +77514,7 @@ async function startCLIAuth(provider, options = {}) {
|
|
|
77357
77514
|
config2.command,
|
|
77358
77515
|
...args
|
|
77359
77516
|
];
|
|
77360
|
-
const proc = (0,
|
|
77517
|
+
const proc = (0, import_node_child_process15.spawn)(relayPtyPath, relayArgs, {
|
|
77361
77518
|
cwd: process.cwd(),
|
|
77362
77519
|
env: {
|
|
77363
77520
|
...process.env,
|
|
@@ -78599,11 +78756,11 @@ var HookRegistry = class {
|
|
|
78599
78756
|
};
|
|
78600
78757
|
|
|
78601
78758
|
// packages/trajectory/dist/integration.js
|
|
78602
|
-
var
|
|
78759
|
+
var import_node_child_process16 = require("node:child_process");
|
|
78603
78760
|
async function runTrail2(args) {
|
|
78604
78761
|
return new Promise((resolve5) => {
|
|
78605
78762
|
const trajectoryEnv = getTrajectoryEnvVars();
|
|
78606
|
-
const proc = (0,
|
|
78763
|
+
const proc = (0, import_node_child_process16.spawn)("trail", args, {
|
|
78607
78764
|
cwd: getProjectPaths().projectRoot,
|
|
78608
78765
|
env: { ...process.env, ...trajectoryEnv },
|
|
78609
78766
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -78874,7 +79031,7 @@ var TrajectoryIntegration2 = class {
|
|
|
78874
79031
|
*/
|
|
78875
79032
|
isTrailInstalledSync() {
|
|
78876
79033
|
try {
|
|
78877
|
-
(0,
|
|
79034
|
+
(0, import_node_child_process16.execSync)("which trail", { stdio: "pipe" });
|
|
78878
79035
|
return true;
|
|
78879
79036
|
} catch {
|
|
78880
79037
|
return false;
|
package/dist/src/cli/index.js
CHANGED
|
@@ -2140,6 +2140,49 @@ program
|
|
|
2140
2140
|
process.exit(1);
|
|
2141
2141
|
}
|
|
2142
2142
|
});
|
|
2143
|
+
// send - Send a message to an agent via the local daemon
|
|
2144
|
+
program
|
|
2145
|
+
.command('send')
|
|
2146
|
+
.description('Send a message to an agent')
|
|
2147
|
+
.argument('<agent>', 'Target agent name (or * for broadcast, #channel for channel)')
|
|
2148
|
+
.argument('<message>', 'Message to send')
|
|
2149
|
+
.option('--from <name>', 'Sender name', 'cli')
|
|
2150
|
+
.option('--thread <id>', 'Thread identifier')
|
|
2151
|
+
.action(async (agent, message, options) => {
|
|
2152
|
+
const paths = getProjectPaths();
|
|
2153
|
+
const client = new RelayClient({
|
|
2154
|
+
socketPath: paths.socketPath,
|
|
2155
|
+
agentName: options.from,
|
|
2156
|
+
entityType: 'user',
|
|
2157
|
+
quiet: true,
|
|
2158
|
+
reconnect: false,
|
|
2159
|
+
maxReconnectAttempts: 0,
|
|
2160
|
+
reconnectDelayMs: 0,
|
|
2161
|
+
reconnectMaxDelayMs: 0,
|
|
2162
|
+
});
|
|
2163
|
+
try {
|
|
2164
|
+
await client.connect();
|
|
2165
|
+
const sent = client.sendMessage(agent, message, 'message', undefined, options.thread);
|
|
2166
|
+
if (sent) {
|
|
2167
|
+
console.log(`Message sent to ${agent}`);
|
|
2168
|
+
}
|
|
2169
|
+
else {
|
|
2170
|
+
console.error('Failed to send message');
|
|
2171
|
+
process.exit(1);
|
|
2172
|
+
}
|
|
2173
|
+
client.disconnect();
|
|
2174
|
+
}
|
|
2175
|
+
catch (err) {
|
|
2176
|
+
if (err.code === 'ECONNREFUSED' || err.code === 'ENOENT' || err.message?.includes('Cannot connect')) {
|
|
2177
|
+
console.error(`Cannot connect to daemon. Is it running?`);
|
|
2178
|
+
console.log(`Run 'agent-relay up' to start the daemon.`);
|
|
2179
|
+
}
|
|
2180
|
+
else {
|
|
2181
|
+
console.error(`Failed to send message: ${err.message}`);
|
|
2182
|
+
}
|
|
2183
|
+
process.exit(1);
|
|
2184
|
+
}
|
|
2185
|
+
});
|
|
2143
2186
|
// agents:kill - Kill a spawned agent by PID
|
|
2144
2187
|
program
|
|
2145
2188
|
.command('agents:kill')
|