agent-relay 2.1.3 → 2.1.4
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/bin/relay-pty-darwin-arm64 +0 -0
- package/bin/relay-pty-darwin-x64 +0 -0
- package/bin/relay-pty-linux-arm64 +0 -0
- package/bin/relay-pty-linux-x64 +0 -0
- package/dist/index.cjs +214 -172
- package/package.json +18 -18
- package/packages/api-types/package.json +1 -1
- package/packages/benchmark/package.json +4 -4
- package/packages/bridge/dist/cli-resolution.d.ts +32 -0
- package/packages/bridge/dist/cli-resolution.d.ts.map +1 -0
- package/packages/bridge/dist/cli-resolution.js +88 -0
- package/packages/bridge/dist/cli-resolution.js.map +1 -0
- package/packages/bridge/dist/index.d.ts +1 -0
- package/packages/bridge/dist/index.d.ts.map +1 -1
- package/packages/bridge/dist/index.js +2 -0
- package/packages/bridge/dist/index.js.map +1 -1
- package/packages/bridge/dist/spawner.d.ts.map +1 -1
- package/packages/bridge/dist/spawner.js +4 -12
- package/packages/bridge/dist/spawner.js.map +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/bridge/src/cli-resolution.test.ts +225 -0
- package/packages/bridge/src/cli-resolution.ts +100 -0
- package/packages/bridge/src/index.ts +9 -0
- package/packages/bridge/src/spawner.ts +4 -13
- 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/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/package.json +3 -3
- 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 +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- 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 +2 -2
- package/packages/wrapper/dist/shared.d.ts.map +1 -1
- package/packages/wrapper/dist/shared.js +5 -0
- package/packages/wrapper/dist/shared.js.map +1 -1
- package/packages/wrapper/package.json +6 -6
- package/packages/wrapper/src/shared.ts +5 -0
package/dist/index.cjs
CHANGED
|
@@ -3147,13 +3147,13 @@ var init_logger = __esm({
|
|
|
3147
3147
|
});
|
|
3148
3148
|
|
|
3149
3149
|
// packages/config/dist/bridge-utils.js
|
|
3150
|
-
var
|
|
3150
|
+
var import_node_child_process9, import_node_util3, execAsync2;
|
|
3151
3151
|
var init_bridge_utils = __esm({
|
|
3152
3152
|
"packages/config/dist/bridge-utils.js"() {
|
|
3153
3153
|
"use strict";
|
|
3154
|
-
|
|
3154
|
+
import_node_child_process9 = require("node:child_process");
|
|
3155
3155
|
import_node_util3 = require("node:util");
|
|
3156
|
-
execAsync2 = (0, import_node_util3.promisify)(
|
|
3156
|
+
execAsync2 = (0, import_node_util3.promisify)(import_node_child_process9.exec);
|
|
3157
3157
|
}
|
|
3158
3158
|
});
|
|
3159
3159
|
|
|
@@ -7441,11 +7441,11 @@ var require_core = __commonJS({
|
|
|
7441
7441
|
Ajv2.ValidationError = validation_error_1.default;
|
|
7442
7442
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
7443
7443
|
exports2.default = Ajv2;
|
|
7444
|
-
function checkOptions(checkOpts, options, msg,
|
|
7444
|
+
function checkOptions(checkOpts, options, msg, log8 = "error") {
|
|
7445
7445
|
for (const key in checkOpts) {
|
|
7446
7446
|
const opt = key;
|
|
7447
7447
|
if (opt in options)
|
|
7448
|
-
this.logger[
|
|
7448
|
+
this.logger[log8](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
7449
7449
|
}
|
|
7450
7450
|
}
|
|
7451
7451
|
function getSchEnv(keyRef) {
|
|
@@ -20852,7 +20852,7 @@ var require_node = __commonJS({
|
|
|
20852
20852
|
var tty = require("tty");
|
|
20853
20853
|
var util2 = require("util");
|
|
20854
20854
|
exports2.init = init;
|
|
20855
|
-
exports2.log =
|
|
20855
|
+
exports2.log = log8;
|
|
20856
20856
|
exports2.formatArgs = formatArgs;
|
|
20857
20857
|
exports2.save = save;
|
|
20858
20858
|
exports2.load = load;
|
|
@@ -20987,7 +20987,7 @@ var require_node = __commonJS({
|
|
|
20987
20987
|
}
|
|
20988
20988
|
return (/* @__PURE__ */ new Date()).toISOString() + " ";
|
|
20989
20989
|
}
|
|
20990
|
-
function
|
|
20990
|
+
function log8(...args) {
|
|
20991
20991
|
return process.stderr.write(util2.formatWithOptions(exports2.inspectOpts, ...args) + "\n");
|
|
20992
20992
|
}
|
|
20993
20993
|
function save(namespaces) {
|
|
@@ -31619,13 +31619,13 @@ var channel_membership_store_exports = {};
|
|
|
31619
31619
|
__export(channel_membership_store_exports, {
|
|
31620
31620
|
CloudChannelMembershipStore: () => CloudChannelMembershipStore
|
|
31621
31621
|
});
|
|
31622
|
-
var
|
|
31622
|
+
var log7, CloudChannelMembershipStore;
|
|
31623
31623
|
var init_channel_membership_store = __esm({
|
|
31624
31624
|
"packages/daemon/dist/channel-membership-store.js"() {
|
|
31625
31625
|
"use strict";
|
|
31626
31626
|
init_esm();
|
|
31627
31627
|
init_logger();
|
|
31628
|
-
|
|
31628
|
+
log7 = createLogger2("channel-membership-store");
|
|
31629
31629
|
CloudChannelMembershipStore = class {
|
|
31630
31630
|
workspaceId;
|
|
31631
31631
|
pool;
|
|
@@ -31655,7 +31655,7 @@ var init_channel_membership_store = __esm({
|
|
|
31655
31655
|
member: row.member_id
|
|
31656
31656
|
})).filter((row) => Boolean(row.channel && row.member));
|
|
31657
31657
|
} catch (err) {
|
|
31658
|
-
|
|
31658
|
+
log7.error("Failed to load channel memberships from cloud DB", {
|
|
31659
31659
|
error: err instanceof Error ? err.message : String(err)
|
|
31660
31660
|
});
|
|
31661
31661
|
return [];
|
|
@@ -31678,7 +31678,7 @@ var init_channel_membership_store = __esm({
|
|
|
31678
31678
|
member: row.member_id
|
|
31679
31679
|
})).filter((row) => Boolean(row.channel && row.member));
|
|
31680
31680
|
} catch (err) {
|
|
31681
|
-
|
|
31681
|
+
log7.error("Failed to load channel memberships for agent from cloud DB", {
|
|
31682
31682
|
memberName,
|
|
31683
31683
|
error: err instanceof Error ? err.message : String(err)
|
|
31684
31684
|
});
|
|
@@ -31704,7 +31704,7 @@ var init_channel_membership_store = __esm({
|
|
|
31704
31704
|
ON CONFLICT (channel_id, member_id) DO NOTHING
|
|
31705
31705
|
`, [channelRowId, member]);
|
|
31706
31706
|
} catch (err) {
|
|
31707
|
-
|
|
31707
|
+
log7.error("Failed to add channel member in cloud DB", {
|
|
31708
31708
|
channel: normalized,
|
|
31709
31709
|
member,
|
|
31710
31710
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -31726,7 +31726,7 @@ var init_channel_membership_store = __esm({
|
|
|
31726
31726
|
try {
|
|
31727
31727
|
await this.pool.query("DELETE FROM channel_members WHERE channel_id = $1 AND member_id = $2", [channelRowId, member]);
|
|
31728
31728
|
} catch (err) {
|
|
31729
|
-
|
|
31729
|
+
log7.error("Failed to remove channel member in cloud DB", {
|
|
31730
31730
|
channel: normalized,
|
|
31731
31731
|
member,
|
|
31732
31732
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -31766,7 +31766,7 @@ var init_channel_membership_store = __esm({
|
|
|
31766
31766
|
LIMIT 1
|
|
31767
31767
|
`, [this.workspaceId, channelId]);
|
|
31768
31768
|
if (!result.rows[0]?.id) {
|
|
31769
|
-
|
|
31769
|
+
log7.warn("Channel not found in cloud DB for membership update", {
|
|
31770
31770
|
workspaceId: this.workspaceId,
|
|
31771
31771
|
channelId
|
|
31772
31772
|
});
|
|
@@ -31774,7 +31774,7 @@ var init_channel_membership_store = __esm({
|
|
|
31774
31774
|
}
|
|
31775
31775
|
return result.rows[0].id;
|
|
31776
31776
|
} catch (err) {
|
|
31777
|
-
|
|
31777
|
+
log7.error("Failed to look up channel row in cloud DB", {
|
|
31778
31778
|
channelId,
|
|
31779
31779
|
error: err instanceof Error ? err.message : String(err)
|
|
31780
31780
|
});
|
|
@@ -37398,6 +37398,7 @@ function createInjectionMetrics() {
|
|
|
37398
37398
|
}
|
|
37399
37399
|
function detectCliType(command) {
|
|
37400
37400
|
const cmdLower = command.toLowerCase();
|
|
37401
|
+
const cmdName = cmdLower.split(/[\s/\\]/).pop() || cmdLower;
|
|
37401
37402
|
if (cmdLower.includes("gemini"))
|
|
37402
37403
|
return "gemini";
|
|
37403
37404
|
if (cmdLower.includes("codex"))
|
|
@@ -37410,6 +37411,8 @@ function detectCliType(command) {
|
|
|
37410
37411
|
return "opencode";
|
|
37411
37412
|
if (cmdLower.includes("cursor"))
|
|
37412
37413
|
return "cursor";
|
|
37414
|
+
if (cmdName === "agent" || cmdName === "cursor-agent")
|
|
37415
|
+
return "cursor";
|
|
37413
37416
|
return "other";
|
|
37414
37417
|
}
|
|
37415
37418
|
function getDefaultRelayPrefix() {
|
|
@@ -43430,9 +43433,9 @@ var AgentHealthMonitor = class extends import_events.EventEmitter {
|
|
|
43430
43433
|
* Get memory and CPU usage for a process
|
|
43431
43434
|
*/
|
|
43432
43435
|
async getProcessUsage(pid) {
|
|
43433
|
-
const { execSync:
|
|
43436
|
+
const { execSync: execSync10 } = await import("child_process");
|
|
43434
43437
|
try {
|
|
43435
|
-
const output =
|
|
43438
|
+
const output = execSync10(`ps -o rss=,pcpu= -p ${pid}`, { encoding: "utf8" }).trim();
|
|
43436
43439
|
const [rss, cpu] = output.split(/\s+/);
|
|
43437
43440
|
return {
|
|
43438
43441
|
memory: parseInt(rss, 10) * 1024,
|
|
@@ -55172,9 +55175,55 @@ async function selectShadowCli(primaryCli, options) {
|
|
|
55172
55175
|
throw new Error("No shadow-capable CLI authenticated. Install Claude or OpenCode (codex) and try again.");
|
|
55173
55176
|
}
|
|
55174
55177
|
|
|
55178
|
+
// packages/bridge/dist/cli-resolution.js
|
|
55179
|
+
var import_node_child_process8 = require("node:child_process");
|
|
55180
|
+
init_logger();
|
|
55181
|
+
var log2 = createLogger2("cli-resolution");
|
|
55182
|
+
function commandExists2(cmd) {
|
|
55183
|
+
try {
|
|
55184
|
+
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
55185
|
+
(0, import_node_child_process8.execSync)(`${whichCmd} ${cmd}`, { stdio: "ignore" });
|
|
55186
|
+
return true;
|
|
55187
|
+
} catch {
|
|
55188
|
+
return false;
|
|
55189
|
+
}
|
|
55190
|
+
}
|
|
55191
|
+
var detectedCursorCli = null;
|
|
55192
|
+
function detectCursorCli() {
|
|
55193
|
+
if (detectedCursorCli !== null) {
|
|
55194
|
+
return detectedCursorCli;
|
|
55195
|
+
}
|
|
55196
|
+
if (commandExists2("agent")) {
|
|
55197
|
+
detectedCursorCli = "agent";
|
|
55198
|
+
log2.debug("Detected Cursor CLI: agent (newer version)");
|
|
55199
|
+
return "agent";
|
|
55200
|
+
}
|
|
55201
|
+
if (commandExists2("cursor-agent")) {
|
|
55202
|
+
detectedCursorCli = "cursor-agent";
|
|
55203
|
+
log2.debug("Detected Cursor CLI: cursor-agent (older version)");
|
|
55204
|
+
return "cursor-agent";
|
|
55205
|
+
}
|
|
55206
|
+
log2.debug("Cursor CLI not found (neither agent nor cursor-agent)");
|
|
55207
|
+
return null;
|
|
55208
|
+
}
|
|
55209
|
+
function resolveCli(rawCommand) {
|
|
55210
|
+
const cmdLower = rawCommand.toLowerCase();
|
|
55211
|
+
if (cmdLower === "cursor" || cmdLower === "cursor-agent") {
|
|
55212
|
+
const cursorCli = detectCursorCli();
|
|
55213
|
+
if (cursorCli) {
|
|
55214
|
+
return cursorCli;
|
|
55215
|
+
}
|
|
55216
|
+
return "agent";
|
|
55217
|
+
}
|
|
55218
|
+
if (cmdLower === "google") {
|
|
55219
|
+
return "gemini";
|
|
55220
|
+
}
|
|
55221
|
+
return rawCommand;
|
|
55222
|
+
}
|
|
55223
|
+
|
|
55175
55224
|
// packages/bridge/dist/spawner.js
|
|
55176
55225
|
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
55177
|
-
var
|
|
55226
|
+
var import_node_child_process12 = require("node:child_process");
|
|
55178
55227
|
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
55179
55228
|
var import_node_url3 = require("node:url");
|
|
55180
55229
|
|
|
@@ -63297,8 +63346,8 @@ var relayStatusSchema = external_exports.object({});
|
|
|
63297
63346
|
|
|
63298
63347
|
// packages/mcp/dist/tools/relay-logs.js
|
|
63299
63348
|
var import_node_util4 = require("node:util");
|
|
63300
|
-
var
|
|
63301
|
-
var execAsync3 = (0, import_node_util4.promisify)(
|
|
63349
|
+
var import_node_child_process10 = require("node:child_process");
|
|
63350
|
+
var execAsync3 = (0, import_node_util4.promisify)(import_node_child_process10.exec);
|
|
63302
63351
|
var relayLogsSchema = external_exports.object({
|
|
63303
63352
|
agent: external_exports.string().describe("Name of the agent to get logs for"),
|
|
63304
63353
|
lines: external_exports.number().optional().default(50).describe("Number of lines to retrieve (default: 50)")
|
|
@@ -63393,7 +63442,7 @@ var relayVoteSchema = external_exports.object({
|
|
|
63393
63442
|
var import_node_fs13 = require("node:fs");
|
|
63394
63443
|
var import_node_path16 = require("node:path");
|
|
63395
63444
|
var import_node_os9 = require("node:os");
|
|
63396
|
-
var
|
|
63445
|
+
var import_node_child_process11 = require("node:child_process");
|
|
63397
63446
|
|
|
63398
63447
|
// node_modules/smol-toml/dist/error.js
|
|
63399
63448
|
function getLineColFromPtr(string3, ptr) {
|
|
@@ -64301,7 +64350,7 @@ function getConfigPaths() {
|
|
|
64301
64350
|
}
|
|
64302
64351
|
function isUsingNvm() {
|
|
64303
64352
|
try {
|
|
64304
|
-
const nodePath = (0,
|
|
64353
|
+
const nodePath = (0, import_node_child_process11.execSync)("which node", { encoding: "utf-8" }).trim();
|
|
64305
64354
|
return nodePath.includes(".nvm");
|
|
64306
64355
|
} catch {
|
|
64307
64356
|
return false;
|
|
@@ -64309,14 +64358,14 @@ function isUsingNvm() {
|
|
|
64309
64358
|
}
|
|
64310
64359
|
function getNodePath() {
|
|
64311
64360
|
try {
|
|
64312
|
-
return (0,
|
|
64361
|
+
return (0, import_node_child_process11.execSync)("which node", { encoding: "utf-8" }).trim();
|
|
64313
64362
|
} catch {
|
|
64314
64363
|
return null;
|
|
64315
64364
|
}
|
|
64316
64365
|
}
|
|
64317
64366
|
function getGlobalMcpBinPath() {
|
|
64318
64367
|
try {
|
|
64319
|
-
const npmPrefix = (0,
|
|
64368
|
+
const npmPrefix = (0, import_node_child_process11.execSync)("npm prefix -g", { encoding: "utf-8" }).trim();
|
|
64320
64369
|
const binPath = (0, import_node_path16.join)(npmPrefix, "lib", "node_modules", "@agent-relay", "mcp", "dist", "bin.js");
|
|
64321
64370
|
if ((0, import_node_fs13.existsSync)(binPath)) {
|
|
64322
64371
|
return binPath;
|
|
@@ -64544,14 +64593,7 @@ function installMcpConfig(configPath, options = {}) {
|
|
|
64544
64593
|
// packages/bridge/dist/spawner.js
|
|
64545
64594
|
var __filename3 = (0, import_node_url3.fileURLToPath)(import_meta_url);
|
|
64546
64595
|
var __dirname3 = import_node_path17.default.dirname(__filename3);
|
|
64547
|
-
var
|
|
64548
|
-
var CLI_COMMAND_MAP = {
|
|
64549
|
-
cursor: "agent",
|
|
64550
|
-
// Cursor CLI installs as 'agent'
|
|
64551
|
-
google: "gemini"
|
|
64552
|
-
// Google provider uses 'gemini' CLI
|
|
64553
|
-
// Other providers use their name as the command (claude, codex, etc.)
|
|
64554
|
-
};
|
|
64596
|
+
var log3 = createLogger2("spawner");
|
|
64555
64597
|
function extractGhTokenFromHosts(content) {
|
|
64556
64598
|
const lines = content.split(/\r?\n/);
|
|
64557
64599
|
let inGithubSection = false;
|
|
@@ -64614,7 +64656,7 @@ function ensureMcpPermissions(projectRoot, cliType, debug = false) {
|
|
|
64614
64656
|
const config2 = configMap[effectiveCli];
|
|
64615
64657
|
if (!config2) {
|
|
64616
64658
|
if (debug)
|
|
64617
|
-
|
|
64659
|
+
log3.debug(`CLI ${cliType} uses flag-based permissions, skipping config setup`);
|
|
64618
64660
|
return;
|
|
64619
64661
|
}
|
|
64620
64662
|
const settingsPath = import_node_path17.default.join(config2.settingsDir, config2.settingsFile);
|
|
@@ -64634,7 +64676,7 @@ function ensureMcpPermissions(projectRoot, cliType, debug = false) {
|
|
|
64634
64676
|
if (config2.enableAllKey && settings[config2.enableAllKey] !== true) {
|
|
64635
64677
|
settings[config2.enableAllKey] = true;
|
|
64636
64678
|
if (debug)
|
|
64637
|
-
|
|
64679
|
+
log3.debug(`Setting ${config2.enableAllKey}: true`);
|
|
64638
64680
|
}
|
|
64639
64681
|
if (config2.permissionKey) {
|
|
64640
64682
|
const keyParts = config2.permissionKey.split(".");
|
|
@@ -64655,14 +64697,14 @@ function ensureMcpPermissions(projectRoot, cliType, debug = false) {
|
|
|
64655
64697
|
if (!allowList.includes(agentRelayPermission)) {
|
|
64656
64698
|
allowList.push(agentRelayPermission);
|
|
64657
64699
|
if (debug)
|
|
64658
|
-
|
|
64700
|
+
log3.debug(`Added MCP permission: ${agentRelayPermission}`);
|
|
64659
64701
|
}
|
|
64660
64702
|
}
|
|
64661
64703
|
import_node_fs14.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
64662
64704
|
if (debug)
|
|
64663
|
-
|
|
64705
|
+
log3.debug(`MCP permissions configured at ${settingsPath}`);
|
|
64664
64706
|
} catch (err) {
|
|
64665
|
-
|
|
64707
|
+
log3.warn("Failed to pre-configure MCP permissions", {
|
|
64666
64708
|
cli: cliType,
|
|
64667
64709
|
error: err instanceof Error ? err.message : String(err)
|
|
64668
64710
|
});
|
|
@@ -64712,9 +64754,9 @@ function hasRelayPtyBinary2() {
|
|
|
64712
64754
|
relayPtyBinaryChecked = true;
|
|
64713
64755
|
if (process.env.DEBUG_SPAWN === "1") {
|
|
64714
64756
|
if (relayPtyBinaryPath) {
|
|
64715
|
-
|
|
64757
|
+
log3.debug(`relay-pty binary found: ${relayPtyBinaryPath}`);
|
|
64716
64758
|
} else {
|
|
64717
|
-
|
|
64759
|
+
log3.debug("relay-pty binary not found, will use PtyWrapper fallback");
|
|
64718
64760
|
}
|
|
64719
64761
|
}
|
|
64720
64762
|
}
|
|
@@ -64743,7 +64785,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64743
64785
|
const effectiveTeamDir = options.teamDir ?? paths.teamDir;
|
|
64744
64786
|
this.agentsPath = import_node_path17.default.join(effectiveTeamDir, "connected-agents.json");
|
|
64745
64787
|
this.registryPath = import_node_path17.default.join(effectiveTeamDir, "agents.json");
|
|
64746
|
-
|
|
64788
|
+
log3.info(`AgentSpawner paths: projectRoot=${this.projectRoot} teamDir=${effectiveTeamDir} (explicit=${!!options.teamDir}) agentsPath=${this.agentsPath}`);
|
|
64747
64789
|
this.socketPath = options.socketPath ?? paths.socketPath;
|
|
64748
64790
|
this.logsDir = import_node_path17.default.join(effectiveTeamDir, "worker-logs");
|
|
64749
64791
|
this.workersPath = import_node_path17.default.join(effectiveTeamDir, "workers.json");
|
|
@@ -64758,7 +64800,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64758
64800
|
workspaceId: process.env.WORKSPACE_ID,
|
|
64759
64801
|
strictMode: process.env.AGENT_POLICY_STRICT === "1"
|
|
64760
64802
|
});
|
|
64761
|
-
|
|
64803
|
+
log3.info("Policy enforcement enabled");
|
|
64762
64804
|
}
|
|
64763
64805
|
}
|
|
64764
64806
|
/**
|
|
@@ -64800,7 +64842,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64800
64842
|
});
|
|
64801
64843
|
clearTimeout(timeoutId);
|
|
64802
64844
|
if (!response.ok) {
|
|
64803
|
-
|
|
64845
|
+
log3.warn(`Failed to fetch GH token from cloud: ${response.status} ${response.statusText}`);
|
|
64804
64846
|
return null;
|
|
64805
64847
|
}
|
|
64806
64848
|
const data = await response.json();
|
|
@@ -64808,9 +64850,9 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64808
64850
|
} catch (err) {
|
|
64809
64851
|
const message = err instanceof Error ? err.message : String(err);
|
|
64810
64852
|
if (message.includes("abort")) {
|
|
64811
|
-
|
|
64853
|
+
log3.info("Cloud API timeout (5s) - using local auth");
|
|
64812
64854
|
} else {
|
|
64813
|
-
|
|
64855
|
+
log3.warn("Failed to fetch GH token from cloud", { error: message });
|
|
64814
64856
|
}
|
|
64815
64857
|
return null;
|
|
64816
64858
|
}
|
|
@@ -64857,7 +64899,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64857
64899
|
return null;
|
|
64858
64900
|
}
|
|
64859
64901
|
return await new Promise((resolve5) => {
|
|
64860
|
-
(0,
|
|
64902
|
+
(0, import_node_child_process12.execFile)(ghPath, ["auth", "token", "--hostname", "github.com"], { timeout: 5e3 }, (err, stdout) => {
|
|
64861
64903
|
if (err) {
|
|
64862
64904
|
resolve5(null);
|
|
64863
64905
|
return;
|
|
@@ -64901,7 +64943,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64901
64943
|
* Called after the dashboard server starts and we know the actual port.
|
|
64902
64944
|
*/
|
|
64903
64945
|
setDashboardPort(port) {
|
|
64904
|
-
|
|
64946
|
+
log3.info(`Dashboard port set to ${port} - nested spawns now enabled`);
|
|
64905
64947
|
this.dashboardPort = port;
|
|
64906
64948
|
}
|
|
64907
64949
|
/**
|
|
@@ -64920,7 +64962,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64920
64962
|
*/
|
|
64921
64963
|
setCloudPersistence(handler) {
|
|
64922
64964
|
this.cloudPersistence = handler;
|
|
64923
|
-
|
|
64965
|
+
log3.info("Cloud persistence handler set");
|
|
64924
64966
|
}
|
|
64925
64967
|
/**
|
|
64926
64968
|
* Bind cloud persistence event handlers to a RelayPtyOrchestrator.
|
|
@@ -64933,14 +64975,14 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64933
64975
|
try {
|
|
64934
64976
|
await this.cloudPersistence.onSummary(name, event);
|
|
64935
64977
|
} catch (err) {
|
|
64936
|
-
|
|
64978
|
+
log3.error(`Cloud persistence summary error for ${name}`, { error: err instanceof Error ? err.message : String(err) });
|
|
64937
64979
|
}
|
|
64938
64980
|
};
|
|
64939
64981
|
const sessionEndListener = async (event) => {
|
|
64940
64982
|
try {
|
|
64941
64983
|
await this.cloudPersistence.onSessionEnd(name, event);
|
|
64942
64984
|
} catch (err) {
|
|
64943
|
-
|
|
64985
|
+
log3.error(`Cloud persistence session-end error for ${name}`, { error: err instanceof Error ? err.message : String(err) });
|
|
64944
64986
|
}
|
|
64945
64987
|
};
|
|
64946
64988
|
pty.on("summary", summaryListener);
|
|
@@ -64993,7 +65035,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
64993
65035
|
const maxAgents = parseInt(process.env.MAX_AGENTS ?? "", 10) || 1e4;
|
|
64994
65036
|
const currentAgentCount = this.activeWorkers.size;
|
|
64995
65037
|
if (currentAgentCount >= maxAgents) {
|
|
64996
|
-
|
|
65038
|
+
log3.warn(`Agent limit reached: ${currentAgentCount}/${maxAgents}`);
|
|
64997
65039
|
return {
|
|
64998
65040
|
success: false,
|
|
64999
65041
|
name,
|
|
@@ -65003,7 +65045,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65003
65045
|
if (this.policyEnforcementEnabled && this.policyService && spawnerName) {
|
|
65004
65046
|
const decision = await this.policyService.canSpawn(spawnerName, name, cli);
|
|
65005
65047
|
if (!decision.allowed) {
|
|
65006
|
-
|
|
65048
|
+
log3.warn(`Policy blocked spawn: ${spawnerName} -> ${name}: ${decision.reason}`);
|
|
65007
65049
|
return {
|
|
65008
65050
|
success: false,
|
|
65009
65051
|
name,
|
|
@@ -65012,26 +65054,26 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65012
65054
|
};
|
|
65013
65055
|
}
|
|
65014
65056
|
if (debug) {
|
|
65015
|
-
|
|
65057
|
+
log3.debug(`Policy allowed spawn: ${spawnerName} -> ${name} (source: ${decision.policySource})`);
|
|
65016
65058
|
}
|
|
65017
65059
|
}
|
|
65018
65060
|
try {
|
|
65019
65061
|
const cliParts = cli.split(" ");
|
|
65020
65062
|
const rawCommandName = cliParts[0];
|
|
65021
|
-
const commandName =
|
|
65063
|
+
const commandName = resolveCli(rawCommandName);
|
|
65022
65064
|
const args = cliParts.slice(1);
|
|
65023
65065
|
if (commandName !== rawCommandName && debug) {
|
|
65024
|
-
|
|
65066
|
+
log3.debug(`Mapped CLI '${rawCommandName}' -> '${commandName}'`);
|
|
65025
65067
|
}
|
|
65026
65068
|
const command = resolveCommand(commandName);
|
|
65027
65069
|
if (debug)
|
|
65028
|
-
|
|
65070
|
+
log3.debug(`Resolved '${commandName}' -> '${command}'`);
|
|
65029
65071
|
if (command === commandName && !commandName.startsWith("/")) {
|
|
65030
|
-
|
|
65072
|
+
log3.warn(`Could not resolve path for '${commandName}', spawn may fail`);
|
|
65031
65073
|
}
|
|
65032
65074
|
ensureMcpPermissions(this.projectRoot, commandName, debug);
|
|
65033
65075
|
const isClaudeCli = commandName.startsWith("claude");
|
|
65034
|
-
const isCursorCli = commandName === "agent" || rawCommandName === "cursor";
|
|
65076
|
+
const isCursorCli = commandName === "agent" || rawCommandName === "cursor" || rawCommandName === "cursor-agent";
|
|
65035
65077
|
if (!interactive) {
|
|
65036
65078
|
if (isClaudeCli && !args.includes("--dangerously-skip-permissions")) {
|
|
65037
65079
|
args.push("--dangerously-skip-permissions");
|
|
@@ -65041,7 +65083,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65041
65083
|
}
|
|
65042
65084
|
} else {
|
|
65043
65085
|
if (debug)
|
|
65044
|
-
|
|
65086
|
+
log3.debug(`Interactive mode: skipping auto-accept flags for ${name}`);
|
|
65045
65087
|
}
|
|
65046
65088
|
if (isClaudeCli) {
|
|
65047
65089
|
const agentConfig = findAgentConfig(name, this.projectRoot);
|
|
@@ -65051,9 +65093,9 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65051
65093
|
const configuredArgs = buildClaudeArgs(name, args, this.projectRoot);
|
|
65052
65094
|
args.length = 0;
|
|
65053
65095
|
args.push(...configuredArgs);
|
|
65054
|
-
|
|
65096
|
+
log3.info(`Agent ${name}: model=${effectiveModel}, cli=${cli}, variant=${cliVariant}`);
|
|
65055
65097
|
if (debug)
|
|
65056
|
-
|
|
65098
|
+
log3.debug(`Applied agent config for ${name}: ${args.join(" ")}`);
|
|
65057
65099
|
}
|
|
65058
65100
|
const isCodexCli = commandName.startsWith("codex");
|
|
65059
65101
|
const isGeminiCli = commandName === "gemini";
|
|
@@ -65079,12 +65121,12 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65079
65121
|
});
|
|
65080
65122
|
if (result.success) {
|
|
65081
65123
|
if (debug)
|
|
65082
|
-
|
|
65124
|
+
log3.debug(`Auto-installed MCP config at ${projectMcpConfigPath}`);
|
|
65083
65125
|
} else {
|
|
65084
|
-
|
|
65126
|
+
log3.warn(`Failed to auto-install MCP config: ${result.error}`);
|
|
65085
65127
|
}
|
|
65086
65128
|
} catch (err) {
|
|
65087
|
-
|
|
65129
|
+
log3.warn("Failed to auto-install MCP config", {
|
|
65088
65130
|
error: err instanceof Error ? err.message : String(err)
|
|
65089
65131
|
});
|
|
65090
65132
|
}
|
|
@@ -65099,7 +65141,7 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65099
65141
|
}
|
|
65100
65142
|
}
|
|
65101
65143
|
if (debug && hasMcp)
|
|
65102
|
-
|
|
65144
|
+
log3.debug(`MCP tools available for ${name} (MCP config found, socket ${relaySocket})`);
|
|
65103
65145
|
let relayInstructions = getRelayInstructions(name, { hasMcp, includeWorkflowConventions });
|
|
65104
65146
|
const agentConfigForRole = isClaudeCli ? findAgentConfig(name, this.projectRoot) : null;
|
|
65105
65147
|
if (agentConfigForRole?.role) {
|
|
@@ -65115,10 +65157,10 @@ var AgentSpawner = class _AgentSpawner {
|
|
|
65115
65157
|
|
|
65116
65158
|
${relayInstructions}`;
|
|
65117
65159
|
if (debug)
|
|
65118
|
-
|
|
65160
|
+
log3.debug(`Composed role prompt for ${name} (role: ${role})`);
|
|
65119
65161
|
}
|
|
65120
65162
|
} catch (err) {
|
|
65121
|
-
|
|
65163
|
+
log3.warn(`Failed to compose role prompt for ${name}: ${err.message}`);
|
|
65122
65164
|
}
|
|
65123
65165
|
}
|
|
65124
65166
|
}
|
|
@@ -65135,7 +65177,7 @@ ${relayInstructions}`;
|
|
|
65135
65177
|
args.unshift("login");
|
|
65136
65178
|
}
|
|
65137
65179
|
if (debug)
|
|
65138
|
-
|
|
65180
|
+
log3.debug(`Spawning ${name} with: ${command} ${args.join(" ")}`);
|
|
65139
65181
|
let agentCwd;
|
|
65140
65182
|
if (request.cwd && typeof request.cwd === "string") {
|
|
65141
65183
|
const resolvedCwd = import_node_path17.default.resolve(this.projectRoot, request.cwd);
|
|
@@ -65152,14 +65194,14 @@ ${relayInstructions}`;
|
|
|
65152
65194
|
} else {
|
|
65153
65195
|
agentCwd = this.projectRoot;
|
|
65154
65196
|
}
|
|
65155
|
-
|
|
65197
|
+
log3.info(`Spawning ${name}: dashboardPort=${this.dashboardPort || "none"} (${this.dashboardPort ? "nested spawns enabled" : "nested spawns disabled"})`);
|
|
65156
65198
|
let userEnv;
|
|
65157
65199
|
if (userId) {
|
|
65158
65200
|
try {
|
|
65159
65201
|
const userDirService = getUserDirectoryService();
|
|
65160
65202
|
userEnv = userDirService.getUserEnvironment(userId);
|
|
65161
65203
|
} catch (err) {
|
|
65162
|
-
|
|
65204
|
+
log3.warn("Failed to resolve user environment, using default", {
|
|
65163
65205
|
userId,
|
|
65164
65206
|
error: err instanceof Error ? err.message : String(err)
|
|
65165
65207
|
});
|
|
@@ -65176,7 +65218,7 @@ ${relayInstructions}`;
|
|
|
65176
65218
|
userEnv = mergedUserEnv;
|
|
65177
65219
|
}
|
|
65178
65220
|
if (debug)
|
|
65179
|
-
|
|
65221
|
+
log3.debug(`Socket path for ${name}: ${this.socketPath ?? "undefined"}`);
|
|
65180
65222
|
if (!hasRelayPtyBinary2()) {
|
|
65181
65223
|
const checkedPaths = getLastSearchPaths();
|
|
65182
65224
|
const tracedError = createTraceableError("relay-pty binary not found", {
|
|
@@ -65188,10 +65230,10 @@ ${relayInstructions}`;
|
|
|
65188
65230
|
totalPathsChecked: checkedPaths.length,
|
|
65189
65231
|
hint: "Set RELAY_PTY_BINARY env var to override, or reinstall: npm install agent-relay"
|
|
65190
65232
|
});
|
|
65191
|
-
|
|
65233
|
+
log3.error(tracedError.logMessage);
|
|
65192
65234
|
if (debug) {
|
|
65193
|
-
|
|
65194
|
-
checkedPaths.forEach((p, i) =>
|
|
65235
|
+
log3.debug("All paths checked for relay-pty binary:");
|
|
65236
|
+
checkedPaths.forEach((p, i) => log3.debug(` ${i + 1}. ${p}`));
|
|
65195
65237
|
}
|
|
65196
65238
|
return {
|
|
65197
65239
|
success: false,
|
|
@@ -65202,7 +65244,7 @@ ${relayInstructions}`;
|
|
|
65202
65244
|
}
|
|
65203
65245
|
const onExitHandler = (code) => {
|
|
65204
65246
|
if (debug)
|
|
65205
|
-
|
|
65247
|
+
log3.debug(`Worker ${name} exited with code ${code}`);
|
|
65206
65248
|
const worker = this.activeWorkers.get(name);
|
|
65207
65249
|
const agentId = worker?.pty?.getAgentId?.();
|
|
65208
65250
|
if (worker?.listeners) {
|
|
@@ -65212,7 +65254,7 @@ ${relayInstructions}`;
|
|
|
65212
65254
|
try {
|
|
65213
65255
|
this.saveWorkersMetadata();
|
|
65214
65256
|
} catch (err) {
|
|
65215
|
-
|
|
65257
|
+
log3.error("Failed to save metadata on exit", { error: err instanceof Error ? err.message : String(err) });
|
|
65216
65258
|
}
|
|
65217
65259
|
if (code !== 0 && code !== null && this.onAgentDeath) {
|
|
65218
65260
|
const crashError = createTraceableError("Agent crashed unexpectedly", {
|
|
@@ -65221,7 +65263,7 @@ ${relayInstructions}`;
|
|
|
65221
65263
|
cli,
|
|
65222
65264
|
agentId
|
|
65223
65265
|
});
|
|
65224
|
-
|
|
65266
|
+
log3.error(crashError.logMessage);
|
|
65225
65267
|
this.onAgentDeath({
|
|
65226
65268
|
name,
|
|
65227
65269
|
exitCode: code,
|
|
@@ -65233,7 +65275,7 @@ ${relayInstructions}`;
|
|
|
65233
65275
|
};
|
|
65234
65276
|
const onSpawnHandler = this.dashboardPort ? void 0 : async (workerName, workerCli, workerTask) => {
|
|
65235
65277
|
if (debug)
|
|
65236
|
-
|
|
65278
|
+
log3.debug(`Nested spawn: ${workerName}`);
|
|
65237
65279
|
await this.spawn({
|
|
65238
65280
|
name: workerName,
|
|
65239
65281
|
cli: workerCli,
|
|
@@ -65243,7 +65285,7 @@ ${relayInstructions}`;
|
|
|
65243
65285
|
};
|
|
65244
65286
|
const onReleaseHandler = this.dashboardPort ? void 0 : async (workerName) => {
|
|
65245
65287
|
if (debug)
|
|
65246
|
-
|
|
65288
|
+
log3.debug(`Release request: ${workerName}`);
|
|
65247
65289
|
await this.release(workerName);
|
|
65248
65290
|
};
|
|
65249
65291
|
if (isOpenCodeCli) {
|
|
@@ -65253,7 +65295,7 @@ ${relayInstructions}`;
|
|
|
65253
65295
|
const shouldUseHttpApi = serveAvailable || isCloudWorkspace2;
|
|
65254
65296
|
if (shouldUseHttpApi) {
|
|
65255
65297
|
if (debug)
|
|
65256
|
-
|
|
65298
|
+
log3.debug(`OpenCode: serve=${serveAvailable ? "available" : "will-auto-start"}, cloud=${isCloudWorkspace2}, using OpenCodeWrapper for ${name}`);
|
|
65257
65299
|
const openCodeConfig = {
|
|
65258
65300
|
name,
|
|
65259
65301
|
command,
|
|
@@ -65295,11 +65337,11 @@ ${relayInstructions}`;
|
|
|
65295
65337
|
if (this.onMarkSpawning) {
|
|
65296
65338
|
this.onMarkSpawning(name);
|
|
65297
65339
|
if (debug)
|
|
65298
|
-
|
|
65340
|
+
log3.debug(`Marked ${name} as spawning`);
|
|
65299
65341
|
}
|
|
65300
65342
|
await openCodeWrapper.start();
|
|
65301
65343
|
if (debug)
|
|
65302
|
-
|
|
65344
|
+
log3.debug(`OpenCodeWrapper started for ${name}, HTTP mode: ${openCodeWrapper.isHttpApiMode}`);
|
|
65303
65345
|
const registered2 = await this.waitForAgentRegistration(name, 3e4, 500);
|
|
65304
65346
|
if (!registered2) {
|
|
65305
65347
|
const tracedError = createTraceableError("Agent registration timeout", {
|
|
@@ -65308,7 +65350,7 @@ ${relayInstructions}`;
|
|
|
65308
65350
|
pid: openCodeWrapper.pid,
|
|
65309
65351
|
timeoutMs: 3e4
|
|
65310
65352
|
});
|
|
65311
|
-
|
|
65353
|
+
log3.error(tracedError.logMessage);
|
|
65312
65354
|
if (this.onClearSpawning) {
|
|
65313
65355
|
this.onClearSpawning(name);
|
|
65314
65356
|
}
|
|
@@ -65325,12 +65367,12 @@ ${relayInstructions}`;
|
|
|
65325
65367
|
if (ready) {
|
|
65326
65368
|
const taskSent = await openCodeWrapper.injectTask(task, spawnerName || "spawner");
|
|
65327
65369
|
if (!taskSent) {
|
|
65328
|
-
|
|
65370
|
+
log3.warn(`Failed to inject task for ${name} via OpenCodeWrapper`);
|
|
65329
65371
|
} else if (debug) {
|
|
65330
|
-
|
|
65372
|
+
log3.debug(`Task injected to ${name} via OpenCodeWrapper`);
|
|
65331
65373
|
}
|
|
65332
65374
|
} else {
|
|
65333
|
-
|
|
65375
|
+
log3.warn(`OpenCodeWrapper ${name} not ready for task injection`);
|
|
65334
65376
|
}
|
|
65335
65377
|
}
|
|
65336
65378
|
const workerInfo2 = {
|
|
@@ -65349,7 +65391,7 @@ ${relayInstructions}`;
|
|
|
65349
65391
|
this.saveWorkersMetadata();
|
|
65350
65392
|
const teamInfo2 = team ? ` [team: ${team}]` : "";
|
|
65351
65393
|
const shadowInfo2 = request.shadowOf ? ` [shadow of: ${request.shadowOf}]` : "";
|
|
65352
|
-
|
|
65394
|
+
log3.info(`Spawned ${name} (${cli}) via OpenCodeWrapper${teamInfo2}${shadowInfo2} [HTTP mode: ${openCodeWrapper.isHttpApiMode}]`);
|
|
65353
65395
|
return {
|
|
65354
65396
|
success: true,
|
|
65355
65397
|
name,
|
|
@@ -65357,7 +65399,7 @@ ${relayInstructions}`;
|
|
|
65357
65399
|
};
|
|
65358
65400
|
}
|
|
65359
65401
|
if (debug)
|
|
65360
|
-
|
|
65402
|
+
log3.debug(`OpenCode: serve not available, not cloud workspace, falling back to RelayPtyOrchestrator for ${name}`);
|
|
65361
65403
|
}
|
|
65362
65404
|
const ptyConfig = {
|
|
65363
65405
|
name,
|
|
@@ -65391,7 +65433,7 @@ ${relayInstructions}`;
|
|
|
65391
65433
|
};
|
|
65392
65434
|
const pty = new RelayPtyOrchestrator(ptyConfig);
|
|
65393
65435
|
if (debug)
|
|
65394
|
-
|
|
65436
|
+
log3.debug(`Using RelayPtyOrchestrator for ${name}`);
|
|
65395
65437
|
const listeners = {};
|
|
65396
65438
|
const outputListener = (data) => {
|
|
65397
65439
|
const broadcast = global.__broadcastLogOutput;
|
|
@@ -65409,19 +65451,19 @@ ${relayInstructions}`;
|
|
|
65409
65451
|
if (this.onMarkSpawning) {
|
|
65410
65452
|
this.onMarkSpawning(name);
|
|
65411
65453
|
if (debug)
|
|
65412
|
-
|
|
65454
|
+
log3.debug(`Marked ${name} as spawning`);
|
|
65413
65455
|
}
|
|
65414
65456
|
await pty.start();
|
|
65415
65457
|
if (debug)
|
|
65416
|
-
|
|
65458
|
+
log3.debug(`PTY started, pid: ${pty.pid}`);
|
|
65417
65459
|
if (isCursorCli && interactive) {
|
|
65418
65460
|
await sleep2(1500);
|
|
65419
65461
|
if (debug)
|
|
65420
|
-
|
|
65462
|
+
log3.debug(`Sending initial keystroke for Cursor setup to bypass "Press any key" prompt`);
|
|
65421
65463
|
try {
|
|
65422
65464
|
await pty.write("\r");
|
|
65423
65465
|
} catch (err) {
|
|
65424
|
-
|
|
65466
|
+
log3.warn(`Failed to send initial keystroke for Cursor: ${err}`);
|
|
65425
65467
|
}
|
|
65426
65468
|
}
|
|
65427
65469
|
const registered = await this.waitForAgentRegistration(name, 3e4, 500);
|
|
@@ -65432,7 +65474,7 @@ ${relayInstructions}`;
|
|
|
65432
65474
|
pid: pty.pid,
|
|
65433
65475
|
timeoutMs: 3e4
|
|
65434
65476
|
});
|
|
65435
|
-
|
|
65477
|
+
log3.error(tracedError.logMessage);
|
|
65436
65478
|
if (this.onClearSpawning) {
|
|
65437
65479
|
this.onClearSpawning(name);
|
|
65438
65480
|
}
|
|
@@ -65454,12 +65496,12 @@ ${relayInstructions}`;
|
|
|
65454
65496
|
const orchestrator = pty;
|
|
65455
65497
|
const ready = await orchestrator.waitUntilReadyForMessages(2e4, 100);
|
|
65456
65498
|
if (!ready) {
|
|
65457
|
-
|
|
65499
|
+
log3.debug(`Attempt ${attempt}/${maxRetries}: ${name} not ready for messages within timeout`);
|
|
65458
65500
|
if (attempt < maxRetries) {
|
|
65459
65501
|
await sleep2(retryDelayMs);
|
|
65460
65502
|
continue;
|
|
65461
65503
|
}
|
|
65462
|
-
|
|
65504
|
+
log3.error(`${name} failed to become ready after ${maxRetries} attempts - task may be lost`);
|
|
65463
65505
|
break;
|
|
65464
65506
|
}
|
|
65465
65507
|
} else if ("waitUntilCliReady" in pty) {
|
|
@@ -65469,13 +65511,13 @@ ${relayInstructions}`;
|
|
|
65469
65511
|
if (success) {
|
|
65470
65512
|
taskSent = true;
|
|
65471
65513
|
if (debug)
|
|
65472
|
-
|
|
65514
|
+
log3.debug(`Task injected to ${name} (attempt ${attempt})`);
|
|
65473
65515
|
break;
|
|
65474
65516
|
} else {
|
|
65475
65517
|
throw new Error("Task injection returned false");
|
|
65476
65518
|
}
|
|
65477
65519
|
} catch (err) {
|
|
65478
|
-
|
|
65520
|
+
log3.debug(`Attempt ${attempt}/${maxRetries}: Error injecting task for ${name}: ${err.message}`);
|
|
65479
65521
|
if (attempt < maxRetries) {
|
|
65480
65522
|
await sleep2(retryDelayMs);
|
|
65481
65523
|
}
|
|
@@ -65488,7 +65530,7 @@ ${relayInstructions}`;
|
|
|
65488
65530
|
attempts: maxRetries,
|
|
65489
65531
|
taskLength: task.length
|
|
65490
65532
|
});
|
|
65491
|
-
|
|
65533
|
+
log3.error(`CRITICAL: ${tracedError.logMessage}`);
|
|
65492
65534
|
}
|
|
65493
65535
|
}
|
|
65494
65536
|
const workerInfo = {
|
|
@@ -65508,7 +65550,7 @@ ${relayInstructions}`;
|
|
|
65508
65550
|
this.saveWorkersMetadata();
|
|
65509
65551
|
const teamInfo = team ? ` [team: ${team}]` : "";
|
|
65510
65552
|
const shadowInfo = request.shadowOf ? ` [shadow of: ${request.shadowOf}]` : "";
|
|
65511
|
-
|
|
65553
|
+
log3.info(`Spawned ${name} (${cli})${teamInfo}${shadowInfo} [pid: ${pty.pid}]`);
|
|
65512
65554
|
return {
|
|
65513
65555
|
success: true,
|
|
65514
65556
|
name,
|
|
@@ -65520,9 +65562,9 @@ ${relayInstructions}`;
|
|
|
65520
65562
|
cli,
|
|
65521
65563
|
task: task?.substring(0, 100)
|
|
65522
65564
|
}, err instanceof Error ? err : void 0);
|
|
65523
|
-
|
|
65565
|
+
log3.error(tracedError.logMessage);
|
|
65524
65566
|
if (debug)
|
|
65525
|
-
|
|
65567
|
+
log3.debug("Full error", { error: err?.stack || String(err) });
|
|
65526
65568
|
if (this.onClearSpawning) {
|
|
65527
65569
|
this.onClearSpawning(name);
|
|
65528
65570
|
}
|
|
@@ -65569,12 +65611,12 @@ ${relayInstructions}`;
|
|
|
65569
65611
|
preferredShadowCli: shadow.command
|
|
65570
65612
|
});
|
|
65571
65613
|
} catch (err) {
|
|
65572
|
-
|
|
65614
|
+
log3.warn(`Shadow CLI selection failed for ${shadow.name}: ${err.message}`);
|
|
65573
65615
|
}
|
|
65574
65616
|
if (debug) {
|
|
65575
65617
|
const mode = shadowSelection?.mode ?? "unknown";
|
|
65576
65618
|
const cli = shadowSelection?.command ?? shadow.command ?? primary.command ?? "claude";
|
|
65577
|
-
|
|
65619
|
+
log3.debug(`spawnWithShadow: primary=${primary.name}, shadow=${shadow.name}, mode=${mode}, cli=${cli}, speakOn=${speakOn.join(",")}`);
|
|
65578
65620
|
}
|
|
65579
65621
|
const primaryResult = await this.spawn({
|
|
65580
65622
|
name: primary.name,
|
|
@@ -65591,7 +65633,7 @@ ${relayInstructions}`;
|
|
|
65591
65633
|
}
|
|
65592
65634
|
await sleep2(1e3);
|
|
65593
65635
|
if (shadowSelection?.mode === "subagent") {
|
|
65594
|
-
|
|
65636
|
+
log3.info(`Shadow ${shadow.name} will run as ${shadowSelection.cli} subagent inside ${primary.name} (no separate process)`);
|
|
65595
65637
|
return {
|
|
65596
65638
|
success: true,
|
|
65597
65639
|
primary: primaryResult,
|
|
@@ -65602,7 +65644,7 @@ ${relayInstructions}`;
|
|
|
65602
65644
|
};
|
|
65603
65645
|
}
|
|
65604
65646
|
if (!shadowSelection) {
|
|
65605
|
-
|
|
65647
|
+
log3.warn(`No authenticated shadow CLI available; ${primary.name} will run without a shadow`);
|
|
65606
65648
|
return {
|
|
65607
65649
|
success: true,
|
|
65608
65650
|
primary: primaryResult,
|
|
@@ -65618,7 +65660,7 @@ ${relayInstructions}`;
|
|
|
65618
65660
|
shadowSpeakOn: speakOn
|
|
65619
65661
|
});
|
|
65620
65662
|
if (!shadowResult.success) {
|
|
65621
|
-
|
|
65663
|
+
log3.warn(`Shadow agent ${shadow.name} failed to spawn, primary ${primary.name} continues without shadow`);
|
|
65622
65664
|
return {
|
|
65623
65665
|
success: true,
|
|
65624
65666
|
// Primary succeeded, overall operation is partial success
|
|
@@ -65627,7 +65669,7 @@ ${relayInstructions}`;
|
|
|
65627
65669
|
error: `Shadow spawn failed: ${shadowResult.error}`
|
|
65628
65670
|
};
|
|
65629
65671
|
}
|
|
65630
|
-
|
|
65672
|
+
log3.info(`Spawned pair: ${primary.name} with shadow ${shadow.name} (speakOn: ${speakOn.join(",")})`);
|
|
65631
65673
|
return {
|
|
65632
65674
|
success: true,
|
|
65633
65675
|
primary: primaryResult,
|
|
@@ -65640,7 +65682,7 @@ ${relayInstructions}`;
|
|
|
65640
65682
|
async release(name) {
|
|
65641
65683
|
const worker = this.activeWorkers.get(name);
|
|
65642
65684
|
if (!worker) {
|
|
65643
|
-
|
|
65685
|
+
log3.debug(`Worker ${name} not found`);
|
|
65644
65686
|
return false;
|
|
65645
65687
|
}
|
|
65646
65688
|
try {
|
|
@@ -65651,10 +65693,10 @@ ${relayInstructions}`;
|
|
|
65651
65693
|
}
|
|
65652
65694
|
this.activeWorkers.delete(name);
|
|
65653
65695
|
this.saveWorkersMetadata();
|
|
65654
|
-
|
|
65696
|
+
log3.info(`Released ${name}`);
|
|
65655
65697
|
return true;
|
|
65656
65698
|
} catch (err) {
|
|
65657
|
-
|
|
65699
|
+
log3.error(`Failed to release ${name}: ${err.message}`);
|
|
65658
65700
|
this.unbindListeners(worker.pty, worker.listeners);
|
|
65659
65701
|
this.activeWorkers.delete(name);
|
|
65660
65702
|
this.saveWorkersMetadata();
|
|
@@ -65747,15 +65789,15 @@ ${relayInstructions}`;
|
|
|
65747
65789
|
const connected = this.isAgentConnected(name);
|
|
65748
65790
|
const recentlySeen = this.isAgentRecentlySeen(name);
|
|
65749
65791
|
if (pollCount <= 3 || pollCount % 10 === 0) {
|
|
65750
|
-
|
|
65792
|
+
log3.info(`Registration poll #${pollCount} for ${name}: connected=${connected} recentlySeen=${recentlySeen} agentsPath=${this.agentsPath}`);
|
|
65751
65793
|
}
|
|
65752
65794
|
if (connected && recentlySeen) {
|
|
65753
|
-
|
|
65795
|
+
log3.info(`Agent ${name} registered after ${pollCount} polls`);
|
|
65754
65796
|
return true;
|
|
65755
65797
|
}
|
|
65756
65798
|
await sleep2(pollIntervalMs);
|
|
65757
65799
|
}
|
|
65758
|
-
|
|
65800
|
+
log3.info(`Registration timeout for ${name} after ${pollCount} polls`);
|
|
65759
65801
|
return false;
|
|
65760
65802
|
}
|
|
65761
65803
|
isAgentRegistered(name) {
|
|
@@ -65765,12 +65807,12 @@ ${relayInstructions}`;
|
|
|
65765
65807
|
const debug = process.env.DEBUG_SPAWN === "1";
|
|
65766
65808
|
if (!this.agentsPath) {
|
|
65767
65809
|
if (debug)
|
|
65768
|
-
|
|
65810
|
+
log3.debug(`isAgentConnected(${name}): no agentsPath`);
|
|
65769
65811
|
return false;
|
|
65770
65812
|
}
|
|
65771
65813
|
if (!import_node_fs14.default.existsSync(this.agentsPath)) {
|
|
65772
65814
|
if (debug)
|
|
65773
|
-
|
|
65815
|
+
log3.debug(`isAgentConnected(${name}): file not found: ${this.agentsPath}`);
|
|
65774
65816
|
return false;
|
|
65775
65817
|
}
|
|
65776
65818
|
try {
|
|
@@ -65779,14 +65821,14 @@ ${relayInstructions}`;
|
|
|
65779
65821
|
const updatedAt = typeof raw?.updatedAt === "number" ? raw.updatedAt : 0;
|
|
65780
65822
|
const isFresh = Date.now() - updatedAt <= _AgentSpawner.ONLINE_THRESHOLD_MS;
|
|
65781
65823
|
if (debug) {
|
|
65782
|
-
|
|
65824
|
+
log3.debug(`isAgentConnected(${name}): path=${this.agentsPath} agents=${agents.join(",")} updatedAt=${updatedAt} isFresh=${isFresh}`);
|
|
65783
65825
|
}
|
|
65784
65826
|
if (!isFresh)
|
|
65785
65827
|
return false;
|
|
65786
65828
|
const lowerName = name.toLowerCase();
|
|
65787
65829
|
return agents.some((a) => typeof a === "string" && a.toLowerCase() === lowerName);
|
|
65788
65830
|
} catch (err) {
|
|
65789
|
-
|
|
65831
|
+
log3.error("Failed to read connected-agents.json", { error: err.message, path: this.agentsPath });
|
|
65790
65832
|
return false;
|
|
65791
65833
|
}
|
|
65792
65834
|
}
|
|
@@ -65804,7 +65846,7 @@ ${relayInstructions}`;
|
|
|
65804
65846
|
return false;
|
|
65805
65847
|
return Date.now() - new Date(agent.lastSeen).getTime() <= _AgentSpawner.ONLINE_THRESHOLD_MS;
|
|
65806
65848
|
} catch (err) {
|
|
65807
|
-
|
|
65849
|
+
log3.error("Failed to read agents.json", { error: err.message });
|
|
65808
65850
|
return false;
|
|
65809
65851
|
}
|
|
65810
65852
|
}
|
|
@@ -65825,7 +65867,7 @@ ${relayInstructions}`;
|
|
|
65825
65867
|
}));
|
|
65826
65868
|
import_node_fs14.default.writeFileSync(this.workersPath, JSON.stringify({ workers }, null, 2));
|
|
65827
65869
|
} catch (err) {
|
|
65828
|
-
|
|
65870
|
+
log3.error("Failed to save workers metadata", { error: err.message });
|
|
65829
65871
|
}
|
|
65830
65872
|
}
|
|
65831
65873
|
/**
|
|
@@ -70262,7 +70304,7 @@ async function createStorageAdapter(dbPath, config2) {
|
|
|
70262
70304
|
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
70263
70305
|
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
70264
70306
|
init_logger();
|
|
70265
|
-
var
|
|
70307
|
+
var log4 = createLogger2("registry");
|
|
70266
70308
|
var AgentRegistry = class {
|
|
70267
70309
|
registryPath;
|
|
70268
70310
|
agents = /* @__PURE__ */ new Map();
|
|
@@ -70385,7 +70427,7 @@ var AgentRegistry = class {
|
|
|
70385
70427
|
if (lastSeenTime < cutoff) {
|
|
70386
70428
|
this.agents.delete(name);
|
|
70387
70429
|
removed++;
|
|
70388
|
-
|
|
70430
|
+
log4.info("Pruned stale agent", { name, lastSeen: record2.lastSeen });
|
|
70389
70431
|
}
|
|
70390
70432
|
}
|
|
70391
70433
|
if (removed > 0) {
|
|
@@ -70442,7 +70484,7 @@ var AgentRegistry = class {
|
|
|
70442
70484
|
this.agents.set(record2.name, record2);
|
|
70443
70485
|
}
|
|
70444
70486
|
} catch (err) {
|
|
70445
|
-
|
|
70487
|
+
log4.error("Failed to load agents.json", { error: String(err) });
|
|
70446
70488
|
}
|
|
70447
70489
|
}
|
|
70448
70490
|
save() {
|
|
@@ -70452,7 +70494,7 @@ var AgentRegistry = class {
|
|
|
70452
70494
|
import_node_fs21.default.writeFileSync(tempPath, data, "utf-8");
|
|
70453
70495
|
import_node_fs21.default.renameSync(tempPath, this.registryPath);
|
|
70454
70496
|
} catch (err) {
|
|
70455
|
-
|
|
70497
|
+
log4.error("Failed to write agents.json", { error: String(err) });
|
|
70456
70498
|
}
|
|
70457
70499
|
}
|
|
70458
70500
|
};
|
|
@@ -70476,7 +70518,7 @@ var import_node_zlib = require("node:zlib");
|
|
|
70476
70518
|
var import_node_util5 = require("node:util");
|
|
70477
70519
|
init_logger();
|
|
70478
70520
|
var gzipAsync = (0, import_node_util5.promisify)(import_node_zlib.gzip);
|
|
70479
|
-
var
|
|
70521
|
+
var log5 = createLogger2("sync-queue");
|
|
70480
70522
|
var DEFAULT_SYNC_QUEUE_CONFIG = {
|
|
70481
70523
|
cloudUrl: "https://agent-relay.com",
|
|
70482
70524
|
apiKey: "",
|
|
@@ -70532,7 +70574,7 @@ var SyncQueue = class {
|
|
|
70532
70574
|
} else if (!this.flushTimer) {
|
|
70533
70575
|
this.flushTimer = setTimeout(() => {
|
|
70534
70576
|
this.flush().catch((err) => {
|
|
70535
|
-
|
|
70577
|
+
log5.error("Timer flush failed", { error: String(err) });
|
|
70536
70578
|
});
|
|
70537
70579
|
}, this.config.batchDelayMs);
|
|
70538
70580
|
}
|
|
@@ -70594,7 +70636,7 @@ var SyncQueue = class {
|
|
|
70594
70636
|
if (attempt < this.config.maxRetries - 1) {
|
|
70595
70637
|
const delay = this.config.retryDelayMs * Math.pow(2, attempt);
|
|
70596
70638
|
if (this.config.verbose) {
|
|
70597
|
-
|
|
70639
|
+
log5.warn(`Sync attempt ${attempt + 1} failed, retrying in ${delay}ms`, {
|
|
70598
70640
|
error: lastError.message
|
|
70599
70641
|
});
|
|
70600
70642
|
}
|
|
@@ -70602,7 +70644,7 @@ var SyncQueue = class {
|
|
|
70602
70644
|
}
|
|
70603
70645
|
}
|
|
70604
70646
|
}
|
|
70605
|
-
|
|
70647
|
+
log5.error("Sync failed after retries, spilling to disk", {
|
|
70606
70648
|
count: messages.length,
|
|
70607
70649
|
error: lastError?.message
|
|
70608
70650
|
});
|
|
@@ -70646,7 +70688,7 @@ var SyncQueue = class {
|
|
|
70646
70688
|
contentEncoding = "gzip";
|
|
70647
70689
|
if (this.config.verbose) {
|
|
70648
70690
|
const ratio = ((1 - body.length / payloadBytes) * 100).toFixed(1);
|
|
70649
|
-
|
|
70691
|
+
log5.info(`Compressed ${payloadBytes} \u2192 ${body.length} bytes (${ratio}% reduction)`);
|
|
70650
70692
|
}
|
|
70651
70693
|
} else {
|
|
70652
70694
|
body = payloadJson;
|
|
@@ -70687,11 +70729,11 @@ var SyncQueue = class {
|
|
|
70687
70729
|
await fs25.writeFile(filepath, JSON.stringify(messages));
|
|
70688
70730
|
this.stats.spilledFiles++;
|
|
70689
70731
|
if (this.config.verbose) {
|
|
70690
|
-
|
|
70732
|
+
log5.info(`Spilled ${messages.length} messages to ${filename}`);
|
|
70691
70733
|
}
|
|
70692
70734
|
await this.cleanupSpillFiles();
|
|
70693
70735
|
} catch (err) {
|
|
70694
|
-
|
|
70736
|
+
log5.error("Failed to spill to disk", { error: String(err) });
|
|
70695
70737
|
}
|
|
70696
70738
|
}
|
|
70697
70739
|
/**
|
|
@@ -70715,23 +70757,23 @@ var SyncQueue = class {
|
|
|
70715
70757
|
recovered += messages.length;
|
|
70716
70758
|
this.stats.spilledFiles = Math.max(0, this.stats.spilledFiles - 1);
|
|
70717
70759
|
if (this.config.verbose) {
|
|
70718
|
-
|
|
70760
|
+
log5.info(`Recovered ${messages.length} messages from ${file}`);
|
|
70719
70761
|
}
|
|
70720
70762
|
} else {
|
|
70721
70763
|
failed += messages.length;
|
|
70722
70764
|
}
|
|
70723
70765
|
} catch (err) {
|
|
70724
|
-
|
|
70766
|
+
log5.warn(`Failed to recover ${file}`, { error: String(err) });
|
|
70725
70767
|
failed++;
|
|
70726
70768
|
}
|
|
70727
70769
|
}
|
|
70728
70770
|
} catch (err) {
|
|
70729
70771
|
if (err.code !== "ENOENT") {
|
|
70730
|
-
|
|
70772
|
+
log5.error("Failed to scan spill directory", { error: String(err) });
|
|
70731
70773
|
}
|
|
70732
70774
|
}
|
|
70733
70775
|
if (recovered > 0) {
|
|
70734
|
-
|
|
70776
|
+
log5.info(`Recovered ${recovered} messages from spill files`);
|
|
70735
70777
|
}
|
|
70736
70778
|
return { recovered, failed };
|
|
70737
70779
|
}
|
|
@@ -70749,7 +70791,7 @@ var SyncQueue = class {
|
|
|
70749
70791
|
});
|
|
70750
70792
|
}
|
|
70751
70793
|
if (this.config.verbose) {
|
|
70752
|
-
|
|
70794
|
+
log5.info(`Cleaned up ${toDelete.length} old spill files`);
|
|
70753
70795
|
}
|
|
70754
70796
|
}
|
|
70755
70797
|
} catch {
|
|
@@ -70799,7 +70841,7 @@ var SyncQueue = class {
|
|
|
70799
70841
|
// packages/utils/dist/git-remote.js
|
|
70800
70842
|
var fs26 = __toESM(require("node:fs"), 1);
|
|
70801
70843
|
var path27 = __toESM(require("node:path"), 1);
|
|
70802
|
-
var
|
|
70844
|
+
var import_node_child_process13 = require("node:child_process");
|
|
70803
70845
|
function parseGitRemoteUrl(url) {
|
|
70804
70846
|
if (!url)
|
|
70805
70847
|
return null;
|
|
@@ -70819,7 +70861,7 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
|
|
|
70819
70861
|
if (!fs26.existsSync(gitDir)) {
|
|
70820
70862
|
return null;
|
|
70821
70863
|
}
|
|
70822
|
-
const result = (0,
|
|
70864
|
+
const result = (0, import_node_child_process13.execSync)(`git remote get-url ${remoteName}`, {
|
|
70823
70865
|
cwd: workingDirectory,
|
|
70824
70866
|
encoding: "utf-8",
|
|
70825
70867
|
timeout: 5e3,
|
|
@@ -70872,7 +70914,7 @@ function getRepoFullNameFromPath(workingDirectory) {
|
|
|
70872
70914
|
}
|
|
70873
70915
|
|
|
70874
70916
|
// packages/daemon/dist/cloud-sync.js
|
|
70875
|
-
var
|
|
70917
|
+
var log6 = createLogger2("cloud-sync");
|
|
70876
70918
|
var CloudSyncService = class extends import_events7.EventEmitter {
|
|
70877
70919
|
config;
|
|
70878
70920
|
heartbeatTimer;
|
|
@@ -70907,7 +70949,7 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
70907
70949
|
this.projectDirectory = this.config.projectDirectory || process.cwd();
|
|
70908
70950
|
this.repoFullName = getRepoFullNameFromPath(this.projectDirectory);
|
|
70909
70951
|
if (this.repoFullName) {
|
|
70910
|
-
|
|
70952
|
+
log6.info("Detected git repository", { repoFullName: this.repoFullName });
|
|
70911
70953
|
}
|
|
70912
70954
|
if (this.config.useOptimizedSync && this.config.apiKey) {
|
|
70913
70955
|
this.syncQueue = new SyncQueue({
|
|
@@ -70940,19 +70982,19 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
70940
70982
|
*/
|
|
70941
70983
|
async start() {
|
|
70942
70984
|
if (!this.config.enabled || !this.config.apiKey) {
|
|
70943
|
-
|
|
70944
|
-
|
|
70985
|
+
log6.info("Disabled (no API key configured)");
|
|
70986
|
+
log6.info("Run `agent-relay cloud link` to connect to cloud");
|
|
70945
70987
|
return;
|
|
70946
70988
|
}
|
|
70947
|
-
|
|
70989
|
+
log6.info("Starting cloud sync", { url: this.config.cloudUrl });
|
|
70948
70990
|
if (this.syncQueue) {
|
|
70949
70991
|
const { recovered, failed } = await this.syncQueue.recoverSpilledMessages();
|
|
70950
70992
|
if (recovered > 0 || failed > 0) {
|
|
70951
|
-
|
|
70993
|
+
log6.info("Recovered spilled messages", { recovered, failed });
|
|
70952
70994
|
}
|
|
70953
70995
|
}
|
|
70954
70996
|
await this.sendHeartbeat();
|
|
70955
|
-
this.heartbeatTimer = setInterval(() => this.sendHeartbeat().catch((err) =>
|
|
70997
|
+
this.heartbeatTimer = setInterval(() => this.sendHeartbeat().catch((err) => log6.error("Heartbeat failed", { error: String(err) })), this.config.heartbeatInterval);
|
|
70956
70998
|
this.connected = true;
|
|
70957
70999
|
this.emit("connected");
|
|
70958
71000
|
}
|
|
@@ -70979,7 +71021,7 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
70979
71021
|
this.localAgents.set(agent.name, agent);
|
|
70980
71022
|
}
|
|
70981
71023
|
if (this.connected) {
|
|
70982
|
-
this.syncAgents().catch((err) =>
|
|
71024
|
+
this.syncAgents().catch((err) => log6.error("Agent sync failed", { error: String(err) }));
|
|
70983
71025
|
}
|
|
70984
71026
|
}
|
|
70985
71027
|
/**
|
|
@@ -71046,7 +71088,7 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71046
71088
|
}).finally(() => clearTimeout(timeoutId));
|
|
71047
71089
|
if (!response.ok) {
|
|
71048
71090
|
if (response.status === 401) {
|
|
71049
|
-
|
|
71091
|
+
log6.error("Invalid API key. Run `agent-relay cloud link` to re-authenticate.");
|
|
71050
71092
|
this.stop();
|
|
71051
71093
|
return;
|
|
71052
71094
|
}
|
|
@@ -71067,18 +71109,18 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71067
71109
|
} catch (error2) {
|
|
71068
71110
|
const errorMessage = String(error2);
|
|
71069
71111
|
if (error2 instanceof Error && error2.name === "AbortError") {
|
|
71070
|
-
|
|
71112
|
+
log6.error("Heartbeat timeout (10s)", { url: this.config.cloudUrl });
|
|
71071
71113
|
} else if (errorMessage.includes("fetch failed") || errorMessage.includes("ECONNREFUSED")) {
|
|
71072
|
-
|
|
71114
|
+
log6.error("Heartbeat network error - cloud server unreachable", {
|
|
71073
71115
|
url: this.config.cloudUrl,
|
|
71074
71116
|
error: errorMessage
|
|
71075
71117
|
});
|
|
71076
71118
|
} else if (errorMessage.includes("ENOTFOUND") || errorMessage.includes("getaddrinfo")) {
|
|
71077
|
-
|
|
71119
|
+
log6.error("Heartbeat DNS error - cannot resolve cloud server", {
|
|
71078
71120
|
url: this.config.cloudUrl
|
|
71079
71121
|
});
|
|
71080
71122
|
} else {
|
|
71081
|
-
|
|
71123
|
+
log6.error("Heartbeat error", { error: errorMessage });
|
|
71082
71124
|
}
|
|
71083
71125
|
this.emit("error", error2);
|
|
71084
71126
|
}
|
|
@@ -71168,14 +71210,14 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71168
71210
|
*/
|
|
71169
71211
|
setStorage(storage) {
|
|
71170
71212
|
this.storage = storage;
|
|
71171
|
-
|
|
71213
|
+
log6.info("Storage adapter configured for message sync");
|
|
71172
71214
|
}
|
|
71173
71215
|
/**
|
|
71174
71216
|
* Set the metrics provider for agent metrics sync
|
|
71175
71217
|
*/
|
|
71176
71218
|
setMetricsProvider(provider) {
|
|
71177
71219
|
this.metricsProvider = provider;
|
|
71178
|
-
|
|
71220
|
+
log6.info("Metrics provider configured for agent metrics sync");
|
|
71179
71221
|
}
|
|
71180
71222
|
/**
|
|
71181
71223
|
* Push agent metrics to cloud monitoring API.
|
|
@@ -71222,11 +71264,11 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71222
71264
|
}
|
|
71223
71265
|
const result = await response.json();
|
|
71224
71266
|
if (result.recorded > 0) {
|
|
71225
|
-
|
|
71267
|
+
log6.info(`Pushed ${result.recorded} agent metrics to cloud`);
|
|
71226
71268
|
}
|
|
71227
71269
|
return { recorded: result.recorded };
|
|
71228
71270
|
} catch (error2) {
|
|
71229
|
-
|
|
71271
|
+
log6.error("Failed to push agent metrics", { error: String(error2) });
|
|
71230
71272
|
return null;
|
|
71231
71273
|
}
|
|
71232
71274
|
}
|
|
@@ -71257,10 +71299,10 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71257
71299
|
throw new Error(`Session create failed: ${response.status}`);
|
|
71258
71300
|
}
|
|
71259
71301
|
const result = await response.json();
|
|
71260
|
-
|
|
71302
|
+
log6.info(`Created session ${result.sessionId.substring(0, 8)} for ${agentName}`);
|
|
71261
71303
|
return result.sessionId;
|
|
71262
71304
|
} catch (error2) {
|
|
71263
|
-
|
|
71305
|
+
log6.error("Failed to create session", { agentName, error: String(error2) });
|
|
71264
71306
|
return null;
|
|
71265
71307
|
}
|
|
71266
71308
|
}
|
|
@@ -71288,10 +71330,10 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71288
71330
|
throw new Error(`Summary add failed: ${response.status}`);
|
|
71289
71331
|
}
|
|
71290
71332
|
const result = await response.json();
|
|
71291
|
-
|
|
71333
|
+
log6.info(`Added summary for ${agentName}: ${summary.currentTask || "no task"}`);
|
|
71292
71334
|
return result.summaryId;
|
|
71293
71335
|
} catch (error2) {
|
|
71294
|
-
|
|
71336
|
+
log6.error("Failed to add summary", { sessionId, agentName, error: String(error2) });
|
|
71295
71337
|
return null;
|
|
71296
71338
|
}
|
|
71297
71339
|
}
|
|
@@ -71317,10 +71359,10 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71317
71359
|
if (!response.ok) {
|
|
71318
71360
|
throw new Error(`Session end failed: ${response.status}`);
|
|
71319
71361
|
}
|
|
71320
|
-
|
|
71362
|
+
log6.info(`Ended session ${sessionId.substring(0, 8)}: ${endMarker?.summary || "no summary"}`);
|
|
71321
71363
|
return true;
|
|
71322
71364
|
} catch (error2) {
|
|
71323
|
-
|
|
71365
|
+
log6.error("Failed to end session", { sessionId, error: String(error2) });
|
|
71324
71366
|
return false;
|
|
71325
71367
|
}
|
|
71326
71368
|
}
|
|
@@ -71409,11 +71451,11 @@ var CloudSyncService = class extends import_events7.EventEmitter {
|
|
|
71409
71451
|
this.lastMessageSyncTs = Math.max(...messages.map((m) => m.ts));
|
|
71410
71452
|
}
|
|
71411
71453
|
if (result.synced > 0) {
|
|
71412
|
-
|
|
71454
|
+
log6.info(`Synced ${result.synced} messages to cloud`, { duplicates: result.duplicates });
|
|
71413
71455
|
}
|
|
71414
71456
|
return result;
|
|
71415
71457
|
} catch (error2) {
|
|
71416
|
-
|
|
71458
|
+
log6.error("Message sync error", { error: String(error2) });
|
|
71417
71459
|
return { synced: 0, duplicates: 0 };
|
|
71418
71460
|
} finally {
|
|
71419
71461
|
this.messageSyncInProgress = false;
|
|
@@ -71438,7 +71480,7 @@ function createCloudPersistenceHandler(cloudSync, workspaceId) {
|
|
|
71438
71480
|
sessionId = newSessionId;
|
|
71439
71481
|
agentSessions.set(agentName, sessionId);
|
|
71440
71482
|
} else {
|
|
71441
|
-
|
|
71483
|
+
log6.warn(`Failed to create session for ${agentName}, skipping summary`);
|
|
71442
71484
|
return;
|
|
71443
71485
|
}
|
|
71444
71486
|
}
|
|
@@ -71450,7 +71492,7 @@ function createCloudPersistenceHandler(cloudSync, workspaceId) {
|
|
|
71450
71492
|
await cloudSync.endSession(sessionId, event.marker);
|
|
71451
71493
|
agentSessions.delete(agentName);
|
|
71452
71494
|
} else {
|
|
71453
|
-
|
|
71495
|
+
log6.warn(`No session found for ${agentName} on session-end`);
|
|
71454
71496
|
}
|
|
71455
71497
|
},
|
|
71456
71498
|
destroy() {
|
|
@@ -74347,15 +74389,15 @@ var Orchestrator = class extends import_events8.EventEmitter {
|
|
|
74347
74389
|
*/
|
|
74348
74390
|
getGitInfo(workspacePath) {
|
|
74349
74391
|
try {
|
|
74350
|
-
const { execSync:
|
|
74351
|
-
const branch =
|
|
74392
|
+
const { execSync: execSync10 } = require("child_process");
|
|
74393
|
+
const branch = execSync10("git branch --show-current", {
|
|
74352
74394
|
cwd: workspacePath,
|
|
74353
74395
|
encoding: "utf8",
|
|
74354
74396
|
stdio: ["pipe", "pipe", "pipe"]
|
|
74355
74397
|
}).trim();
|
|
74356
74398
|
let remote;
|
|
74357
74399
|
try {
|
|
74358
|
-
remote =
|
|
74400
|
+
remote = execSync10("git remote get-url origin", {
|
|
74359
74401
|
cwd: workspacePath,
|
|
74360
74402
|
encoding: "utf8",
|
|
74361
74403
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -76839,7 +76881,7 @@ function manageContext(compactor, messages) {
|
|
|
76839
76881
|
}
|
|
76840
76882
|
|
|
76841
76883
|
// packages/daemon/dist/cli-auth.js
|
|
76842
|
-
var
|
|
76884
|
+
var import_node_child_process14 = require("node:child_process");
|
|
76843
76885
|
var fs33 = __toESM(require("fs/promises"), 1);
|
|
76844
76886
|
var os15 = __toESM(require("os"), 1);
|
|
76845
76887
|
var import_node_path27 = require("node:path");
|
|
@@ -76956,7 +76998,7 @@ async function startCLIAuth(provider, options = {}) {
|
|
|
76956
76998
|
config2.command,
|
|
76957
76999
|
...args
|
|
76958
77000
|
];
|
|
76959
|
-
const proc = (0,
|
|
77001
|
+
const proc = (0, import_node_child_process14.spawn)(relayPtyPath, relayArgs, {
|
|
76960
77002
|
cwd: process.cwd(),
|
|
76961
77003
|
env: {
|
|
76962
77004
|
...process.env,
|
|
@@ -78198,11 +78240,11 @@ var HookRegistry = class {
|
|
|
78198
78240
|
};
|
|
78199
78241
|
|
|
78200
78242
|
// packages/trajectory/dist/integration.js
|
|
78201
|
-
var
|
|
78243
|
+
var import_node_child_process15 = require("node:child_process");
|
|
78202
78244
|
async function runTrail2(args) {
|
|
78203
78245
|
return new Promise((resolve5) => {
|
|
78204
78246
|
const trajectoryEnv = getTrajectoryEnvVars();
|
|
78205
|
-
const proc = (0,
|
|
78247
|
+
const proc = (0, import_node_child_process15.spawn)("trail", args, {
|
|
78206
78248
|
cwd: getProjectPaths().projectRoot,
|
|
78207
78249
|
env: { ...process.env, ...trajectoryEnv },
|
|
78208
78250
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -78473,7 +78515,7 @@ var TrajectoryIntegration2 = class {
|
|
|
78473
78515
|
*/
|
|
78474
78516
|
isTrailInstalledSync() {
|
|
78475
78517
|
try {
|
|
78476
|
-
(0,
|
|
78518
|
+
(0, import_node_child_process15.execSync)("which trail", { stdio: "pipe" });
|
|
78477
78519
|
return true;
|
|
78478
78520
|
} catch {
|
|
78479
78521
|
return false;
|