@adhdev/daemon-standalone 0.9.82-rc.3 → 0.9.82-rc.30
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 +866 -292
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-BNKDsz6G.css +1 -0
- package/public/assets/index-qNy5VemC.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`);
|
|
24106
|
+
}
|
|
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
|
+
}
|
|
24115
|
+
}
|
|
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
|
+
}
|
|
24055
24136
|
}
|
|
24056
|
-
function getPendingMeshCoordinatorEvents() {
|
|
24057
|
-
|
|
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
|
+
}
|
|
24058
24153
|
}
|
|
24059
|
-
function clearPendingMeshCoordinatorEvents() {
|
|
24060
|
-
|
|
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,52 +46052,33 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45812
46052
|
}
|
|
45813
46053
|
return void 0;
|
|
45814
46054
|
}
|
|
45815
|
-
function
|
|
45816
|
-
|
|
45817
|
-
const
|
|
45818
|
-
|
|
45819
|
-
const
|
|
45820
|
-
const
|
|
45821
|
-
const
|
|
45822
|
-
|
|
45823
|
-
|
|
45824
|
-
|
|
45825
|
-
|
|
45826
|
-
|
|
45827
|
-
|
|
45828
|
-
|
|
45829
|
-
|
|
45830
|
-
|
|
45831
|
-
|
|
45832
|
-
|
|
45833
|
-
|
|
45834
|
-
|
|
45835
|
-
|
|
45836
|
-
untracked: readNumberValue(cachedGit.untracked) ?? 0,
|
|
45837
|
-
deleted: readNumberValue(cachedGit.deleted) ?? 0,
|
|
45838
|
-
renamed: readNumberValue(cachedGit.renamed) ?? 0,
|
|
45839
|
-
hasConflicts: hasConflicts2,
|
|
45840
|
-
conflictFiles: conflictFiles2,
|
|
45841
|
-
stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
|
|
45842
|
-
lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now()
|
|
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 readGitSubmodules(value) {
|
|
46056
|
+
if (!Array.isArray(value)) return void 0;
|
|
46057
|
+
const submodules = value.map((entry) => {
|
|
46058
|
+
const submodule = readObjectRecord(entry);
|
|
46059
|
+
const path28 = readStringValue(submodule.path);
|
|
46060
|
+
const commit = readStringValue(submodule.commit);
|
|
46061
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
|
|
46062
|
+
if (!path28 || !commit || !repoPath) return null;
|
|
46063
|
+
return {
|
|
46064
|
+
path: path28,
|
|
46065
|
+
commit,
|
|
46066
|
+
repoPath,
|
|
46067
|
+
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
46068
|
+
outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
46069
|
+
lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
|
|
46070
|
+
...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
|
|
46071
|
+
};
|
|
46072
|
+
}).filter((entry) => entry !== null);
|
|
46073
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
46074
|
+
}
|
|
46075
|
+
function normalizeInlineMeshGitStatus(status, node, options) {
|
|
45856
46076
|
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
45857
46077
|
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
45858
46078
|
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
45859
46079
|
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
45860
46080
|
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
46081
|
+
const submodules = readGitSubmodules(status.submodules);
|
|
45861
46082
|
return {
|
|
45862
46083
|
workspace: readStringValue(status.workspace, node?.workspace) || "",
|
|
45863
46084
|
repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
@@ -45876,29 +46097,285 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45876
46097
|
hasConflicts,
|
|
45877
46098
|
conflictFiles,
|
|
45878
46099
|
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
45879
|
-
lastCheckedAt: Date.now()
|
|
46100
|
+
lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
|
|
46101
|
+
...submodules ? { submodules } : {}
|
|
45880
46102
|
};
|
|
45881
46103
|
}
|
|
45882
|
-
function
|
|
46104
|
+
function buildInlineMeshTransitGitStatus(node) {
|
|
46105
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
46106
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
46107
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
46108
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
46109
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
46110
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
46111
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
46112
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
46113
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
46114
|
+
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46115
|
+
return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
|
|
46116
|
+
}
|
|
46117
|
+
function buildCachedInlineMeshGitStatus(node) {
|
|
46118
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46119
|
+
if (liveGit) return liveGit;
|
|
46120
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46121
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46122
|
+
if (!Object.keys(cachedGit).length) return void 0;
|
|
46123
|
+
return normalizeInlineMeshGitStatus(cachedGit, node);
|
|
46124
|
+
}
|
|
46125
|
+
function shouldDiscardCachedInlineMeshStatus(node) {
|
|
45883
46126
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
45884
|
-
|
|
45885
|
-
const
|
|
45886
|
-
const
|
|
46127
|
+
if (!Object.keys(cachedStatus).length) return false;
|
|
46128
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46129
|
+
const workspaceError = readStringValue(cachedStatus.error, node?.error);
|
|
46130
|
+
if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
|
|
46131
|
+
const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
|
|
46132
|
+
const branch = readStringValue(cachedGit.branch);
|
|
46133
|
+
const headCommit = readStringValue(cachedGit.headCommit);
|
|
46134
|
+
return isGitRepo === false && !branch && !headCommit;
|
|
46135
|
+
}
|
|
46136
|
+
function stripInlineMeshTransientNodeState(node) {
|
|
46137
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
46138
|
+
const {
|
|
46139
|
+
cachedStatus,
|
|
46140
|
+
lastGit: _lastGit,
|
|
46141
|
+
last_git: _lastGitLegacy,
|
|
46142
|
+
lastProbe: _lastProbe,
|
|
46143
|
+
last_probe: _lastProbeLegacy,
|
|
46144
|
+
error: _error,
|
|
46145
|
+
health: _health,
|
|
46146
|
+
machineStatus: _machineStatus,
|
|
46147
|
+
lastSeenAt: _lastSeenAt,
|
|
46148
|
+
last_seen_at: _lastSeenAtLegacy,
|
|
46149
|
+
updatedAt: _updatedAt,
|
|
46150
|
+
updated_at: _updatedAtLegacy,
|
|
46151
|
+
activeSession: _activeSession,
|
|
46152
|
+
active_session: _activeSessionLegacy,
|
|
46153
|
+
activeSessionId: _activeSessionId,
|
|
46154
|
+
active_session_id: _activeSessionIdLegacy,
|
|
46155
|
+
sessionId: _sessionId,
|
|
46156
|
+
session_id: _sessionIdLegacy,
|
|
46157
|
+
providerType: _providerType,
|
|
46158
|
+
provider_type: _providerTypeLegacy,
|
|
46159
|
+
providers: _providers,
|
|
46160
|
+
...rest
|
|
46161
|
+
} = node;
|
|
46162
|
+
if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
|
|
46163
|
+
return { ...rest, cachedStatus };
|
|
46164
|
+
}
|
|
46165
|
+
return rest;
|
|
46166
|
+
}
|
|
46167
|
+
function hasInlineMeshTransientNodeState(node) {
|
|
46168
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return false;
|
|
46169
|
+
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 || "providers" in node;
|
|
46170
|
+
}
|
|
46171
|
+
function readInlineMeshNodeId(node) {
|
|
46172
|
+
return readStringValue(node?.id, node?.nodeId) || "";
|
|
46173
|
+
}
|
|
46174
|
+
function sanitizeInlineMesh(inlineMesh) {
|
|
46175
|
+
if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
|
|
46176
|
+
if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
|
|
46177
|
+
let changed = false;
|
|
46178
|
+
const nodes = inlineMesh.nodes.map((node) => {
|
|
46179
|
+
if (!hasInlineMeshTransientNodeState(node)) return node;
|
|
46180
|
+
changed = true;
|
|
46181
|
+
return stripInlineMeshTransientNodeState(node);
|
|
46182
|
+
});
|
|
46183
|
+
if (!changed) return inlineMesh;
|
|
46184
|
+
return {
|
|
46185
|
+
...inlineMesh,
|
|
46186
|
+
nodes
|
|
46187
|
+
};
|
|
46188
|
+
}
|
|
46189
|
+
function reconcileInlineMeshCache(cached2, incoming) {
|
|
46190
|
+
if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
|
|
46191
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
|
|
46192
|
+
const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
|
|
46193
|
+
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
46194
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
|
|
46195
|
+
const incomingById = /* @__PURE__ */ new Map();
|
|
46196
|
+
for (const node of incomingNodes) {
|
|
46197
|
+
const nodeId = readInlineMeshNodeId(node);
|
|
46198
|
+
if (nodeId) incomingById.set(nodeId, node);
|
|
46199
|
+
}
|
|
46200
|
+
const nodes = cachedNodes.map((cachedNode) => {
|
|
46201
|
+
const nodeId = readInlineMeshNodeId(cachedNode);
|
|
46202
|
+
const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
|
|
46203
|
+
if (!incomingNode) return cachedNode;
|
|
46204
|
+
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
46205
|
+
return { ...cachedNode, ...incomingNode };
|
|
46206
|
+
}
|
|
46207
|
+
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
46208
|
+
});
|
|
46209
|
+
return {
|
|
46210
|
+
...cached2,
|
|
46211
|
+
...incoming,
|
|
46212
|
+
nodes
|
|
46213
|
+
};
|
|
46214
|
+
}
|
|
46215
|
+
function hasGitWorktreeChanges(git) {
|
|
46216
|
+
if (!git) return false;
|
|
46217
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
46218
|
+
}
|
|
46219
|
+
function getGitSubmoduleDriftState(git) {
|
|
46220
|
+
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
46221
|
+
let dirty = false;
|
|
46222
|
+
let outOfSync = false;
|
|
46223
|
+
for (const entry of submodules) {
|
|
46224
|
+
const submodule = readObjectRecord(entry);
|
|
46225
|
+
if (readBooleanValue(submodule.dirty) === true) dirty = true;
|
|
46226
|
+
if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
|
|
46227
|
+
}
|
|
46228
|
+
return { dirty, outOfSync };
|
|
46229
|
+
}
|
|
46230
|
+
function deriveMeshNodeHealthFromGit(git) {
|
|
46231
|
+
if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
|
|
46232
|
+
const branch = readStringValue(git.branch);
|
|
46233
|
+
if (!branch) return "degraded";
|
|
46234
|
+
const submoduleDrift = getGitSubmoduleDriftState(git);
|
|
46235
|
+
if (submoduleDrift.outOfSync) return "degraded";
|
|
46236
|
+
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
46237
|
+
return "online";
|
|
46238
|
+
}
|
|
46239
|
+
function readCachedInlineMeshActiveSessions(node) {
|
|
46240
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46241
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46242
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46243
|
+
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
46244
|
+
return sessionId ? [sessionId] : [];
|
|
46245
|
+
}
|
|
46246
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
46247
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46248
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46249
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46250
|
+
const sessionId = readStringValue(
|
|
46251
|
+
fallbackSession.id,
|
|
46252
|
+
fallbackSession.sessionId,
|
|
46253
|
+
fallbackSession.session_id,
|
|
46254
|
+
node?.activeSessionId,
|
|
46255
|
+
node?.active_session_id,
|
|
46256
|
+
node?.sessionId,
|
|
46257
|
+
node?.session_id
|
|
46258
|
+
);
|
|
46259
|
+
if (!sessionId) return [];
|
|
46260
|
+
return [{
|
|
46261
|
+
sessionId,
|
|
46262
|
+
providerType: readStringValue(
|
|
46263
|
+
fallbackSession.providerType,
|
|
46264
|
+
fallbackSession.provider_type,
|
|
46265
|
+
fallbackSession.cliType,
|
|
46266
|
+
fallbackSession.cli_type,
|
|
46267
|
+
fallbackSession.provider,
|
|
46268
|
+
node?.providerType,
|
|
46269
|
+
node?.provider_type
|
|
46270
|
+
),
|
|
46271
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
46272
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
46273
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
46274
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
46275
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
46276
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
46277
|
+
isCached: true
|
|
46278
|
+
}];
|
|
46279
|
+
}
|
|
46280
|
+
function readLiveMeshSessionState(record2) {
|
|
46281
|
+
return readStringValue(
|
|
46282
|
+
record2?.meta?.sessionStatus,
|
|
46283
|
+
record2?.meta?.status,
|
|
46284
|
+
record2?.meta?.providerStatus,
|
|
46285
|
+
record2?.status,
|
|
46286
|
+
record2?.state,
|
|
46287
|
+
record2?.lifecycle
|
|
46288
|
+
);
|
|
46289
|
+
}
|
|
46290
|
+
function toIsoTimestamp(value) {
|
|
46291
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
46292
|
+
const stringValue = readStringValue(value);
|
|
46293
|
+
return stringValue || null;
|
|
46294
|
+
}
|
|
46295
|
+
function summarizeMeshSessionRecord(record2) {
|
|
46296
|
+
return {
|
|
46297
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
46298
|
+
providerType: readStringValue(record2?.providerType),
|
|
46299
|
+
state: readLiveMeshSessionState(record2),
|
|
46300
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
46301
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
46302
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
46303
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
46304
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
46305
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
46306
|
+
isCached: false
|
|
46307
|
+
};
|
|
46308
|
+
}
|
|
46309
|
+
function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
|
|
46310
|
+
const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
|
|
46311
|
+
if (!recordNodeId || recordNodeId !== nodeId) return false;
|
|
46312
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46313
|
+
return !recordMeshId || recordMeshId === meshId;
|
|
46314
|
+
}
|
|
46315
|
+
function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
|
|
46316
|
+
const recordWorkspace = readStringValue(record2?.workspace);
|
|
46317
|
+
if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
|
|
46318
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46319
|
+
if (recordMeshId) return recordMeshId === meshId;
|
|
46320
|
+
return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
|
|
46321
|
+
}
|
|
46322
|
+
function readLiveMeshNodeWorkspace(args) {
|
|
46323
|
+
const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
|
|
46324
|
+
if (directNodeWorkspace) {
|
|
46325
|
+
return readStringValue(directNodeWorkspace.workspace) || "";
|
|
46326
|
+
}
|
|
46327
|
+
if (args.allowCoordinatorSession) {
|
|
46328
|
+
const coordinatorWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record2?.workspace));
|
|
46329
|
+
if (coordinatorWorkspace) {
|
|
46330
|
+
return readStringValue(coordinatorWorkspace.workspace) || "";
|
|
46331
|
+
}
|
|
46332
|
+
}
|
|
46333
|
+
return "";
|
|
46334
|
+
}
|
|
46335
|
+
function collectLiveMeshSessionRecords(args) {
|
|
46336
|
+
const matches = args.liveSessionRecords.filter((record2) => {
|
|
46337
|
+
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
46338
|
+
if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
|
|
46339
|
+
return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
|
|
46340
|
+
});
|
|
46341
|
+
if (args.allowCoordinatorSession) {
|
|
46342
|
+
for (const record2 of args.liveSessionRecords) {
|
|
46343
|
+
if (readStringValue(record2?.meta?.meshCoordinatorFor) !== args.meshId) continue;
|
|
46344
|
+
const sessionId = readStringValue(record2?.sessionId);
|
|
46345
|
+
if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
|
|
46346
|
+
matches.push(record2);
|
|
46347
|
+
}
|
|
46348
|
+
}
|
|
46349
|
+
return matches;
|
|
46350
|
+
}
|
|
46351
|
+
function applyCachedInlineMeshNodeStatus(status, node, options) {
|
|
46352
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46353
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46354
|
+
const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
|
|
46355
|
+
const error48 = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
|
|
46356
|
+
const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
|
|
45887
46357
|
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
45888
|
-
|
|
45889
|
-
|
|
46358
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
46359
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
46360
|
+
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
46361
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
46362
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
45890
46363
|
if (git) status.git = git;
|
|
45891
46364
|
if (error48) status.error = error48;
|
|
46365
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46366
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
46367
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
46368
|
+
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
46369
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
45892
46370
|
if (health) {
|
|
45893
46371
|
status.health = health;
|
|
45894
46372
|
return true;
|
|
45895
46373
|
}
|
|
45896
46374
|
if (git) {
|
|
45897
|
-
|
|
45898
|
-
status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
|
|
46375
|
+
status.health = deriveMeshNodeHealthFromGit(git);
|
|
45899
46376
|
return true;
|
|
45900
46377
|
}
|
|
45901
|
-
return
|
|
46378
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
45902
46379
|
}
|
|
45903
46380
|
async function resolveProviderTypeFromPriority(args) {
|
|
45904
46381
|
if (!args.providerPriority.length) {
|
|
@@ -45936,7 +46413,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
45936
46413
|
}
|
|
45937
46414
|
function readPackageScripts(workspace) {
|
|
45938
46415
|
try {
|
|
45939
|
-
const packageJsonPath = (0,
|
|
46416
|
+
const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
|
|
45940
46417
|
const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
|
|
45941
46418
|
return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
|
|
45942
46419
|
} catch {
|
|
@@ -46144,13 +46621,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46144
46621
|
}
|
|
46145
46622
|
function resolveHermesUserHome() {
|
|
46146
46623
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
46147
|
-
return explicitHome || (0,
|
|
46624
|
+
return explicitHome || (0, import_path7.join)((0, import_os3.homedir)(), ".hermes");
|
|
46148
46625
|
}
|
|
46149
46626
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
46150
46627
|
const sourceHome = resolveHermesUserHome();
|
|
46151
|
-
const sourceConfigPath = (0,
|
|
46628
|
+
const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
|
|
46152
46629
|
if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46153
|
-
if ((0,
|
|
46630
|
+
if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46154
46631
|
const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
46155
46632
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
46156
46633
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -46184,10 +46661,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46184
46661
|
return sanitized;
|
|
46185
46662
|
}
|
|
46186
46663
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
46187
|
-
if ((0,
|
|
46664
|
+
if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
|
|
46188
46665
|
for (const fileName of [".env", "auth.json"]) {
|
|
46189
|
-
const sourcePath = (0,
|
|
46190
|
-
const targetPath = (0,
|
|
46666
|
+
const sourcePath = (0, import_path7.join)(sourceHome, fileName);
|
|
46667
|
+
const targetPath = (0, import_path7.join)(targetHome, fileName);
|
|
46191
46668
|
if (!fs10.existsSync(sourcePath)) continue;
|
|
46192
46669
|
try {
|
|
46193
46670
|
fs10.copyFileSync(sourcePath, targetPath);
|
|
@@ -46296,25 +46773,40 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46296
46773
|
}
|
|
46297
46774
|
getCachedInlineMesh(meshId, inlineMesh) {
|
|
46298
46775
|
if (inlineMesh && typeof inlineMesh === "object") {
|
|
46299
|
-
this.
|
|
46300
|
-
return inlineMesh;
|
|
46776
|
+
return this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46301
46777
|
}
|
|
46302
46778
|
return this.inlineMeshCache.get(meshId);
|
|
46303
46779
|
}
|
|
46780
|
+
warmInlineMeshCache(meshId, inlineMesh) {
|
|
46781
|
+
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
46782
|
+
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
|
|
46783
|
+
const cached2 = this.inlineMeshCache.get(meshId);
|
|
46784
|
+
if (cached2) {
|
|
46785
|
+
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
46786
|
+
this.inlineMeshCache.set(meshId, merged);
|
|
46787
|
+
return merged;
|
|
46788
|
+
}
|
|
46789
|
+
this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
|
|
46790
|
+
return sanitizedInlineMesh;
|
|
46791
|
+
}
|
|
46304
46792
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
46305
46793
|
const preferInline = options?.preferInline === true;
|
|
46306
46794
|
if (preferInline) {
|
|
46307
|
-
const cached22 = this.getCachedInlineMesh(meshId
|
|
46308
|
-
if (cached22) return { mesh: cached22, inline: true };
|
|
46795
|
+
const cached22 = this.getCachedInlineMesh(meshId);
|
|
46796
|
+
if (cached22) return { mesh: cached22, inline: true, source: "inline_cache" };
|
|
46797
|
+
const warmedInline2 = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46798
|
+
if (warmedInline2) return { mesh: warmedInline2, inline: true, source: "inline_bootstrap" };
|
|
46309
46799
|
}
|
|
46310
46800
|
try {
|
|
46311
46801
|
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
46312
46802
|
const mesh = getMesh3(meshId);
|
|
46313
|
-
if (mesh) return { mesh, inline: false };
|
|
46803
|
+
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
46314
46804
|
} catch {
|
|
46315
46805
|
}
|
|
46316
|
-
const cached2 = this.getCachedInlineMesh(meshId
|
|
46317
|
-
|
|
46806
|
+
const cached2 = this.getCachedInlineMesh(meshId);
|
|
46807
|
+
if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
|
|
46808
|
+
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46809
|
+
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
46318
46810
|
}
|
|
46319
46811
|
updateInlineMeshNode(meshId, mesh, node) {
|
|
46320
46812
|
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
@@ -46379,7 +46871,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46379
46871
|
}
|
|
46380
46872
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
46381
46873
|
const normalizePath = (value) => {
|
|
46382
|
-
const resolved = (0,
|
|
46874
|
+
const resolved = (0, import_path7.resolve)(value);
|
|
46383
46875
|
try {
|
|
46384
46876
|
return fs10.realpathSync(resolved);
|
|
46385
46877
|
} catch {
|
|
@@ -46543,6 +47035,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46543
47035
|
const deletedSessionIds = [];
|
|
46544
47036
|
const skippedSessionIds = [];
|
|
46545
47037
|
const skippedLiveSessionIds = [];
|
|
47038
|
+
const skippedCoordinatorSessionIds = [];
|
|
46546
47039
|
const deleteUnsupportedSessionIds = [];
|
|
46547
47040
|
const recordsRemainSessionIds = [];
|
|
46548
47041
|
const errors = [];
|
|
@@ -46575,6 +47068,12 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46575
47068
|
const completed = this.isCompletedHostedSession(record2);
|
|
46576
47069
|
const surfaceKind = getSessionHostSurfaceKind(record2);
|
|
46577
47070
|
const liveRuntime = surfaceKind === "live_runtime";
|
|
47071
|
+
const coordinatorSession = readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId;
|
|
47072
|
+
if (!hasExplicitSessionIds && coordinatorSession) {
|
|
47073
|
+
skippedSessionIds.push(sessionId);
|
|
47074
|
+
skippedCoordinatorSessionIds.push(sessionId);
|
|
47075
|
+
continue;
|
|
47076
|
+
}
|
|
46578
47077
|
if (!hasExplicitSessionIds && liveRuntime) {
|
|
46579
47078
|
skippedSessionIds.push(sessionId);
|
|
46580
47079
|
skippedLiveSessionIds.push(sessionId);
|
|
@@ -46640,6 +47139,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46640
47139
|
deletedSessionIds,
|
|
46641
47140
|
skippedSessionIds,
|
|
46642
47141
|
skippedLiveSessionIds,
|
|
47142
|
+
skippedCoordinatorSessionIds,
|
|
46643
47143
|
...deleteUnsupported ? {
|
|
46644
47144
|
deleteUnsupported: true,
|
|
46645
47145
|
effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
|
|
@@ -46772,7 +47272,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
46772
47272
|
return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
|
|
46773
47273
|
}
|
|
46774
47274
|
case "get_pending_mesh_events": {
|
|
46775
|
-
const
|
|
47275
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47276
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
|
|
46776
47277
|
return { success: true, events };
|
|
46777
47278
|
}
|
|
46778
47279
|
case "launch_cli":
|
|
@@ -47301,14 +47802,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
47301
47802
|
case "get_mesh": {
|
|
47302
47803
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47303
47804
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
47304
|
-
|
|
47305
|
-
|
|
47306
|
-
const mesh = getMesh3(meshId);
|
|
47307
|
-
if (mesh) return { success: true, mesh };
|
|
47308
|
-
} catch {
|
|
47309
|
-
}
|
|
47310
|
-
const cached2 = this.inlineMeshCache.get(meshId);
|
|
47311
|
-
if (cached2) return { success: true, mesh: cached2 };
|
|
47805
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
47806
|
+
if (meshRecord?.mesh) return { success: true, mesh: meshRecord.mesh };
|
|
47312
47807
|
return { success: false, error: "Mesh not found" };
|
|
47313
47808
|
}
|
|
47314
47809
|
case "create_mesh": {
|
|
@@ -47830,7 +48325,14 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
|
47830
48325
|
cliType
|
|
47831
48326
|
};
|
|
47832
48327
|
}
|
|
47833
|
-
const
|
|
48328
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48329
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48330
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
48331
|
+
meshId,
|
|
48332
|
+
nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
|
|
48333
|
+
liveSessionRecords: liveMeshSessions,
|
|
48334
|
+
allowCoordinatorSession: true
|
|
48335
|
+
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
47834
48336
|
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
47835
48337
|
if (!cliType) {
|
|
47836
48338
|
const resolved = await resolveProviderTypeFromPriority({
|
|
@@ -47992,7 +48494,7 @@ ${block}`);
|
|
|
47992
48494
|
workspace
|
|
47993
48495
|
};
|
|
47994
48496
|
}
|
|
47995
|
-
const { existsSync:
|
|
48497
|
+
const { existsSync: existsSync26, readFileSync: readFileSync18, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
|
|
47996
48498
|
const { dirname: dirname9 } = await import("path");
|
|
47997
48499
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
47998
48500
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -48035,14 +48537,14 @@ ${block}`);
|
|
|
48035
48537
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
48036
48538
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
48037
48539
|
}
|
|
48038
|
-
const hadExistingMcpConfig =
|
|
48540
|
+
const hadExistingMcpConfig = existsSync26(mcpConfigPath);
|
|
48039
48541
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
48040
48542
|
if (hermesBaseConfig) {
|
|
48041
48543
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
48042
48544
|
}
|
|
48043
48545
|
if (hadExistingMcpConfig) {
|
|
48044
48546
|
try {
|
|
48045
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
48547
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync18(mcpConfigPath, "utf-8"), configFormat);
|
|
48046
48548
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
48047
48549
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
48048
48550
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -48138,92 +48640,157 @@ ${block}`);
|
|
|
48138
48640
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48139
48641
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
48140
48642
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
48643
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48644
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48645
|
+
const localMachineId = loadConfig2().machineId || "";
|
|
48646
|
+
const selectedCoordinatorNodeId = readStringValue(
|
|
48647
|
+
mesh.coordinator?.preferredNodeId,
|
|
48648
|
+
mesh.nodes?.[0]?.id,
|
|
48649
|
+
mesh.nodes?.[0]?.nodeId
|
|
48650
|
+
);
|
|
48651
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
48652
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48141
48653
|
const nodeStatuses = [];
|
|
48142
|
-
for (const node of mesh.nodes || []) {
|
|
48654
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
48655
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
48656
|
+
const daemonId = readStringValue(node.daemonId);
|
|
48657
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
48658
|
+
const isSelfNode = Boolean(
|
|
48659
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
48660
|
+
) || Boolean(
|
|
48661
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
48662
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
48143
48663
|
const status = {
|
|
48144
|
-
nodeId
|
|
48664
|
+
nodeId,
|
|
48145
48665
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
48146
48666
|
workspace: node.workspace,
|
|
48147
48667
|
repoRoot: node.repoRoot,
|
|
48148
48668
|
isLocalWorktree: node.isLocalWorktree,
|
|
48149
48669
|
worktreeBranch: node.worktreeBranch,
|
|
48150
|
-
daemonId
|
|
48670
|
+
daemonId,
|
|
48151
48671
|
machineId: node.machineId,
|
|
48672
|
+
machineStatus: node.machineStatus,
|
|
48152
48673
|
health: "unknown",
|
|
48153
48674
|
providers: node.providers || [],
|
|
48154
|
-
|
|
48675
|
+
providerPriority,
|
|
48676
|
+
activeSessions: [],
|
|
48677
|
+
activeSessionDetails: [],
|
|
48678
|
+
launchReady: false
|
|
48155
48679
|
};
|
|
48156
|
-
if (
|
|
48157
|
-
|
|
48158
|
-
|
|
48159
|
-
|
|
48680
|
+
if (isSelfNode) {
|
|
48681
|
+
status.connection = {
|
|
48682
|
+
perspective: "selected_coordinator",
|
|
48683
|
+
source: "mesh_peer_status",
|
|
48684
|
+
state: "self",
|
|
48685
|
+
transport: "local",
|
|
48686
|
+
reported: true,
|
|
48687
|
+
reason: "Selected coordinator daemon",
|
|
48688
|
+
lastStateChangeAt: refreshedAt
|
|
48689
|
+
};
|
|
48690
|
+
} else if (daemonId) {
|
|
48691
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
48692
|
+
status.connection = connection ?? {
|
|
48693
|
+
perspective: "selected_coordinator",
|
|
48694
|
+
source: "not_reported",
|
|
48695
|
+
state: "unknown",
|
|
48696
|
+
transport: "unknown",
|
|
48697
|
+
reported: false,
|
|
48698
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
48699
|
+
};
|
|
48700
|
+
} else {
|
|
48701
|
+
status.connection = {
|
|
48702
|
+
perspective: "selected_coordinator",
|
|
48703
|
+
source: "not_reported",
|
|
48704
|
+
state: "unknown",
|
|
48705
|
+
transport: "unknown",
|
|
48706
|
+
reported: false,
|
|
48707
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
48708
|
+
};
|
|
48709
|
+
}
|
|
48710
|
+
const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
|
|
48711
|
+
meshId,
|
|
48712
|
+
node,
|
|
48713
|
+
nodeId,
|
|
48714
|
+
liveSessionRecords: liveMeshSessions,
|
|
48715
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
48716
|
+
});
|
|
48717
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
48718
|
+
meshId,
|
|
48719
|
+
nodeId,
|
|
48720
|
+
liveSessionRecords: matchedLiveSessionRecords,
|
|
48721
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
48722
|
+
}) || (typeof node.workspace === "string" ? node.workspace : "");
|
|
48723
|
+
status.workspace = workspace || node.workspace;
|
|
48724
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
48725
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
48726
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
48727
|
+
status.activeSessions = sessionIds;
|
|
48728
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
48729
|
+
if (providerTypes.length > 0) {
|
|
48730
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
48160
48731
|
}
|
|
48161
|
-
|
|
48162
|
-
|
|
48163
|
-
|
|
48164
|
-
|
|
48165
|
-
|
|
48166
|
-
|
|
48167
|
-
|
|
48168
|
-
|
|
48169
|
-
|
|
48170
|
-
|
|
48171
|
-
|
|
48172
|
-
|
|
48173
|
-
|
|
48174
|
-
|
|
48175
|
-
|
|
48176
|
-
|
|
48177
|
-
|
|
48178
|
-
const stashCount = await runGit2(["stash", "list"]).catch(() => "");
|
|
48179
|
-
let ahead = 0, behind = 0;
|
|
48180
|
-
if (aheadBehind) {
|
|
48181
|
-
const parts = aheadBehind.split(/\s+/);
|
|
48182
|
-
if (parts.length >= 2) {
|
|
48183
|
-
behind = parseInt(parts[0], 10) || 0;
|
|
48184
|
-
ahead = parseInt(parts[1], 10) || 0;
|
|
48732
|
+
}
|
|
48733
|
+
if (workspace) {
|
|
48734
|
+
if (!fs10.existsSync(workspace)) {
|
|
48735
|
+
let remoteProbeApplied = false;
|
|
48736
|
+
if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
|
|
48737
|
+
try {
|
|
48738
|
+
const remoteResult = await Promise.race([
|
|
48739
|
+
this.deps.dispatchMeshCommand(daemonId, "git_status", { workspace }),
|
|
48740
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 8e3))
|
|
48741
|
+
]);
|
|
48742
|
+
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
48743
|
+
if (remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean") {
|
|
48744
|
+
status.git = remoteGit;
|
|
48745
|
+
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
48746
|
+
remoteProbeApplied = true;
|
|
48747
|
+
}
|
|
48748
|
+
} catch {
|
|
48185
48749
|
}
|
|
48186
48750
|
}
|
|
48187
|
-
|
|
48188
|
-
|
|
48189
|
-
|
|
48190
|
-
|
|
48191
|
-
|
|
48192
|
-
|
|
48193
|
-
|
|
48194
|
-
|
|
48195
|
-
if (
|
|
48196
|
-
|
|
48751
|
+
if (!remoteProbeApplied) {
|
|
48752
|
+
const connectionState = readStringValue(status.connection?.state);
|
|
48753
|
+
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
48754
|
+
const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
|
|
48755
|
+
if (pendingPeerGitProbe) {
|
|
48756
|
+
status.gitProbePending = true;
|
|
48757
|
+
status.health = "unknown";
|
|
48758
|
+
}
|
|
48759
|
+
if (applyCachedInlineMeshNodeStatus(
|
|
48760
|
+
status,
|
|
48761
|
+
node,
|
|
48762
|
+
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
48763
|
+
)) {
|
|
48764
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48765
|
+
nodeStatuses.push(status);
|
|
48766
|
+
continue;
|
|
48767
|
+
}
|
|
48768
|
+
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
48769
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48770
|
+
nodeStatuses.push(status);
|
|
48771
|
+
continue;
|
|
48772
|
+
}
|
|
48197
48773
|
}
|
|
48198
|
-
|
|
48199
|
-
|
|
48200
|
-
|
|
48201
|
-
|
|
48202
|
-
|
|
48203
|
-
|
|
48204
|
-
|
|
48205
|
-
|
|
48206
|
-
|
|
48207
|
-
|
|
48208
|
-
|
|
48209
|
-
|
|
48210
|
-
|
|
48211
|
-
|
|
48212
|
-
renamed,
|
|
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";
|
|
48774
|
+
} else {
|
|
48775
|
+
try {
|
|
48776
|
+
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
48777
|
+
status.git = gitStatus;
|
|
48778
|
+
if (gitStatus.isGitRepo) {
|
|
48779
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
48780
|
+
} else {
|
|
48781
|
+
status.health = "degraded";
|
|
48782
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
48783
|
+
}
|
|
48784
|
+
} catch {
|
|
48785
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
48786
|
+
status.health = "degraded";
|
|
48787
|
+
}
|
|
48222
48788
|
}
|
|
48223
48789
|
}
|
|
48224
48790
|
} else {
|
|
48225
48791
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
48226
48792
|
}
|
|
48793
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48227
48794
|
nodeStatuses.push(status);
|
|
48228
48795
|
}
|
|
48229
48796
|
return {
|
|
@@ -48232,6 +48799,12 @@ ${block}`);
|
|
|
48232
48799
|
meshName: mesh.name,
|
|
48233
48800
|
repoIdentity: mesh.repoIdentity,
|
|
48234
48801
|
defaultBranch: mesh.defaultBranch,
|
|
48802
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48803
|
+
sourceOfTruth: {
|
|
48804
|
+
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
48805
|
+
coordinatorOwnsLiveTruth: meshRecord?.source !== "inline_bootstrap",
|
|
48806
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
48807
|
+
},
|
|
48235
48808
|
nodes: nodeStatuses,
|
|
48236
48809
|
queue: { tasks: queue, summary: queueSummary },
|
|
48237
48810
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -56107,6 +56680,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
56107
56680
|
sessionHostControl: config2.sessionHostControl,
|
|
56108
56681
|
statusInstanceId: config2.statusInstanceId,
|
|
56109
56682
|
statusVersion: config2.statusVersion,
|
|
56683
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
56110
56684
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
|
|
56111
56685
|
});
|
|
56112
56686
|
poller = new AgentStreamPoller({
|