@adhdev/daemon-core 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/boot/daemon-lifecycle.d.ts +3 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +3 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +14 -4
- package/dist/commands/mesh-coordinator.d.ts +10 -0
- package/dist/commands/router.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +389 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +386 -44
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +2 -7
- package/dist/mesh/mesh-work-queue.d.ts +35 -1
- package/dist/shared-types.d.ts +14 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +5 -0
- package/src/cli-adapters/provider-cli-adapter.ts +25 -4
- package/src/cli-adapters/provider-cli-shared.ts +14 -4
- package/src/commands/cli-manager.ts +0 -4
- package/src/commands/mesh-coordinator.ts +55 -7
- package/src/commands/router.ts +160 -3
- package/src/commands/stream-commands.ts +8 -1
- package/src/index.ts +2 -2
- package/src/mesh/mesh-events.ts +147 -20
- package/src/mesh/mesh-work-queue.ts +103 -6
- package/src/providers/cli-provider-instance.ts +2 -0
- package/src/shared-types.ts +14 -0
package/dist/index.js
CHANGED
|
@@ -978,6 +978,17 @@ var init_mesh_ledger = __esm({
|
|
|
978
978
|
});
|
|
979
979
|
|
|
980
980
|
// src/mesh/mesh-work-queue.ts
|
|
981
|
+
var mesh_work_queue_exports = {};
|
|
982
|
+
__export(mesh_work_queue_exports, {
|
|
983
|
+
cancelTask: () => cancelTask,
|
|
984
|
+
claimNextTask: () => claimNextTask,
|
|
985
|
+
enqueueTask: () => enqueueTask,
|
|
986
|
+
getMeshQueueStats: () => getMeshQueueStats,
|
|
987
|
+
getQueue: () => getQueue,
|
|
988
|
+
requeueTask: () => requeueTask,
|
|
989
|
+
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
990
|
+
updateTaskStatus: () => updateTaskStatus
|
|
991
|
+
});
|
|
981
992
|
function getQueuePath(meshId) {
|
|
982
993
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
983
994
|
return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.json`);
|
|
@@ -1004,6 +1015,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
1004
1015
|
message,
|
|
1005
1016
|
status: "pending",
|
|
1006
1017
|
targetNodeId: opts?.targetNodeId,
|
|
1018
|
+
targetSessionId: opts?.targetSessionId,
|
|
1007
1019
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1008
1020
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1009
1021
|
};
|
|
@@ -1021,9 +1033,14 @@ function getQueue(meshId, opts) {
|
|
|
1021
1033
|
}
|
|
1022
1034
|
function claimNextTask(meshId, nodeId, sessionId) {
|
|
1023
1035
|
const queue = readQueue(meshId);
|
|
1024
|
-
|
|
1036
|
+
const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
|
|
1037
|
+
if (hasActiveAssignment) return null;
|
|
1038
|
+
let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
|
|
1039
|
+
if (targetIdx === -1) {
|
|
1040
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
|
|
1041
|
+
}
|
|
1025
1042
|
if (targetIdx === -1) {
|
|
1026
|
-
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId);
|
|
1043
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
|
|
1027
1044
|
}
|
|
1028
1045
|
if (targetIdx === -1) return null;
|
|
1029
1046
|
const entry = queue[targetIdx];
|
|
@@ -1043,6 +1060,40 @@ function updateTaskStatus(meshId, taskId, status) {
|
|
|
1043
1060
|
writeQueue(meshId, queue);
|
|
1044
1061
|
return queue[idx];
|
|
1045
1062
|
}
|
|
1063
|
+
function cancelTask(meshId, taskId, opts) {
|
|
1064
|
+
const queue = readQueue(meshId);
|
|
1065
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
1066
|
+
if (idx === -1) return null;
|
|
1067
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1068
|
+
queue[idx].status = "cancelled";
|
|
1069
|
+
queue[idx].updatedAt = now;
|
|
1070
|
+
queue[idx].cancelledAt = now;
|
|
1071
|
+
if (opts?.reason) queue[idx].cancelReason = opts.reason;
|
|
1072
|
+
writeQueue(meshId, queue);
|
|
1073
|
+
return queue[idx];
|
|
1074
|
+
}
|
|
1075
|
+
function requeueTask(meshId, taskId, opts) {
|
|
1076
|
+
const queue = readQueue(meshId);
|
|
1077
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
1078
|
+
if (idx === -1) return null;
|
|
1079
|
+
const entry = queue[idx];
|
|
1080
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1081
|
+
entry.status = "pending";
|
|
1082
|
+
delete entry.assignedNodeId;
|
|
1083
|
+
delete entry.assignedSessionId;
|
|
1084
|
+
delete entry.cancelledAt;
|
|
1085
|
+
delete entry.cancelReason;
|
|
1086
|
+
if (opts?.clearTargetNode) delete entry.targetNodeId;
|
|
1087
|
+
if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
|
|
1088
|
+
if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
|
|
1089
|
+
if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
|
|
1090
|
+
entry.updatedAt = now;
|
|
1091
|
+
entry.requeuedAt = now;
|
|
1092
|
+
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
1093
|
+
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
1094
|
+
writeQueue(meshId, queue);
|
|
1095
|
+
return entry;
|
|
1096
|
+
}
|
|
1046
1097
|
function updateSessionTaskStatus(meshId, sessionId, status) {
|
|
1047
1098
|
const queue = readQueue(meshId);
|
|
1048
1099
|
for (let i = queue.length - 1; i >= 0; i--) {
|
|
@@ -1061,7 +1112,14 @@ function getMeshQueueStats(meshId) {
|
|
|
1061
1112
|
pending: queue.filter((q) => q.status === "pending").length,
|
|
1062
1113
|
assigned: queue.filter((q) => q.status === "assigned").length,
|
|
1063
1114
|
completed: queue.filter((q) => q.status === "completed").length,
|
|
1064
|
-
failed: queue.filter((q) => q.status === "failed").length
|
|
1115
|
+
failed: queue.filter((q) => q.status === "failed").length,
|
|
1116
|
+
cancelled: queue.filter((q) => q.status === "cancelled").length,
|
|
1117
|
+
activeAssignments: queue.filter((q) => q.status === "assigned").map((q) => ({
|
|
1118
|
+
id: q.id,
|
|
1119
|
+
nodeId: q.assignedNodeId,
|
|
1120
|
+
sessionId: q.assignedSessionId,
|
|
1121
|
+
message: q.message
|
|
1122
|
+
}))
|
|
1065
1123
|
};
|
|
1066
1124
|
}
|
|
1067
1125
|
var import_fs4, import_path4, import_crypto5;
|
|
@@ -1304,6 +1362,9 @@ function drainPendingMeshCoordinatorEvents() {
|
|
|
1304
1362
|
function readNonEmptyString(value) {
|
|
1305
1363
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
1306
1364
|
}
|
|
1365
|
+
function resolveEventSessionId(event, fallback) {
|
|
1366
|
+
return readNonEmptyString(event.targetSessionId) || readNonEmptyString(event.sessionId) || readNonEmptyString(event.instanceId) || readNonEmptyString(fallback);
|
|
1367
|
+
}
|
|
1307
1368
|
function isMeshCoordinatorEvent(eventName) {
|
|
1308
1369
|
return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
|
|
1309
1370
|
}
|
|
@@ -1315,38 +1376,74 @@ function formatCompletionMetadata(event) {
|
|
|
1315
1376
|
].filter(Boolean);
|
|
1316
1377
|
return parts.length > 0 ? ` (${parts.join("; ")})` : "";
|
|
1317
1378
|
}
|
|
1379
|
+
function getMeshWithCache(components, meshId) {
|
|
1380
|
+
const localMesh = getMesh(meshId);
|
|
1381
|
+
if (localMesh) return localMesh;
|
|
1382
|
+
return components.router?.getCachedInlineMesh(meshId);
|
|
1383
|
+
}
|
|
1318
1384
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
1319
1385
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
1320
|
-
if (!task)
|
|
1386
|
+
if (!task) {
|
|
1387
|
+
return false;
|
|
1388
|
+
}
|
|
1321
1389
|
LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
|
|
1390
|
+
const mesh = getMeshWithCache(components, meshId);
|
|
1391
|
+
const node = mesh?.nodes.find((n) => n.id === nodeId);
|
|
1392
|
+
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
1393
|
+
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
1394
|
+
if (!isLocalNode) {
|
|
1395
|
+
components.dispatchMeshCommand(node.daemonId, "agent_command", {
|
|
1396
|
+
targetSessionId: sessionId,
|
|
1397
|
+
cliType: providerType,
|
|
1398
|
+
action: "send_chat",
|
|
1399
|
+
message: task.message
|
|
1400
|
+
}).catch((e) => {
|
|
1401
|
+
LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
1402
|
+
updateTaskStatus(meshId, task.id, "failed");
|
|
1403
|
+
});
|
|
1404
|
+
return true;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1322
1407
|
components.cliManager.handleCliCommand("agent_command", {
|
|
1323
1408
|
targetSessionId: sessionId,
|
|
1324
1409
|
cliType: providerType,
|
|
1325
1410
|
action: "send_chat",
|
|
1326
|
-
|
|
1411
|
+
message: task.message
|
|
1327
1412
|
}).catch((e) => {
|
|
1328
|
-
LOG.error("MeshQueue", `Failed to dispatch task to node ${nodeId}: ${e?.message}`);
|
|
1413
|
+
LOG.error("MeshQueue", `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
1414
|
+
updateTaskStatus(meshId, task.id, "failed");
|
|
1329
1415
|
});
|
|
1330
1416
|
return true;
|
|
1331
1417
|
}
|
|
1332
1418
|
function triggerMeshQueue(components, meshId) {
|
|
1333
|
-
const mesh =
|
|
1419
|
+
const mesh = getMeshWithCache(components, meshId);
|
|
1334
1420
|
if (!mesh) return;
|
|
1335
1421
|
const cliInstances = components.instanceManager.getByCategory("cli");
|
|
1336
1422
|
for (const inst of cliInstances) {
|
|
1337
1423
|
const state = inst.getState();
|
|
1338
1424
|
const settings = state.settings || {};
|
|
1339
1425
|
const instMeshId = readNonEmptyString(settings.meshNodeFor);
|
|
1340
|
-
if (instMeshId !== meshId
|
|
1426
|
+
if (instMeshId !== meshId) continue;
|
|
1341
1427
|
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
1342
1428
|
if (!nodeId) continue;
|
|
1343
|
-
|
|
1429
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
1430
|
+
if (["stopped", "failed", "terminated", "exited", "closed"].includes(status)) continue;
|
|
1431
|
+
if (status !== "idle" && state.activeChat?.status !== "waiting_input") continue;
|
|
1344
1432
|
const sessionId = state.instanceId;
|
|
1345
1433
|
const providerType = state.type || readNonEmptyString(settings.providerType);
|
|
1346
1434
|
if (providerType) {
|
|
1347
1435
|
tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
1348
1436
|
}
|
|
1349
1437
|
}
|
|
1438
|
+
for (const [key, idle] of remoteIdleSessions.entries()) {
|
|
1439
|
+
const node = mesh.nodes.find((n) => n.id === idle.nodeId);
|
|
1440
|
+
if (node) {
|
|
1441
|
+
const assigned = tryAssignQueueTask(components, meshId, idle.nodeId, idle.sessionId, idle.providerType);
|
|
1442
|
+
if (assigned) {
|
|
1443
|
+
remoteIdleSessions.delete(key);
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1350
1447
|
}
|
|
1351
1448
|
function buildMeshSystemMessage(args) {
|
|
1352
1449
|
const metadata = formatCompletionMetadata(args.metadataEvent);
|
|
@@ -1393,20 +1490,67 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
1393
1490
|
return "";
|
|
1394
1491
|
}
|
|
1395
1492
|
function injectMeshSystemMessage(components, args) {
|
|
1493
|
+
let completedTaskForLedger = null;
|
|
1396
1494
|
if (args.event === "agent:generating_completed") {
|
|
1397
|
-
const sessionId =
|
|
1398
|
-
const nodeId = readNonEmptyString(args.
|
|
1495
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
1496
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
1399
1497
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
1400
1498
|
if (sessionId) {
|
|
1401
|
-
updateSessionTaskStatus(args.meshId, sessionId, "completed");
|
|
1499
|
+
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
|
|
1500
|
+
completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
|
|
1402
1501
|
if (nodeId && providerType) {
|
|
1403
1502
|
setTimeout(() => {
|
|
1404
1503
|
tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
1405
1504
|
}, 500);
|
|
1406
1505
|
}
|
|
1407
1506
|
}
|
|
1507
|
+
} else if (args.event === "agent:ready") {
|
|
1508
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
1509
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
1510
|
+
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
1511
|
+
const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
|
|
1512
|
+
if (completedTask) {
|
|
1513
|
+
completedTaskForLedger = { id: completedTask.id };
|
|
1514
|
+
try {
|
|
1515
|
+
appendLedgerEntry(args.meshId, {
|
|
1516
|
+
kind: "task_completed",
|
|
1517
|
+
nodeId: nodeId || void 0,
|
|
1518
|
+
sessionId,
|
|
1519
|
+
providerType: providerType || void 0,
|
|
1520
|
+
payload: {
|
|
1521
|
+
event: args.event,
|
|
1522
|
+
nodeLabel: args.nodeLabel,
|
|
1523
|
+
taskId: completedTask.id,
|
|
1524
|
+
completedViaReady: true,
|
|
1525
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
1526
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
} catch (e) {
|
|
1530
|
+
LOG.warn("MeshLedger", `Failed to record task_completed from ready: ${e?.message || e}`);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
if (sessionId && nodeId && providerType) {
|
|
1534
|
+
remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
|
|
1535
|
+
setTimeout(() => {
|
|
1536
|
+
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
1537
|
+
if (assigned) {
|
|
1538
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
1539
|
+
}
|
|
1540
|
+
}, 500);
|
|
1541
|
+
}
|
|
1542
|
+
} else if (args.event === "agent:generating_started") {
|
|
1543
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
1544
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
1545
|
+
if (sessionId && nodeId) {
|
|
1546
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
1547
|
+
}
|
|
1408
1548
|
} else if (args.event === "agent:stopped") {
|
|
1409
|
-
const sessionId =
|
|
1549
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
1550
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
1551
|
+
if (sessionId && nodeId) {
|
|
1552
|
+
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
1553
|
+
}
|
|
1410
1554
|
if (sessionId) {
|
|
1411
1555
|
updateSessionTaskStatus(args.meshId, sessionId, "failed");
|
|
1412
1556
|
}
|
|
@@ -1416,13 +1560,15 @@ function injectMeshSystemMessage(components, args) {
|
|
|
1416
1560
|
try {
|
|
1417
1561
|
appendLedgerEntry(args.meshId, {
|
|
1418
1562
|
kind: ledgerKind,
|
|
1419
|
-
nodeId: readNonEmptyString(args.
|
|
1420
|
-
sessionId:
|
|
1563
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
|
|
1564
|
+
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
1421
1565
|
providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
|
|
1422
1566
|
payload: {
|
|
1423
1567
|
event: args.event,
|
|
1424
1568
|
nodeLabel: args.nodeLabel,
|
|
1425
|
-
|
|
1569
|
+
taskId: completedTaskForLedger?.id || void 0,
|
|
1570
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
1571
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
1426
1572
|
}
|
|
1427
1573
|
});
|
|
1428
1574
|
} catch (e) {
|
|
@@ -1435,8 +1581,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
1435
1581
|
const mesh = getMesh(args.meshId);
|
|
1436
1582
|
const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
|
|
1437
1583
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
1438
|
-
sessionId:
|
|
1439
|
-
nodeId: readNonEmptyString(args.
|
|
1584
|
+
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
1585
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
|
|
1440
1586
|
maxRetries
|
|
1441
1587
|
});
|
|
1442
1588
|
recoveryContext.failedProviderType = readNonEmptyString(args.metadataEvent.providerType) || null;
|
|
@@ -1531,12 +1677,14 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
1531
1677
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
|
|
1532
1678
|
return injectMeshSystemMessage(components, {
|
|
1533
1679
|
meshId,
|
|
1680
|
+
nodeId,
|
|
1534
1681
|
nodeLabel,
|
|
1535
1682
|
event: eventName,
|
|
1536
1683
|
metadataEvent: {
|
|
1537
|
-
targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId),
|
|
1684
|
+
targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId) || readNonEmptyString(payload.instanceId),
|
|
1538
1685
|
providerType: readNonEmptyString(payload.providerType),
|
|
1539
|
-
providerSessionId: readNonEmptyString(payload.providerSessionId)
|
|
1686
|
+
providerSessionId: readNonEmptyString(payload.providerSessionId),
|
|
1687
|
+
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary)
|
|
1540
1688
|
}
|
|
1541
1689
|
});
|
|
1542
1690
|
}
|
|
@@ -1555,22 +1703,24 @@ function setupMeshEventForwarding(components) {
|
|
|
1555
1703
|
const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
|
|
1556
1704
|
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
1557
1705
|
if (!isMeshDelegate) return;
|
|
1558
|
-
const mesh = meshIdFromRuntime ?
|
|
1706
|
+
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
1559
1707
|
const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
|
|
1560
1708
|
if (!meshId) return;
|
|
1561
1709
|
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
1562
1710
|
const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
|
|
1711
|
+
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
1563
1712
|
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
1564
1713
|
injectMeshSystemMessage(components, {
|
|
1565
1714
|
meshId,
|
|
1566
1715
|
sourceInstanceId: instanceId,
|
|
1716
|
+
nodeId: resolvedNodeId,
|
|
1567
1717
|
nodeLabel,
|
|
1568
1718
|
event: event.event,
|
|
1569
1719
|
metadataEvent: event
|
|
1570
1720
|
});
|
|
1571
1721
|
});
|
|
1572
1722
|
}
|
|
1573
|
-
var MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND;
|
|
1723
|
+
var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND;
|
|
1574
1724
|
var init_mesh_events = __esm({
|
|
1575
1725
|
"src/mesh/mesh-events.ts"() {
|
|
1576
1726
|
"use strict";
|
|
@@ -1578,12 +1728,15 @@ var init_mesh_events = __esm({
|
|
|
1578
1728
|
init_logger();
|
|
1579
1729
|
init_mesh_ledger();
|
|
1580
1730
|
init_mesh_work_queue();
|
|
1731
|
+
remoteIdleSessions = /* @__PURE__ */ new Map();
|
|
1581
1732
|
MAX_PENDING_EVENTS = 50;
|
|
1582
1733
|
pendingMeshCoordinatorEvents = [];
|
|
1583
1734
|
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
1735
|
+
"agent:generating_started",
|
|
1584
1736
|
"agent:generating_completed",
|
|
1585
1737
|
"agent:waiting_approval",
|
|
1586
1738
|
"agent:stopped",
|
|
1739
|
+
"agent:ready",
|
|
1587
1740
|
"monitor:long_generating"
|
|
1588
1741
|
]);
|
|
1589
1742
|
EVENT_TO_LEDGER_KIND = {
|
|
@@ -2699,6 +2852,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2699
2852
|
statusHistory = [];
|
|
2700
2853
|
// ─── CLI Scripts (script-based parsing) ───
|
|
2701
2854
|
cliScripts;
|
|
2855
|
+
/** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
|
|
2856
|
+
scriptState = null;
|
|
2702
2857
|
runtimeSettings = {};
|
|
2703
2858
|
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
2704
2859
|
accumulatedBuffer = "";
|
|
@@ -2777,7 +2932,7 @@ ${lastSnapshot}`;
|
|
|
2777
2932
|
}
|
|
2778
2933
|
getFreshParsedStatusCache() {
|
|
2779
2934
|
const cached = this.parsedStatusCache;
|
|
2780
|
-
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.screenText === this.lastScreenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
2935
|
+
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.accumulatedRawBuffer === this.accumulatedRawBuffer && cached.screenText === this.lastScreenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
2781
2936
|
return cached.result;
|
|
2782
2937
|
}
|
|
2783
2938
|
return null;
|
|
@@ -2880,6 +3035,7 @@ ${lastSnapshot}`;
|
|
|
2880
3035
|
this.cliScripts = scripts;
|
|
2881
3036
|
this.parsedStatusCache = null;
|
|
2882
3037
|
this.parseErrorMessage = null;
|
|
3038
|
+
this.scriptState = typeof scripts.createState === "function" ? scripts.createState() : null;
|
|
2883
3039
|
const scriptNames = listCliScriptNames(scripts);
|
|
2884
3040
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
2885
3041
|
}
|
|
@@ -2997,6 +3153,7 @@ ${lastSnapshot}`;
|
|
|
2997
3153
|
this.ready = false;
|
|
2998
3154
|
this.startupParseGate = false;
|
|
2999
3155
|
this.spawnAt = 0;
|
|
3156
|
+
this.scriptState = null;
|
|
3000
3157
|
this.onStatusChange?.();
|
|
3001
3158
|
});
|
|
3002
3159
|
this.spawnAt = Date.now();
|
|
@@ -3750,6 +3907,11 @@ ${lastSnapshot}`;
|
|
|
3750
3907
|
};
|
|
3751
3908
|
}
|
|
3752
3909
|
// ─── Script Execution ──────────────────────────
|
|
3910
|
+
invokeCliScript(script, input) {
|
|
3911
|
+
const hasStateFactory = typeof this.cliScripts?.createState === "function";
|
|
3912
|
+
const expectsStateArgument = hasStateFactory || this.scriptState !== null || script.length >= 2;
|
|
3913
|
+
return expectsStateArgument ? script(this.scriptState, input) : script(input);
|
|
3914
|
+
}
|
|
3753
3915
|
runParseSession() {
|
|
3754
3916
|
if (typeof this.cliScripts?.parseSession !== "function") {
|
|
3755
3917
|
this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
|
|
@@ -3770,7 +3932,10 @@ ${lastSnapshot}`;
|
|
|
3770
3932
|
scope: this.currentTurnScope,
|
|
3771
3933
|
runtimeSettings: this.runtimeSettings
|
|
3772
3934
|
});
|
|
3773
|
-
const session = this.
|
|
3935
|
+
const session = this.invokeCliScript(
|
|
3936
|
+
this.cliScripts.parseSession,
|
|
3937
|
+
{ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) }
|
|
3938
|
+
);
|
|
3774
3939
|
this.parseErrorMessage = null;
|
|
3775
3940
|
return session && typeof session === "object" ? session : null;
|
|
3776
3941
|
} catch (e) {
|
|
@@ -3784,7 +3949,7 @@ ${lastSnapshot}`;
|
|
|
3784
3949
|
if (!this.cliScripts?.detectStatus) return null;
|
|
3785
3950
|
try {
|
|
3786
3951
|
const screenText = this.terminalScreen.getText();
|
|
3787
|
-
const status = this.cliScripts.detectStatus
|
|
3952
|
+
const status = this.invokeCliScript(this.cliScripts.detectStatus, {
|
|
3788
3953
|
tail: text.slice(-500),
|
|
3789
3954
|
screenText,
|
|
3790
3955
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3803,7 +3968,7 @@ ${lastSnapshot}`;
|
|
|
3803
3968
|
try {
|
|
3804
3969
|
const screenText = this.terminalScreen.getText();
|
|
3805
3970
|
const buffer = screenText || this.accumulatedBuffer;
|
|
3806
|
-
return this.cliScripts.parseApproval
|
|
3971
|
+
return this.invokeCliScript(this.cliScripts.parseApproval, {
|
|
3807
3972
|
buffer,
|
|
3808
3973
|
screenText,
|
|
3809
3974
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3859,7 +4024,7 @@ ${lastSnapshot}`;
|
|
|
3859
4024
|
const screenText = this.readTerminalScreenText();
|
|
3860
4025
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
3861
4026
|
const cached = this.parsedStatusCache;
|
|
3862
|
-
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.screenText === parseScreenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
4027
|
+
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.accumulatedRawBuffer === this.accumulatedRawBuffer && cached.screenText === parseScreenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
3863
4028
|
return cached.result;
|
|
3864
4029
|
}
|
|
3865
4030
|
const parsed = this.runParseSession();
|
|
@@ -3887,6 +4052,7 @@ ${lastSnapshot}`;
|
|
|
3887
4052
|
currentTurnScope: this.currentTurnScope,
|
|
3888
4053
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
3889
4054
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
4055
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3890
4056
|
screenText: parseScreenText,
|
|
3891
4057
|
currentStatus: this.currentStatus,
|
|
3892
4058
|
activeModal: this.activeModal,
|
|
@@ -3911,7 +4077,7 @@ ${lastSnapshot}`;
|
|
|
3911
4077
|
scope: this.currentTurnScope,
|
|
3912
4078
|
runtimeSettings: this.runtimeSettings
|
|
3913
4079
|
});
|
|
3914
|
-
return await Promise.resolve(fn({
|
|
4080
|
+
return await Promise.resolve(fn(this.scriptState, {
|
|
3915
4081
|
...input,
|
|
3916
4082
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
3917
4083
|
}));
|
|
@@ -4722,6 +4888,7 @@ __export(index_exports, {
|
|
|
4722
4888
|
buildThoughtChatMessage: () => buildThoughtChatMessage,
|
|
4723
4889
|
buildToolChatMessage: () => buildToolChatMessage,
|
|
4724
4890
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
4891
|
+
cancelTask: () => cancelTask,
|
|
4725
4892
|
claimNextTask: () => claimNextTask,
|
|
4726
4893
|
classifyChatMessageVisibility: () => classifyChatMessageVisibility,
|
|
4727
4894
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
|
|
@@ -4765,6 +4932,7 @@ __export(index_exports, {
|
|
|
4765
4932
|
getLogLevel: () => getLogLevel,
|
|
4766
4933
|
getMesh: () => getMesh,
|
|
4767
4934
|
getMeshByRepo: () => getMeshByRepo,
|
|
4935
|
+
getMeshQueueStats: () => getMeshQueueStats,
|
|
4768
4936
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
4769
4937
|
getQueue: () => getQueue,
|
|
4770
4938
|
getRecentActivity: () => getRecentActivity,
|
|
@@ -4833,6 +5001,7 @@ __export(index_exports, {
|
|
|
4833
5001
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
4834
5002
|
removeNode: () => removeNode,
|
|
4835
5003
|
removeWorktree: () => removeWorktree,
|
|
5004
|
+
requeueTask: () => requeueTask,
|
|
4836
5005
|
resetConfig: () => resetConfig,
|
|
4837
5006
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
4838
5007
|
resetState: () => resetState,
|
|
@@ -15205,11 +15374,13 @@ async function handleOpenPanel(h, args) {
|
|
|
15205
15374
|
async function handlePtyInput(h, args) {
|
|
15206
15375
|
const { cliType, data, targetSessionId } = args || {};
|
|
15207
15376
|
if (!data) return { success: false, error: "data required" };
|
|
15377
|
+
const cleanData = typeof data === "string" ? data.replace(/\x1b\[[?>][0-9;]*c/g, "") : data;
|
|
15378
|
+
if (!cleanData) return { success: true };
|
|
15208
15379
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
15209
15380
|
if (!adapter || typeof adapter.writeRaw !== "function") {
|
|
15210
15381
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
15211
15382
|
}
|
|
15212
|
-
await adapter.writeRaw(
|
|
15383
|
+
await adapter.writeRaw(cleanData);
|
|
15213
15384
|
return { success: true };
|
|
15214
15385
|
}
|
|
15215
15386
|
function handlePtyResize(_h, args) {
|
|
@@ -16839,6 +17010,8 @@ var CliProviderInstance = class {
|
|
|
16839
17010
|
this.completedDebounceTimer = null;
|
|
16840
17011
|
}, 3e3);
|
|
16841
17012
|
}
|
|
17013
|
+
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
17014
|
+
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
16842
17015
|
} else if (newStatus === "stopped") {
|
|
16843
17016
|
if (this.generatingDebounceTimer) {
|
|
16844
17017
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -18582,9 +18755,6 @@ function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
|
18582
18755
|
const cliType = String(input.cliType || "").trim();
|
|
18583
18756
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
18584
18757
|
const env = { ...input.env || {}, ...COORDINATOR_DELEGATED_ENV_UNSETS };
|
|
18585
|
-
if (cliType === "hermes-cli" && !hasCliArg(cliArgs, "--ignore-user-config")) {
|
|
18586
|
-
cliArgs.unshift("--ignore-user-config");
|
|
18587
|
-
}
|
|
18588
18758
|
if (cliType === "claude-cli" && !hasCliArg(cliArgs, "--mcp-config")) {
|
|
18589
18759
|
cliArgs.unshift("--mcp-config", ensureEmptyDelegatedMcpConfig(input.workspace));
|
|
18590
18760
|
}
|
|
@@ -21830,7 +22000,9 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
21830
22000
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
21831
22001
|
meshId: options.meshId,
|
|
21832
22002
|
nodeExecutable: options.nodeExecutable,
|
|
21833
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath
|
|
22003
|
+
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
22004
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
22005
|
+
adhdevMcpPort: options.adhdevMcpPort
|
|
21834
22006
|
});
|
|
21835
22007
|
if (!mcpServer) {
|
|
21836
22008
|
return {
|
|
@@ -21897,7 +22069,9 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
21897
22069
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
21898
22070
|
meshId,
|
|
21899
22071
|
nodeExecutable: options.nodeExecutable,
|
|
21900
|
-
adhdevMcpEntryPath: options.adhdevMcpEntryPath
|
|
22072
|
+
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
22073
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
22074
|
+
adhdevMcpPort: options.adhdevMcpPort
|
|
21901
22075
|
});
|
|
21902
22076
|
if (!mcpServer) {
|
|
21903
22077
|
return {
|
|
@@ -21919,6 +22093,22 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
21919
22093
|
if (!instructions || !template?.trim()) {
|
|
21920
22094
|
return { kind: "unsupported", reason: "Provider manual MCP setup is missing instructions or template" };
|
|
21921
22095
|
}
|
|
22096
|
+
const renderedTemplate = renderMeshCoordinatorTemplate(template, {
|
|
22097
|
+
meshId,
|
|
22098
|
+
workspace,
|
|
22099
|
+
serverName,
|
|
22100
|
+
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
22101
|
+
});
|
|
22102
|
+
const isCliCommand = !renderedTemplate.trim().includes("\n") && !renderedTemplate.trim().startsWith("{");
|
|
22103
|
+
if (isCliCommand) {
|
|
22104
|
+
return {
|
|
22105
|
+
kind: "cli_command",
|
|
22106
|
+
serverName,
|
|
22107
|
+
command: renderedTemplate.trim(),
|
|
22108
|
+
requiresRestart: mcpConfig.requiresRestart === true,
|
|
22109
|
+
instructions
|
|
22110
|
+
};
|
|
22111
|
+
}
|
|
21922
22112
|
return {
|
|
21923
22113
|
kind: "manual",
|
|
21924
22114
|
serverName,
|
|
@@ -21926,12 +22116,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
21926
22116
|
configPathCommand: mcpConfig.configPathCommand,
|
|
21927
22117
|
requiresRestart: mcpConfig.requiresRestart === true,
|
|
21928
22118
|
instructions,
|
|
21929
|
-
template:
|
|
21930
|
-
meshId,
|
|
21931
|
-
workspace,
|
|
21932
|
-
serverName,
|
|
21933
|
-
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
21934
|
-
})
|
|
22119
|
+
template: renderedTemplate
|
|
21935
22120
|
};
|
|
21936
22121
|
}
|
|
21937
22122
|
return {
|
|
@@ -21960,11 +22145,27 @@ function resolveAdhdevMcpServerLaunch(options) {
|
|
|
21960
22145
|
if (!entryPath) return null;
|
|
21961
22146
|
const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
|
|
21962
22147
|
if (!nodeExecutable) return null;
|
|
22148
|
+
const transport = resolveMcpTransport(options.adhdevMcpTransport);
|
|
22149
|
+
const args = [entryPath, "--mode", transport, "--repo-mesh", options.meshId];
|
|
22150
|
+
const port = resolveMcpPort(options.adhdevMcpPort);
|
|
22151
|
+
if (port !== void 0) args.push("--port", String(port));
|
|
21963
22152
|
return {
|
|
21964
22153
|
command: nodeExecutable,
|
|
21965
|
-
args
|
|
22154
|
+
args
|
|
21966
22155
|
};
|
|
21967
22156
|
}
|
|
22157
|
+
function resolveMcpTransport(explicitTransport) {
|
|
22158
|
+
if (explicitTransport === "local" || explicitTransport === "ipc") return explicitTransport;
|
|
22159
|
+
const envTransport = process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT?.trim();
|
|
22160
|
+
return envTransport === "local" ? "local" : "ipc";
|
|
22161
|
+
}
|
|
22162
|
+
function resolveMcpPort(explicitPort) {
|
|
22163
|
+
if (typeof explicitPort === "number" && Number.isInteger(explicitPort) && explicitPort > 0) return explicitPort;
|
|
22164
|
+
const raw = process.env.ADHDEV_COORDINATOR_MCP_PORT?.trim();
|
|
22165
|
+
if (!raw) return void 0;
|
|
22166
|
+
const parsed = Number(raw);
|
|
22167
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
22168
|
+
}
|
|
21968
22169
|
function resolveMcpNodeExecutable(explicitExecutable) {
|
|
21969
22170
|
const explicit = explicitExecutable?.trim();
|
|
21970
22171
|
if (explicit) return explicit;
|
|
@@ -23785,6 +23986,51 @@ var DaemonCommandRouter = class {
|
|
|
23785
23986
|
return { success: false, error: e.message };
|
|
23786
23987
|
}
|
|
23787
23988
|
}
|
|
23989
|
+
case "get_mesh_queue": {
|
|
23990
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
23991
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
23992
|
+
try {
|
|
23993
|
+
const { getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
23994
|
+
const status = Array.isArray(args?.status) ? args.status.map((s) => typeof s === "string" ? s.trim() : "").filter(Boolean) : void 0;
|
|
23995
|
+
const queue = getQueue2(meshId, { status });
|
|
23996
|
+
return { success: true, queue };
|
|
23997
|
+
} catch (e) {
|
|
23998
|
+
return { success: false, error: e.message };
|
|
23999
|
+
}
|
|
24000
|
+
}
|
|
24001
|
+
case "cancel_mesh_queue_task": {
|
|
24002
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
24003
|
+
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
24004
|
+
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
24005
|
+
try {
|
|
24006
|
+
const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
24007
|
+
const reason = typeof args?.reason === "string" ? args.reason : void 0;
|
|
24008
|
+
const task = cancelTask2(meshId, taskId, { reason });
|
|
24009
|
+
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
24010
|
+
return { success: true, task };
|
|
24011
|
+
} catch (e) {
|
|
24012
|
+
return { success: false, error: e.message };
|
|
24013
|
+
}
|
|
24014
|
+
}
|
|
24015
|
+
case "requeue_mesh_queue_task": {
|
|
24016
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
24017
|
+
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
24018
|
+
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
24019
|
+
try {
|
|
24020
|
+
const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
24021
|
+
const task = requeueTask2(meshId, taskId, {
|
|
24022
|
+
reason: typeof args?.reason === "string" ? args.reason : void 0,
|
|
24023
|
+
targetNodeId: typeof args?.targetNodeId === "string" ? args.targetNodeId.trim() : void 0,
|
|
24024
|
+
targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : void 0,
|
|
24025
|
+
clearTargetNode: args?.clearTargetNode === true,
|
|
24026
|
+
clearTargetSession: args?.clearTargetSession !== false
|
|
24027
|
+
});
|
|
24028
|
+
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
24029
|
+
return { success: true, task };
|
|
24030
|
+
} catch (e) {
|
|
24031
|
+
return { success: false, error: e.message };
|
|
24032
|
+
}
|
|
24033
|
+
}
|
|
23788
24034
|
case "add_mesh_node": {
|
|
23789
24035
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
23790
24036
|
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -23942,7 +24188,13 @@ var DaemonCommandRouter = class {
|
|
|
23942
24188
|
appendLedgerEntry2(meshId, {
|
|
23943
24189
|
kind: "node_removed",
|
|
23944
24190
|
nodeId,
|
|
23945
|
-
payload: {
|
|
24191
|
+
payload: {
|
|
24192
|
+
worktree: !!node?.isLocalWorktree,
|
|
24193
|
+
sessionCleanupMode,
|
|
24194
|
+
workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
|
|
24195
|
+
daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
|
|
24196
|
+
worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0
|
|
24197
|
+
}
|
|
23946
24198
|
});
|
|
23947
24199
|
} catch {
|
|
23948
24200
|
}
|
|
@@ -24113,6 +24365,93 @@ var DaemonCommandRouter = class {
|
|
|
24113
24365
|
meshCoordinatorSetup: coordinatorSetup
|
|
24114
24366
|
};
|
|
24115
24367
|
}
|
|
24368
|
+
if (coordinatorSetup.kind === "cli_command") {
|
|
24369
|
+
let cliCmdSystemPrompt = "";
|
|
24370
|
+
try {
|
|
24371
|
+
cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
24372
|
+
} catch (error) {
|
|
24373
|
+
const message = error?.message || String(error);
|
|
24374
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
24375
|
+
return {
|
|
24376
|
+
success: false,
|
|
24377
|
+
code: "mesh_coordinator_prompt_failed",
|
|
24378
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
24379
|
+
meshId,
|
|
24380
|
+
cliType,
|
|
24381
|
+
workspace
|
|
24382
|
+
};
|
|
24383
|
+
}
|
|
24384
|
+
try {
|
|
24385
|
+
const { execFileSync: execCmdSync } = await import("child_process");
|
|
24386
|
+
const cmdParts = coordinatorSetup.command.trim().split(/\s+/);
|
|
24387
|
+
const [regCmd, ...regArgs] = cmdParts;
|
|
24388
|
+
LOG.info("MeshCoordinator", `Running MCP registration: ${coordinatorSetup.command}`);
|
|
24389
|
+
execCmdSync(regCmd, regArgs, { stdio: "pipe", timeout: 15e3 });
|
|
24390
|
+
} catch (error) {
|
|
24391
|
+
LOG.warn("MeshCoordinator", `MCP registration command failed (may be pre-registered): ${error?.message || error}`);
|
|
24392
|
+
}
|
|
24393
|
+
const cliCmdArgs = [];
|
|
24394
|
+
const cliCmdEnv = {};
|
|
24395
|
+
if (cliCmdSystemPrompt) {
|
|
24396
|
+
if (cliType === "codex-cli") {
|
|
24397
|
+
cliCmdArgs.push("-c", `developer_instructions=${JSON.stringify(cliCmdSystemPrompt)}`);
|
|
24398
|
+
} else if (cliType === "gemini-cli") {
|
|
24399
|
+
try {
|
|
24400
|
+
const { writeFileSync: wfs, existsSync: efs, readFileSync: rfs } = await import("fs");
|
|
24401
|
+
const geminiMdPath = `${workspace}/GEMINI.md`;
|
|
24402
|
+
const marker = "<!-- adhdev-mesh-coordinator-prompt -->";
|
|
24403
|
+
const markerEnd = "<!-- /adhdev-mesh-coordinator-prompt -->";
|
|
24404
|
+
const block = `${marker}
|
|
24405
|
+
${cliCmdSystemPrompt}
|
|
24406
|
+
${markerEnd}`;
|
|
24407
|
+
if (efs(geminiMdPath)) {
|
|
24408
|
+
const existing = rfs(geminiMdPath, "utf-8");
|
|
24409
|
+
const replaced = existing.replace(
|
|
24410
|
+
new RegExp(`${marker}[\\s\\S]*?${markerEnd}`, "g"),
|
|
24411
|
+
block
|
|
24412
|
+
);
|
|
24413
|
+
wfs(geminiMdPath, replaced.includes(marker) ? replaced : `${existing}
|
|
24414
|
+
|
|
24415
|
+
${block}`);
|
|
24416
|
+
} else {
|
|
24417
|
+
wfs(geminiMdPath, block);
|
|
24418
|
+
}
|
|
24419
|
+
LOG.info("MeshCoordinator", `Wrote coordinator prompt to ${workspace}/GEMINI.md`);
|
|
24420
|
+
} catch (e) {
|
|
24421
|
+
LOG.warn("MeshCoordinator", `Could not write GEMINI.md: ${e?.message || e}`);
|
|
24422
|
+
}
|
|
24423
|
+
}
|
|
24424
|
+
}
|
|
24425
|
+
const cliCmdLaunch = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
24426
|
+
cliType,
|
|
24427
|
+
dir: workspace,
|
|
24428
|
+
cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
|
|
24429
|
+
env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
|
|
24430
|
+
settings: { meshCoordinatorFor: meshId }
|
|
24431
|
+
});
|
|
24432
|
+
if (!cliCmdLaunch?.success) {
|
|
24433
|
+
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
24434
|
+
}
|
|
24435
|
+
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
24436
|
+
try {
|
|
24437
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
24438
|
+
appendLedgerEntry2(meshId, {
|
|
24439
|
+
kind: "coordinator_started",
|
|
24440
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
24441
|
+
providerType: cliType,
|
|
24442
|
+
payload: { workspace }
|
|
24443
|
+
});
|
|
24444
|
+
} catch {
|
|
24445
|
+
}
|
|
24446
|
+
return {
|
|
24447
|
+
success: true,
|
|
24448
|
+
meshId,
|
|
24449
|
+
cliType,
|
|
24450
|
+
workspace,
|
|
24451
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
24452
|
+
mcpRegistered: true
|
|
24453
|
+
};
|
|
24454
|
+
}
|
|
24116
24455
|
const configFormat = coordinatorSetup.configFormat;
|
|
24117
24456
|
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
24118
24457
|
return {
|
|
@@ -24167,9 +24506,11 @@ var DaemonCommandRouter = class {
|
|
|
24167
24506
|
args: coordinatorSetup.mcpServer.args
|
|
24168
24507
|
};
|
|
24169
24508
|
if (args?.inlineMesh) {
|
|
24509
|
+
const modeArgIndex = coordinatorSetup.mcpServer.args.findIndex((value) => value === "--mode");
|
|
24510
|
+
const mcpTransport = modeArgIndex >= 0 ? coordinatorSetup.mcpServer.args[modeArgIndex + 1] : "ipc";
|
|
24170
24511
|
mcpServerEntry.env = {
|
|
24171
24512
|
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
24172
|
-
ADHDEV_MCP_TRANSPORT: "ipc"
|
|
24513
|
+
ADHDEV_MCP_TRANSPORT: mcpTransport === "local" ? "local" : "ipc"
|
|
24173
24514
|
};
|
|
24174
24515
|
}
|
|
24175
24516
|
try {
|
|
@@ -32211,7 +32552,8 @@ async function initDaemonComponents(config) {
|
|
|
32211
32552
|
cdpManagers,
|
|
32212
32553
|
sessionRegistry,
|
|
32213
32554
|
detectedIdes: detectedIdesRef,
|
|
32214
|
-
refreshProviderAvailability
|
|
32555
|
+
refreshProviderAvailability,
|
|
32556
|
+
dispatchMeshCommand: config.dispatchMeshCommand
|
|
32215
32557
|
};
|
|
32216
32558
|
setupMeshEventForwarding(components);
|
|
32217
32559
|
return components;
|
|
@@ -32343,6 +32685,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
32343
32685
|
buildThoughtChatMessage,
|
|
32344
32686
|
buildToolChatMessage,
|
|
32345
32687
|
buildUserChatMessage,
|
|
32688
|
+
cancelTask,
|
|
32346
32689
|
claimNextTask,
|
|
32347
32690
|
classifyChatMessageVisibility,
|
|
32348
32691
|
classifyHotChatSessionsForSubscriptionFlush,
|
|
@@ -32386,6 +32729,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
32386
32729
|
getLogLevel,
|
|
32387
32730
|
getMesh,
|
|
32388
32731
|
getMeshByRepo,
|
|
32732
|
+
getMeshQueueStats,
|
|
32389
32733
|
getNpmExecOptions,
|
|
32390
32734
|
getQueue,
|
|
32391
32735
|
getRecentActivity,
|
|
@@ -32454,6 +32798,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
32454
32798
|
registerExtensionProviders,
|
|
32455
32799
|
removeNode,
|
|
32456
32800
|
removeWorktree,
|
|
32801
|
+
requeueTask,
|
|
32457
32802
|
resetConfig,
|
|
32458
32803
|
resetDebugRuntimeConfig,
|
|
32459
32804
|
resetState,
|