@adhdev/daemon-standalone 0.9.82-rc.3 → 0.9.82-rc.31
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 +1055 -293
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-BNKDsz6G.css +1 -0
- package/public/assets/index-DOk2hPy6.js +98 -0
- package/public/assets/{terminal-Cz61jYPm.js → terminal-CfAvHQvJ.js} +1 -1
- package/public/assets/vendor-CgiI0UIA.js +2745 -0
- package/public/index.html +3 -3
- package/vendor/mcp-server/index.js +324 -31
- package/vendor/mcp-server/index.js.map +1 -1
- package/public/assets/index-01wE493H.css +0 -1
- package/public/assets/index-BU3NAjAr.js +0 -98
- package/public/assets/vendor-CLec0455.js +0 -2723
package/dist/index.js
CHANGED
|
@@ -23490,6 +23490,36 @@ Follow these recovery rules:
|
|
|
23490
23490
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23491
23491
|
return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.json`);
|
|
23492
23492
|
}
|
|
23493
|
+
function getLockPath(meshId) {
|
|
23494
|
+
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23495
|
+
return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.lock`);
|
|
23496
|
+
}
|
|
23497
|
+
function withQueueLock(meshId, fn) {
|
|
23498
|
+
const lockPath = getLockPath(meshId);
|
|
23499
|
+
let fd = -1;
|
|
23500
|
+
for (let i = 0; i < 10; i++) {
|
|
23501
|
+
try {
|
|
23502
|
+
fd = (0, import_fs4.openSync)(lockPath, "wx");
|
|
23503
|
+
break;
|
|
23504
|
+
} catch {
|
|
23505
|
+
const deadline = Date.now() + 30;
|
|
23506
|
+
while (Date.now() < deadline) {
|
|
23507
|
+
}
|
|
23508
|
+
}
|
|
23509
|
+
}
|
|
23510
|
+
try {
|
|
23511
|
+
return fn();
|
|
23512
|
+
} finally {
|
|
23513
|
+
if (fd !== -1) try {
|
|
23514
|
+
(0, import_fs4.closeSync)(fd);
|
|
23515
|
+
} catch {
|
|
23516
|
+
}
|
|
23517
|
+
try {
|
|
23518
|
+
(0, import_fs4.unlinkSync)(lockPath);
|
|
23519
|
+
} catch {
|
|
23520
|
+
}
|
|
23521
|
+
}
|
|
23522
|
+
}
|
|
23493
23523
|
function readQueue(meshId) {
|
|
23494
23524
|
const path28 = getQueuePath(meshId);
|
|
23495
23525
|
if (!(0, import_fs4.existsSync)(path28)) return [];
|
|
@@ -23505,20 +23535,22 @@ Follow these recovery rules:
|
|
|
23505
23535
|
(0, import_fs4.writeFileSync)(path28, JSON.stringify(queue, null, 2), "utf-8");
|
|
23506
23536
|
}
|
|
23507
23537
|
function enqueueTask(meshId, message, opts) {
|
|
23508
|
-
|
|
23509
|
-
|
|
23510
|
-
|
|
23511
|
-
|
|
23512
|
-
|
|
23513
|
-
|
|
23514
|
-
|
|
23515
|
-
|
|
23516
|
-
|
|
23517
|
-
|
|
23518
|
-
|
|
23519
|
-
|
|
23520
|
-
|
|
23521
|
-
|
|
23538
|
+
return withQueueLock(meshId, () => {
|
|
23539
|
+
const queue = readQueue(meshId);
|
|
23540
|
+
const entry = {
|
|
23541
|
+
id: (0, import_crypto5.randomUUID)(),
|
|
23542
|
+
meshId,
|
|
23543
|
+
message,
|
|
23544
|
+
status: "pending",
|
|
23545
|
+
targetNodeId: opts?.targetNodeId,
|
|
23546
|
+
targetSessionId: opts?.targetSessionId,
|
|
23547
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23548
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23549
|
+
};
|
|
23550
|
+
queue.push(entry);
|
|
23551
|
+
writeQueue(meshId, queue);
|
|
23552
|
+
return entry;
|
|
23553
|
+
});
|
|
23522
23554
|
}
|
|
23523
23555
|
function getQueue(meshId, opts) {
|
|
23524
23556
|
let queue = readQueue(meshId);
|
|
@@ -23529,100 +23561,111 @@ Follow these recovery rules:
|
|
|
23529
23561
|
return queue;
|
|
23530
23562
|
}
|
|
23531
23563
|
function claimNextTask(meshId, nodeId, sessionId) {
|
|
23532
|
-
|
|
23533
|
-
|
|
23534
|
-
|
|
23535
|
-
|
|
23536
|
-
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23541
|
-
|
|
23542
|
-
|
|
23543
|
-
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
|
|
23547
|
-
|
|
23548
|
-
|
|
23549
|
-
|
|
23550
|
-
|
|
23564
|
+
return withQueueLock(meshId, () => {
|
|
23565
|
+
const queue = readQueue(meshId);
|
|
23566
|
+
const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
|
|
23567
|
+
if (hasActiveAssignment) return null;
|
|
23568
|
+
let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
|
|
23569
|
+
if (targetIdx === -1) {
|
|
23570
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
|
|
23571
|
+
}
|
|
23572
|
+
if (targetIdx === -1) {
|
|
23573
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
|
|
23574
|
+
}
|
|
23575
|
+
if (targetIdx === -1) return null;
|
|
23576
|
+
const entry = queue[targetIdx];
|
|
23577
|
+
entry.status = "assigned";
|
|
23578
|
+
entry.assignedNodeId = nodeId;
|
|
23579
|
+
entry.assignedSessionId = sessionId;
|
|
23580
|
+
entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
23581
|
+
entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23582
|
+
writeQueue(meshId, queue);
|
|
23583
|
+
return entry;
|
|
23584
|
+
});
|
|
23551
23585
|
}
|
|
23552
23586
|
function updateTaskStatus(meshId, taskId, status) {
|
|
23553
|
-
|
|
23554
|
-
|
|
23555
|
-
|
|
23556
|
-
|
|
23557
|
-
|
|
23558
|
-
|
|
23559
|
-
|
|
23587
|
+
return withQueueLock(meshId, () => {
|
|
23588
|
+
const queue = readQueue(meshId);
|
|
23589
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
23590
|
+
if (idx === -1) return null;
|
|
23591
|
+
queue[idx].status = status;
|
|
23592
|
+
queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23593
|
+
writeQueue(meshId, queue);
|
|
23594
|
+
return queue[idx];
|
|
23595
|
+
});
|
|
23560
23596
|
}
|
|
23561
23597
|
function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
...autoLaunch,
|
|
23568
|
-
updatedAt
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
|
|
23572
|
-
return queue[idx];
|
|
23598
|
+
return withQueueLock(meshId, () => {
|
|
23599
|
+
const queue = readQueue(meshId);
|
|
23600
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
23601
|
+
if (idx === -1) return null;
|
|
23602
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23603
|
+
queue[idx].autoLaunch = { ...autoLaunch, updatedAt: now };
|
|
23604
|
+
queue[idx].updatedAt = now;
|
|
23605
|
+
writeQueue(meshId, queue);
|
|
23606
|
+
return queue[idx];
|
|
23607
|
+
});
|
|
23573
23608
|
}
|
|
23574
23609
|
function cancelTask(meshId, taskId, opts) {
|
|
23575
|
-
|
|
23576
|
-
|
|
23577
|
-
|
|
23578
|
-
|
|
23579
|
-
|
|
23580
|
-
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23584
|
-
|
|
23610
|
+
return withQueueLock(meshId, () => {
|
|
23611
|
+
const queue = readQueue(meshId);
|
|
23612
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
23613
|
+
if (idx === -1) return null;
|
|
23614
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23615
|
+
queue[idx].status = "cancelled";
|
|
23616
|
+
queue[idx].updatedAt = now;
|
|
23617
|
+
queue[idx].cancelledAt = now;
|
|
23618
|
+
if (opts?.reason) queue[idx].cancelReason = opts.reason;
|
|
23619
|
+
writeQueue(meshId, queue);
|
|
23620
|
+
return queue[idx];
|
|
23621
|
+
});
|
|
23585
23622
|
}
|
|
23586
23623
|
function requeueTask(meshId, taskId, opts) {
|
|
23587
|
-
|
|
23588
|
-
|
|
23589
|
-
|
|
23590
|
-
|
|
23591
|
-
|
|
23592
|
-
|
|
23593
|
-
|
|
23594
|
-
|
|
23595
|
-
|
|
23596
|
-
|
|
23597
|
-
|
|
23598
|
-
|
|
23599
|
-
|
|
23600
|
-
|
|
23601
|
-
|
|
23602
|
-
|
|
23603
|
-
|
|
23604
|
-
|
|
23605
|
-
|
|
23606
|
-
|
|
23607
|
-
|
|
23608
|
-
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
|
|
23612
|
-
|
|
23613
|
-
|
|
23624
|
+
return withQueueLock(meshId, () => {
|
|
23625
|
+
const queue = readQueue(meshId);
|
|
23626
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
23627
|
+
if (idx === -1) return null;
|
|
23628
|
+
const entry = queue[idx];
|
|
23629
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
23630
|
+
entry.status = "pending";
|
|
23631
|
+
delete entry.assignedNodeId;
|
|
23632
|
+
delete entry.assignedSessionId;
|
|
23633
|
+
delete entry.cancelledAt;
|
|
23634
|
+
delete entry.cancelReason;
|
|
23635
|
+
if (opts?.clearTargetNode) delete entry.targetNodeId;
|
|
23636
|
+
if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
|
|
23637
|
+
if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
|
|
23638
|
+
if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
|
|
23639
|
+
entry.updatedAt = now;
|
|
23640
|
+
entry.requeuedAt = now;
|
|
23641
|
+
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
23642
|
+
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
23643
|
+
writeQueue(meshId, queue);
|
|
23644
|
+
return entry;
|
|
23645
|
+
});
|
|
23646
|
+
}
|
|
23647
|
+
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
23648
|
+
return withQueueLock(meshId, () => {
|
|
23649
|
+
const queue = readQueue(meshId);
|
|
23650
|
+
const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
|
|
23651
|
+
const hasOccurredAt = Number.isFinite(occurredAtTime);
|
|
23652
|
+
let bestIdx = -1;
|
|
23653
|
+
let bestTime = 0;
|
|
23654
|
+
for (let i = queue.length - 1; i >= 0; i--) {
|
|
23655
|
+
if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
|
|
23614
23656
|
const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
|
|
23657
|
+
if (hasOccurredAt && Number.isFinite(time3) && time3 > occurredAtTime) continue;
|
|
23615
23658
|
if (time3 > bestTime) {
|
|
23616
23659
|
bestTime = time3;
|
|
23617
23660
|
bestIdx = i;
|
|
23618
23661
|
}
|
|
23619
23662
|
}
|
|
23620
|
-
|
|
23621
|
-
|
|
23622
|
-
|
|
23623
|
-
|
|
23624
|
-
|
|
23625
|
-
|
|
23663
|
+
if (bestIdx === -1) return null;
|
|
23664
|
+
queue[bestIdx].status = status;
|
|
23665
|
+
queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23666
|
+
writeQueue(meshId, queue);
|
|
23667
|
+
return queue[bestIdx];
|
|
23668
|
+
});
|
|
23626
23669
|
}
|
|
23627
23670
|
function getMeshQueueStats(meshId) {
|
|
23628
23671
|
const queue = readQueue(meshId);
|
|
@@ -24046,18 +24089,75 @@ Follow these recovery rules:
|
|
|
24046
24089
|
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
24047
24090
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
24048
24091
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
24092
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
24049
24093
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
24050
24094
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
24051
24095
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
24052
24096
|
});
|
|
24053
|
-
function
|
|
24054
|
-
|
|
24097
|
+
function sweepExpiredRemoteIdleSessions() {
|
|
24098
|
+
const now = Date.now();
|
|
24099
|
+
for (const [key, session] of remoteIdleSessions) {
|
|
24100
|
+
if (session.expiresAt <= now) remoteIdleSessions.delete(key);
|
|
24101
|
+
}
|
|
24102
|
+
}
|
|
24103
|
+
function getPendingEventsPath(meshId) {
|
|
24104
|
+
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
24105
|
+
return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
24055
24106
|
}
|
|
24056
|
-
function
|
|
24057
|
-
|
|
24107
|
+
function queuePendingMeshCoordinatorEvent(event) {
|
|
24108
|
+
try {
|
|
24109
|
+
(0, import_fs6.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
|
|
24110
|
+
return true;
|
|
24111
|
+
} catch (e) {
|
|
24112
|
+
LOG2.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
24113
|
+
return false;
|
|
24114
|
+
}
|
|
24058
24115
|
}
|
|
24059
|
-
function
|
|
24060
|
-
|
|
24116
|
+
function drainPendingMeshCoordinatorEvents(meshId) {
|
|
24117
|
+
if (!meshId) return [];
|
|
24118
|
+
const path28 = getPendingEventsPath(meshId);
|
|
24119
|
+
if (!(0, import_fs6.existsSync)(path28)) return [];
|
|
24120
|
+
try {
|
|
24121
|
+
const raw = (0, import_fs6.readFileSync)(path28, "utf-8");
|
|
24122
|
+
try {
|
|
24123
|
+
(0, import_fs6.unlinkSync)(path28);
|
|
24124
|
+
} catch {
|
|
24125
|
+
}
|
|
24126
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
24127
|
+
try {
|
|
24128
|
+
return [JSON.parse(line)];
|
|
24129
|
+
} catch {
|
|
24130
|
+
return [];
|
|
24131
|
+
}
|
|
24132
|
+
});
|
|
24133
|
+
} catch {
|
|
24134
|
+
return [];
|
|
24135
|
+
}
|
|
24136
|
+
}
|
|
24137
|
+
function getPendingMeshCoordinatorEvents(meshId) {
|
|
24138
|
+
if (!meshId) return [];
|
|
24139
|
+
const path28 = getPendingEventsPath(meshId);
|
|
24140
|
+
if (!(0, import_fs6.existsSync)(path28)) return [];
|
|
24141
|
+
try {
|
|
24142
|
+
const raw = (0, import_fs6.readFileSync)(path28, "utf-8");
|
|
24143
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
24144
|
+
try {
|
|
24145
|
+
return [JSON.parse(line)];
|
|
24146
|
+
} catch {
|
|
24147
|
+
return [];
|
|
24148
|
+
}
|
|
24149
|
+
});
|
|
24150
|
+
} catch {
|
|
24151
|
+
return [];
|
|
24152
|
+
}
|
|
24153
|
+
}
|
|
24154
|
+
function clearPendingMeshCoordinatorEvents(meshId) {
|
|
24155
|
+
if (!meshId) return;
|
|
24156
|
+
const path28 = getPendingEventsPath(meshId);
|
|
24157
|
+
if ((0, import_fs6.existsSync)(path28)) try {
|
|
24158
|
+
(0, import_fs6.unlinkSync)(path28);
|
|
24159
|
+
} catch {
|
|
24160
|
+
}
|
|
24061
24161
|
}
|
|
24062
24162
|
function readNonEmptyString(value) {
|
|
24063
24163
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
@@ -24103,6 +24203,38 @@ Follow these recovery rules:
|
|
|
24103
24203
|
if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
|
|
24104
24204
|
return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
|
|
24105
24205
|
}
|
|
24206
|
+
function readEventTimestamp(value) {
|
|
24207
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
24208
|
+
if (typeof value === "string" && value.trim()) {
|
|
24209
|
+
const numeric = Number(value);
|
|
24210
|
+
if (Number.isFinite(numeric)) return numeric;
|
|
24211
|
+
const parsed = Date.parse(value);
|
|
24212
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
24213
|
+
}
|
|
24214
|
+
return null;
|
|
24215
|
+
}
|
|
24216
|
+
function buildMeshCompletionFingerprint(args) {
|
|
24217
|
+
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
|
|
24218
|
+
return [
|
|
24219
|
+
args.meshId,
|
|
24220
|
+
args.event,
|
|
24221
|
+
args.sessionId,
|
|
24222
|
+
args.providerType || "",
|
|
24223
|
+
args.providerSessionId || "",
|
|
24224
|
+
timestampPart
|
|
24225
|
+
].join("::");
|
|
24226
|
+
}
|
|
24227
|
+
function isDuplicateMeshCompletionEvent(args) {
|
|
24228
|
+
const fingerprint = buildMeshCompletionFingerprint(args);
|
|
24229
|
+
if (!fingerprint) return false;
|
|
24230
|
+
const now = Date.now();
|
|
24231
|
+
for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
|
|
24232
|
+
if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
|
|
24233
|
+
}
|
|
24234
|
+
if (recentCompletionFingerprints.has(fingerprint)) return true;
|
|
24235
|
+
recentCompletionFingerprints.set(fingerprint, now);
|
|
24236
|
+
return false;
|
|
24237
|
+
}
|
|
24106
24238
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
24107
24239
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
24108
24240
|
if (!task) {
|
|
@@ -24121,7 +24253,16 @@ Follow these recovery rules:
|
|
|
24121
24253
|
message: task.message
|
|
24122
24254
|
}).catch((e) => {
|
|
24123
24255
|
LOG2.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
24124
|
-
updateTaskStatus(meshId, task.id, "
|
|
24256
|
+
updateTaskStatus(meshId, task.id, "pending");
|
|
24257
|
+
try {
|
|
24258
|
+
appendLedgerEntry(meshId, {
|
|
24259
|
+
kind: "dispatch_failed",
|
|
24260
|
+
nodeId,
|
|
24261
|
+
sessionId,
|
|
24262
|
+
payload: { taskId: task.id, error: e?.message, retryable: true }
|
|
24263
|
+
});
|
|
24264
|
+
} catch {
|
|
24265
|
+
}
|
|
24125
24266
|
});
|
|
24126
24267
|
return true;
|
|
24127
24268
|
}
|
|
@@ -24455,18 +24596,36 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24455
24596
|
LOG2.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
|
|
24456
24597
|
return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
|
|
24457
24598
|
}
|
|
24599
|
+
const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
|
|
24600
|
+
if (args.event === "agent:generating_completed" && eventSessionId) {
|
|
24601
|
+
const duplicateCompletion = isDuplicateMeshCompletionEvent({
|
|
24602
|
+
meshId: args.meshId,
|
|
24603
|
+
event: args.event,
|
|
24604
|
+
sessionId: eventSessionId,
|
|
24605
|
+
providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
|
|
24606
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
24607
|
+
timestamp: eventTimestamp,
|
|
24608
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
24609
|
+
});
|
|
24610
|
+
if (duplicateCompletion) {
|
|
24611
|
+
LOG2.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
24612
|
+
return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
|
|
24613
|
+
}
|
|
24614
|
+
}
|
|
24458
24615
|
let completedTaskForLedger = null;
|
|
24459
24616
|
if (args.event === "agent:generating_completed") {
|
|
24460
24617
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
24461
24618
|
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
24462
24619
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
24463
24620
|
if (sessionId) {
|
|
24464
|
-
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed"
|
|
24621
|
+
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
|
|
24622
|
+
occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
|
|
24623
|
+
});
|
|
24465
24624
|
completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
|
|
24466
24625
|
if (nodeId && providerType) {
|
|
24467
|
-
|
|
24626
|
+
setImmediate(() => {
|
|
24468
24627
|
tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
24469
|
-
}
|
|
24628
|
+
});
|
|
24470
24629
|
}
|
|
24471
24630
|
}
|
|
24472
24631
|
} else if (args.event === "agent:ready") {
|
|
@@ -24504,13 +24663,17 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24504
24663
|
}
|
|
24505
24664
|
}
|
|
24506
24665
|
if (sessionId && nodeId && providerType) {
|
|
24507
|
-
|
|
24508
|
-
|
|
24666
|
+
sweepExpiredRemoteIdleSessions();
|
|
24667
|
+
remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
|
|
24668
|
+
nodeId,
|
|
24669
|
+
sessionId,
|
|
24670
|
+
providerType,
|
|
24671
|
+
expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
|
|
24672
|
+
});
|
|
24673
|
+
setImmediate(() => {
|
|
24509
24674
|
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
24510
|
-
if (assigned) {
|
|
24511
|
-
|
|
24512
|
-
}
|
|
24513
|
-
}, 500);
|
|
24675
|
+
if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
24676
|
+
});
|
|
24514
24677
|
}
|
|
24515
24678
|
} else if (args.event === "agent:generating_started") {
|
|
24516
24679
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
@@ -24621,17 +24784,18 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24621
24784
|
return true;
|
|
24622
24785
|
});
|
|
24623
24786
|
if (coordinatorInstances.length === 0) {
|
|
24624
|
-
if (
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
|
|
24629
|
-
|
|
24630
|
-
|
|
24631
|
-
|
|
24632
|
-
}
|
|
24633
|
-
|
|
24634
|
-
|
|
24787
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
24788
|
+
event: args.event,
|
|
24789
|
+
meshId: args.meshId,
|
|
24790
|
+
nodeLabel: args.nodeLabel,
|
|
24791
|
+
nodeId: args.nodeId || void 0,
|
|
24792
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
24793
|
+
metadataEvent: {
|
|
24794
|
+
...args.metadataEvent,
|
|
24795
|
+
...recoveryContext ? { recoveryContext } : {}
|
|
24796
|
+
},
|
|
24797
|
+
queuedAt: Date.now()
|
|
24798
|
+
})) {
|
|
24635
24799
|
LOG2.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
24636
24800
|
}
|
|
24637
24801
|
return { success: true, forwarded: 0 };
|
|
@@ -24670,6 +24834,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24670
24834
|
providerType: readNonEmptyString(payload.providerType),
|
|
24671
24835
|
providerSessionId: readNonEmptyString(payload.providerSessionId),
|
|
24672
24836
|
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
|
|
24837
|
+
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
24673
24838
|
intentional: payload.intentional === true,
|
|
24674
24839
|
intentionalStop: payload.intentionalStop === true,
|
|
24675
24840
|
operatorCleanup: payload.operatorCleanup === true,
|
|
@@ -24712,27 +24877,31 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24712
24877
|
});
|
|
24713
24878
|
});
|
|
24714
24879
|
}
|
|
24880
|
+
var import_fs6;
|
|
24881
|
+
var import_path5;
|
|
24882
|
+
var REMOTE_IDLE_SESSION_TTL_MS;
|
|
24715
24883
|
var remoteIdleSessions;
|
|
24716
|
-
var MAX_PENDING_EVENTS;
|
|
24717
|
-
var pendingMeshCoordinatorEvents;
|
|
24718
24884
|
var MESH_COORDINATOR_EVENTS;
|
|
24719
24885
|
var EVENT_TO_LEDGER_KIND;
|
|
24720
24886
|
var INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS;
|
|
24887
|
+
var RECENT_COMPLETION_FINGERPRINT_TTL_MS;
|
|
24888
|
+
var recentCompletionFingerprints;
|
|
24721
24889
|
var autoLaunchInProgress;
|
|
24722
24890
|
var autoLaunchCooldownUntil;
|
|
24723
24891
|
var AUTO_LAUNCH_COOLDOWN_MS;
|
|
24724
24892
|
var init_mesh_events = __esm2({
|
|
24725
24893
|
"src/mesh/mesh-events.ts"() {
|
|
24726
24894
|
"use strict";
|
|
24895
|
+
import_fs6 = require("fs");
|
|
24896
|
+
import_path5 = require("path");
|
|
24727
24897
|
init_config();
|
|
24728
24898
|
init_mesh_config();
|
|
24729
24899
|
init_cli_detector();
|
|
24730
24900
|
init_logger();
|
|
24731
24901
|
init_mesh_ledger();
|
|
24732
24902
|
init_mesh_work_queue();
|
|
24903
|
+
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
24733
24904
|
remoteIdleSessions = /* @__PURE__ */ new Map();
|
|
24734
|
-
MAX_PENDING_EVENTS = 50;
|
|
24735
|
-
pendingMeshCoordinatorEvents = [];
|
|
24736
24905
|
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
24737
24906
|
"agent:generating_started",
|
|
24738
24907
|
"agent:generating_completed",
|
|
@@ -24748,6 +24917,8 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
24748
24917
|
"monitor:long_generating": "task_stalled"
|
|
24749
24918
|
};
|
|
24750
24919
|
INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
|
|
24920
|
+
RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
|
|
24921
|
+
recentCompletionFingerprints = /* @__PURE__ */ new Map();
|
|
24751
24922
|
autoLaunchInProgress = /* @__PURE__ */ new Set();
|
|
24752
24923
|
autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
|
|
24753
24924
|
AUTO_LAUNCH_COOLDOWN_MS = 5e3;
|
|
@@ -28013,6 +28184,7 @@ ${lastSnapshot}`;
|
|
|
28013
28184
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate2,
|
|
28014
28185
|
prepareSessionModalUpdate: () => prepareSessionModalUpdate2,
|
|
28015
28186
|
probeCdpPort: () => probeCdpPort,
|
|
28187
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
28016
28188
|
readChatHistory: () => readChatHistory,
|
|
28017
28189
|
readLedgerEntries: () => readLedgerEntries,
|
|
28018
28190
|
readLedgerSlice: () => readLedgerSlice,
|
|
@@ -28062,8 +28234,14 @@ ${lastSnapshot}`;
|
|
|
28062
28234
|
const includeSubmodules = options.includeSubmodules !== false;
|
|
28063
28235
|
try {
|
|
28064
28236
|
const repo = await resolveGitRepository(workspace, options);
|
|
28065
|
-
|
|
28066
|
-
|
|
28237
|
+
let parsed = await readPorcelainStatus(repo, options);
|
|
28238
|
+
let upstreamProbe = getInitialUpstreamProbe(parsed);
|
|
28239
|
+
if (options.refreshUpstream) {
|
|
28240
|
+
upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
|
|
28241
|
+
if (upstreamProbe.upstreamStatus === "fresh") {
|
|
28242
|
+
parsed = await readPorcelainStatus(repo, options);
|
|
28243
|
+
}
|
|
28244
|
+
}
|
|
28067
28245
|
const head = await readHead(repo, options);
|
|
28068
28246
|
const stashCount = await readStashCount(repo, options);
|
|
28069
28247
|
let submodules;
|
|
@@ -28078,6 +28256,9 @@ ${lastSnapshot}`;
|
|
|
28078
28256
|
headCommit: head.commit,
|
|
28079
28257
|
headMessage: head.message,
|
|
28080
28258
|
upstream: parsed.upstream,
|
|
28259
|
+
upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
|
|
28260
|
+
upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
|
|
28261
|
+
upstreamFetchError: upstreamProbe.upstreamFetchError,
|
|
28081
28262
|
ahead: parsed.ahead,
|
|
28082
28263
|
behind: parsed.behind,
|
|
28083
28264
|
staged: parsed.staged,
|
|
@@ -28102,6 +28283,60 @@ ${lastSnapshot}`;
|
|
|
28102
28283
|
);
|
|
28103
28284
|
}
|
|
28104
28285
|
}
|
|
28286
|
+
async function readPorcelainStatus(repo, options) {
|
|
28287
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
28288
|
+
return parsePorcelainV2Status(statusOutput.stdout);
|
|
28289
|
+
}
|
|
28290
|
+
function getInitialUpstreamProbe(parsed) {
|
|
28291
|
+
return {
|
|
28292
|
+
upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
|
|
28293
|
+
};
|
|
28294
|
+
}
|
|
28295
|
+
async function refreshTrackedUpstream(repo, parsed, options) {
|
|
28296
|
+
if (!parsed.upstream || !parsed.branch) {
|
|
28297
|
+
return { upstreamStatus: "no_upstream" };
|
|
28298
|
+
}
|
|
28299
|
+
const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
|
|
28300
|
+
if (!remoteName) {
|
|
28301
|
+
return {
|
|
28302
|
+
upstreamStatus: "stale",
|
|
28303
|
+
upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
|
|
28304
|
+
};
|
|
28305
|
+
}
|
|
28306
|
+
try {
|
|
28307
|
+
await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
|
|
28308
|
+
return {
|
|
28309
|
+
upstreamStatus: "fresh",
|
|
28310
|
+
upstreamFetchedAt: Date.now()
|
|
28311
|
+
};
|
|
28312
|
+
} catch (error48) {
|
|
28313
|
+
return {
|
|
28314
|
+
upstreamStatus: "stale",
|
|
28315
|
+
upstreamFetchError: formatGitError(error48)
|
|
28316
|
+
};
|
|
28317
|
+
}
|
|
28318
|
+
}
|
|
28319
|
+
async function readBranchRemote(repo, branch, options) {
|
|
28320
|
+
try {
|
|
28321
|
+
const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
|
|
28322
|
+
return result.stdout.trim() || null;
|
|
28323
|
+
} catch {
|
|
28324
|
+
return null;
|
|
28325
|
+
}
|
|
28326
|
+
}
|
|
28327
|
+
function inferRemoteName(upstream) {
|
|
28328
|
+
const [remoteName] = upstream.split("/");
|
|
28329
|
+
return remoteName?.trim() || null;
|
|
28330
|
+
}
|
|
28331
|
+
function formatGitError(error48) {
|
|
28332
|
+
if (error48 instanceof GitCommandError) {
|
|
28333
|
+
return error48.stderr || error48.message;
|
|
28334
|
+
}
|
|
28335
|
+
if (error48 instanceof Error) {
|
|
28336
|
+
return error48.message;
|
|
28337
|
+
}
|
|
28338
|
+
return String(error48);
|
|
28339
|
+
}
|
|
28105
28340
|
function parsePorcelainV2Status(output) {
|
|
28106
28341
|
const parsed = {
|
|
28107
28342
|
branch: null,
|
|
@@ -28196,6 +28431,7 @@ ${lastSnapshot}`;
|
|
|
28196
28431
|
headCommit: null,
|
|
28197
28432
|
headMessage: null,
|
|
28198
28433
|
upstream: null,
|
|
28434
|
+
upstreamStatus: "unavailable",
|
|
28199
28435
|
ahead: 0,
|
|
28200
28436
|
behind: 0,
|
|
28201
28437
|
staged: 0,
|
|
@@ -28472,6 +28708,9 @@ ${lastSnapshot}`;
|
|
|
28472
28708
|
isGitRepo: status.isGitRepo,
|
|
28473
28709
|
repoRoot: status.repoRoot,
|
|
28474
28710
|
branch: status.branch,
|
|
28711
|
+
upstreamStatus: status.upstreamStatus,
|
|
28712
|
+
upstreamFetchedAt: status.upstreamFetchedAt,
|
|
28713
|
+
upstreamFetchError: status.upstreamFetchError,
|
|
28475
28714
|
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
28476
28715
|
changedFiles,
|
|
28477
28716
|
ahead: status.ahead,
|
|
@@ -28810,7 +29049,7 @@ ${lastSnapshot}`;
|
|
|
28810
29049
|
});
|
|
28811
29050
|
function createDefaultGitCommandServices() {
|
|
28812
29051
|
return {
|
|
28813
|
-
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
29052
|
+
getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
|
|
28814
29053
|
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
28815
29054
|
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
28816
29055
|
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
@@ -28896,7 +29135,7 @@ ${lastSnapshot}`;
|
|
|
28896
29135
|
switch (command) {
|
|
28897
29136
|
case "git_status": {
|
|
28898
29137
|
if (!services.getStatus) return serviceNotImplemented(command);
|
|
28899
|
-
const status = await runService(() => services.getStatus({ workspace }));
|
|
29138
|
+
const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
|
|
28900
29139
|
return "success" in status ? status : { success: true, status };
|
|
28901
29140
|
}
|
|
28902
29141
|
case "git_diff_summary": {
|
|
@@ -29904,8 +30143,8 @@ ${lastSnapshot}`;
|
|
|
29904
30143
|
this.targetDaemonId = context.targetDaemonId;
|
|
29905
30144
|
}
|
|
29906
30145
|
};
|
|
29907
|
-
var
|
|
29908
|
-
var
|
|
30146
|
+
var import_fs7 = require("fs");
|
|
30147
|
+
var import_path6 = require("path");
|
|
29909
30148
|
init_config();
|
|
29910
30149
|
var DEFAULT_STATE = {
|
|
29911
30150
|
recentActivity: [],
|
|
@@ -29919,7 +30158,7 @@ ${lastSnapshot}`;
|
|
|
29919
30158
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
29920
30159
|
}
|
|
29921
30160
|
function getStatePath() {
|
|
29922
|
-
return (0,
|
|
30161
|
+
return (0, import_path6.join)(getConfigDir(), "state.json");
|
|
29923
30162
|
}
|
|
29924
30163
|
function normalizeState(raw) {
|
|
29925
30164
|
const parsed = isPlainObject22(raw) ? raw : {};
|
|
@@ -29955,11 +30194,11 @@ ${lastSnapshot}`;
|
|
|
29955
30194
|
}
|
|
29956
30195
|
function loadState() {
|
|
29957
30196
|
const statePath = getStatePath();
|
|
29958
|
-
if (!(0,
|
|
30197
|
+
if (!(0, import_fs7.existsSync)(statePath)) {
|
|
29959
30198
|
return { ...DEFAULT_STATE };
|
|
29960
30199
|
}
|
|
29961
30200
|
try {
|
|
29962
|
-
const raw = (0,
|
|
30201
|
+
const raw = (0, import_fs7.readFileSync)(statePath, "utf-8");
|
|
29963
30202
|
return normalizeState(JSON.parse(raw));
|
|
29964
30203
|
} catch {
|
|
29965
30204
|
return { ...DEFAULT_STATE };
|
|
@@ -29968,13 +30207,13 @@ ${lastSnapshot}`;
|
|
|
29968
30207
|
function saveState(state) {
|
|
29969
30208
|
const statePath = getStatePath();
|
|
29970
30209
|
const normalized = normalizeState(state);
|
|
29971
|
-
(0,
|
|
30210
|
+
(0, import_fs7.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
29972
30211
|
}
|
|
29973
30212
|
function resetState() {
|
|
29974
30213
|
saveState({ ...DEFAULT_STATE });
|
|
29975
30214
|
}
|
|
29976
30215
|
var import_child_process2 = require("child_process");
|
|
29977
|
-
var
|
|
30216
|
+
var import_fs8 = require("fs");
|
|
29978
30217
|
var import_os22 = require("os");
|
|
29979
30218
|
var path10 = __toESM2(require("path"));
|
|
29980
30219
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -29998,7 +30237,7 @@ ${lastSnapshot}`;
|
|
|
29998
30237
|
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
29999
30238
|
const candidate = trimmed.startsWith("~") ? path10.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
30000
30239
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
30001
|
-
return (0,
|
|
30240
|
+
return (0, import_fs8.existsSync)(resolved) ? resolved : null;
|
|
30002
30241
|
}
|
|
30003
30242
|
try {
|
|
30004
30243
|
const result = (0, import_child_process2.execSync)(
|
|
@@ -30029,9 +30268,9 @@ ${lastSnapshot}`;
|
|
|
30029
30268
|
if (normalized.includes("*")) {
|
|
30030
30269
|
const username = home.split(/[\\/]/).pop() || "";
|
|
30031
30270
|
const resolved = normalized.replace("*", username);
|
|
30032
|
-
if ((0,
|
|
30271
|
+
if ((0, import_fs8.existsSync)(resolved)) return resolved;
|
|
30033
30272
|
} else {
|
|
30034
|
-
if ((0,
|
|
30273
|
+
if ((0, import_fs8.existsSync)(normalized)) return normalized;
|
|
30035
30274
|
}
|
|
30036
30275
|
}
|
|
30037
30276
|
return null;
|
|
@@ -30045,7 +30284,7 @@ ${lastSnapshot}`;
|
|
|
30045
30284
|
let resolvedCli = cliPath;
|
|
30046
30285
|
if (!resolvedCli && appPath && os222 === "darwin") {
|
|
30047
30286
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
30048
|
-
if ((0,
|
|
30287
|
+
if ((0, import_fs8.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
30049
30288
|
}
|
|
30050
30289
|
if (!resolvedCli && appPath && os222 === "win32") {
|
|
30051
30290
|
const { dirname: dirname9 } = await import("path");
|
|
@@ -30058,7 +30297,7 @@ ${lastSnapshot}`;
|
|
|
30058
30297
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
30059
30298
|
];
|
|
30060
30299
|
for (const c of candidates) {
|
|
30061
|
-
if ((0,
|
|
30300
|
+
if ((0, import_fs8.existsSync)(c)) {
|
|
30062
30301
|
resolvedCli = c;
|
|
30063
30302
|
break;
|
|
30064
30303
|
}
|
|
@@ -31928,7 +32167,8 @@ ${lastSnapshot}`;
|
|
|
31928
32167
|
}
|
|
31929
32168
|
}
|
|
31930
32169
|
};
|
|
31931
|
-
|
|
32170
|
+
var DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
|
|
32171
|
+
function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
|
|
31932
32172
|
if (!Array.isArray(messages) || messages.length === 0) return "";
|
|
31933
32173
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
31934
32174
|
const msg = messages[i];
|
|
@@ -39122,7 +39362,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39122
39362
|
var os13 = __toESM2(require("os"));
|
|
39123
39363
|
var path18 = __toESM2(require("path"));
|
|
39124
39364
|
var crypto4 = __toESM2(require("crypto"));
|
|
39125
|
-
var
|
|
39365
|
+
var import_fs9 = require("fs");
|
|
39126
39366
|
var import_child_process6 = require("child_process");
|
|
39127
39367
|
var import_chalk = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
39128
39368
|
init_provider_cli_adapter();
|
|
@@ -41580,7 +41820,7 @@ ${rawInput}` : rawInput;
|
|
|
41580
41820
|
const trimmed = command.trim();
|
|
41581
41821
|
if (!trimmed) return false;
|
|
41582
41822
|
if (isExplicitCommand(trimmed)) {
|
|
41583
|
-
return (0,
|
|
41823
|
+
return (0, import_fs9.existsSync)(expandExecutable(trimmed));
|
|
41584
41824
|
}
|
|
41585
41825
|
try {
|
|
41586
41826
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -41609,10 +41849,10 @@ ${rawInput}` : rawInput;
|
|
|
41609
41849
|
}
|
|
41610
41850
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
41611
41851
|
const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
41612
|
-
(0,
|
|
41852
|
+
(0, import_fs9.mkdirSync)(baseDir, { recursive: true });
|
|
41613
41853
|
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
41614
41854
|
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
41615
|
-
(0,
|
|
41855
|
+
(0, import_fs9.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
41616
41856
|
return filePath;
|
|
41617
41857
|
}
|
|
41618
41858
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -45763,7 +46003,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45763
46003
|
}
|
|
45764
46004
|
}
|
|
45765
46005
|
var import_os3 = require("os");
|
|
45766
|
-
var
|
|
46006
|
+
var import_path7 = require("path");
|
|
45767
46007
|
var fs10 = __toESM2(require("fs"));
|
|
45768
46008
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
45769
46009
|
var CHANNEL_SERVER_URL = {
|
|
@@ -45812,55 +46052,45 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45812
46052
|
}
|
|
45813
46053
|
return void 0;
|
|
45814
46054
|
}
|
|
45815
|
-
function
|
|
45816
|
-
const
|
|
45817
|
-
const
|
|
45818
|
-
if (
|
|
45819
|
-
|
|
45820
|
-
|
|
45821
|
-
|
|
45822
|
-
|
|
45823
|
-
|
|
45824
|
-
|
|
45825
|
-
|
|
45826
|
-
|
|
45827
|
-
|
|
45828
|
-
|
|
45829
|
-
|
|
45830
|
-
|
|
45831
|
-
|
|
45832
|
-
|
|
45833
|
-
|
|
45834
|
-
|
|
45835
|
-
|
|
45836
|
-
|
|
45837
|
-
|
|
45838
|
-
|
|
45839
|
-
|
|
45840
|
-
|
|
45841
|
-
|
|
45842
|
-
|
|
45843
|
-
|
|
45844
|
-
}
|
|
45845
|
-
}
|
|
45846
|
-
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
45847
|
-
const gitResult = readObjectRecord(rawGit.result);
|
|
45848
|
-
const directStatus = readObjectRecord(rawGit.status);
|
|
45849
|
-
const nestedStatus = readObjectRecord(gitResult.status);
|
|
45850
|
-
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
45851
|
-
const probeGit = readObjectRecord(rawProbe.git);
|
|
45852
|
-
const probeGitResult = readObjectRecord(probeGit.result);
|
|
45853
|
-
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
45854
|
-
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
45855
|
-
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46055
|
+
function joinRepoPath(root, relativePath) {
|
|
46056
|
+
const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
|
|
46057
|
+
const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
|
|
46058
|
+
if (!normalizedPath) return void 0;
|
|
46059
|
+
if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
|
|
46060
|
+
if (!normalizedRoot) return void 0;
|
|
46061
|
+
return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
|
|
46062
|
+
}
|
|
46063
|
+
function readGitSubmodules(value, parentRepoRoot) {
|
|
46064
|
+
if (!Array.isArray(value)) return void 0;
|
|
46065
|
+
const submodules = value.map((entry) => {
|
|
46066
|
+
const submodule = readObjectRecord(entry);
|
|
46067
|
+
const path28 = readStringValue(submodule.path);
|
|
46068
|
+
const commit = readStringValue(submodule.commit);
|
|
46069
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path28);
|
|
46070
|
+
if (!path28 || !commit || !repoPath) return null;
|
|
46071
|
+
return {
|
|
46072
|
+
path: path28,
|
|
46073
|
+
commit,
|
|
46074
|
+
repoPath,
|
|
46075
|
+
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
46076
|
+
outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
46077
|
+
lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
|
|
46078
|
+
...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
|
|
46079
|
+
};
|
|
46080
|
+
}).filter((entry) => entry !== null);
|
|
46081
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
46082
|
+
}
|
|
46083
|
+
function normalizeInlineMeshGitStatus(status, node, options) {
|
|
45856
46084
|
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
45857
46085
|
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
45858
46086
|
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
45859
46087
|
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
45860
46088
|
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
46089
|
+
const repoRoot = readStringValue(status.repoRoot, status.repo_root, node?.repoRoot, node?.repo_root, status.workspace, node?.workspace) || void 0;
|
|
46090
|
+
const submodules = readGitSubmodules(status.submodules, repoRoot);
|
|
45861
46091
|
return {
|
|
45862
46092
|
workspace: readStringValue(status.workspace, node?.workspace) || "",
|
|
45863
|
-
repoRoot:
|
|
46093
|
+
repoRoot: repoRoot ?? null,
|
|
45864
46094
|
isGitRepo,
|
|
45865
46095
|
branch: readStringValue(status.branch) ?? null,
|
|
45866
46096
|
headCommit: readStringValue(status.headCommit) ?? null,
|
|
@@ -45876,29 +46106,407 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45876
46106
|
hasConflicts,
|
|
45877
46107
|
conflictFiles,
|
|
45878
46108
|
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
45879
|
-
lastCheckedAt: Date.now()
|
|
46109
|
+
lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
|
|
46110
|
+
...submodules ? { submodules } : {}
|
|
46111
|
+
};
|
|
46112
|
+
}
|
|
46113
|
+
function buildInlineMeshTransitGitStatus(node) {
|
|
46114
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
46115
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
46116
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
46117
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
46118
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
46119
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
46120
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
46121
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
46122
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
46123
|
+
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46124
|
+
return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
|
|
46125
|
+
}
|
|
46126
|
+
function recordInlineMeshDirectGitTruth(node, git, source) {
|
|
46127
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return;
|
|
46128
|
+
const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
|
|
46129
|
+
const updatedAt = new Date(checkedAt).toISOString();
|
|
46130
|
+
const nextGit = {
|
|
46131
|
+
...git,
|
|
46132
|
+
lastCheckedAt: checkedAt
|
|
46133
|
+
};
|
|
46134
|
+
node.lastGit = {
|
|
46135
|
+
source,
|
|
46136
|
+
checkedAt,
|
|
46137
|
+
status: nextGit
|
|
46138
|
+
};
|
|
46139
|
+
node.last_git = node.lastGit;
|
|
46140
|
+
node.machineStatus = "online";
|
|
46141
|
+
node.updatedAt = updatedAt;
|
|
46142
|
+
node.lastSeenAt = updatedAt;
|
|
46143
|
+
const repoRoot = readStringValue(nextGit.repoRoot);
|
|
46144
|
+
if (repoRoot && !readStringValue(node.repoRoot)) node.repoRoot = repoRoot;
|
|
46145
|
+
}
|
|
46146
|
+
function buildCachedInlineMeshGitStatus(node) {
|
|
46147
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46148
|
+
if (liveGit) return liveGit;
|
|
46149
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46150
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46151
|
+
if (!Object.keys(cachedGit).length) return void 0;
|
|
46152
|
+
return normalizeInlineMeshGitStatus(cachedGit, node);
|
|
46153
|
+
}
|
|
46154
|
+
function shouldDiscardCachedInlineMeshStatus(node) {
|
|
46155
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46156
|
+
if (!Object.keys(cachedStatus).length) return false;
|
|
46157
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46158
|
+
const workspaceError = readStringValue(cachedStatus.error, node?.error);
|
|
46159
|
+
if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
|
|
46160
|
+
const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
|
|
46161
|
+
const branch = readStringValue(cachedGit.branch);
|
|
46162
|
+
const headCommit = readStringValue(cachedGit.headCommit);
|
|
46163
|
+
return isGitRepo === false && !branch && !headCommit;
|
|
46164
|
+
}
|
|
46165
|
+
function stripInlineMeshTransientNodeState(node) {
|
|
46166
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
46167
|
+
const {
|
|
46168
|
+
cachedStatus,
|
|
46169
|
+
lastGit: _lastGit,
|
|
46170
|
+
last_git: _lastGitLegacy,
|
|
46171
|
+
lastProbe: _lastProbe,
|
|
46172
|
+
last_probe: _lastProbeLegacy,
|
|
46173
|
+
error: _error,
|
|
46174
|
+
health: _health,
|
|
46175
|
+
machineStatus: _machineStatus,
|
|
46176
|
+
lastSeenAt: _lastSeenAt,
|
|
46177
|
+
last_seen_at: _lastSeenAtLegacy,
|
|
46178
|
+
updatedAt: _updatedAt,
|
|
46179
|
+
updated_at: _updatedAtLegacy,
|
|
46180
|
+
activeSession: _activeSession,
|
|
46181
|
+
active_session: _activeSessionLegacy,
|
|
46182
|
+
activeSessionId: _activeSessionId,
|
|
46183
|
+
active_session_id: _activeSessionIdLegacy,
|
|
46184
|
+
sessionId: _sessionId,
|
|
46185
|
+
session_id: _sessionIdLegacy,
|
|
46186
|
+
providerType: _providerType,
|
|
46187
|
+
provider_type: _providerTypeLegacy,
|
|
46188
|
+
...rest
|
|
46189
|
+
} = node;
|
|
46190
|
+
if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
|
|
46191
|
+
return { ...rest, cachedStatus };
|
|
46192
|
+
}
|
|
46193
|
+
return rest;
|
|
46194
|
+
}
|
|
46195
|
+
function hasInlineMeshTransientNodeState(node) {
|
|
46196
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return false;
|
|
46197
|
+
return "cachedStatus" in node || "lastGit" in node || "last_git" in node || "lastProbe" in node || "last_probe" in node || "error" in node || "health" in node || "machineStatus" in node || "lastSeenAt" in node || "last_seen_at" in node || "updatedAt" in node || "updated_at" in node || "activeSession" in node || "active_session" in node || "activeSessionId" in node || "active_session_id" in node || "sessionId" in node || "session_id" in node || "providerType" in node || "provider_type" in node;
|
|
46198
|
+
}
|
|
46199
|
+
function readInlineMeshNodeId(node) {
|
|
46200
|
+
return readStringValue(node?.id, node?.nodeId) || "";
|
|
46201
|
+
}
|
|
46202
|
+
function sanitizeInlineMesh(inlineMesh) {
|
|
46203
|
+
if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
|
|
46204
|
+
if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
|
|
46205
|
+
let changed = false;
|
|
46206
|
+
const nodes = inlineMesh.nodes.map((node) => {
|
|
46207
|
+
if (!hasInlineMeshTransientNodeState(node)) return node;
|
|
46208
|
+
changed = true;
|
|
46209
|
+
return stripInlineMeshTransientNodeState(node);
|
|
46210
|
+
});
|
|
46211
|
+
if (!changed) return inlineMesh;
|
|
46212
|
+
return {
|
|
46213
|
+
...inlineMesh,
|
|
46214
|
+
nodes
|
|
46215
|
+
};
|
|
46216
|
+
}
|
|
46217
|
+
function reconcileInlineMeshCache(cached2, incoming) {
|
|
46218
|
+
if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
|
|
46219
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
|
|
46220
|
+
const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
|
|
46221
|
+
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
46222
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
|
|
46223
|
+
const incomingById = /* @__PURE__ */ new Map();
|
|
46224
|
+
for (const node of incomingNodes) {
|
|
46225
|
+
const nodeId = readInlineMeshNodeId(node);
|
|
46226
|
+
if (nodeId) incomingById.set(nodeId, node);
|
|
46227
|
+
}
|
|
46228
|
+
const nodes = cachedNodes.map((cachedNode) => {
|
|
46229
|
+
const nodeId = readInlineMeshNodeId(cachedNode);
|
|
46230
|
+
const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
|
|
46231
|
+
if (!incomingNode) return cachedNode;
|
|
46232
|
+
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
46233
|
+
return { ...cachedNode, ...incomingNode };
|
|
46234
|
+
}
|
|
46235
|
+
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
46236
|
+
});
|
|
46237
|
+
return {
|
|
46238
|
+
...cached2,
|
|
46239
|
+
...incoming,
|
|
46240
|
+
nodes
|
|
46241
|
+
};
|
|
46242
|
+
}
|
|
46243
|
+
function hasGitWorktreeChanges(git) {
|
|
46244
|
+
if (!git) return false;
|
|
46245
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
46246
|
+
}
|
|
46247
|
+
function getGitSubmoduleDriftState(git) {
|
|
46248
|
+
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
46249
|
+
let dirty = false;
|
|
46250
|
+
let outOfSync = false;
|
|
46251
|
+
for (const entry of submodules) {
|
|
46252
|
+
const submodule = readObjectRecord(entry);
|
|
46253
|
+
if (readBooleanValue(submodule.dirty) === true) dirty = true;
|
|
46254
|
+
if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
|
|
46255
|
+
}
|
|
46256
|
+
return { dirty, outOfSync };
|
|
46257
|
+
}
|
|
46258
|
+
function deriveMeshNodeHealthFromGit(git) {
|
|
46259
|
+
if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
|
|
46260
|
+
const branch = readStringValue(git.branch);
|
|
46261
|
+
if (!branch) return "degraded";
|
|
46262
|
+
const submoduleDrift = getGitSubmoduleDriftState(git);
|
|
46263
|
+
if (submoduleDrift.outOfSync) return "degraded";
|
|
46264
|
+
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
46265
|
+
return "online";
|
|
46266
|
+
}
|
|
46267
|
+
function readCachedInlineMeshActiveSessions(node) {
|
|
46268
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46269
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46270
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46271
|
+
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
46272
|
+
return sessionId ? [sessionId] : [];
|
|
46273
|
+
}
|
|
46274
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
46275
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46276
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46277
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46278
|
+
const sessionId = readStringValue(
|
|
46279
|
+
fallbackSession.id,
|
|
46280
|
+
fallbackSession.sessionId,
|
|
46281
|
+
fallbackSession.session_id,
|
|
46282
|
+
node?.activeSessionId,
|
|
46283
|
+
node?.active_session_id,
|
|
46284
|
+
node?.sessionId,
|
|
46285
|
+
node?.session_id
|
|
46286
|
+
);
|
|
46287
|
+
if (!sessionId) return [];
|
|
46288
|
+
return [{
|
|
46289
|
+
sessionId,
|
|
46290
|
+
providerType: readStringValue(
|
|
46291
|
+
fallbackSession.providerType,
|
|
46292
|
+
fallbackSession.provider_type,
|
|
46293
|
+
fallbackSession.cliType,
|
|
46294
|
+
fallbackSession.cli_type,
|
|
46295
|
+
fallbackSession.provider,
|
|
46296
|
+
node?.providerType,
|
|
46297
|
+
node?.provider_type
|
|
46298
|
+
),
|
|
46299
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
46300
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
46301
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
46302
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
46303
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
46304
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
46305
|
+
isCached: true
|
|
46306
|
+
}];
|
|
46307
|
+
}
|
|
46308
|
+
function readLiveMeshSessionState(record2) {
|
|
46309
|
+
return readStringValue(
|
|
46310
|
+
record2?.meta?.sessionStatus,
|
|
46311
|
+
record2?.meta?.status,
|
|
46312
|
+
record2?.meta?.providerStatus,
|
|
46313
|
+
record2?.status,
|
|
46314
|
+
record2?.state,
|
|
46315
|
+
record2?.lifecycle
|
|
46316
|
+
);
|
|
46317
|
+
}
|
|
46318
|
+
function toIsoTimestamp(value) {
|
|
46319
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
46320
|
+
const stringValue = readStringValue(value);
|
|
46321
|
+
return stringValue || null;
|
|
46322
|
+
}
|
|
46323
|
+
function synthesizeMeshNodeFreshnessFromConnection(status) {
|
|
46324
|
+
const connection = readObjectRecord(status.connection);
|
|
46325
|
+
const connectionFreshAt = toIsoTimestamp(connection.lastCommandAt ?? connection.lastConnectedAt ?? connection.lastStateChangeAt);
|
|
46326
|
+
const git = readObjectRecord(status.git);
|
|
46327
|
+
const gitCheckedAt = toIsoTimestamp(git.lastCheckedAt);
|
|
46328
|
+
if (!status.lastSeenAt && connectionFreshAt) status.lastSeenAt = connectionFreshAt;
|
|
46329
|
+
if (!status.updatedAt && (gitCheckedAt || connectionFreshAt)) {
|
|
46330
|
+
status.updatedAt = gitCheckedAt ?? connectionFreshAt;
|
|
46331
|
+
}
|
|
46332
|
+
}
|
|
46333
|
+
function finalizeMeshNodeStatus(args) {
|
|
46334
|
+
const { status, node, daemonId, isSelfNode } = args;
|
|
46335
|
+
if (!readStringValue(status.machineStatus)) {
|
|
46336
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46337
|
+
const machineStatus = readStringValue(cachedStatus.machineStatus, cachedStatus.machine_status, node?.machineStatus);
|
|
46338
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46339
|
+
}
|
|
46340
|
+
synthesizeMeshNodeFreshnessFromConnection(status);
|
|
46341
|
+
const connectionState = readStringValue(readObjectRecord(status.connection).state);
|
|
46342
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
|
|
46343
|
+
}
|
|
46344
|
+
async function probeRemoteMeshGitStatus(args) {
|
|
46345
|
+
if (!args.dispatchMeshCommand) return null;
|
|
46346
|
+
const remoteResult = await Promise.race([
|
|
46347
|
+
args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
|
|
46348
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
|
|
46349
|
+
]);
|
|
46350
|
+
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
46351
|
+
return remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean" ? remoteGit : null;
|
|
46352
|
+
}
|
|
46353
|
+
async function hydrateInlineMeshDirectTruth(args) {
|
|
46354
|
+
const nodes = Array.isArray(args.mesh?.nodes) ? args.mesh.nodes : [];
|
|
46355
|
+
if (!nodes.length) {
|
|
46356
|
+
return {
|
|
46357
|
+
directEvidenceCount: 0,
|
|
46358
|
+
localConfirmedCount: 0,
|
|
46359
|
+
peerAttemptedCount: 0,
|
|
46360
|
+
peerConfirmedCount: 0,
|
|
46361
|
+
unavailableNodeIds: []
|
|
46362
|
+
};
|
|
46363
|
+
}
|
|
46364
|
+
const selectedCoordinatorNodeId = readStringValue(
|
|
46365
|
+
args.mesh?.coordinator?.preferredNodeId,
|
|
46366
|
+
nodes[0]?.id,
|
|
46367
|
+
nodes[0]?.nodeId
|
|
46368
|
+
);
|
|
46369
|
+
let localConfirmedCount = 0;
|
|
46370
|
+
let peerAttemptedCount = 0;
|
|
46371
|
+
let peerConfirmedCount = 0;
|
|
46372
|
+
const unavailableNodeIds = [];
|
|
46373
|
+
for (const [nodeIndex, node] of nodes.entries()) {
|
|
46374
|
+
const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
|
|
46375
|
+
const workspace = readStringValue(node?.workspace);
|
|
46376
|
+
const daemonId = readStringValue(node?.daemonId);
|
|
46377
|
+
const isSelfNode = Boolean(
|
|
46378
|
+
nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
|
|
46379
|
+
) || Boolean(
|
|
46380
|
+
daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
|
|
46381
|
+
) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
|
|
46382
|
+
if (!workspace) {
|
|
46383
|
+
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
46384
|
+
continue;
|
|
46385
|
+
}
|
|
46386
|
+
if (isSelfNode && fs10.existsSync(workspace)) {
|
|
46387
|
+
try {
|
|
46388
|
+
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
46389
|
+
if (localGit?.isGitRepo) {
|
|
46390
|
+
recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
|
|
46391
|
+
localConfirmedCount += 1;
|
|
46392
|
+
continue;
|
|
46393
|
+
}
|
|
46394
|
+
} catch {
|
|
46395
|
+
}
|
|
46396
|
+
}
|
|
46397
|
+
if (!daemonId || !args.dispatchMeshCommand) {
|
|
46398
|
+
if (!isSelfNode) unavailableNodeIds.push(nodeId);
|
|
46399
|
+
continue;
|
|
46400
|
+
}
|
|
46401
|
+
peerAttemptedCount += 1;
|
|
46402
|
+
try {
|
|
46403
|
+
const remoteGit = await probeRemoteMeshGitStatus({
|
|
46404
|
+
dispatchMeshCommand: args.dispatchMeshCommand,
|
|
46405
|
+
daemonId,
|
|
46406
|
+
workspace,
|
|
46407
|
+
timeoutMs: 8e3
|
|
46408
|
+
});
|
|
46409
|
+
if (remoteGit) {
|
|
46410
|
+
recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
46411
|
+
peerConfirmedCount += 1;
|
|
46412
|
+
continue;
|
|
46413
|
+
}
|
|
46414
|
+
} catch {
|
|
46415
|
+
}
|
|
46416
|
+
unavailableNodeIds.push(nodeId);
|
|
46417
|
+
}
|
|
46418
|
+
return {
|
|
46419
|
+
directEvidenceCount: localConfirmedCount + peerConfirmedCount,
|
|
46420
|
+
localConfirmedCount,
|
|
46421
|
+
peerAttemptedCount,
|
|
46422
|
+
peerConfirmedCount,
|
|
46423
|
+
unavailableNodeIds
|
|
45880
46424
|
};
|
|
45881
46425
|
}
|
|
45882
|
-
function
|
|
46426
|
+
function summarizeMeshSessionRecord(record2) {
|
|
46427
|
+
return {
|
|
46428
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
46429
|
+
providerType: readStringValue(record2?.providerType),
|
|
46430
|
+
state: readLiveMeshSessionState(record2),
|
|
46431
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
46432
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
46433
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
46434
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
46435
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
46436
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
46437
|
+
isCached: false
|
|
46438
|
+
};
|
|
46439
|
+
}
|
|
46440
|
+
function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
|
|
46441
|
+
const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
|
|
46442
|
+
if (!recordNodeId || recordNodeId !== nodeId) return false;
|
|
46443
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46444
|
+
return !recordMeshId || recordMeshId === meshId;
|
|
46445
|
+
}
|
|
46446
|
+
function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
|
|
46447
|
+
const recordWorkspace = readStringValue(record2?.workspace);
|
|
46448
|
+
if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
|
|
46449
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46450
|
+
if (recordMeshId) return recordMeshId === meshId;
|
|
46451
|
+
return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
|
|
46452
|
+
}
|
|
46453
|
+
function readLiveMeshNodeWorkspace(args) {
|
|
46454
|
+
const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
|
|
46455
|
+
if (directNodeWorkspace) {
|
|
46456
|
+
return readStringValue(directNodeWorkspace.workspace) || "";
|
|
46457
|
+
}
|
|
46458
|
+
if (args.allowCoordinatorSession) {
|
|
46459
|
+
const coordinatorWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record2?.workspace));
|
|
46460
|
+
if (coordinatorWorkspace) {
|
|
46461
|
+
return readStringValue(coordinatorWorkspace.workspace) || "";
|
|
46462
|
+
}
|
|
46463
|
+
}
|
|
46464
|
+
return "";
|
|
46465
|
+
}
|
|
46466
|
+
function collectLiveMeshSessionRecords(args) {
|
|
46467
|
+
const matches = args.liveSessionRecords.filter((record2) => {
|
|
46468
|
+
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
46469
|
+
if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
|
|
46470
|
+
return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
|
|
46471
|
+
});
|
|
46472
|
+
if (args.allowCoordinatorSession) {
|
|
46473
|
+
for (const record2 of args.liveSessionRecords) {
|
|
46474
|
+
if (readStringValue(record2?.meta?.meshCoordinatorFor) !== args.meshId) continue;
|
|
46475
|
+
const sessionId = readStringValue(record2?.sessionId);
|
|
46476
|
+
if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
|
|
46477
|
+
matches.push(record2);
|
|
46478
|
+
}
|
|
46479
|
+
}
|
|
46480
|
+
return matches;
|
|
46481
|
+
}
|
|
46482
|
+
function applyCachedInlineMeshNodeStatus(status, node, options) {
|
|
45883
46483
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
45884
|
-
const
|
|
45885
|
-
const
|
|
45886
|
-
const
|
|
46484
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46485
|
+
const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
|
|
46486
|
+
const error48 = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
|
|
46487
|
+
const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
|
|
45887
46488
|
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
45888
|
-
|
|
45889
|
-
|
|
46489
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
46490
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
46491
|
+
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
46492
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
46493
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
45890
46494
|
if (git) status.git = git;
|
|
45891
46495
|
if (error48) status.error = error48;
|
|
46496
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46497
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
46498
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
46499
|
+
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
46500
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
45892
46501
|
if (health) {
|
|
45893
46502
|
status.health = health;
|
|
45894
46503
|
return true;
|
|
45895
46504
|
}
|
|
45896
46505
|
if (git) {
|
|
45897
|
-
|
|
45898
|
-
status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
|
|
46506
|
+
status.health = deriveMeshNodeHealthFromGit(git);
|
|
45899
46507
|
return true;
|
|
45900
46508
|
}
|
|
45901
|
-
return
|
|
46509
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
45902
46510
|
}
|
|
45903
46511
|
async function resolveProviderTypeFromPriority(args) {
|
|
45904
46512
|
if (!args.providerPriority.length) {
|
|
@@ -45936,7 +46544,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45936
46544
|
}
|
|
45937
46545
|
function readPackageScripts(workspace) {
|
|
45938
46546
|
try {
|
|
45939
|
-
const packageJsonPath = (0,
|
|
46547
|
+
const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
|
|
45940
46548
|
const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
|
|
45941
46549
|
return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
|
|
45942
46550
|
} catch {
|
|
@@ -46144,13 +46752,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46144
46752
|
}
|
|
46145
46753
|
function resolveHermesUserHome() {
|
|
46146
46754
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
46147
|
-
return explicitHome || (0,
|
|
46755
|
+
return explicitHome || (0, import_path7.join)((0, import_os3.homedir)(), ".hermes");
|
|
46148
46756
|
}
|
|
46149
46757
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
46150
46758
|
const sourceHome = resolveHermesUserHome();
|
|
46151
|
-
const sourceConfigPath = (0,
|
|
46759
|
+
const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
|
|
46152
46760
|
if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46153
|
-
if ((0,
|
|
46761
|
+
if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46154
46762
|
const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
46155
46763
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
46156
46764
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -46184,10 +46792,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46184
46792
|
return sanitized;
|
|
46185
46793
|
}
|
|
46186
46794
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
46187
|
-
if ((0,
|
|
46795
|
+
if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
|
|
46188
46796
|
for (const fileName of [".env", "auth.json"]) {
|
|
46189
|
-
const sourcePath = (0,
|
|
46190
|
-
const targetPath = (0,
|
|
46797
|
+
const sourcePath = (0, import_path7.join)(sourceHome, fileName);
|
|
46798
|
+
const targetPath = (0, import_path7.join)(targetHome, fileName);
|
|
46191
46799
|
if (!fs10.existsSync(sourcePath)) continue;
|
|
46192
46800
|
try {
|
|
46193
46801
|
fs10.copyFileSync(sourcePath, targetPath);
|
|
@@ -46296,25 +46904,40 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46296
46904
|
}
|
|
46297
46905
|
getCachedInlineMesh(meshId, inlineMesh) {
|
|
46298
46906
|
if (inlineMesh && typeof inlineMesh === "object") {
|
|
46299
|
-
this.
|
|
46300
|
-
return inlineMesh;
|
|
46907
|
+
return this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46301
46908
|
}
|
|
46302
46909
|
return this.inlineMeshCache.get(meshId);
|
|
46303
46910
|
}
|
|
46911
|
+
warmInlineMeshCache(meshId, inlineMesh) {
|
|
46912
|
+
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
46913
|
+
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
|
|
46914
|
+
const cached2 = this.inlineMeshCache.get(meshId);
|
|
46915
|
+
if (cached2) {
|
|
46916
|
+
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
46917
|
+
this.inlineMeshCache.set(meshId, merged);
|
|
46918
|
+
return merged;
|
|
46919
|
+
}
|
|
46920
|
+
this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
|
|
46921
|
+
return sanitizedInlineMesh;
|
|
46922
|
+
}
|
|
46304
46923
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
46305
46924
|
const preferInline = options?.preferInline === true;
|
|
46306
46925
|
if (preferInline) {
|
|
46307
|
-
const cached22 = this.getCachedInlineMesh(meshId
|
|
46308
|
-
if (cached22) return { mesh: cached22, inline: true };
|
|
46926
|
+
const cached22 = this.getCachedInlineMesh(meshId);
|
|
46927
|
+
if (cached22) return { mesh: cached22, inline: true, source: "inline_cache" };
|
|
46928
|
+
const warmedInline2 = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46929
|
+
if (warmedInline2) return { mesh: warmedInline2, inline: true, source: "inline_bootstrap" };
|
|
46309
46930
|
}
|
|
46310
46931
|
try {
|
|
46311
46932
|
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
46312
46933
|
const mesh = getMesh3(meshId);
|
|
46313
|
-
if (mesh) return { mesh, inline: false };
|
|
46934
|
+
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
46314
46935
|
} catch {
|
|
46315
46936
|
}
|
|
46316
|
-
const cached2 = this.getCachedInlineMesh(meshId
|
|
46317
|
-
|
|
46937
|
+
const cached2 = this.getCachedInlineMesh(meshId);
|
|
46938
|
+
if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
|
|
46939
|
+
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46940
|
+
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
46318
46941
|
}
|
|
46319
46942
|
updateInlineMeshNode(meshId, mesh, node) {
|
|
46320
46943
|
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
@@ -46379,7 +47002,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46379
47002
|
}
|
|
46380
47003
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
46381
47004
|
const normalizePath = (value) => {
|
|
46382
|
-
const resolved = (0,
|
|
47005
|
+
const resolved = (0, import_path7.resolve)(value);
|
|
46383
47006
|
try {
|
|
46384
47007
|
return fs10.realpathSync(resolved);
|
|
46385
47008
|
} catch {
|
|
@@ -46543,6 +47166,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46543
47166
|
const deletedSessionIds = [];
|
|
46544
47167
|
const skippedSessionIds = [];
|
|
46545
47168
|
const skippedLiveSessionIds = [];
|
|
47169
|
+
const skippedCoordinatorSessionIds = [];
|
|
46546
47170
|
const deleteUnsupportedSessionIds = [];
|
|
46547
47171
|
const recordsRemainSessionIds = [];
|
|
46548
47172
|
const errors = [];
|
|
@@ -46575,6 +47199,12 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46575
47199
|
const completed = this.isCompletedHostedSession(record2);
|
|
46576
47200
|
const surfaceKind = getSessionHostSurfaceKind(record2);
|
|
46577
47201
|
const liveRuntime = surfaceKind === "live_runtime";
|
|
47202
|
+
const coordinatorSession = readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId;
|
|
47203
|
+
if (!hasExplicitSessionIds && coordinatorSession) {
|
|
47204
|
+
skippedSessionIds.push(sessionId);
|
|
47205
|
+
skippedCoordinatorSessionIds.push(sessionId);
|
|
47206
|
+
continue;
|
|
47207
|
+
}
|
|
46578
47208
|
if (!hasExplicitSessionIds && liveRuntime) {
|
|
46579
47209
|
skippedSessionIds.push(sessionId);
|
|
46580
47210
|
skippedLiveSessionIds.push(sessionId);
|
|
@@ -46640,6 +47270,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46640
47270
|
deletedSessionIds,
|
|
46641
47271
|
skippedSessionIds,
|
|
46642
47272
|
skippedLiveSessionIds,
|
|
47273
|
+
skippedCoordinatorSessionIds,
|
|
46643
47274
|
...deleteUnsupported ? {
|
|
46644
47275
|
deleteUnsupported: true,
|
|
46645
47276
|
effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
|
|
@@ -46772,7 +47403,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46772
47403
|
return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
|
|
46773
47404
|
}
|
|
46774
47405
|
case "get_pending_mesh_events": {
|
|
46775
|
-
const
|
|
47406
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47407
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
|
|
46776
47408
|
return { success: true, events };
|
|
46777
47409
|
}
|
|
46778
47410
|
case "launch_cli":
|
|
@@ -47301,15 +47933,39 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
47301
47933
|
case "get_mesh": {
|
|
47302
47934
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47303
47935
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
47304
|
-
|
|
47305
|
-
|
|
47306
|
-
|
|
47307
|
-
|
|
47308
|
-
|
|
47936
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
47937
|
+
if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
|
|
47938
|
+
const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
|
|
47939
|
+
const directTruth = await hydrateInlineMeshDirectTruth({
|
|
47940
|
+
mesh: meshRecord.mesh,
|
|
47941
|
+
meshSource: meshRecord.source,
|
|
47942
|
+
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
47943
|
+
statusInstanceId: this.deps.statusInstanceId,
|
|
47944
|
+
localMachineId: loadConfig2().machineId || ""
|
|
47945
|
+
});
|
|
47946
|
+
const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
|
|
47947
|
+
const sourceOfTruth = {
|
|
47948
|
+
membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
47949
|
+
coordinatorOwnsLiveTruth: directTruthSatisfied,
|
|
47950
|
+
directPeerTruth: {
|
|
47951
|
+
required: requireDirectPeerTruth,
|
|
47952
|
+
satisfied: directTruthSatisfied,
|
|
47953
|
+
directEvidenceCount: directTruth.directEvidenceCount,
|
|
47954
|
+
localConfirmedCount: directTruth.localConfirmedCount,
|
|
47955
|
+
peerAttemptedCount: directTruth.peerAttemptedCount,
|
|
47956
|
+
peerConfirmedCount: directTruth.peerConfirmedCount,
|
|
47957
|
+
unavailableNodeIds: directTruth.unavailableNodeIds
|
|
47958
|
+
}
|
|
47959
|
+
};
|
|
47960
|
+
if (requireDirectPeerTruth && !directTruthSatisfied) {
|
|
47961
|
+
return {
|
|
47962
|
+
success: false,
|
|
47963
|
+
code: "mesh_direct_peer_truth_unavailable",
|
|
47964
|
+
error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
|
|
47965
|
+
sourceOfTruth
|
|
47966
|
+
};
|
|
47309
47967
|
}
|
|
47310
|
-
|
|
47311
|
-
if (cached2) return { success: true, mesh: cached2 };
|
|
47312
|
-
return { success: false, error: "Mesh not found" };
|
|
47968
|
+
return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
|
|
47313
47969
|
}
|
|
47314
47970
|
case "create_mesh": {
|
|
47315
47971
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
@@ -47830,7 +48486,14 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
47830
48486
|
cliType
|
|
47831
48487
|
};
|
|
47832
48488
|
}
|
|
47833
|
-
const
|
|
48489
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48490
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48491
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
48492
|
+
meshId,
|
|
48493
|
+
nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
|
|
48494
|
+
liveSessionRecords: liveMeshSessions,
|
|
48495
|
+
allowCoordinatorSession: true
|
|
48496
|
+
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
47834
48497
|
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
47835
48498
|
if (!cliType) {
|
|
47836
48499
|
const resolved = await resolveProviderTypeFromPriority({
|
|
@@ -47992,7 +48655,7 @@ ${block}`);
|
|
|
47992
48655
|
workspace
|
|
47993
48656
|
};
|
|
47994
48657
|
}
|
|
47995
|
-
const { existsSync:
|
|
48658
|
+
const { existsSync: existsSync26, readFileSync: readFileSync18, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
|
|
47996
48659
|
const { dirname: dirname9 } = await import("path");
|
|
47997
48660
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
47998
48661
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -48035,14 +48698,14 @@ ${block}`);
|
|
|
48035
48698
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
48036
48699
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
48037
48700
|
}
|
|
48038
|
-
const hadExistingMcpConfig =
|
|
48701
|
+
const hadExistingMcpConfig = existsSync26(mcpConfigPath);
|
|
48039
48702
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
48040
48703
|
if (hermesBaseConfig) {
|
|
48041
48704
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
48042
48705
|
}
|
|
48043
48706
|
if (hadExistingMcpConfig) {
|
|
48044
48707
|
try {
|
|
48045
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
48708
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync18(mcpConfigPath, "utf-8"), configFormat);
|
|
48046
48709
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
48047
48710
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
48048
48711
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -48138,92 +48801,184 @@ ${block}`);
|
|
|
48138
48801
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48139
48802
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
48140
48803
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
48804
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48805
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48806
|
+
const localMachineId = loadConfig2().machineId || "";
|
|
48807
|
+
const selectedCoordinatorNodeId = readStringValue(
|
|
48808
|
+
mesh.coordinator?.preferredNodeId,
|
|
48809
|
+
mesh.nodes?.[0]?.id,
|
|
48810
|
+
mesh.nodes?.[0]?.nodeId
|
|
48811
|
+
);
|
|
48812
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
48813
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48141
48814
|
const nodeStatuses = [];
|
|
48142
|
-
for (const node of mesh.nodes || []) {
|
|
48815
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
48816
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
48817
|
+
const daemonId = readStringValue(node.daemonId);
|
|
48818
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
48819
|
+
const isSelfNode = Boolean(
|
|
48820
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
48821
|
+
) || Boolean(
|
|
48822
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
48823
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
48143
48824
|
const status = {
|
|
48144
|
-
nodeId
|
|
48825
|
+
nodeId,
|
|
48145
48826
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
48146
48827
|
workspace: node.workspace,
|
|
48147
48828
|
repoRoot: node.repoRoot,
|
|
48148
48829
|
isLocalWorktree: node.isLocalWorktree,
|
|
48149
48830
|
worktreeBranch: node.worktreeBranch,
|
|
48150
|
-
daemonId
|
|
48831
|
+
daemonId,
|
|
48151
48832
|
machineId: node.machineId,
|
|
48833
|
+
machineStatus: node.machineStatus,
|
|
48152
48834
|
health: "unknown",
|
|
48153
48835
|
providers: node.providers || [],
|
|
48154
|
-
|
|
48836
|
+
providerPriority,
|
|
48837
|
+
activeSessions: [],
|
|
48838
|
+
activeSessionDetails: [],
|
|
48839
|
+
launchReady: false
|
|
48155
48840
|
};
|
|
48156
|
-
if (
|
|
48157
|
-
|
|
48158
|
-
|
|
48159
|
-
|
|
48841
|
+
if (isSelfNode) {
|
|
48842
|
+
status.connection = {
|
|
48843
|
+
perspective: "selected_coordinator",
|
|
48844
|
+
source: "mesh_peer_status",
|
|
48845
|
+
state: "self",
|
|
48846
|
+
transport: "local",
|
|
48847
|
+
reported: true,
|
|
48848
|
+
reason: "Selected coordinator daemon",
|
|
48849
|
+
lastStateChangeAt: refreshedAt
|
|
48850
|
+
};
|
|
48851
|
+
} else if (daemonId) {
|
|
48852
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
48853
|
+
status.connection = connection ?? {
|
|
48854
|
+
perspective: "selected_coordinator",
|
|
48855
|
+
source: "not_reported",
|
|
48856
|
+
state: "unknown",
|
|
48857
|
+
transport: "unknown",
|
|
48858
|
+
reported: false,
|
|
48859
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
48860
|
+
};
|
|
48861
|
+
} else {
|
|
48862
|
+
status.connection = {
|
|
48863
|
+
perspective: "selected_coordinator",
|
|
48864
|
+
source: "not_reported",
|
|
48865
|
+
state: "unknown",
|
|
48866
|
+
transport: "unknown",
|
|
48867
|
+
reported: false,
|
|
48868
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
48869
|
+
};
|
|
48870
|
+
}
|
|
48871
|
+
const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
|
|
48872
|
+
meshId,
|
|
48873
|
+
node,
|
|
48874
|
+
nodeId,
|
|
48875
|
+
liveSessionRecords: liveMeshSessions,
|
|
48876
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
48877
|
+
});
|
|
48878
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
48879
|
+
meshId,
|
|
48880
|
+
nodeId,
|
|
48881
|
+
liveSessionRecords: matchedLiveSessionRecords,
|
|
48882
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
48883
|
+
}) || (typeof node.workspace === "string" ? node.workspace : "");
|
|
48884
|
+
status.workspace = workspace || node.workspace;
|
|
48885
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
48886
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
48887
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
48888
|
+
status.activeSessions = sessionIds;
|
|
48889
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
48890
|
+
if (providerTypes.length > 0) {
|
|
48891
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
48160
48892
|
}
|
|
48161
|
-
|
|
48162
|
-
|
|
48163
|
-
|
|
48164
|
-
const
|
|
48165
|
-
|
|
48166
|
-
|
|
48167
|
-
|
|
48168
|
-
|
|
48169
|
-
|
|
48170
|
-
|
|
48171
|
-
|
|
48172
|
-
|
|
48173
|
-
|
|
48174
|
-
|
|
48175
|
-
|
|
48176
|
-
|
|
48177
|
-
|
|
48178
|
-
|
|
48179
|
-
|
|
48180
|
-
|
|
48181
|
-
|
|
48182
|
-
|
|
48183
|
-
|
|
48184
|
-
|
|
48893
|
+
}
|
|
48894
|
+
if (workspace) {
|
|
48895
|
+
if (!fs10.existsSync(workspace)) {
|
|
48896
|
+
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
48897
|
+
let remoteProbeApplied = false;
|
|
48898
|
+
if (inlineTransitGit) {
|
|
48899
|
+
status.git = inlineTransitGit;
|
|
48900
|
+
status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
|
|
48901
|
+
remoteProbeApplied = true;
|
|
48902
|
+
} else if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
|
|
48903
|
+
try {
|
|
48904
|
+
const remoteGit = await probeRemoteMeshGitStatus({
|
|
48905
|
+
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
48906
|
+
daemonId,
|
|
48907
|
+
workspace,
|
|
48908
|
+
timeoutMs: 8e3
|
|
48909
|
+
});
|
|
48910
|
+
if (remoteGit) {
|
|
48911
|
+
status.git = remoteGit;
|
|
48912
|
+
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
48913
|
+
recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
48914
|
+
remoteProbeApplied = true;
|
|
48915
|
+
}
|
|
48916
|
+
} catch {
|
|
48917
|
+
const refreshedConnection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
48918
|
+
const refreshedConnectionState = readStringValue(refreshedConnection?.state);
|
|
48919
|
+
if (refreshedConnection && refreshedConnectionState === "connected") {
|
|
48920
|
+
status.connection = refreshedConnection;
|
|
48921
|
+
try {
|
|
48922
|
+
const remoteGit = await probeRemoteMeshGitStatus({
|
|
48923
|
+
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
48924
|
+
daemonId,
|
|
48925
|
+
workspace,
|
|
48926
|
+
timeoutMs: 12e3
|
|
48927
|
+
});
|
|
48928
|
+
if (remoteGit) {
|
|
48929
|
+
status.git = remoteGit;
|
|
48930
|
+
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
48931
|
+
recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
48932
|
+
remoteProbeApplied = true;
|
|
48933
|
+
}
|
|
48934
|
+
} catch {
|
|
48935
|
+
}
|
|
48936
|
+
}
|
|
48185
48937
|
}
|
|
48186
48938
|
}
|
|
48187
|
-
|
|
48188
|
-
|
|
48189
|
-
|
|
48190
|
-
|
|
48191
|
-
|
|
48192
|
-
|
|
48193
|
-
|
|
48194
|
-
if (
|
|
48195
|
-
|
|
48196
|
-
|
|
48939
|
+
if (!remoteProbeApplied) {
|
|
48940
|
+
const connectionState = readStringValue(status.connection?.state);
|
|
48941
|
+
const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
|
|
48942
|
+
if (pendingPeerGitProbe) {
|
|
48943
|
+
status.gitProbePending = true;
|
|
48944
|
+
status.health = "unknown";
|
|
48945
|
+
}
|
|
48946
|
+
if (applyCachedInlineMeshNodeStatus(
|
|
48947
|
+
status,
|
|
48948
|
+
node,
|
|
48949
|
+
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
48950
|
+
)) {
|
|
48951
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
48952
|
+
nodeStatuses.push(status);
|
|
48953
|
+
continue;
|
|
48954
|
+
}
|
|
48955
|
+
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
48956
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
48957
|
+
nodeStatuses.push(status);
|
|
48958
|
+
continue;
|
|
48959
|
+
}
|
|
48197
48960
|
}
|
|
48198
|
-
|
|
48199
|
-
|
|
48200
|
-
|
|
48201
|
-
|
|
48202
|
-
|
|
48203
|
-
|
|
48204
|
-
|
|
48205
|
-
|
|
48206
|
-
|
|
48207
|
-
|
|
48208
|
-
|
|
48209
|
-
|
|
48210
|
-
|
|
48211
|
-
|
|
48212
|
-
|
|
48213
|
-
hasConflicts: false,
|
|
48214
|
-
conflictFiles: [],
|
|
48215
|
-
stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
|
|
48216
|
-
lastCheckedAt: Date.now()
|
|
48217
|
-
};
|
|
48218
|
-
status.health = branch ? dirty ? "dirty" : "online" : "degraded";
|
|
48219
|
-
} catch {
|
|
48220
|
-
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
48221
|
-
status.health = "degraded";
|
|
48961
|
+
} else {
|
|
48962
|
+
try {
|
|
48963
|
+
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
48964
|
+
status.git = gitStatus;
|
|
48965
|
+
recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
|
|
48966
|
+
if (gitStatus.isGitRepo) {
|
|
48967
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
48968
|
+
} else {
|
|
48969
|
+
status.health = "degraded";
|
|
48970
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
48971
|
+
}
|
|
48972
|
+
} catch {
|
|
48973
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
48974
|
+
status.health = "degraded";
|
|
48975
|
+
}
|
|
48222
48976
|
}
|
|
48223
48977
|
}
|
|
48224
48978
|
} else {
|
|
48225
48979
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
48226
48980
|
}
|
|
48981
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
48227
48982
|
nodeStatuses.push(status);
|
|
48228
48983
|
}
|
|
48229
48984
|
return {
|
|
@@ -48232,6 +48987,12 @@ ${block}`);
|
|
|
48232
48987
|
meshName: mesh.name,
|
|
48233
48988
|
repoIdentity: mesh.repoIdentity,
|
|
48234
48989
|
defaultBranch: mesh.defaultBranch,
|
|
48990
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48991
|
+
sourceOfTruth: {
|
|
48992
|
+
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
48993
|
+
coordinatorOwnsLiveTruth: meshRecord?.source !== "inline_bootstrap",
|
|
48994
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
48995
|
+
},
|
|
48235
48996
|
nodes: nodeStatuses,
|
|
48236
48997
|
queue: { tasks: queue, summary: queueSummary },
|
|
48237
48998
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -56107,6 +56868,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
56107
56868
|
sessionHostControl: config2.sessionHostControl,
|
|
56108
56869
|
statusInstanceId: config2.statusInstanceId,
|
|
56109
56870
|
statusVersion: config2.statusVersion,
|
|
56871
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
56110
56872
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
|
|
56111
56873
|
});
|
|
56112
56874
|
poller = new AgentStreamPoller({
|