@adhdev/daemon-standalone 0.9.77-rc.4 → 0.9.77-rc.40
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.js +1122 -9886
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/public/assets/{index-6WEc6L46.js → index-BWLH33S7.js} +27 -27
- package/public/assets/index-BdY6qPu0.css +1 -0
- package/public/assets/{terminal-BeBmUW3m.js → terminal-B-dmfv31.js} +11 -11
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +944 -76
- package/vendor/mcp-server/index.js.map +1 -1
- package/public/assets/index-DftJ2WZr.css +0 -1
|
@@ -25120,6 +25120,7 @@ __export(dist_exports, {
|
|
|
25120
25120
|
buildThoughtChatMessage: () => buildThoughtChatMessage,
|
|
25121
25121
|
buildToolChatMessage: () => buildToolChatMessage,
|
|
25122
25122
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
25123
|
+
cancelTask: () => cancelTask,
|
|
25123
25124
|
claimNextTask: () => claimNextTask,
|
|
25124
25125
|
classifyChatMessageVisibility: () => classifyChatMessageVisibility,
|
|
25125
25126
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
|
|
@@ -25163,6 +25164,7 @@ __export(dist_exports, {
|
|
|
25163
25164
|
getLogLevel: () => getLogLevel,
|
|
25164
25165
|
getMesh: () => getMesh,
|
|
25165
25166
|
getMeshByRepo: () => getMeshByRepo,
|
|
25167
|
+
getMeshQueueStats: () => getMeshQueueStats,
|
|
25166
25168
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
25167
25169
|
getQueue: () => getQueue,
|
|
25168
25170
|
getRecentActivity: () => getRecentActivity,
|
|
@@ -25231,6 +25233,7 @@ __export(dist_exports, {
|
|
|
25231
25233
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
25232
25234
|
removeNode: () => removeNode,
|
|
25233
25235
|
removeWorktree: () => removeWorktree,
|
|
25236
|
+
requeueTask: () => requeueTask,
|
|
25234
25237
|
resetConfig: () => resetConfig,
|
|
25235
25238
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
25236
25239
|
resetState: () => resetState,
|
|
@@ -26029,6 +26032,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
26029
26032
|
message,
|
|
26030
26033
|
status: "pending",
|
|
26031
26034
|
targetNodeId: opts?.targetNodeId,
|
|
26035
|
+
targetSessionId: opts?.targetSessionId,
|
|
26032
26036
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26033
26037
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26034
26038
|
};
|
|
@@ -26046,9 +26050,14 @@ function getQueue(meshId, opts) {
|
|
|
26046
26050
|
}
|
|
26047
26051
|
function claimNextTask(meshId, nodeId, sessionId) {
|
|
26048
26052
|
const queue = readQueue(meshId);
|
|
26049
|
-
|
|
26053
|
+
const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
|
|
26054
|
+
if (hasActiveAssignment) return null;
|
|
26055
|
+
let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
|
|
26050
26056
|
if (targetIdx === -1) {
|
|
26051
|
-
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.
|
|
26057
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
|
|
26058
|
+
}
|
|
26059
|
+
if (targetIdx === -1) {
|
|
26060
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
|
|
26052
26061
|
}
|
|
26053
26062
|
if (targetIdx === -1) return null;
|
|
26054
26063
|
const entry = queue[targetIdx];
|
|
@@ -26068,6 +26077,40 @@ function updateTaskStatus(meshId, taskId, status) {
|
|
|
26068
26077
|
writeQueue(meshId, queue);
|
|
26069
26078
|
return queue[idx];
|
|
26070
26079
|
}
|
|
26080
|
+
function cancelTask(meshId, taskId, opts) {
|
|
26081
|
+
const queue = readQueue(meshId);
|
|
26082
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
26083
|
+
if (idx === -1) return null;
|
|
26084
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26085
|
+
queue[idx].status = "cancelled";
|
|
26086
|
+
queue[idx].updatedAt = now;
|
|
26087
|
+
queue[idx].cancelledAt = now;
|
|
26088
|
+
if (opts?.reason) queue[idx].cancelReason = opts.reason;
|
|
26089
|
+
writeQueue(meshId, queue);
|
|
26090
|
+
return queue[idx];
|
|
26091
|
+
}
|
|
26092
|
+
function requeueTask(meshId, taskId, opts) {
|
|
26093
|
+
const queue = readQueue(meshId);
|
|
26094
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
26095
|
+
if (idx === -1) return null;
|
|
26096
|
+
const entry = queue[idx];
|
|
26097
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26098
|
+
entry.status = "pending";
|
|
26099
|
+
delete entry.assignedNodeId;
|
|
26100
|
+
delete entry.assignedSessionId;
|
|
26101
|
+
delete entry.cancelledAt;
|
|
26102
|
+
delete entry.cancelReason;
|
|
26103
|
+
if (opts?.clearTargetNode) delete entry.targetNodeId;
|
|
26104
|
+
if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
|
|
26105
|
+
if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
|
|
26106
|
+
if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
|
|
26107
|
+
entry.updatedAt = now;
|
|
26108
|
+
entry.requeuedAt = now;
|
|
26109
|
+
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
26110
|
+
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
26111
|
+
writeQueue(meshId, queue);
|
|
26112
|
+
return entry;
|
|
26113
|
+
}
|
|
26071
26114
|
function updateSessionTaskStatus(meshId, sessionId, status) {
|
|
26072
26115
|
const queue = readQueue(meshId);
|
|
26073
26116
|
for (let i = queue.length - 1; i >= 0; i--) {
|
|
@@ -26086,7 +26129,14 @@ function getMeshQueueStats(meshId) {
|
|
|
26086
26129
|
pending: queue.filter((q) => q.status === "pending").length,
|
|
26087
26130
|
assigned: queue.filter((q) => q.status === "assigned").length,
|
|
26088
26131
|
completed: queue.filter((q) => q.status === "completed").length,
|
|
26089
|
-
failed: queue.filter((q) => q.status === "failed").length
|
|
26132
|
+
failed: queue.filter((q) => q.status === "failed").length,
|
|
26133
|
+
cancelled: queue.filter((q) => q.status === "cancelled").length,
|
|
26134
|
+
activeAssignments: queue.filter((q) => q.status === "assigned").map((q) => ({
|
|
26135
|
+
id: q.id,
|
|
26136
|
+
nodeId: q.assignedNodeId,
|
|
26137
|
+
sessionId: q.assignedSessionId,
|
|
26138
|
+
message: q.message
|
|
26139
|
+
}))
|
|
26090
26140
|
};
|
|
26091
26141
|
}
|
|
26092
26142
|
function setLogLevel(level) {
|
|
@@ -26245,6 +26295,9 @@ function drainPendingMeshCoordinatorEvents() {
|
|
|
26245
26295
|
function readNonEmptyString(value) {
|
|
26246
26296
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
26247
26297
|
}
|
|
26298
|
+
function resolveEventSessionId(event, fallback) {
|
|
26299
|
+
return readNonEmptyString(event.targetSessionId) || readNonEmptyString(event.sessionId) || readNonEmptyString(event.instanceId) || readNonEmptyString(fallback);
|
|
26300
|
+
}
|
|
26248
26301
|
function isMeshCoordinatorEvent(eventName) {
|
|
26249
26302
|
return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
|
|
26250
26303
|
}
|
|
@@ -26256,38 +26309,74 @@ function formatCompletionMetadata(event) {
|
|
|
26256
26309
|
].filter(Boolean);
|
|
26257
26310
|
return parts.length > 0 ? ` (${parts.join("; ")})` : "";
|
|
26258
26311
|
}
|
|
26312
|
+
function getMeshWithCache(components, meshId) {
|
|
26313
|
+
const localMesh = getMesh(meshId);
|
|
26314
|
+
if (localMesh) return localMesh;
|
|
26315
|
+
return components.router?.getCachedInlineMesh(meshId);
|
|
26316
|
+
}
|
|
26259
26317
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
26260
26318
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
26261
|
-
if (!task)
|
|
26319
|
+
if (!task) {
|
|
26320
|
+
return false;
|
|
26321
|
+
}
|
|
26262
26322
|
LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
|
|
26323
|
+
const mesh = getMeshWithCache(components, meshId);
|
|
26324
|
+
const node = mesh?.nodes.find((n) => n.id === nodeId);
|
|
26325
|
+
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
26326
|
+
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
26327
|
+
if (!isLocalNode) {
|
|
26328
|
+
components.dispatchMeshCommand(node.daemonId, "agent_command", {
|
|
26329
|
+
targetSessionId: sessionId,
|
|
26330
|
+
cliType: providerType,
|
|
26331
|
+
action: "send_chat",
|
|
26332
|
+
message: task.message
|
|
26333
|
+
}).catch((e) => {
|
|
26334
|
+
LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
26335
|
+
updateTaskStatus(meshId, task.id, "failed");
|
|
26336
|
+
});
|
|
26337
|
+
return true;
|
|
26338
|
+
}
|
|
26339
|
+
}
|
|
26263
26340
|
components.cliManager.handleCliCommand("agent_command", {
|
|
26264
26341
|
targetSessionId: sessionId,
|
|
26265
26342
|
cliType: providerType,
|
|
26266
26343
|
action: "send_chat",
|
|
26267
|
-
|
|
26344
|
+
message: task.message
|
|
26268
26345
|
}).catch((e) => {
|
|
26269
|
-
LOG.error("MeshQueue", `Failed to dispatch task to node ${nodeId}: ${e?.message}`);
|
|
26346
|
+
LOG.error("MeshQueue", `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
26347
|
+
updateTaskStatus(meshId, task.id, "failed");
|
|
26270
26348
|
});
|
|
26271
26349
|
return true;
|
|
26272
26350
|
}
|
|
26273
26351
|
function triggerMeshQueue(components, meshId) {
|
|
26274
|
-
const mesh =
|
|
26352
|
+
const mesh = getMeshWithCache(components, meshId);
|
|
26275
26353
|
if (!mesh) return;
|
|
26276
26354
|
const cliInstances = components.instanceManager.getByCategory("cli");
|
|
26277
26355
|
for (const inst of cliInstances) {
|
|
26278
26356
|
const state = inst.getState();
|
|
26279
26357
|
const settings = state.settings || {};
|
|
26280
26358
|
const instMeshId = readNonEmptyString(settings.meshNodeFor);
|
|
26281
|
-
if (instMeshId !== meshId
|
|
26359
|
+
if (instMeshId !== meshId) continue;
|
|
26282
26360
|
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
26283
26361
|
if (!nodeId) continue;
|
|
26284
|
-
|
|
26362
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
26363
|
+
if (["stopped", "failed", "terminated", "exited", "closed"].includes(status)) continue;
|
|
26364
|
+
if (status !== "idle" && state.activeChat?.status !== "waiting_input") continue;
|
|
26285
26365
|
const sessionId = state.instanceId;
|
|
26286
26366
|
const providerType = state.type || readNonEmptyString(settings.providerType);
|
|
26287
26367
|
if (providerType) {
|
|
26288
26368
|
tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
26289
26369
|
}
|
|
26290
26370
|
}
|
|
26371
|
+
for (const [key, idle] of remoteIdleSessions.entries()) {
|
|
26372
|
+
const node = mesh.nodes.find((n) => n.id === idle.nodeId);
|
|
26373
|
+
if (node) {
|
|
26374
|
+
const assigned = tryAssignQueueTask(components, meshId, idle.nodeId, idle.sessionId, idle.providerType);
|
|
26375
|
+
if (assigned) {
|
|
26376
|
+
remoteIdleSessions.delete(key);
|
|
26377
|
+
}
|
|
26378
|
+
}
|
|
26379
|
+
}
|
|
26291
26380
|
}
|
|
26292
26381
|
function buildMeshSystemMessage(args) {
|
|
26293
26382
|
const metadata = formatCompletionMetadata(args.metadataEvent);
|
|
@@ -26334,20 +26423,67 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
26334
26423
|
return "";
|
|
26335
26424
|
}
|
|
26336
26425
|
function injectMeshSystemMessage(components, args) {
|
|
26426
|
+
let completedTaskForLedger = null;
|
|
26337
26427
|
if (args.event === "agent:generating_completed") {
|
|
26338
|
-
const sessionId =
|
|
26339
|
-
const nodeId = readNonEmptyString(args.
|
|
26428
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
26429
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
26340
26430
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
26341
26431
|
if (sessionId) {
|
|
26342
|
-
updateSessionTaskStatus(args.meshId, sessionId, "completed");
|
|
26432
|
+
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
|
|
26433
|
+
completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
|
|
26343
26434
|
if (nodeId && providerType) {
|
|
26344
26435
|
setTimeout(() => {
|
|
26345
26436
|
tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
26346
26437
|
}, 500);
|
|
26347
26438
|
}
|
|
26348
26439
|
}
|
|
26440
|
+
} else if (args.event === "agent:ready") {
|
|
26441
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
26442
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
26443
|
+
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
26444
|
+
const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
|
|
26445
|
+
if (completedTask) {
|
|
26446
|
+
completedTaskForLedger = { id: completedTask.id };
|
|
26447
|
+
try {
|
|
26448
|
+
appendLedgerEntry(args.meshId, {
|
|
26449
|
+
kind: "task_completed",
|
|
26450
|
+
nodeId: nodeId || void 0,
|
|
26451
|
+
sessionId,
|
|
26452
|
+
providerType: providerType || void 0,
|
|
26453
|
+
payload: {
|
|
26454
|
+
event: args.event,
|
|
26455
|
+
nodeLabel: args.nodeLabel,
|
|
26456
|
+
taskId: completedTask.id,
|
|
26457
|
+
completedViaReady: true,
|
|
26458
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
26459
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
26460
|
+
}
|
|
26461
|
+
});
|
|
26462
|
+
} catch (e) {
|
|
26463
|
+
LOG.warn("MeshLedger", `Failed to record task_completed from ready: ${e?.message || e}`);
|
|
26464
|
+
}
|
|
26465
|
+
}
|
|
26466
|
+
if (sessionId && nodeId && providerType) {
|
|
26467
|
+
remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
|
|
26468
|
+
setTimeout(() => {
|
|
26469
|
+
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
26470
|
+
if (assigned) {
|
|
26471
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
26472
|
+
}
|
|
26473
|
+
}, 500);
|
|
26474
|
+
}
|
|
26475
|
+
} else if (args.event === "agent:generating_started") {
|
|
26476
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
26477
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
26478
|
+
if (sessionId && nodeId) {
|
|
26479
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
26480
|
+
}
|
|
26349
26481
|
} else if (args.event === "agent:stopped") {
|
|
26350
|
-
const sessionId =
|
|
26482
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
26483
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
26484
|
+
if (sessionId && nodeId) {
|
|
26485
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
26486
|
+
}
|
|
26351
26487
|
if (sessionId) {
|
|
26352
26488
|
updateSessionTaskStatus(args.meshId, sessionId, "failed");
|
|
26353
26489
|
}
|
|
@@ -26357,13 +26493,15 @@ function injectMeshSystemMessage(components, args) {
|
|
|
26357
26493
|
try {
|
|
26358
26494
|
appendLedgerEntry(args.meshId, {
|
|
26359
26495
|
kind: ledgerKind,
|
|
26360
|
-
nodeId: readNonEmptyString(args.
|
|
26361
|
-
sessionId:
|
|
26496
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
|
|
26497
|
+
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
26362
26498
|
providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
|
|
26363
26499
|
payload: {
|
|
26364
26500
|
event: args.event,
|
|
26365
26501
|
nodeLabel: args.nodeLabel,
|
|
26366
|
-
|
|
26502
|
+
taskId: completedTaskForLedger?.id || void 0,
|
|
26503
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
26504
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
26367
26505
|
}
|
|
26368
26506
|
});
|
|
26369
26507
|
} catch (e) {
|
|
@@ -26376,8 +26514,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
26376
26514
|
const mesh = getMesh(args.meshId);
|
|
26377
26515
|
const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
|
|
26378
26516
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
26379
|
-
sessionId:
|
|
26380
|
-
nodeId: readNonEmptyString(args.
|
|
26517
|
+
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
26518
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
|
|
26381
26519
|
maxRetries
|
|
26382
26520
|
});
|
|
26383
26521
|
recoveryContext.failedProviderType = readNonEmptyString(args.metadataEvent.providerType) || null;
|
|
@@ -26472,12 +26610,14 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
26472
26610
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
|
|
26473
26611
|
return injectMeshSystemMessage(components, {
|
|
26474
26612
|
meshId,
|
|
26613
|
+
nodeId,
|
|
26475
26614
|
nodeLabel,
|
|
26476
26615
|
event: eventName,
|
|
26477
26616
|
metadataEvent: {
|
|
26478
|
-
targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId),
|
|
26617
|
+
targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId) || readNonEmptyString(payload.instanceId),
|
|
26479
26618
|
providerType: readNonEmptyString(payload.providerType),
|
|
26480
|
-
providerSessionId: readNonEmptyString(payload.providerSessionId)
|
|
26619
|
+
providerSessionId: readNonEmptyString(payload.providerSessionId),
|
|
26620
|
+
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary)
|
|
26481
26621
|
}
|
|
26482
26622
|
});
|
|
26483
26623
|
}
|
|
@@ -26496,15 +26636,17 @@ function setupMeshEventForwarding(components) {
|
|
|
26496
26636
|
const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
|
|
26497
26637
|
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
26498
26638
|
if (!isMeshDelegate) return;
|
|
26499
|
-
const mesh = meshIdFromRuntime ?
|
|
26639
|
+
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
26500
26640
|
const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
|
|
26501
26641
|
if (!meshId) return;
|
|
26502
26642
|
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
26503
26643
|
const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
|
|
26644
|
+
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
26504
26645
|
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
26505
26646
|
injectMeshSystemMessage(components, {
|
|
26506
26647
|
meshId,
|
|
26507
26648
|
sourceInstanceId: instanceId,
|
|
26649
|
+
nodeId: resolvedNodeId,
|
|
26508
26650
|
nodeLabel,
|
|
26509
26651
|
event: event.event,
|
|
26510
26652
|
metadataEvent: event
|
|
@@ -33701,11 +33843,13 @@ async function handleOpenPanel(h, args) {
|
|
|
33701
33843
|
async function handlePtyInput(h, args) {
|
|
33702
33844
|
const { cliType, data, targetSessionId } = args || {};
|
|
33703
33845
|
if (!data) return { success: false, error: "data required" };
|
|
33846
|
+
const cleanData = typeof data === "string" ? data.replace(/\x1b\[[?>][0-9;]*c/g, "") : data;
|
|
33847
|
+
if (!cleanData) return { success: true };
|
|
33704
33848
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
33705
33849
|
if (!adapter || typeof adapter.writeRaw !== "function") {
|
|
33706
33850
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
33707
33851
|
}
|
|
33708
|
-
await adapter.writeRaw(
|
|
33852
|
+
await adapter.writeRaw(cleanData);
|
|
33709
33853
|
return { success: true };
|
|
33710
33854
|
}
|
|
33711
33855
|
function handlePtyResize(_h, args) {
|
|
@@ -34532,9 +34676,6 @@ function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
|
34532
34676
|
const cliType = String(input.cliType || "").trim();
|
|
34533
34677
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
34534
34678
|
const env2 = { ...input.env || {}, ...COORDINATOR_DELEGATED_ENV_UNSETS };
|
|
34535
|
-
if (cliType === "hermes-cli" && !hasCliArg(cliArgs, "--ignore-user-config")) {
|
|
34536
|
-
cliArgs.unshift("--ignore-user-config");
|
|
34537
|
-
}
|
|
34538
34679
|
if (cliType === "claude-cli" && !hasCliArg(cliArgs, "--mcp-config")) {
|
|
34539
34680
|
cliArgs.unshift("--mcp-config", ensureEmptyDelegatedMcpConfig(input.workspace));
|
|
34540
34681
|
}
|
|
@@ -35478,7 +35619,9 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
35478
35619
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
35479
35620
|
meshId: options.meshId,
|
|
35480
35621
|
nodeExecutable: options.nodeExecutable,
|
|
35481
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath
|
|
35622
|
+
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
35623
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
35624
|
+
adhdevMcpPort: options.adhdevMcpPort
|
|
35482
35625
|
});
|
|
35483
35626
|
if (!mcpServer) {
|
|
35484
35627
|
return {
|
|
@@ -35545,7 +35688,9 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
35545
35688
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
35546
35689
|
meshId,
|
|
35547
35690
|
nodeExecutable: options.nodeExecutable,
|
|
35548
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath
|
|
35691
|
+
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
35692
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
35693
|
+
adhdevMcpPort: options.adhdevMcpPort
|
|
35549
35694
|
});
|
|
35550
35695
|
if (!mcpServer) {
|
|
35551
35696
|
return {
|
|
@@ -35567,6 +35712,22 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
35567
35712
|
if (!instructions || !template?.trim()) {
|
|
35568
35713
|
return { kind: "unsupported", reason: "Provider manual MCP setup is missing instructions or template" };
|
|
35569
35714
|
}
|
|
35715
|
+
const renderedTemplate = renderMeshCoordinatorTemplate(template, {
|
|
35716
|
+
meshId,
|
|
35717
|
+
workspace,
|
|
35718
|
+
serverName,
|
|
35719
|
+
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
35720
|
+
});
|
|
35721
|
+
const isCliCommand = !renderedTemplate.trim().includes("\n") && !renderedTemplate.trim().startsWith("{");
|
|
35722
|
+
if (isCliCommand) {
|
|
35723
|
+
return {
|
|
35724
|
+
kind: "cli_command",
|
|
35725
|
+
serverName,
|
|
35726
|
+
command: renderedTemplate.trim(),
|
|
35727
|
+
requiresRestart: mcpConfig.requiresRestart === true,
|
|
35728
|
+
instructions
|
|
35729
|
+
};
|
|
35730
|
+
}
|
|
35570
35731
|
return {
|
|
35571
35732
|
kind: "manual",
|
|
35572
35733
|
serverName,
|
|
@@ -35574,12 +35735,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
35574
35735
|
configPathCommand: mcpConfig.configPathCommand,
|
|
35575
35736
|
requiresRestart: mcpConfig.requiresRestart === true,
|
|
35576
35737
|
instructions,
|
|
35577
|
-
template:
|
|
35578
|
-
meshId,
|
|
35579
|
-
workspace,
|
|
35580
|
-
serverName,
|
|
35581
|
-
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
35582
|
-
})
|
|
35738
|
+
template: renderedTemplate
|
|
35583
35739
|
};
|
|
35584
35740
|
}
|
|
35585
35741
|
return {
|
|
@@ -35608,11 +35764,27 @@ function resolveAdhdevMcpServerLaunch(options) {
|
|
|
35608
35764
|
if (!entryPath) return null;
|
|
35609
35765
|
const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
|
|
35610
35766
|
if (!nodeExecutable) return null;
|
|
35767
|
+
const transport = resolveMcpTransport(options.adhdevMcpTransport);
|
|
35768
|
+
const args = [entryPath, "--mode", transport, "--repo-mesh", options.meshId];
|
|
35769
|
+
const port = resolveMcpPort(options.adhdevMcpPort);
|
|
35770
|
+
if (port !== void 0) args.push("--port", String(port));
|
|
35611
35771
|
return {
|
|
35612
35772
|
command: nodeExecutable,
|
|
35613
|
-
args
|
|
35773
|
+
args
|
|
35614
35774
|
};
|
|
35615
35775
|
}
|
|
35776
|
+
function resolveMcpTransport(explicitTransport) {
|
|
35777
|
+
if (explicitTransport === "local" || explicitTransport === "ipc") return explicitTransport;
|
|
35778
|
+
const envTransport = process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT?.trim();
|
|
35779
|
+
return envTransport === "local" ? "local" : "ipc";
|
|
35780
|
+
}
|
|
35781
|
+
function resolveMcpPort(explicitPort) {
|
|
35782
|
+
if (typeof explicitPort === "number" && Number.isInteger(explicitPort) && explicitPort > 0) return explicitPort;
|
|
35783
|
+
const raw = process.env.ADHDEV_COORDINATOR_MCP_PORT?.trim();
|
|
35784
|
+
if (!raw) return void 0;
|
|
35785
|
+
const parsed = Number(raw);
|
|
35786
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
35787
|
+
}
|
|
35616
35788
|
function resolveMcpNodeExecutable(explicitExecutable) {
|
|
35617
35789
|
const explicit = explicitExecutable?.trim();
|
|
35618
35790
|
if (explicit) return explicit;
|
|
@@ -40855,7 +41027,8 @@ async function initDaemonComponents(config2) {
|
|
|
40855
41027
|
cdpManagers,
|
|
40856
41028
|
sessionRegistry,
|
|
40857
41029
|
detectedIdes: detectedIdesRef,
|
|
40858
|
-
refreshProviderAvailability
|
|
41030
|
+
refreshProviderAvailability,
|
|
41031
|
+
dispatchMeshCommand: config2.dispatchMeshCommand
|
|
40859
41032
|
};
|
|
40860
41033
|
setupMeshEventForwarding(components);
|
|
40861
41034
|
return components;
|
|
@@ -40913,7 +41086,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
40913
41086
|
}
|
|
40914
41087
|
cdpManagers.clear();
|
|
40915
41088
|
}
|
|
40916
|
-
var path4, import_promises4, import_fs3, import_child_process, import_util3, import_os2, import_path, import_fs4, import_crypto2, import_fs5, import_path2, import_crypto3, import_fs6, import_path3, import_crypto4, import_events2, import_fs7, import_path4, import_crypto5, fs2, path8, os22, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs8, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os4, path5, import_crypto6, path6, path7, import_fs9, import_path5, import_child_process4, import_fs10, import_os3, path9, import_child_process5, os32, path10, import_fs11, os42, import_child_process6, http, crypto2, fs3, path11, os5, fs4, os6, path12, import_crypto7, fs5, path13, os7, os13, path18, crypto4, import_fs12, import_child_process7, os12, path16, crypto3, fs6, import_module, path17, import_stream2, import_child_process8, import_child_process9, net2, os15, path20, fs7, path19, os14, fs8, path21, os16, import_child_process10, import_crypto8, import_fs13, import_module2, os17, import_path6, os18, import_child_process11, import_child_process12, fs9, os19, path222, import_os4, import_path7, fs10, fs11, path23, os20, import_child_process13, import_os5, http2, fs15, path27, fs12, path24, fs13, path25, fs14, path26, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, mesh_ledger_exports, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, meshLedgerEvents, init_mesh_ledger, init_mesh_work_queue, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, mesh_events_exports, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, init_mesh_events, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, TerminalTranscriptAccumulator, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, VALID_INPUT_MEDIA_TYPES, VALID_INPUT_STRATEGIES, TEXT_ONLY_MESSAGE_INPUT_SUPPORT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, HERMES_CLI_STARTING_SEND_SETTLE_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, IMAGE_MIME_EXTENSIONS, MATERIALIZED_IMAGE_MAX_AGE_MS, MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS, lastMaterializedImageCleanupAt, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, VALID_INPUT_STRATEGIES2, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, SessionHostCompatibilityError, EXTENSION_CATALOG, SessionRegistry;
|
|
41089
|
+
var path4, import_promises4, import_fs3, import_child_process, import_util3, import_os2, import_path, import_fs4, import_crypto2, import_fs5, import_path2, import_crypto3, import_fs6, import_path3, import_crypto4, import_events2, import_fs7, import_path4, import_crypto5, fs2, path8, os22, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs8, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os4, path5, import_crypto6, path6, path7, import_fs9, import_path5, import_child_process4, import_fs10, import_os3, path9, import_child_process5, os32, path10, import_fs11, os42, import_child_process6, http, crypto2, fs3, path11, os5, fs4, os6, path12, import_crypto7, fs5, path13, os7, os13, path18, crypto4, import_fs12, import_child_process7, os12, path16, crypto3, fs6, import_module, path17, import_stream2, import_child_process8, import_child_process9, net2, os15, path20, fs7, path19, os14, fs8, path21, os16, import_child_process10, import_crypto8, import_fs13, import_module2, os17, import_path6, os18, import_child_process11, import_child_process12, fs9, os19, path222, import_os4, import_path7, fs10, fs11, path23, os20, import_child_process13, import_os5, http2, fs15, path27, fs12, path24, fs13, path25, fs14, path26, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, mesh_ledger_exports, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, meshLedgerEvents, init_mesh_ledger, mesh_work_queue_exports, init_mesh_work_queue, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, mesh_events_exports, remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, init_mesh_events, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, TerminalTranscriptAccumulator, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, VALID_INPUT_MEDIA_TYPES, VALID_INPUT_STRATEGIES, TEXT_ONLY_MESSAGE_INPUT_SUPPORT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, HERMES_CLI_STARTING_SEND_SETTLE_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, IMAGE_MIME_EXTENSIONS, MATERIALIZED_IMAGE_MAX_AGE_MS, MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS, lastMaterializedImageCleanupAt, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, VALID_INPUT_STRATEGIES2, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, SessionHostCompatibilityError, EXTENSION_CATALOG, SessionRegistry;
|
|
40917
41090
|
var init_dist2 = __esm({
|
|
40918
41091
|
"../daemon-core/dist/index.mjs"() {
|
|
40919
41092
|
"use strict";
|
|
@@ -41246,6 +41419,17 @@ Follow these recovery rules:
|
|
|
41246
41419
|
meshLedgerEvents = new import_events2.EventEmitter();
|
|
41247
41420
|
}
|
|
41248
41421
|
});
|
|
41422
|
+
mesh_work_queue_exports = {};
|
|
41423
|
+
__export2(mesh_work_queue_exports, {
|
|
41424
|
+
cancelTask: () => cancelTask,
|
|
41425
|
+
claimNextTask: () => claimNextTask,
|
|
41426
|
+
enqueueTask: () => enqueueTask,
|
|
41427
|
+
getMeshQueueStats: () => getMeshQueueStats,
|
|
41428
|
+
getQueue: () => getQueue,
|
|
41429
|
+
requeueTask: () => requeueTask,
|
|
41430
|
+
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
41431
|
+
updateTaskStatus: () => updateTaskStatus
|
|
41432
|
+
});
|
|
41249
41433
|
init_mesh_work_queue = __esm2({
|
|
41250
41434
|
"src/mesh/mesh-work-queue.ts"() {
|
|
41251
41435
|
"use strict";
|
|
@@ -41325,12 +41509,15 @@ Follow these recovery rules:
|
|
|
41325
41509
|
init_logger();
|
|
41326
41510
|
init_mesh_ledger();
|
|
41327
41511
|
init_mesh_work_queue();
|
|
41512
|
+
remoteIdleSessions = /* @__PURE__ */ new Map();
|
|
41328
41513
|
MAX_PENDING_EVENTS = 50;
|
|
41329
41514
|
pendingMeshCoordinatorEvents = [];
|
|
41330
41515
|
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
41516
|
+
"agent:generating_started",
|
|
41331
41517
|
"agent:generating_completed",
|
|
41332
41518
|
"agent:waiting_approval",
|
|
41333
41519
|
"agent:stopped",
|
|
41520
|
+
"agent:ready",
|
|
41334
41521
|
"monitor:long_generating"
|
|
41335
41522
|
]);
|
|
41336
41523
|
EVENT_TO_LEDGER_KIND = {
|
|
@@ -41865,6 +42052,8 @@ Follow these recovery rules:
|
|
|
41865
42052
|
statusHistory = [];
|
|
41866
42053
|
// ─── CLI Scripts (script-based parsing) ───
|
|
41867
42054
|
cliScripts;
|
|
42055
|
+
/** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
|
|
42056
|
+
scriptState = null;
|
|
41868
42057
|
runtimeSettings = {};
|
|
41869
42058
|
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
41870
42059
|
accumulatedBuffer = "";
|
|
@@ -41943,7 +42132,7 @@ ${lastSnapshot}`;
|
|
|
41943
42132
|
}
|
|
41944
42133
|
getFreshParsedStatusCache() {
|
|
41945
42134
|
const cached2 = this.parsedStatusCache;
|
|
41946
|
-
if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
|
|
42135
|
+
if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
|
|
41947
42136
|
return cached2.result;
|
|
41948
42137
|
}
|
|
41949
42138
|
return null;
|
|
@@ -42046,6 +42235,7 @@ ${lastSnapshot}`;
|
|
|
42046
42235
|
this.cliScripts = scripts;
|
|
42047
42236
|
this.parsedStatusCache = null;
|
|
42048
42237
|
this.parseErrorMessage = null;
|
|
42238
|
+
this.scriptState = typeof scripts.createState === "function" ? scripts.createState() : null;
|
|
42049
42239
|
const scriptNames = listCliScriptNames(scripts);
|
|
42050
42240
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
42051
42241
|
}
|
|
@@ -42163,6 +42353,7 @@ ${lastSnapshot}`;
|
|
|
42163
42353
|
this.ready = false;
|
|
42164
42354
|
this.startupParseGate = false;
|
|
42165
42355
|
this.spawnAt = 0;
|
|
42356
|
+
this.scriptState = null;
|
|
42166
42357
|
this.onStatusChange?.();
|
|
42167
42358
|
});
|
|
42168
42359
|
this.spawnAt = Date.now();
|
|
@@ -42916,6 +43107,11 @@ ${lastSnapshot}`;
|
|
|
42916
43107
|
};
|
|
42917
43108
|
}
|
|
42918
43109
|
// ─── Script Execution ──────────────────────────
|
|
43110
|
+
invokeCliScript(script, input) {
|
|
43111
|
+
const hasStateFactory = typeof this.cliScripts?.createState === "function";
|
|
43112
|
+
const expectsStateArgument = hasStateFactory || this.scriptState !== null || script.length >= 2;
|
|
43113
|
+
return expectsStateArgument ? script(this.scriptState, input) : script(input);
|
|
43114
|
+
}
|
|
42919
43115
|
runParseSession() {
|
|
42920
43116
|
if (typeof this.cliScripts?.parseSession !== "function") {
|
|
42921
43117
|
this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
|
|
@@ -42936,7 +43132,10 @@ ${lastSnapshot}`;
|
|
|
42936
43132
|
scope: this.currentTurnScope,
|
|
42937
43133
|
runtimeSettings: this.runtimeSettings
|
|
42938
43134
|
});
|
|
42939
|
-
const session = this.
|
|
43135
|
+
const session = this.invokeCliScript(
|
|
43136
|
+
this.cliScripts.parseSession,
|
|
43137
|
+
{ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) }
|
|
43138
|
+
);
|
|
42940
43139
|
this.parseErrorMessage = null;
|
|
42941
43140
|
return session && typeof session === "object" ? session : null;
|
|
42942
43141
|
} catch (e) {
|
|
@@ -42950,7 +43149,7 @@ ${lastSnapshot}`;
|
|
|
42950
43149
|
if (!this.cliScripts?.detectStatus) return null;
|
|
42951
43150
|
try {
|
|
42952
43151
|
const screenText = this.terminalScreen.getText();
|
|
42953
|
-
const status = this.cliScripts.detectStatus
|
|
43152
|
+
const status = this.invokeCliScript(this.cliScripts.detectStatus, {
|
|
42954
43153
|
tail: text.slice(-500),
|
|
42955
43154
|
screenText,
|
|
42956
43155
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -42969,7 +43168,7 @@ ${lastSnapshot}`;
|
|
|
42969
43168
|
try {
|
|
42970
43169
|
const screenText = this.terminalScreen.getText();
|
|
42971
43170
|
const buffer = screenText || this.accumulatedBuffer;
|
|
42972
|
-
return this.cliScripts.parseApproval
|
|
43171
|
+
return this.invokeCliScript(this.cliScripts.parseApproval, {
|
|
42973
43172
|
buffer,
|
|
42974
43173
|
screenText,
|
|
42975
43174
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -43025,7 +43224,7 @@ ${lastSnapshot}`;
|
|
|
43025
43224
|
const screenText = this.readTerminalScreenText();
|
|
43026
43225
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
43027
43226
|
const cached2 = this.parsedStatusCache;
|
|
43028
|
-
if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === parseScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
|
|
43227
|
+
if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === parseScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
|
|
43029
43228
|
return cached2.result;
|
|
43030
43229
|
}
|
|
43031
43230
|
const parsed = this.runParseSession();
|
|
@@ -43053,6 +43252,7 @@ ${lastSnapshot}`;
|
|
|
43053
43252
|
currentTurnScope: this.currentTurnScope,
|
|
43054
43253
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
43055
43254
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
43255
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
43056
43256
|
screenText: parseScreenText,
|
|
43057
43257
|
currentStatus: this.currentStatus,
|
|
43058
43258
|
activeModal: this.activeModal,
|
|
@@ -43077,7 +43277,7 @@ ${lastSnapshot}`;
|
|
|
43077
43277
|
scope: this.currentTurnScope,
|
|
43078
43278
|
runtimeSettings: this.runtimeSettings
|
|
43079
43279
|
});
|
|
43080
|
-
return await Promise.resolve(fn({
|
|
43280
|
+
return await Promise.resolve(fn(this.scriptState, {
|
|
43081
43281
|
...input,
|
|
43082
43282
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
43083
43283
|
}));
|
|
@@ -48296,6 +48496,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
48296
48496
|
this.completedDebounceTimer = null;
|
|
48297
48497
|
}, 3e3);
|
|
48298
48498
|
}
|
|
48499
|
+
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
48500
|
+
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
48299
48501
|
} else if (newStatus === "stopped") {
|
|
48300
48502
|
if (this.generatingDebounceTimer) {
|
|
48301
48503
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -53014,6 +53216,51 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
53014
53216
|
return { success: false, error: e.message };
|
|
53015
53217
|
}
|
|
53016
53218
|
}
|
|
53219
|
+
case "get_mesh_queue": {
|
|
53220
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53221
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
53222
|
+
try {
|
|
53223
|
+
const { getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
53224
|
+
const status = Array.isArray(args?.status) ? args.status.map((s) => typeof s === "string" ? s.trim() : "").filter(Boolean) : void 0;
|
|
53225
|
+
const queue = getQueue2(meshId, { status });
|
|
53226
|
+
return { success: true, queue };
|
|
53227
|
+
} catch (e) {
|
|
53228
|
+
return { success: false, error: e.message };
|
|
53229
|
+
}
|
|
53230
|
+
}
|
|
53231
|
+
case "cancel_mesh_queue_task": {
|
|
53232
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53233
|
+
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
53234
|
+
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
53235
|
+
try {
|
|
53236
|
+
const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
53237
|
+
const reason = typeof args?.reason === "string" ? args.reason : void 0;
|
|
53238
|
+
const task = cancelTask2(meshId, taskId, { reason });
|
|
53239
|
+
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
53240
|
+
return { success: true, task };
|
|
53241
|
+
} catch (e) {
|
|
53242
|
+
return { success: false, error: e.message };
|
|
53243
|
+
}
|
|
53244
|
+
}
|
|
53245
|
+
case "requeue_mesh_queue_task": {
|
|
53246
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53247
|
+
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
53248
|
+
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
53249
|
+
try {
|
|
53250
|
+
const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
53251
|
+
const task = requeueTask2(meshId, taskId, {
|
|
53252
|
+
reason: typeof args?.reason === "string" ? args.reason : void 0,
|
|
53253
|
+
targetNodeId: typeof args?.targetNodeId === "string" ? args.targetNodeId.trim() : void 0,
|
|
53254
|
+
targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : void 0,
|
|
53255
|
+
clearTargetNode: args?.clearTargetNode === true,
|
|
53256
|
+
clearTargetSession: args?.clearTargetSession !== false
|
|
53257
|
+
});
|
|
53258
|
+
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
53259
|
+
return { success: true, task };
|
|
53260
|
+
} catch (e) {
|
|
53261
|
+
return { success: false, error: e.message };
|
|
53262
|
+
}
|
|
53263
|
+
}
|
|
53017
53264
|
case "add_mesh_node": {
|
|
53018
53265
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53019
53266
|
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -53171,7 +53418,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
53171
53418
|
appendLedgerEntry2(meshId, {
|
|
53172
53419
|
kind: "node_removed",
|
|
53173
53420
|
nodeId,
|
|
53174
|
-
payload: {
|
|
53421
|
+
payload: {
|
|
53422
|
+
worktree: !!node?.isLocalWorktree,
|
|
53423
|
+
sessionCleanupMode,
|
|
53424
|
+
workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
|
|
53425
|
+
daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
|
|
53426
|
+
worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0
|
|
53427
|
+
}
|
|
53175
53428
|
});
|
|
53176
53429
|
} catch {
|
|
53177
53430
|
}
|
|
@@ -53342,6 +53595,93 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
53342
53595
|
meshCoordinatorSetup: coordinatorSetup
|
|
53343
53596
|
};
|
|
53344
53597
|
}
|
|
53598
|
+
if (coordinatorSetup.kind === "cli_command") {
|
|
53599
|
+
let cliCmdSystemPrompt = "";
|
|
53600
|
+
try {
|
|
53601
|
+
cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
53602
|
+
} catch (error48) {
|
|
53603
|
+
const message = error48?.message || String(error48);
|
|
53604
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
53605
|
+
return {
|
|
53606
|
+
success: false,
|
|
53607
|
+
code: "mesh_coordinator_prompt_failed",
|
|
53608
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
53609
|
+
meshId,
|
|
53610
|
+
cliType,
|
|
53611
|
+
workspace
|
|
53612
|
+
};
|
|
53613
|
+
}
|
|
53614
|
+
try {
|
|
53615
|
+
const { execFileSync: execCmdSync } = await import("child_process");
|
|
53616
|
+
const cmdParts = coordinatorSetup.command.trim().split(/\s+/);
|
|
53617
|
+
const [regCmd, ...regArgs] = cmdParts;
|
|
53618
|
+
LOG.info("MeshCoordinator", `Running MCP registration: ${coordinatorSetup.command}`);
|
|
53619
|
+
execCmdSync(regCmd, regArgs, { stdio: "pipe", timeout: 15e3 });
|
|
53620
|
+
} catch (error48) {
|
|
53621
|
+
LOG.warn("MeshCoordinator", `MCP registration command failed (may be pre-registered): ${error48?.message || error48}`);
|
|
53622
|
+
}
|
|
53623
|
+
const cliCmdArgs = [];
|
|
53624
|
+
const cliCmdEnv = {};
|
|
53625
|
+
if (cliCmdSystemPrompt) {
|
|
53626
|
+
if (cliType === "codex-cli") {
|
|
53627
|
+
cliCmdArgs.push("-c", `developer_instructions=${JSON.stringify(cliCmdSystemPrompt)}`);
|
|
53628
|
+
} else if (cliType === "gemini-cli") {
|
|
53629
|
+
try {
|
|
53630
|
+
const { writeFileSync: wfs, existsSync: efs, readFileSync: rfs } = await import("fs");
|
|
53631
|
+
const geminiMdPath = `${workspace}/GEMINI.md`;
|
|
53632
|
+
const marker = "<!-- adhdev-mesh-coordinator-prompt -->";
|
|
53633
|
+
const markerEnd = "<!-- /adhdev-mesh-coordinator-prompt -->";
|
|
53634
|
+
const block = `${marker}
|
|
53635
|
+
${cliCmdSystemPrompt}
|
|
53636
|
+
${markerEnd}`;
|
|
53637
|
+
if (efs(geminiMdPath)) {
|
|
53638
|
+
const existing = rfs(geminiMdPath, "utf-8");
|
|
53639
|
+
const replaced = existing.replace(
|
|
53640
|
+
new RegExp(`${marker}[\\s\\S]*?${markerEnd}`, "g"),
|
|
53641
|
+
block
|
|
53642
|
+
);
|
|
53643
|
+
wfs(geminiMdPath, replaced.includes(marker) ? replaced : `${existing}
|
|
53644
|
+
|
|
53645
|
+
${block}`);
|
|
53646
|
+
} else {
|
|
53647
|
+
wfs(geminiMdPath, block);
|
|
53648
|
+
}
|
|
53649
|
+
LOG.info("MeshCoordinator", `Wrote coordinator prompt to ${workspace}/GEMINI.md`);
|
|
53650
|
+
} catch (e) {
|
|
53651
|
+
LOG.warn("MeshCoordinator", `Could not write GEMINI.md: ${e?.message || e}`);
|
|
53652
|
+
}
|
|
53653
|
+
}
|
|
53654
|
+
}
|
|
53655
|
+
const cliCmdLaunch = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
53656
|
+
cliType,
|
|
53657
|
+
dir: workspace,
|
|
53658
|
+
cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
|
|
53659
|
+
env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
|
|
53660
|
+
settings: { meshCoordinatorFor: meshId }
|
|
53661
|
+
});
|
|
53662
|
+
if (!cliCmdLaunch?.success) {
|
|
53663
|
+
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
53664
|
+
}
|
|
53665
|
+
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
53666
|
+
try {
|
|
53667
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53668
|
+
appendLedgerEntry2(meshId, {
|
|
53669
|
+
kind: "coordinator_started",
|
|
53670
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
53671
|
+
providerType: cliType,
|
|
53672
|
+
payload: { workspace }
|
|
53673
|
+
});
|
|
53674
|
+
} catch {
|
|
53675
|
+
}
|
|
53676
|
+
return {
|
|
53677
|
+
success: true,
|
|
53678
|
+
meshId,
|
|
53679
|
+
cliType,
|
|
53680
|
+
workspace,
|
|
53681
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
53682
|
+
mcpRegistered: true
|
|
53683
|
+
};
|
|
53684
|
+
}
|
|
53345
53685
|
const configFormat = coordinatorSetup.configFormat;
|
|
53346
53686
|
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
53347
53687
|
return {
|
|
@@ -53396,9 +53736,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
53396
53736
|
args: coordinatorSetup.mcpServer.args
|
|
53397
53737
|
};
|
|
53398
53738
|
if (args?.inlineMesh) {
|
|
53739
|
+
const modeArgIndex = coordinatorSetup.mcpServer.args.findIndex((value) => value === "--mode");
|
|
53740
|
+
const mcpTransport = modeArgIndex >= 0 ? coordinatorSetup.mcpServer.args[modeArgIndex + 1] : "ipc";
|
|
53399
53741
|
mcpServerEntry.env = {
|
|
53400
53742
|
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
53401
|
-
ADHDEV_MCP_TRANSPORT: "ipc"
|
|
53743
|
+
ADHDEV_MCP_TRANSPORT: mcpTransport === "local" ? "local" : "ipc"
|
|
53402
53744
|
};
|
|
53403
53745
|
}
|
|
53404
53746
|
try {
|
|
@@ -57240,6 +57582,11 @@ function annotateRapidReadChatAdvisory(payload, options) {
|
|
|
57240
57582
|
// src/tools/mesh-tools.ts
|
|
57241
57583
|
init_dist2();
|
|
57242
57584
|
var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
|
|
57585
|
+
function readString(value) {
|
|
57586
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
57587
|
+
}
|
|
57588
|
+
var DUPLICATE_DISPATCH_WINDOW_MS = 6e4;
|
|
57589
|
+
var STALE_ASSIGNED_QUEUE_MS = 30 * 6e4;
|
|
57243
57590
|
async function refreshMeshFromDaemon(ctx) {
|
|
57244
57591
|
if (!(ctx.transport instanceof IpcTransport)) return;
|
|
57245
57592
|
try {
|
|
@@ -57260,6 +57607,138 @@ async function findNodeWithRefresh(ctx, nodeId) {
|
|
|
57260
57607
|
if (!refreshed) throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
|
|
57261
57608
|
return refreshed;
|
|
57262
57609
|
}
|
|
57610
|
+
async function findOptionalNodeWithRefresh(ctx, nodeId) {
|
|
57611
|
+
const hit = ctx.mesh.nodes.find((n) => n.id === nodeId);
|
|
57612
|
+
if (hit) return hit;
|
|
57613
|
+
await refreshMeshFromDaemon(ctx);
|
|
57614
|
+
return ctx.mesh.nodes.find((n) => n.id === nodeId) ?? null;
|
|
57615
|
+
}
|
|
57616
|
+
function hasRecentDuplicateDispatch(ctx, args) {
|
|
57617
|
+
const now = Date.now();
|
|
57618
|
+
const normalizedMessage = args.message.trim();
|
|
57619
|
+
for (const task of getQueue(ctx.mesh.id)) {
|
|
57620
|
+
const timestamp2 = new Date(task.updatedAt || task.createdAt).getTime();
|
|
57621
|
+
if (!Number.isFinite(timestamp2) || now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) continue;
|
|
57622
|
+
if (task.targetNodeId && task.targetNodeId !== args.node_id) continue;
|
|
57623
|
+
if (task.assignedNodeId && task.assignedNodeId !== args.node_id) continue;
|
|
57624
|
+
if (args.session_id && task.targetSessionId !== args.session_id && task.assignedSessionId !== args.session_id) continue;
|
|
57625
|
+
if (task.message?.trim() === normalizedMessage) {
|
|
57626
|
+
return { duplicate: true, entry: task, source: "queue" };
|
|
57627
|
+
}
|
|
57628
|
+
}
|
|
57629
|
+
const entries = readLedgerEntries(ctx.mesh.id, { tail: 200 });
|
|
57630
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
57631
|
+
const entry = entries[i];
|
|
57632
|
+
const timestamp2 = new Date(entry.timestamp).getTime();
|
|
57633
|
+
if (Number.isFinite(timestamp2) && now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) break;
|
|
57634
|
+
if (entry.kind !== "task_dispatched") continue;
|
|
57635
|
+
if (entry.nodeId !== args.node_id) continue;
|
|
57636
|
+
if (args.session_id && entry.sessionId !== args.session_id) continue;
|
|
57637
|
+
if (typeof entry.payload?.message !== "string") continue;
|
|
57638
|
+
if (entry.payload.message.trim() === normalizedMessage) {
|
|
57639
|
+
return { duplicate: true, entry, source: "ledger" };
|
|
57640
|
+
}
|
|
57641
|
+
}
|
|
57642
|
+
return { duplicate: false };
|
|
57643
|
+
}
|
|
57644
|
+
function buildMissingNodeReadChatRecovery(ctx, args) {
|
|
57645
|
+
const entries = readLedgerEntries(ctx.mesh.id, { tail: 300 });
|
|
57646
|
+
const relatedEntries = entries.filter((entry) => entry.nodeId === args.node_id || entry.sessionId === args.session_id);
|
|
57647
|
+
const completedEntries = relatedEntries.filter((entry) => entry.kind === "task_completed");
|
|
57648
|
+
const lastDispatch = [...relatedEntries].reverse().find((entry) => entry.kind === "task_dispatched");
|
|
57649
|
+
const lastTerminal = [...relatedEntries].reverse().find((entry) => entry.kind === "task_completed" || entry.kind === "task_failed" || entry.kind === "task_stalled");
|
|
57650
|
+
const lastRemoved = [...relatedEntries].reverse().find((entry) => entry.kind === "node_removed");
|
|
57651
|
+
const lastLaunch = [...relatedEntries].reverse().find((entry) => entry.kind === "session_launched");
|
|
57652
|
+
const providerSessionId = args.provider_session_id || readString(lastTerminal?.payload?.providerSessionId) || readString(lastLaunch?.payload?.providerSessionId) || readString(lastDispatch?.payload?.providerSessionId);
|
|
57653
|
+
const finalSummary = readString(lastTerminal?.payload?.finalSummary) || readString(lastTerminal?.payload?.compactSummary) || readString(lastTerminal?.payload?.summary);
|
|
57654
|
+
const ledger = {
|
|
57655
|
+
taskCompletedFound: completedEntries.length > 0,
|
|
57656
|
+
nodeRemovedFound: !!lastRemoved,
|
|
57657
|
+
providerType: lastTerminal?.providerType || lastLaunch?.providerType || lastDispatch?.providerType,
|
|
57658
|
+
providerSessionId,
|
|
57659
|
+
nodeRemovedAt: lastRemoved?.timestamp,
|
|
57660
|
+
sessionCleanupMode: readString(lastRemoved?.payload?.sessionCleanupMode),
|
|
57661
|
+
readDebugLocator: readString(lastTerminal?.payload?.readDebugLocator) || readString(lastTerminal?.payload?.debugBundlePath)
|
|
57662
|
+
};
|
|
57663
|
+
if (finalSummary) {
|
|
57664
|
+
return {
|
|
57665
|
+
success: true,
|
|
57666
|
+
compact: args.compact === true,
|
|
57667
|
+
recoveredFromLedger: true,
|
|
57668
|
+
nodeId: args.node_id,
|
|
57669
|
+
sessionId: args.session_id,
|
|
57670
|
+
summary: finalSummary,
|
|
57671
|
+
ledger,
|
|
57672
|
+
messages: [{ role: "assistant", content: finalSummary, isHistorical: true }]
|
|
57673
|
+
};
|
|
57674
|
+
}
|
|
57675
|
+
return {
|
|
57676
|
+
success: false,
|
|
57677
|
+
recoverable: true,
|
|
57678
|
+
code: "mesh_removed_node_transcript_unavailable",
|
|
57679
|
+
error: `Node '${args.node_id}' is not a current member of mesh '${ctx.mesh.name}'.`,
|
|
57680
|
+
nodeId: args.node_id,
|
|
57681
|
+
sessionId: args.session_id,
|
|
57682
|
+
providerSessionId,
|
|
57683
|
+
reason: "node_not_in_current_mesh_snapshot",
|
|
57684
|
+
ledger,
|
|
57685
|
+
completedSessionSeenInLedger: ledger.taskCompletedFound,
|
|
57686
|
+
lastDispatch: lastDispatch ? {
|
|
57687
|
+
timestamp: lastDispatch.timestamp,
|
|
57688
|
+
sessionId: lastDispatch.sessionId,
|
|
57689
|
+
providerType: lastDispatch.providerType,
|
|
57690
|
+
taskId: typeof lastDispatch.payload?.taskId === "string" ? lastDispatch.payload.taskId : void 0,
|
|
57691
|
+
messagePreview: typeof lastDispatch.payload?.message === "string" ? lastDispatch.payload.message.slice(0, 500) : void 0
|
|
57692
|
+
} : null,
|
|
57693
|
+
lastTerminalEvent: lastTerminal ? {
|
|
57694
|
+
kind: lastTerminal.kind,
|
|
57695
|
+
timestamp: lastTerminal.timestamp,
|
|
57696
|
+
sessionId: lastTerminal.sessionId,
|
|
57697
|
+
providerType: lastTerminal.providerType,
|
|
57698
|
+
taskId: typeof lastTerminal.payload?.taskId === "string" ? lastTerminal.payload.taskId : void 0,
|
|
57699
|
+
payload: lastTerminal.payload
|
|
57700
|
+
} : null,
|
|
57701
|
+
nextSteps: [
|
|
57702
|
+
providerSessionId ? `Retry mesh_read_chat with provider_session_id='${providerSessionId}' on a current live node for the same daemon if one exists.` : "If the node UI shows a provider transcript id, retry mesh_read_chat/mesh_read_debug with provider_session_id.",
|
|
57703
|
+
"Use mesh_read_debug with the provider_session_id or daemon-side debug bundle locator if available.",
|
|
57704
|
+
"Check mesh_task_history for task_completed and node_removed entries before redispatching; do not resend solely because transcript recovery failed.",
|
|
57705
|
+
"If this node was removed with stop_and_delete, the runtime transcript may be gone; rely on the ledger summary/locator or ask the operator for the saved UI output."
|
|
57706
|
+
],
|
|
57707
|
+
recoveryHints: [
|
|
57708
|
+
"The worktree/node may have been removed or the mesh snapshot may be stale after task completion.",
|
|
57709
|
+
"If you have a provider_session_id, retry mesh_read_chat with that value while targeting a live node for the same daemon if available.",
|
|
57710
|
+
"Use mesh_read_debug with provider_session_id, or inspect the daemon/session-host history locator if the transcript has already been archived.",
|
|
57711
|
+
"Avoid redispatching the same task solely because read_chat could not recover the transcript; check task_history and git status first."
|
|
57712
|
+
]
|
|
57713
|
+
};
|
|
57714
|
+
}
|
|
57715
|
+
function annotateQueueStaleness(queue) {
|
|
57716
|
+
const now = Date.now();
|
|
57717
|
+
return queue.map((task) => {
|
|
57718
|
+
const taskStatus = typeof task?.status === "string" ? task.status : void 0;
|
|
57719
|
+
const annotated = {
|
|
57720
|
+
...task,
|
|
57721
|
+
taskStatus,
|
|
57722
|
+
dispatchedAt: task?.createdAt,
|
|
57723
|
+
...taskStatus === "assigned" ? { activeTaskId: task.id } : {},
|
|
57724
|
+
...taskStatus === "completed" || taskStatus === "failed" ? {
|
|
57725
|
+
isHistorical: true,
|
|
57726
|
+
completedAt: task.updatedAt
|
|
57727
|
+
} : {}
|
|
57728
|
+
};
|
|
57729
|
+
if (taskStatus !== "assigned") return annotated;
|
|
57730
|
+
const updatedAt = new Date(task.updatedAt).getTime();
|
|
57731
|
+
const ageMs = Number.isFinite(updatedAt) ? now - updatedAt : null;
|
|
57732
|
+
if (ageMs === null || ageMs < STALE_ASSIGNED_QUEUE_MS) return annotated;
|
|
57733
|
+
return {
|
|
57734
|
+
...annotated,
|
|
57735
|
+
stale: true,
|
|
57736
|
+
staleAssigned: true,
|
|
57737
|
+
staleReason: "assigned task has not reached a terminal state within 30 minutes",
|
|
57738
|
+
assignedAgeMs: ageMs
|
|
57739
|
+
};
|
|
57740
|
+
});
|
|
57741
|
+
}
|
|
57263
57742
|
function unwrapCommandPayload(value) {
|
|
57264
57743
|
let current = value;
|
|
57265
57744
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -57272,6 +57751,26 @@ function unwrapCommandPayload(value) {
|
|
|
57272
57751
|
}
|
|
57273
57752
|
return current;
|
|
57274
57753
|
}
|
|
57754
|
+
function isTerminalSessionRecord(session) {
|
|
57755
|
+
const status = typeof session?.status === "string" ? session.status.toLowerCase() : "";
|
|
57756
|
+
const lifecycle = typeof session?.lifecycle === "string" ? session.lifecycle.toLowerCase() : "";
|
|
57757
|
+
const state = typeof session?.state === "string" ? session.state.toLowerCase() : "";
|
|
57758
|
+
return [status, lifecycle, state].some((value) => ["stopped", "failed", "terminated", "exited", "closed"].includes(value));
|
|
57759
|
+
}
|
|
57760
|
+
function isIdleSessionRecord(session) {
|
|
57761
|
+
if (isTerminalSessionRecord(session)) return false;
|
|
57762
|
+
const status = typeof session?.status === "string" ? session.status.toLowerCase() : "";
|
|
57763
|
+
const chatStatus = typeof session?.activeChat?.status === "string" ? session.activeChat.status.toLowerCase() : "";
|
|
57764
|
+
return status === "idle" || chatStatus === "waiting_input";
|
|
57765
|
+
}
|
|
57766
|
+
function chooseDispatchableSession(sessions, providerType, meshId, nodeId) {
|
|
57767
|
+
const live = sessions.filter((session) => !isTerminalSessionRecord(session));
|
|
57768
|
+
const matchingProvider = (session) => !providerType || session?.providerType === providerType || session?.cliType === providerType;
|
|
57769
|
+
const meshSessions = live.filter(
|
|
57770
|
+
(session) => session?.settings?.meshNodeFor === meshId || session?.settings?.meshNodeId === nodeId
|
|
57771
|
+
);
|
|
57772
|
+
return meshSessions.find((session) => isIdleSessionRecord(session) && matchingProvider(session)) || meshSessions.find(matchingProvider) || live.find((session) => isIdleSessionRecord(session) && matchingProvider(session)) || live.find(matchingProvider) || live.find(isIdleSessionRecord) || live[0];
|
|
57773
|
+
}
|
|
57275
57774
|
function findNestedPayload(value, predicate) {
|
|
57276
57775
|
const seen = /* @__PURE__ */ new Set();
|
|
57277
57776
|
const stack = [{ payload: value, depth: 0 }];
|
|
@@ -57300,12 +57799,136 @@ function extractGitDiff(value) {
|
|
|
57300
57799
|
function extractLaunchPayload(value) {
|
|
57301
57800
|
return findNestedPayload(value, (payload) => Boolean(payload?.sessionId || payload?.id || payload?.runtimeSessionId));
|
|
57302
57801
|
}
|
|
57802
|
+
function classifyMeshLaunchFailure(error48) {
|
|
57803
|
+
const message = error48 instanceof Error ? error48.message : String(error48 || "launch failed");
|
|
57804
|
+
const lower = message.toLowerCase();
|
|
57805
|
+
if (lower.includes("p2p") || lower.includes("datachannel") || lower.includes("node-datachannel")) {
|
|
57806
|
+
return { code: "p2p_unavailable", reason: "daemon_mesh_p2p_transport_unavailable", transport: "daemon_mesh_p2p" };
|
|
57807
|
+
}
|
|
57808
|
+
if (lower.includes("cannot connect to daemon ipc") || lower.includes("daemon ipc command")) {
|
|
57809
|
+
return { code: "local_ipc_unavailable", reason: "local_daemon_ipc_unavailable", transport: "local_ipc" };
|
|
57810
|
+
}
|
|
57811
|
+
if (lower.includes("timed out") || lower.includes("timeout")) {
|
|
57812
|
+
return { code: "mesh_transport_timeout", reason: "mesh_transport_timeout", transport: "mesh_transport" };
|
|
57813
|
+
}
|
|
57814
|
+
return { code: "mesh_launch_failed", reason: "provider_launch_failed", transport: "mesh_transport" };
|
|
57815
|
+
}
|
|
57816
|
+
function buildWorktreeCleanupHint(node) {
|
|
57817
|
+
if (!node.isLocalWorktree) return void 0;
|
|
57818
|
+
return {
|
|
57819
|
+
tool: "mesh_remove_node",
|
|
57820
|
+
args: { node_id: node.id, session_cleanup_mode: "preserve" },
|
|
57821
|
+
hint: `If the worktree is no longer needed, remove the orphan worktree node with mesh_remove_node(node_id: "${node.id}").`
|
|
57822
|
+
};
|
|
57823
|
+
}
|
|
57824
|
+
function buildRecoverableLaunchFailure(ctx, node, providerType, error48) {
|
|
57825
|
+
const message = error48 instanceof Error ? error48.message : String(error48 || "launch failed");
|
|
57826
|
+
const classified = classifyMeshLaunchFailure(error48);
|
|
57827
|
+
const cleanup = buildWorktreeCleanupHint(node);
|
|
57828
|
+
return {
|
|
57829
|
+
success: false,
|
|
57830
|
+
recoverable: true,
|
|
57831
|
+
code: classified.code,
|
|
57832
|
+
reason: classified.reason,
|
|
57833
|
+
transport: classified.transport,
|
|
57834
|
+
error: message,
|
|
57835
|
+
meshId: ctx.mesh.id,
|
|
57836
|
+
nodeId: node.id,
|
|
57837
|
+
daemonId: node.daemonId,
|
|
57838
|
+
workspace: node.workspace,
|
|
57839
|
+
isLocalWorktree: node.isLocalWorktree === true,
|
|
57840
|
+
worktreeBranch: node.worktreeBranch,
|
|
57841
|
+
clonedFromNodeId: node.clonedFromNodeId,
|
|
57842
|
+
...providerType ? { resolvedProviderType: providerType } : {},
|
|
57843
|
+
retryHint: `Retry mesh_launch_session(node_id: "${node.id}"${providerType ? `, type: "${providerType}"` : ""}) after daemon mesh transport/P2P is healthy.`,
|
|
57844
|
+
...cleanup ? { cleanup } : {},
|
|
57845
|
+
nextStepHints: [
|
|
57846
|
+
`Retry mesh_launch_session(node_id: "${node.id}"${providerType ? `, type: "${providerType}"` : ""}) after checking daemon/P2P health.`,
|
|
57847
|
+
...cleanup ? [`Cleanup orphan worktree node with mesh_remove_node(node_id: "${node.id}") if retry is not desired.`] : [],
|
|
57848
|
+
"Run mesh_status to see the degraded reason and recovery hints before redispatching work."
|
|
57849
|
+
]
|
|
57850
|
+
};
|
|
57851
|
+
}
|
|
57852
|
+
function recordRecoverableLaunchFailure(ctx, node, providerType, error48) {
|
|
57853
|
+
const failure2 = buildRecoverableLaunchFailure(ctx, node, providerType, error48);
|
|
57854
|
+
try {
|
|
57855
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
57856
|
+
kind: "recovery_attempted",
|
|
57857
|
+
nodeId: node.id,
|
|
57858
|
+
providerType,
|
|
57859
|
+
payload: {
|
|
57860
|
+
event: "session_launch_failed",
|
|
57861
|
+
...failure2
|
|
57862
|
+
}
|
|
57863
|
+
});
|
|
57864
|
+
} catch {
|
|
57865
|
+
}
|
|
57866
|
+
return failure2;
|
|
57867
|
+
}
|
|
57868
|
+
function getLatestActiveLaunchFailure(meshId, nodeId) {
|
|
57869
|
+
const entries = readLedgerEntries(meshId, { tail: 200 });
|
|
57870
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
57871
|
+
const entry = entries[i];
|
|
57872
|
+
if (entry.nodeId !== nodeId) continue;
|
|
57873
|
+
if (entry.kind === "session_launched" || entry.kind === "node_removed") return null;
|
|
57874
|
+
if (entry.kind === "recovery_attempted" && entry.payload?.event === "session_launch_failed") {
|
|
57875
|
+
return { timestamp: entry.timestamp, ...entry.payload };
|
|
57876
|
+
}
|
|
57877
|
+
}
|
|
57878
|
+
return null;
|
|
57879
|
+
}
|
|
57880
|
+
async function ipcDispatchToRemoteAgent(ctx, node, args) {
|
|
57881
|
+
const transport = ctx.transport;
|
|
57882
|
+
const daemonId = node.daemonId;
|
|
57883
|
+
let sessionId = args.session_id?.trim() || "";
|
|
57884
|
+
const providerPriorityList = Array.isArray(node.policy?.providerPriority) ? node.policy.providerPriority : [];
|
|
57885
|
+
let resolvedProviderType = args.providerType?.trim() || providerPriorityList[0] || "";
|
|
57886
|
+
if (!sessionId) {
|
|
57887
|
+
try {
|
|
57888
|
+
const relayResult = await transport.meshCommand(daemonId, "get_status_metadata", {});
|
|
57889
|
+
const innerResult = relayResult?.result ?? relayResult;
|
|
57890
|
+
const statusObj = innerResult?.status ?? innerResult;
|
|
57891
|
+
const sessions = Array.isArray(statusObj?.sessions) ? statusObj.sessions : [];
|
|
57892
|
+
const targetSession = chooseDispatchableSession(sessions, resolvedProviderType, ctx.mesh.id, node.id);
|
|
57893
|
+
if (targetSession?.id || targetSession?.sessionId) {
|
|
57894
|
+
sessionId = targetSession.id || targetSession.sessionId;
|
|
57895
|
+
if (!resolvedProviderType) {
|
|
57896
|
+
resolvedProviderType = targetSession.providerType || targetSession.cliType || "";
|
|
57897
|
+
}
|
|
57898
|
+
}
|
|
57899
|
+
} catch (e) {
|
|
57900
|
+
}
|
|
57901
|
+
}
|
|
57902
|
+
if (!resolvedProviderType) {
|
|
57903
|
+
return { success: false, error: `Cannot dispatch to remote node '${node.id}': providerType unknown. Set providerPriority on the node policy or call mesh_launch_session first.` };
|
|
57904
|
+
}
|
|
57905
|
+
try {
|
|
57906
|
+
const dispatchResult = await transport.meshCommand(daemonId, "agent_command", {
|
|
57907
|
+
...sessionId ? { targetSessionId: sessionId } : {},
|
|
57908
|
+
agentType: resolvedProviderType,
|
|
57909
|
+
cliType: resolvedProviderType,
|
|
57910
|
+
action: "send_chat",
|
|
57911
|
+
message: args.message
|
|
57912
|
+
});
|
|
57913
|
+
const dispatchPayload = unwrapCommandPayload(dispatchResult);
|
|
57914
|
+
if (dispatchPayload?.success === false || dispatchResult?.success === false) {
|
|
57915
|
+
return { success: false, error: `P2P dispatch failed: ${dispatchPayload?.error || dispatchResult?.error || "agent_command rejected the task"}` };
|
|
57916
|
+
}
|
|
57917
|
+
return { success: true, dispatched: true, sessionId: sessionId || resolvedProviderType };
|
|
57918
|
+
} catch (e) {
|
|
57919
|
+
return { success: false, error: `P2P dispatch failed: ${e?.message || String(e)}` };
|
|
57920
|
+
}
|
|
57921
|
+
}
|
|
57303
57922
|
function resolveCoordinatorNode(ctx) {
|
|
57304
57923
|
const preferredNodeId = typeof ctx.mesh.coordinator?.preferredNodeId === "string" ? ctx.mesh.coordinator.preferredNodeId.trim() : "";
|
|
57305
57924
|
if (preferredNodeId) {
|
|
57306
57925
|
const preferred = ctx.mesh.nodes.find((n) => n.id === preferredNodeId && typeof n.daemonId === "string" && n.daemonId.trim());
|
|
57307
57926
|
if (preferred) return preferred;
|
|
57308
57927
|
}
|
|
57928
|
+
if (ctx.localMachineId) {
|
|
57929
|
+
const byMachine = ctx.mesh.nodes.find((n) => n.machineId === ctx.localMachineId);
|
|
57930
|
+
if (byMachine) return byMachine;
|
|
57931
|
+
}
|
|
57309
57932
|
if (ctx.localDaemonId) {
|
|
57310
57933
|
return ctx.mesh.nodes.find((n) => n.daemonId === ctx.localDaemonId);
|
|
57311
57934
|
}
|
|
@@ -57395,7 +58018,8 @@ function getNodeLaunchReadiness(node) {
|
|
|
57395
58018
|
};
|
|
57396
58019
|
}
|
|
57397
58020
|
async function commandForNode(ctx, node, command, args = {}) {
|
|
57398
|
-
|
|
58021
|
+
const isLocalNode = ctx.localMachineId && node.machineId === ctx.localMachineId || ctx.localDaemonId && node.daemonId === ctx.localDaemonId;
|
|
58022
|
+
if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
|
|
57399
58023
|
return ctx.transport.meshCommand(node.daemonId, command, args);
|
|
57400
58024
|
}
|
|
57401
58025
|
if (isLocalTransport(ctx.transport)) {
|
|
@@ -57405,10 +58029,12 @@ async function commandForNode(ctx, node, command, args = {}) {
|
|
|
57405
58029
|
}
|
|
57406
58030
|
var MESH_STATUS_TOOL = {
|
|
57407
58031
|
name: "mesh_status",
|
|
57408
|
-
description: "Get the current status of all nodes in the repo mesh \u2014 health, git state, active sessions. Use this to decide which node to send work to.",
|
|
58032
|
+
description: "Get the current status of all nodes in the repo mesh \u2014 health, git state, active sessions, recovery hints, and recommended next steps. Use this to decide which node to send work to or how to recover from failures.",
|
|
57409
58033
|
inputSchema: {
|
|
57410
58034
|
type: "object",
|
|
57411
|
-
properties: {
|
|
58035
|
+
properties: {
|
|
58036
|
+
_gemini_compat: { type: "string", description: "Dummy property for Gemini compatibility. Ignore this." }
|
|
58037
|
+
}
|
|
57412
58038
|
}
|
|
57413
58039
|
};
|
|
57414
58040
|
var MESH_LIST_NODES_TOOL = {
|
|
@@ -57416,7 +58042,9 @@ var MESH_LIST_NODES_TOOL = {
|
|
|
57416
58042
|
description: "List all nodes in the mesh with their capabilities, platform, and workspace paths.",
|
|
57417
58043
|
inputSchema: {
|
|
57418
58044
|
type: "object",
|
|
57419
|
-
properties: {
|
|
58045
|
+
properties: {
|
|
58046
|
+
_gemini_compat: { type: "string", description: "Dummy property for Gemini compatibility. Ignore this." }
|
|
58047
|
+
}
|
|
57420
58048
|
}
|
|
57421
58049
|
};
|
|
57422
58050
|
var MESH_ENQUEUE_TASK_TOOL = {
|
|
@@ -57432,18 +58060,46 @@ var MESH_ENQUEUE_TASK_TOOL = {
|
|
|
57432
58060
|
};
|
|
57433
58061
|
var MESH_VIEW_QUEUE_TOOL = {
|
|
57434
58062
|
name: "mesh_view_queue",
|
|
57435
|
-
description: "View the current status of the mesh work queue (pending, assigned, completed, failed tasks).",
|
|
58063
|
+
description: "View the current status of the mesh work queue (pending, assigned, completed, failed, cancelled tasks).",
|
|
57436
58064
|
inputSchema: {
|
|
57437
58065
|
type: "object",
|
|
57438
58066
|
properties: {
|
|
57439
58067
|
status: {
|
|
57440
58068
|
type: "array",
|
|
57441
58069
|
items: { type: "string" },
|
|
57442
|
-
description: "Filter by task status: pending, assigned, completed, failed. Returns all if omitted."
|
|
58070
|
+
description: "Filter by task status: pending, assigned, completed, failed, cancelled. Returns all if omitted."
|
|
57443
58071
|
}
|
|
57444
58072
|
}
|
|
57445
58073
|
}
|
|
57446
58074
|
};
|
|
58075
|
+
var MESH_QUEUE_CANCEL_TOOL = {
|
|
58076
|
+
name: "mesh_queue_cancel",
|
|
58077
|
+
description: "Cancel a pending/assigned/completed/failed mesh queue task without deleting audit history. Use this to retire stale queue items that target dead sessions.",
|
|
58078
|
+
inputSchema: {
|
|
58079
|
+
type: "object",
|
|
58080
|
+
properties: {
|
|
58081
|
+
task_id: { type: "string", description: "Queue task ID to cancel." },
|
|
58082
|
+
reason: { type: "string", description: "Optional operator-visible reason for cancellation." }
|
|
58083
|
+
},
|
|
58084
|
+
required: ["task_id"]
|
|
58085
|
+
}
|
|
58086
|
+
};
|
|
58087
|
+
var MESH_QUEUE_REQUEUE_TOOL = {
|
|
58088
|
+
name: "mesh_queue_requeue",
|
|
58089
|
+
description: "Return a mesh queue task to pending for retry. By default clears stale assigned owner and target session so another live session can claim it.",
|
|
58090
|
+
inputSchema: {
|
|
58091
|
+
type: "object",
|
|
58092
|
+
properties: {
|
|
58093
|
+
task_id: { type: "string", description: "Queue task ID to requeue." },
|
|
58094
|
+
reason: { type: "string", description: "Optional operator-visible reason for requeueing." },
|
|
58095
|
+
target_node_id: { type: "string", description: "Optional replacement target node ID." },
|
|
58096
|
+
target_session_id: { type: "string", description: "Optional replacement target runtime session ID." },
|
|
58097
|
+
clear_target_node: { type: "boolean", description: "When true, remove any existing target node constraint." },
|
|
58098
|
+
keep_target_session: { type: "boolean", description: "When true, preserve an existing target session if target_session_id is not provided. Defaults false to avoid stale session targets." }
|
|
58099
|
+
},
|
|
58100
|
+
required: ["task_id"]
|
|
58101
|
+
}
|
|
58102
|
+
};
|
|
57447
58103
|
var MESH_SEND_TASK_TOOL = {
|
|
57448
58104
|
name: "mesh_send_task",
|
|
57449
58105
|
description: "Legacy push-based task assignment. Enqueues a task specifically targeted at a given node. The node will pull it immediately if idle.",
|
|
@@ -57613,6 +58269,8 @@ var ALL_MESH_TOOLS = [
|
|
|
57613
58269
|
MESH_LIST_NODES_TOOL,
|
|
57614
58270
|
MESH_ENQUEUE_TASK_TOOL,
|
|
57615
58271
|
MESH_VIEW_QUEUE_TOOL,
|
|
58272
|
+
MESH_QUEUE_CANCEL_TOOL,
|
|
58273
|
+
MESH_QUEUE_REQUEUE_TOOL,
|
|
57616
58274
|
MESH_SEND_TASK_TOOL,
|
|
57617
58275
|
MESH_READ_CHAT_TOOL,
|
|
57618
58276
|
MESH_READ_DEBUG_TOOL,
|
|
@@ -57630,6 +58288,7 @@ async function meshStatus(ctx) {
|
|
|
57630
58288
|
await refreshMeshFromDaemon(ctx);
|
|
57631
58289
|
const { mesh, transport } = ctx;
|
|
57632
58290
|
const results = [];
|
|
58291
|
+
const ledgerSummary = getLedgerSummary(mesh.id);
|
|
57633
58292
|
for (const node of mesh.nodes) {
|
|
57634
58293
|
const entry = {
|
|
57635
58294
|
nodeId: node.id,
|
|
@@ -57663,6 +58322,45 @@ async function meshStatus(ctx) {
|
|
|
57663
58322
|
entry.health = "degraded";
|
|
57664
58323
|
entry.error = e.message;
|
|
57665
58324
|
}
|
|
58325
|
+
const recoveryContext = getSessionRecoveryContext(mesh.id, { nodeId: node.id });
|
|
58326
|
+
if (recoveryContext.consecutiveNodeFailures > 0) {
|
|
58327
|
+
entry.recoveryHints = {
|
|
58328
|
+
consecutiveFailures: recoveryContext.consecutiveNodeFailures,
|
|
58329
|
+
lastTaskMessage: recoveryContext.lastTaskMessage,
|
|
58330
|
+
advice: recoveryContext.advice,
|
|
58331
|
+
retryRecommended: recoveryContext.retryRecommended
|
|
58332
|
+
};
|
|
58333
|
+
}
|
|
58334
|
+
const activeLaunchFailure = getLatestActiveLaunchFailure(mesh.id, node.id);
|
|
58335
|
+
if (activeLaunchFailure && node.isLocalWorktree) {
|
|
58336
|
+
entry.health = "degraded";
|
|
58337
|
+
entry.degradedReason = "worktree_launch_failed";
|
|
58338
|
+
entry.launchReady = false;
|
|
58339
|
+
entry.launchBlockedReason = activeLaunchFailure.code || "mesh_launch_failed";
|
|
58340
|
+
entry.launchBlockedMessage = activeLaunchFailure.error || "Previous worktree session launch failed";
|
|
58341
|
+
entry.lastLaunchFailure = activeLaunchFailure;
|
|
58342
|
+
}
|
|
58343
|
+
const nextStepHints = [];
|
|
58344
|
+
if (entry.degradedReason === "worktree_launch_failed") {
|
|
58345
|
+
nextStepHints.push(`Retry mesh_launch_session(node_id: "${node.id}") after daemon mesh transport/P2P is healthy.`);
|
|
58346
|
+
nextStepHints.push(`If retry is not desired, cleanup the orphan worktree node with mesh_remove_node(node_id: "${node.id}").`);
|
|
58347
|
+
} else if (entry.health === "online" && node.isLocalWorktree) {
|
|
58348
|
+
nextStepHints.push(`Merge worktree to base via mesh_refine_node(node_id: "${node.id}")`);
|
|
58349
|
+
} else if (entry.health === "dirty") {
|
|
58350
|
+
nextStepHints.push(`Commit changes via mesh_checkpoint(node_id: "${node.id}", message: "...")`);
|
|
58351
|
+
} else if (entry.health === "degraded" && entry.error?.includes("git")) {
|
|
58352
|
+
nextStepHints.push("Initialize git repository or check workspace path.");
|
|
58353
|
+
}
|
|
58354
|
+
if (recoveryContext.consecutiveNodeFailures > 0) {
|
|
58355
|
+
if (recoveryContext.retryRecommended) {
|
|
58356
|
+
nextStepHints.push(`Retry task on this node or launch a fresh session.`);
|
|
58357
|
+
} else {
|
|
58358
|
+
nextStepHints.push(`Consider reassigning work to a different node.`);
|
|
58359
|
+
}
|
|
58360
|
+
}
|
|
58361
|
+
if (nextStepHints.length > 0) {
|
|
58362
|
+
entry.nextStepHints = nextStepHints;
|
|
58363
|
+
}
|
|
57666
58364
|
const relatedRepos = await collectRelatedRepoStatuses(ctx, node);
|
|
57667
58365
|
if (relatedRepos.length) entry.relatedRepos = relatedRepos;
|
|
57668
58366
|
results.push(entry);
|
|
@@ -57676,7 +58374,7 @@ async function meshStatus(ctx) {
|
|
|
57676
58374
|
nodes: results
|
|
57677
58375
|
};
|
|
57678
58376
|
try {
|
|
57679
|
-
response.ledgerSummary =
|
|
58377
|
+
response.ledgerSummary = ledgerSummary;
|
|
57680
58378
|
} catch {
|
|
57681
58379
|
}
|
|
57682
58380
|
if (ctx.transport instanceof IpcTransport) {
|
|
@@ -57720,12 +58418,38 @@ async function meshListNodes(ctx) {
|
|
|
57720
58418
|
async function meshEnqueueTask(ctx, args) {
|
|
57721
58419
|
try {
|
|
57722
58420
|
const task = enqueueTask(ctx.mesh.id, args.message);
|
|
57723
|
-
if (ctx.transport
|
|
57724
|
-
ctx.transport.
|
|
58421
|
+
if (isLocalTransport(ctx.transport) && !(ctx.transport instanceof IpcTransport)) {
|
|
58422
|
+
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57725
58423
|
});
|
|
57726
|
-
|
|
58424
|
+
return JSON.stringify({ success: true, taskId: task.id, status: task.status });
|
|
58425
|
+
}
|
|
58426
|
+
if (ctx.transport instanceof IpcTransport) {
|
|
57727
58427
|
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57728
58428
|
});
|
|
58429
|
+
const dispatchPromises = [];
|
|
58430
|
+
for (const node of ctx.mesh.nodes) {
|
|
58431
|
+
const isLocalNode = ctx.localMachineId && node.machineId === ctx.localMachineId || ctx.localDaemonId && node.daemonId === ctx.localDaemonId;
|
|
58432
|
+
if (isLocalNode || !node.daemonId) continue;
|
|
58433
|
+
dispatchPromises.push(
|
|
58434
|
+
ipcDispatchToRemoteAgent(ctx, node, { message: args.message }).then((result) => {
|
|
58435
|
+
if (result.success) {
|
|
58436
|
+
try {
|
|
58437
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
58438
|
+
kind: "task_dispatched",
|
|
58439
|
+
nodeId: node.id,
|
|
58440
|
+
sessionId: result.sessionId,
|
|
58441
|
+
payload: { message: args.message, via: "p2p_direct", taskId: task.id }
|
|
58442
|
+
});
|
|
58443
|
+
} catch {
|
|
58444
|
+
}
|
|
58445
|
+
}
|
|
58446
|
+
}).catch(() => {
|
|
58447
|
+
})
|
|
58448
|
+
);
|
|
58449
|
+
}
|
|
58450
|
+
Promise.all(dispatchPromises).catch(() => {
|
|
58451
|
+
});
|
|
58452
|
+
return JSON.stringify({ success: true, taskId: task.id, status: task.status });
|
|
57729
58453
|
}
|
|
57730
58454
|
return JSON.stringify({ success: true, taskId: task.id, status: task.status });
|
|
57731
58455
|
} catch (e) {
|
|
@@ -57734,8 +58458,51 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
57734
58458
|
}
|
|
57735
58459
|
async function meshViewQueue(ctx, args) {
|
|
57736
58460
|
try {
|
|
57737
|
-
const queue = getQueue(ctx.mesh.id, { status: args.status });
|
|
57738
|
-
|
|
58461
|
+
const queue = annotateQueueStaleness(getQueue(ctx.mesh.id, { status: args.status }));
|
|
58462
|
+
const staleAssignedTasks = queue.filter((task) => task?.status === "assigned" && task?.staleAssigned);
|
|
58463
|
+
return JSON.stringify({
|
|
58464
|
+
success: true,
|
|
58465
|
+
queue,
|
|
58466
|
+
staleAssignedTasks,
|
|
58467
|
+
staleAssignedCount: staleAssignedTasks.length,
|
|
58468
|
+
// Back-compat alias for callers already reading the first hardening payload.
|
|
58469
|
+
staleAssignments: staleAssignedTasks
|
|
58470
|
+
}, null, 2);
|
|
58471
|
+
} catch (e) {
|
|
58472
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58473
|
+
}
|
|
58474
|
+
}
|
|
58475
|
+
async function meshQueueCancel(ctx, args) {
|
|
58476
|
+
try {
|
|
58477
|
+
const taskId = (args.task_id || args.taskId || "").trim();
|
|
58478
|
+
if (!taskId) return JSON.stringify({ success: false, error: "task_id required" });
|
|
58479
|
+
const task = cancelTask(ctx.mesh.id, taskId, { reason: args.reason });
|
|
58480
|
+
if (!task) return JSON.stringify({ success: false, error: `Queue task '${taskId}' not found` });
|
|
58481
|
+
return JSON.stringify({ success: true, task }, null, 2);
|
|
58482
|
+
} catch (e) {
|
|
58483
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58484
|
+
}
|
|
58485
|
+
}
|
|
58486
|
+
async function meshQueueRequeue(ctx, args) {
|
|
58487
|
+
try {
|
|
58488
|
+
const taskId = (args.task_id || args.taskId || "").trim();
|
|
58489
|
+
if (!taskId) return JSON.stringify({ success: false, error: "task_id required" });
|
|
58490
|
+
const targetNodeId = (args.target_node_id || args.targetNodeId || "").trim() || void 0;
|
|
58491
|
+
const targetSessionId = (args.target_session_id || args.targetSessionId || "").trim() || void 0;
|
|
58492
|
+
const keepTargetSession = args.keep_target_session === true || args.keepTargetSession === true;
|
|
58493
|
+
const task = requeueTask(ctx.mesh.id, taskId, {
|
|
58494
|
+
reason: args.reason,
|
|
58495
|
+
targetNodeId,
|
|
58496
|
+
targetSessionId,
|
|
58497
|
+
clearTargetNode: args.clear_target_node === true || args.clearTargetNode === true,
|
|
58498
|
+
clearTargetSession: targetSessionId ? false : !keepTargetSession
|
|
58499
|
+
});
|
|
58500
|
+
if (!task) return JSON.stringify({ success: false, error: `Queue task '${taskId}' not found` });
|
|
58501
|
+
if (isLocalTransport(ctx.transport)) {
|
|
58502
|
+
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
58503
|
+
});
|
|
58504
|
+
}
|
|
58505
|
+
return JSON.stringify({ success: true, task }, null, 2);
|
|
57739
58506
|
} catch (e) {
|
|
57740
58507
|
return JSON.stringify({ success: false, error: e.message });
|
|
57741
58508
|
}
|
|
@@ -57745,6 +58512,24 @@ async function meshSendTask(ctx, args) {
|
|
|
57745
58512
|
if (node.policy?.readOnly) {
|
|
57746
58513
|
return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
|
|
57747
58514
|
}
|
|
58515
|
+
const duplicate = hasRecentDuplicateDispatch(ctx, args);
|
|
58516
|
+
if (duplicate.duplicate) {
|
|
58517
|
+
return JSON.stringify({
|
|
58518
|
+
success: true,
|
|
58519
|
+
duplicate: true,
|
|
58520
|
+
dispatched: false,
|
|
58521
|
+
warning: "Duplicate mesh_send_task suppressed: the same node/session/message was dispatched recently.",
|
|
58522
|
+
nodeId: args.node_id,
|
|
58523
|
+
sessionId: args.session_id,
|
|
58524
|
+
source: duplicate.source,
|
|
58525
|
+
previousDispatch: duplicate.entry ? {
|
|
58526
|
+
id: duplicate.entry.id,
|
|
58527
|
+
timestamp: duplicate.entry.timestamp || duplicate.entry.updatedAt || duplicate.entry.createdAt,
|
|
58528
|
+
nodeId: duplicate.entry.nodeId || duplicate.entry.targetNodeId || duplicate.entry.assignedNodeId,
|
|
58529
|
+
sessionId: duplicate.entry.sessionId || duplicate.entry.targetSessionId || duplicate.entry.assignedSessionId
|
|
58530
|
+
} : void 0
|
|
58531
|
+
});
|
|
58532
|
+
}
|
|
57748
58533
|
try {
|
|
57749
58534
|
if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
57750
58535
|
const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
|
|
@@ -57754,11 +58539,66 @@ async function meshSendTask(ctx, args) {
|
|
|
57754
58539
|
});
|
|
57755
58540
|
return JSON.stringify(res);
|
|
57756
58541
|
}
|
|
57757
|
-
const
|
|
57758
|
-
if (ctx.transport instanceof IpcTransport && node.daemonId &&
|
|
57759
|
-
|
|
58542
|
+
const isLocalNode = ctx.localMachineId && node.machineId === ctx.localMachineId || ctx.localDaemonId && node.daemonId === ctx.localDaemonId;
|
|
58543
|
+
if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
|
|
58544
|
+
const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id || ""));
|
|
58545
|
+
const result = await ipcDispatchToRemoteAgent(ctx, node, {
|
|
58546
|
+
session_id: args.session_id,
|
|
58547
|
+
message: args.message,
|
|
58548
|
+
providerType: cached2?.providerType
|
|
57760
58549
|
});
|
|
57761
|
-
|
|
58550
|
+
if (result.success) {
|
|
58551
|
+
const dispatchedSessionId = args.session_id || result.sessionId;
|
|
58552
|
+
try {
|
|
58553
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
58554
|
+
kind: "task_dispatched",
|
|
58555
|
+
nodeId: args.node_id,
|
|
58556
|
+
sessionId: dispatchedSessionId,
|
|
58557
|
+
payload: {
|
|
58558
|
+
message: args.message,
|
|
58559
|
+
via: "p2p_direct",
|
|
58560
|
+
...dispatchedSessionId ? { targetSessionId: dispatchedSessionId } : {}
|
|
58561
|
+
}
|
|
58562
|
+
});
|
|
58563
|
+
} catch {
|
|
58564
|
+
}
|
|
58565
|
+
}
|
|
58566
|
+
return JSON.stringify({ ...result, nodeId: args.node_id, dispatched: result.success === true });
|
|
58567
|
+
}
|
|
58568
|
+
if (args.session_id && isLocalTransport(ctx.transport)) {
|
|
58569
|
+
const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
|
|
58570
|
+
const dispatchResult = await commandForNode(ctx, node, "agent_command", {
|
|
58571
|
+
targetSessionId: args.session_id,
|
|
58572
|
+
...cached2?.providerType ? { agentType: cached2.providerType, cliType: cached2.providerType, providerType: cached2.providerType } : {},
|
|
58573
|
+
action: "send_chat",
|
|
58574
|
+
message: args.message
|
|
58575
|
+
});
|
|
58576
|
+
const dispatchPayload = unwrapCommandPayload(dispatchResult);
|
|
58577
|
+
if (dispatchPayload?.success === false || dispatchResult?.success === false) {
|
|
58578
|
+
return JSON.stringify({
|
|
58579
|
+
success: false,
|
|
58580
|
+
nodeId: args.node_id,
|
|
58581
|
+
sessionId: args.session_id,
|
|
58582
|
+
error: dispatchPayload?.error || dispatchResult?.error || "agent_command rejected the task"
|
|
58583
|
+
});
|
|
58584
|
+
}
|
|
58585
|
+
try {
|
|
58586
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
58587
|
+
kind: "task_dispatched",
|
|
58588
|
+
nodeId: args.node_id,
|
|
58589
|
+
sessionId: args.session_id,
|
|
58590
|
+
providerType: cached2?.providerType,
|
|
58591
|
+
payload: { message: args.message, via: "local_direct" }
|
|
58592
|
+
});
|
|
58593
|
+
} catch {
|
|
58594
|
+
}
|
|
58595
|
+
return JSON.stringify({ success: true, dispatched: true, nodeId: args.node_id, sessionId: args.session_id });
|
|
58596
|
+
}
|
|
58597
|
+
const task = enqueueTask(ctx.mesh.id, args.message, {
|
|
58598
|
+
targetNodeId: args.node_id,
|
|
58599
|
+
targetSessionId: args.session_id
|
|
58600
|
+
});
|
|
58601
|
+
if (isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport) {
|
|
57762
58602
|
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57763
58603
|
});
|
|
57764
58604
|
}
|
|
@@ -57768,7 +58608,10 @@ async function meshSendTask(ctx, args) {
|
|
|
57768
58608
|
}
|
|
57769
58609
|
}
|
|
57770
58610
|
async function meshReadChat(ctx, args) {
|
|
57771
|
-
const node = await
|
|
58611
|
+
const node = await findOptionalNodeWithRefresh(ctx, args.node_id);
|
|
58612
|
+
if (!node) {
|
|
58613
|
+
return JSON.stringify(buildMissingNodeReadChatRecovery(ctx, args), null, 2);
|
|
58614
|
+
}
|
|
57772
58615
|
if (isLocalTransport(ctx.transport)) {
|
|
57773
58616
|
const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
|
|
57774
58617
|
const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached2?.providerSessionId;
|
|
@@ -57871,19 +58714,28 @@ async function meshLaunchSession(ctx, args) {
|
|
|
57871
58714
|
const coordinatorNode = resolveCoordinatorNode(ctx);
|
|
57872
58715
|
const coordinatorDaemonId = coordinatorNode?.daemonId || ctx.localDaemonId;
|
|
57873
58716
|
const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
|
|
57874
|
-
|
|
57875
|
-
|
|
57876
|
-
|
|
57877
|
-
|
|
57878
|
-
|
|
57879
|
-
|
|
57880
|
-
|
|
57881
|
-
|
|
57882
|
-
|
|
57883
|
-
|
|
57884
|
-
|
|
57885
|
-
|
|
58717
|
+
let result;
|
|
58718
|
+
try {
|
|
58719
|
+
result = await commandForNode(ctx, node, "launch_cli", {
|
|
58720
|
+
cliType: resolvedProviderType,
|
|
58721
|
+
dir: node.workspace,
|
|
58722
|
+
settings: {
|
|
58723
|
+
meshNodeFor: ctx.mesh.id,
|
|
58724
|
+
meshNodeId: args.node_id,
|
|
58725
|
+
spawnedSessionVisibility,
|
|
58726
|
+
...coordinatorDaemonId ? { meshCoordinatorDaemonId: coordinatorDaemonId } : {},
|
|
58727
|
+
...coordinatorNode?.id ? { meshCoordinatorNodeId: coordinatorNode.id } : {},
|
|
58728
|
+
launchedByCoordinator: true
|
|
58729
|
+
}
|
|
58730
|
+
});
|
|
58731
|
+
} catch (e) {
|
|
58732
|
+
return JSON.stringify(recordRecoverableLaunchFailure(ctx, node, resolvedProviderType, e), null, 2);
|
|
58733
|
+
}
|
|
57886
58734
|
const launchPayload = extractLaunchPayload(result);
|
|
58735
|
+
if (launchPayload?.success === false || result?.success === false) {
|
|
58736
|
+
const launchError = new Error(launchPayload?.error || result?.error || "launch_cli rejected the session launch");
|
|
58737
|
+
return JSON.stringify(recordRecoverableLaunchFailure(ctx, node, resolvedProviderType, launchError), null, 2);
|
|
58738
|
+
}
|
|
57887
58739
|
const runtimeSessionId = typeof launchPayload?.sessionId === "string" ? launchPayload.sessionId : typeof launchPayload?.id === "string" ? launchPayload.id : typeof launchPayload?.runtimeSessionId === "string" ? launchPayload.runtimeSessionId : "";
|
|
57888
58740
|
const providerSessionId = typeof launchPayload?.providerSessionId === "string" && launchPayload.providerSessionId.trim() ? launchPayload.providerSessionId.trim() : void 0;
|
|
57889
58741
|
if (runtimeSessionId) {
|
|
@@ -57902,7 +58754,8 @@ async function meshLaunchSession(ctx, args) {
|
|
|
57902
58754
|
});
|
|
57903
58755
|
} catch {
|
|
57904
58756
|
}
|
|
57905
|
-
|
|
58757
|
+
const isLocalNode = ctx.localMachineId && node.machineId === ctx.localMachineId || ctx.localDaemonId && node.daemonId === ctx.localDaemonId;
|
|
58758
|
+
if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
|
|
57906
58759
|
ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57907
58760
|
});
|
|
57908
58761
|
} else if (isLocalTransport(ctx.transport)) {
|
|
@@ -57952,7 +58805,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
57952
58805
|
}
|
|
57953
58806
|
return JSON.stringify({ ...res, resolvedProviderType }, null, 2);
|
|
57954
58807
|
} catch (e) {
|
|
57955
|
-
return JSON.stringify(
|
|
58808
|
+
return JSON.stringify(recordRecoverableLaunchFailure(ctx, node, resolvedProviderType, e), null, 2);
|
|
57956
58809
|
}
|
|
57957
58810
|
} else {
|
|
57958
58811
|
return JSON.stringify({ error: "Cloud mesh launch_session requires node daemonId" });
|
|
@@ -59840,6 +60693,15 @@ async function startMcpServer(opts) {
|
|
|
59840
60693
|
process.exit(1);
|
|
59841
60694
|
}
|
|
59842
60695
|
let localDaemonId;
|
|
60696
|
+
let localMachineId;
|
|
60697
|
+
if (transport instanceof LocalTransport || transport instanceof IpcTransport) {
|
|
60698
|
+
try {
|
|
60699
|
+
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
60700
|
+
const cfg = loadConfig2();
|
|
60701
|
+
if (cfg.registeredMachineId) localMachineId = cfg.registeredMachineId;
|
|
60702
|
+
} catch {
|
|
60703
|
+
}
|
|
60704
|
+
}
|
|
59843
60705
|
if (transport instanceof IpcTransport) {
|
|
59844
60706
|
try {
|
|
59845
60707
|
const statusResult = await transport.getStatus();
|
|
@@ -59848,7 +60710,7 @@ async function startMcpServer(opts) {
|
|
|
59848
60710
|
} catch {
|
|
59849
60711
|
}
|
|
59850
60712
|
}
|
|
59851
|
-
const meshCtx = { mesh, transport, ...localDaemonId ? { localDaemonId } : {} };
|
|
60713
|
+
const meshCtx = { mesh, transport, ...localDaemonId ? { localDaemonId } : {}, ...localMachineId ? { localMachineId } : {} };
|
|
59852
60714
|
const coordinatorPrompt = await buildMeshModeCoordinatorPrompt(mesh);
|
|
59853
60715
|
const server2 = new import_server.Server(
|
|
59854
60716
|
{ name: "adhdev-mcp-server", version: "0.9.76" },
|
|
@@ -59888,6 +60750,12 @@ async function startMcpServer(opts) {
|
|
|
59888
60750
|
case "mesh_view_queue":
|
|
59889
60751
|
text = await meshViewQueue(meshCtx, a);
|
|
59890
60752
|
break;
|
|
60753
|
+
case "mesh_queue_cancel":
|
|
60754
|
+
text = await meshQueueCancel(meshCtx, a);
|
|
60755
|
+
break;
|
|
60756
|
+
case "mesh_queue_requeue":
|
|
60757
|
+
text = await meshQueueRequeue(meshCtx, a);
|
|
60758
|
+
break;
|
|
59891
60759
|
case "mesh_send_task":
|
|
59892
60760
|
text = await meshSendTask(meshCtx, a);
|
|
59893
60761
|
break;
|