@adhdev/daemon-standalone 0.9.82-rc.4 → 0.9.82-rc.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js 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
- const queue = readQueue(meshId);
23509
- const entry = {
23510
- id: (0, import_crypto5.randomUUID)(),
23511
- meshId,
23512
- message,
23513
- status: "pending",
23514
- targetNodeId: opts?.targetNodeId,
23515
- targetSessionId: opts?.targetSessionId,
23516
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
23517
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
23518
- };
23519
- queue.push(entry);
23520
- writeQueue(meshId, queue);
23521
- return entry;
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
- const queue = readQueue(meshId);
23533
- const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
23534
- if (hasActiveAssignment) return null;
23535
- let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
23536
- if (targetIdx === -1) {
23537
- targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
23538
- }
23539
- if (targetIdx === -1) {
23540
- targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
23541
- }
23542
- if (targetIdx === -1) return null;
23543
- const entry = queue[targetIdx];
23544
- entry.status = "assigned";
23545
- entry.assignedNodeId = nodeId;
23546
- entry.assignedSessionId = sessionId;
23547
- entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
23548
- entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23549
- writeQueue(meshId, queue);
23550
- return entry;
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
- const queue = readQueue(meshId);
23554
- const idx = queue.findIndex((q) => q.id === taskId);
23555
- if (idx === -1) return null;
23556
- queue[idx].status = status;
23557
- queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23558
- writeQueue(meshId, queue);
23559
- return queue[idx];
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
- const queue = readQueue(meshId);
23563
- const idx = queue.findIndex((q) => q.id === taskId);
23564
- if (idx === -1) return null;
23565
- const now = (/* @__PURE__ */ new Date()).toISOString();
23566
- queue[idx].autoLaunch = {
23567
- ...autoLaunch,
23568
- updatedAt: now
23569
- };
23570
- queue[idx].updatedAt = now;
23571
- writeQueue(meshId, queue);
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
- const queue = readQueue(meshId);
23576
- const idx = queue.findIndex((q) => q.id === taskId);
23577
- if (idx === -1) return null;
23578
- const now = (/* @__PURE__ */ new Date()).toISOString();
23579
- queue[idx].status = "cancelled";
23580
- queue[idx].updatedAt = now;
23581
- queue[idx].cancelledAt = now;
23582
- if (opts?.reason) queue[idx].cancelReason = opts.reason;
23583
- writeQueue(meshId, queue);
23584
- return queue[idx];
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
- const queue = readQueue(meshId);
23588
- const idx = queue.findIndex((q) => q.id === taskId);
23589
- if (idx === -1) return null;
23590
- const entry = queue[idx];
23591
- const now = (/* @__PURE__ */ new Date()).toISOString();
23592
- entry.status = "pending";
23593
- delete entry.assignedNodeId;
23594
- delete entry.assignedSessionId;
23595
- delete entry.cancelledAt;
23596
- delete entry.cancelReason;
23597
- if (opts?.clearTargetNode) delete entry.targetNodeId;
23598
- if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
23599
- if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
23600
- if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
23601
- entry.updatedAt = now;
23602
- entry.requeuedAt = now;
23603
- entry.requeueCount = (entry.requeueCount || 0) + 1;
23604
- if (opts?.reason) entry.requeueReason = opts.reason;
23605
- writeQueue(meshId, queue);
23606
- return entry;
23607
- }
23608
- function updateSessionTaskStatus(meshId, sessionId, status) {
23609
- const queue = readQueue(meshId);
23610
- let bestIdx = -1;
23611
- let bestTime = 0;
23612
- for (let i = queue.length - 1; i >= 0; i--) {
23613
- if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
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
- if (bestIdx === -1) return null;
23622
- queue[bestIdx].status = status;
23623
- queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23624
- writeQueue(meshId, queue);
23625
- return queue[bestIdx];
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 drainPendingMeshCoordinatorEvents() {
24054
- return pendingMeshCoordinatorEvents.splice(0);
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
- return pendingMeshCoordinatorEvents.slice();
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
- pendingMeshCoordinatorEvents.splice(0);
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, "failed");
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
- setTimeout(() => {
24626
+ setImmediate(() => {
24468
24627
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
24469
- }, 500);
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
- remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
24508
- setTimeout(() => {
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
- remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
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 (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
24625
- pendingMeshCoordinatorEvents.push({
24626
- event: args.event,
24627
- meshId: args.meshId,
24628
- nodeLabel: args.nodeLabel,
24629
- metadataEvent: {
24630
- ...args.metadataEvent,
24631
- ...recoveryContext ? { recoveryContext } : {}
24632
- },
24633
- queuedAt: Date.now()
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
- const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
28066
- const parsed = parsePorcelainV2Status(statusOutput.stdout);
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 import_fs6 = require("fs");
29908
- var import_path5 = require("path");
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, import_path5.join)(getConfigDir(), "state.json");
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, import_fs6.existsSync)(statePath)) {
30197
+ if (!(0, import_fs7.existsSync)(statePath)) {
29959
30198
  return { ...DEFAULT_STATE };
29960
30199
  }
29961
30200
  try {
29962
- const raw = (0, import_fs6.readFileSync)(statePath, "utf-8");
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, import_fs6.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
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 import_fs7 = require("fs");
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, import_fs7.existsSync)(resolved) ? resolved : null;
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, import_fs7.existsSync)(resolved)) return resolved;
30271
+ if ((0, import_fs8.existsSync)(resolved)) return resolved;
30033
30272
  } else {
30034
- if ((0, import_fs7.existsSync)(normalized)) return normalized;
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, import_fs7.existsSync)(bundledCli)) resolvedCli = bundledCli;
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, import_fs7.existsSync)(c)) {
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
- function extractFinalSummaryFromMessages(messages, maxChars = 500) {
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 import_fs8 = require("fs");
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, import_fs8.existsSync)(expandExecutable(trimmed));
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, import_fs8.mkdirSync)(baseDir, { recursive: true });
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, import_fs8.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
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 import_path6 = require("path");
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 buildCachedInlineMeshGitStatus(node) {
45816
- const cachedStatus = readObjectRecord(node?.cachedStatus);
45817
- const cachedGit = readObjectRecord(cachedStatus.git);
45818
- if (Object.keys(cachedGit).length) {
45819
- const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
45820
- const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
45821
- const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
45822
- const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
45823
- if (isGitRepo2 !== void 0) {
45824
- return {
45825
- workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
45826
- repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
45827
- isGitRepo: isGitRepo2,
45828
- branch: readStringValue(cachedGit.branch) ?? null,
45829
- headCommit: readStringValue(cachedGit.headCommit) ?? null,
45830
- headMessage: readStringValue(cachedGit.headMessage) ?? null,
45831
- upstream: readStringValue(cachedGit.upstream) ?? null,
45832
- ahead: readNumberValue(cachedGit.ahead) ?? 0,
45833
- behind: readNumberValue(cachedGit.behind) ?? 0,
45834
- staged: readNumberValue(cachedGit.staged) ?? 0,
45835
- modified: readNumberValue(cachedGit.modified) ?? 0,
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 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: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
46093
+ repoRoot: repoRoot ?? null,
45864
46094
  isGitRepo,
45865
46095
  branch: readStringValue(status.branch) ?? null,
45866
46096
  headCommit: readStringValue(status.headCommit) ?? null,
@@ -45876,29 +46106,412 @@ ${(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 inlineMeshCarriesTransientNodeTruth(inlineMesh) {
46200
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return false;
46201
+ if (!Array.isArray(inlineMesh.nodes) || inlineMesh.nodes.length === 0) return false;
46202
+ return inlineMesh.nodes.some((node) => hasInlineMeshTransientNodeState(node));
46203
+ }
46204
+ function readInlineMeshNodeId(node) {
46205
+ return readStringValue(node?.id, node?.nodeId) || "";
46206
+ }
46207
+ function sanitizeInlineMesh(inlineMesh) {
46208
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
46209
+ if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
46210
+ let changed = false;
46211
+ const nodes = inlineMesh.nodes.map((node) => {
46212
+ if (!hasInlineMeshTransientNodeState(node)) return node;
46213
+ changed = true;
46214
+ return stripInlineMeshTransientNodeState(node);
46215
+ });
46216
+ if (!changed) return inlineMesh;
46217
+ return {
46218
+ ...inlineMesh,
46219
+ nodes
46220
+ };
46221
+ }
46222
+ function reconcileInlineMeshCache(cached2, incoming) {
46223
+ if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
46224
+ if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
46225
+ const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
46226
+ const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
46227
+ if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
46228
+ const incomingById = /* @__PURE__ */ new Map();
46229
+ for (const node of incomingNodes) {
46230
+ const nodeId = readInlineMeshNodeId(node);
46231
+ if (nodeId) incomingById.set(nodeId, node);
46232
+ }
46233
+ const nodes = cachedNodes.map((cachedNode) => {
46234
+ const nodeId = readInlineMeshNodeId(cachedNode);
46235
+ const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
46236
+ if (!incomingNode) return cachedNode;
46237
+ if (hasInlineMeshTransientNodeState(incomingNode)) {
46238
+ return { ...cachedNode, ...incomingNode };
46239
+ }
46240
+ return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
46241
+ });
46242
+ return {
46243
+ ...cached2,
46244
+ ...incoming,
46245
+ nodes
46246
+ };
46247
+ }
46248
+ function hasGitWorktreeChanges(git) {
46249
+ if (!git) return false;
46250
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
46251
+ }
46252
+ function getGitSubmoduleDriftState(git) {
46253
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
46254
+ let dirty = false;
46255
+ let outOfSync = false;
46256
+ for (const entry of submodules) {
46257
+ const submodule = readObjectRecord(entry);
46258
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
46259
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
46260
+ }
46261
+ return { dirty, outOfSync };
46262
+ }
46263
+ function deriveMeshNodeHealthFromGit(git) {
46264
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
46265
+ const branch = readStringValue(git.branch);
46266
+ if (!branch) return "degraded";
46267
+ const submoduleDrift = getGitSubmoduleDriftState(git);
46268
+ if (submoduleDrift.outOfSync) return "degraded";
46269
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
46270
+ return "online";
46271
+ }
46272
+ function readCachedInlineMeshActiveSessions(node) {
46273
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
46274
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
46275
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
46276
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
46277
+ return sessionId ? [sessionId] : [];
46278
+ }
46279
+ function readCachedInlineMeshActiveSessionDetails(node) {
46280
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
46281
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
46282
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
46283
+ const sessionId = readStringValue(
46284
+ fallbackSession.id,
46285
+ fallbackSession.sessionId,
46286
+ fallbackSession.session_id,
46287
+ node?.activeSessionId,
46288
+ node?.active_session_id,
46289
+ node?.sessionId,
46290
+ node?.session_id
46291
+ );
46292
+ if (!sessionId) return [];
46293
+ return [{
46294
+ sessionId,
46295
+ providerType: readStringValue(
46296
+ fallbackSession.providerType,
46297
+ fallbackSession.provider_type,
46298
+ fallbackSession.cliType,
46299
+ fallbackSession.cli_type,
46300
+ fallbackSession.provider,
46301
+ node?.providerType,
46302
+ node?.provider_type
46303
+ ),
46304
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
46305
+ lifecycle: readStringValue(fallbackSession.lifecycle),
46306
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
46307
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
46308
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
46309
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
46310
+ isCached: true
46311
+ }];
46312
+ }
46313
+ function readLiveMeshSessionState(record2) {
46314
+ return readStringValue(
46315
+ record2?.meta?.sessionStatus,
46316
+ record2?.meta?.status,
46317
+ record2?.meta?.providerStatus,
46318
+ record2?.status,
46319
+ record2?.state,
46320
+ record2?.lifecycle
46321
+ );
46322
+ }
46323
+ function toIsoTimestamp(value) {
46324
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
46325
+ const stringValue = readStringValue(value);
46326
+ return stringValue || null;
46327
+ }
46328
+ function synthesizeMeshNodeFreshnessFromConnection(status) {
46329
+ const connection = readObjectRecord(status.connection);
46330
+ const connectionFreshAt = toIsoTimestamp(connection.lastCommandAt ?? connection.lastConnectedAt ?? connection.lastStateChangeAt);
46331
+ const git = readObjectRecord(status.git);
46332
+ const gitCheckedAt = toIsoTimestamp(git.lastCheckedAt);
46333
+ if (!status.lastSeenAt && connectionFreshAt) status.lastSeenAt = connectionFreshAt;
46334
+ if (!status.updatedAt && (gitCheckedAt || connectionFreshAt)) {
46335
+ status.updatedAt = gitCheckedAt ?? connectionFreshAt;
46336
+ }
46337
+ }
46338
+ function finalizeMeshNodeStatus(args) {
46339
+ const { status, node, daemonId, isSelfNode } = args;
46340
+ if (!readStringValue(status.machineStatus)) {
46341
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
46342
+ const machineStatus = readStringValue(cachedStatus.machineStatus, cachedStatus.machine_status, node?.machineStatus);
46343
+ if (machineStatus) status.machineStatus = machineStatus;
46344
+ }
46345
+ synthesizeMeshNodeFreshnessFromConnection(status);
46346
+ const connectionState = readStringValue(readObjectRecord(status.connection).state);
46347
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
46348
+ }
46349
+ async function probeRemoteMeshGitStatus(args) {
46350
+ if (!args.dispatchMeshCommand) return null;
46351
+ const remoteResult = await Promise.race([
46352
+ args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
46353
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
46354
+ ]);
46355
+ const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
46356
+ return remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean" ? remoteGit : null;
46357
+ }
46358
+ async function hydrateInlineMeshDirectTruth(args) {
46359
+ const nodes = Array.isArray(args.mesh?.nodes) ? args.mesh.nodes : [];
46360
+ if (!nodes.length) {
46361
+ return {
46362
+ directEvidenceCount: 0,
46363
+ localConfirmedCount: 0,
46364
+ peerAttemptedCount: 0,
46365
+ peerConfirmedCount: 0,
46366
+ unavailableNodeIds: []
46367
+ };
46368
+ }
46369
+ const selectedCoordinatorNodeId = readStringValue(
46370
+ args.mesh?.coordinator?.preferredNodeId,
46371
+ nodes[0]?.id,
46372
+ nodes[0]?.nodeId
46373
+ );
46374
+ let localConfirmedCount = 0;
46375
+ let peerAttemptedCount = 0;
46376
+ let peerConfirmedCount = 0;
46377
+ const unavailableNodeIds = [];
46378
+ for (const [nodeIndex, node] of nodes.entries()) {
46379
+ const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
46380
+ const workspace = readStringValue(node?.workspace);
46381
+ const daemonId = readStringValue(node?.daemonId);
46382
+ const isSelfNode = Boolean(
46383
+ nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
46384
+ ) || Boolean(
46385
+ daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
46386
+ ) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
46387
+ if (!workspace) {
46388
+ if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
46389
+ continue;
46390
+ }
46391
+ if (isSelfNode && fs10.existsSync(workspace)) {
46392
+ try {
46393
+ const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
46394
+ if (localGit?.isGitRepo) {
46395
+ recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
46396
+ localConfirmedCount += 1;
46397
+ continue;
46398
+ }
46399
+ } catch {
46400
+ }
46401
+ }
46402
+ if (!daemonId || !args.dispatchMeshCommand) {
46403
+ if (!isSelfNode) unavailableNodeIds.push(nodeId);
46404
+ continue;
46405
+ }
46406
+ peerAttemptedCount += 1;
46407
+ try {
46408
+ const remoteGit = await probeRemoteMeshGitStatus({
46409
+ dispatchMeshCommand: args.dispatchMeshCommand,
46410
+ daemonId,
46411
+ workspace,
46412
+ timeoutMs: 8e3
46413
+ });
46414
+ if (remoteGit) {
46415
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
46416
+ peerConfirmedCount += 1;
46417
+ continue;
46418
+ }
46419
+ } catch {
46420
+ }
46421
+ unavailableNodeIds.push(nodeId);
46422
+ }
46423
+ return {
46424
+ directEvidenceCount: localConfirmedCount + peerConfirmedCount,
46425
+ localConfirmedCount,
46426
+ peerAttemptedCount,
46427
+ peerConfirmedCount,
46428
+ unavailableNodeIds
45880
46429
  };
45881
46430
  }
45882
- function applyCachedInlineMeshNodeStatus(status, node) {
46431
+ function summarizeMeshSessionRecord(record2) {
46432
+ return {
46433
+ sessionId: readStringValue(record2?.sessionId) || "unknown",
46434
+ providerType: readStringValue(record2?.providerType),
46435
+ state: readLiveMeshSessionState(record2),
46436
+ lifecycle: readStringValue(record2?.lifecycle),
46437
+ surfaceKind: getSessionHostSurfaceKind(record2),
46438
+ recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
46439
+ workspace: readStringValue(record2?.workspace) ?? null,
46440
+ title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
46441
+ lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
46442
+ isCached: false
46443
+ };
46444
+ }
46445
+ function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
46446
+ const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
46447
+ if (!recordNodeId || recordNodeId !== nodeId) return false;
46448
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46449
+ return !recordMeshId || recordMeshId === meshId;
46450
+ }
46451
+ function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
46452
+ const recordWorkspace = readStringValue(record2?.workspace);
46453
+ if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
46454
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46455
+ if (recordMeshId) return recordMeshId === meshId;
46456
+ return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
46457
+ }
46458
+ function readLiveMeshNodeWorkspace(args) {
46459
+ const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
46460
+ if (directNodeWorkspace) {
46461
+ return readStringValue(directNodeWorkspace.workspace) || "";
46462
+ }
46463
+ if (args.allowCoordinatorSession) {
46464
+ const coordinatorWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record2?.workspace));
46465
+ if (coordinatorWorkspace) {
46466
+ return readStringValue(coordinatorWorkspace.workspace) || "";
46467
+ }
46468
+ }
46469
+ return "";
46470
+ }
46471
+ function collectLiveMeshSessionRecords(args) {
46472
+ const matches = args.liveSessionRecords.filter((record2) => {
46473
+ const nodeWorkspace = readStringValue(args.node?.workspace);
46474
+ if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
46475
+ return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
46476
+ });
46477
+ if (args.allowCoordinatorSession) {
46478
+ for (const record2 of args.liveSessionRecords) {
46479
+ if (readStringValue(record2?.meta?.meshCoordinatorFor) !== args.meshId) continue;
46480
+ const sessionId = readStringValue(record2?.sessionId);
46481
+ if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
46482
+ matches.push(record2);
46483
+ }
46484
+ }
46485
+ return matches;
46486
+ }
46487
+ function applyCachedInlineMeshNodeStatus(status, node, options) {
45883
46488
  const cachedStatus = readObjectRecord(node?.cachedStatus);
45884
- const git = buildCachedInlineMeshGitStatus(node);
45885
- const error48 = readStringValue(cachedStatus.error, node?.error);
45886
- const health = readStringValue(cachedStatus.health, node?.health);
46489
+ const liveGit = buildInlineMeshTransitGitStatus(node);
46490
+ const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
46491
+ const error48 = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
46492
+ const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
45887
46493
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
45888
- if (!git && !error48 && !health) return false;
45889
- if (!machineStatus && !git && !error48) return false;
46494
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
46495
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
46496
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
46497
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
46498
+ if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
45890
46499
  if (git) status.git = git;
45891
46500
  if (error48) status.error = error48;
46501
+ if (machineStatus) status.machineStatus = machineStatus;
46502
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
46503
+ if (updatedAt) status.updatedAt = updatedAt;
46504
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
46505
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
45892
46506
  if (health) {
45893
46507
  status.health = health;
45894
46508
  return true;
45895
46509
  }
45896
46510
  if (git) {
45897
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
45898
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
46511
+ status.health = deriveMeshNodeHealthFromGit(git);
45899
46512
  return true;
45900
46513
  }
45901
- return false;
46514
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
45902
46515
  }
45903
46516
  async function resolveProviderTypeFromPriority(args) {
45904
46517
  if (!args.providerPriority.length) {
@@ -45928,15 +46541,92 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
45928
46541
  var REFINE_VALIDATION_OUTPUT_LIMIT_BYTES = 128 * 1024;
45929
46542
  var REFINE_VALIDATION_SUMMARY_CHARS = 2e3;
45930
46543
  var REFINE_VALIDATION_MAX_COMMANDS = 4;
46544
+ var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
45931
46545
  function truncateValidationOutput(value) {
45932
46546
  const text = typeof value === "string" ? value : value == null ? "" : String(value);
45933
46547
  if (text.length <= REFINE_VALIDATION_SUMMARY_CHARS) return text;
45934
46548
  return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
45935
46549
  [truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
45936
46550
  }
46551
+ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
46552
+ stages.push({
46553
+ stage,
46554
+ status,
46555
+ durationMs: Date.now() - startedAt,
46556
+ ...details || {}
46557
+ });
46558
+ }
46559
+ async function computeGitPatchId(cwd, fromRef, toRef) {
46560
+ const { execFileSync: execFileSync4 } = await import("child_process");
46561
+ const diff = execFileSync4("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
46562
+ cwd,
46563
+ encoding: "utf8",
46564
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
46565
+ });
46566
+ if (!diff.trim()) return "";
46567
+ const patchId = execFileSync4("git", ["patch-id", "--stable"], {
46568
+ cwd,
46569
+ input: diff,
46570
+ encoding: "utf8",
46571
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
46572
+ }).trim();
46573
+ return patchId.split(/\s+/)[0] || "";
46574
+ }
46575
+ async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
46576
+ const startedAt = Date.now();
46577
+ try {
46578
+ const { execFileSync: execFileSync4 } = await import("child_process");
46579
+ const git = (args) => execFileSync4("git", args, {
46580
+ cwd: repoRoot,
46581
+ encoding: "utf8",
46582
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
46583
+ });
46584
+ const mergeBase = git(["merge-base", baseHead, branchHead]).trim();
46585
+ const mergeTreeStdout = git(["merge-tree", "--write-tree", baseHead, branchHead]);
46586
+ const mergedTree = mergeTreeStdout.trim().split(/\s+/)[0] || "";
46587
+ if (!mergeBase || !mergedTree) {
46588
+ return {
46589
+ status: "failed",
46590
+ equivalent: false,
46591
+ baseHead,
46592
+ branchHead,
46593
+ mergeBase: mergeBase || void 0,
46594
+ mergedTree: mergedTree || void 0,
46595
+ durationMs: Date.now() - startedAt,
46596
+ error: "patch equivalence preflight could not resolve merge-base or synthetic merge tree",
46597
+ stdout: truncateValidationOutput(mergeTreeStdout)
46598
+ };
46599
+ }
46600
+ const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead);
46601
+ const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree);
46602
+ const equivalent = expectedPatchId === actualPatchId;
46603
+ return {
46604
+ status: equivalent ? "passed" : "failed",
46605
+ equivalent,
46606
+ baseHead,
46607
+ branchHead,
46608
+ mergeBase,
46609
+ mergedTree,
46610
+ expectedPatchId,
46611
+ actualPatchId,
46612
+ durationMs: Date.now() - startedAt
46613
+ };
46614
+ } catch (e) {
46615
+ return {
46616
+ status: "failed",
46617
+ equivalent: false,
46618
+ baseHead,
46619
+ branchHead,
46620
+ durationMs: Date.now() - startedAt,
46621
+ error: e?.message || String(e),
46622
+ stdout: truncateValidationOutput(e?.stdout),
46623
+ stderr: truncateValidationOutput(e?.stderr)
46624
+ };
46625
+ }
46626
+ }
45937
46627
  function readPackageScripts(workspace) {
45938
46628
  try {
45939
- const packageJsonPath = (0, import_path6.join)(workspace, "package.json");
46629
+ const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
45940
46630
  const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
45941
46631
  return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
45942
46632
  } catch {
@@ -46144,13 +46834,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46144
46834
  }
46145
46835
  function resolveHermesUserHome() {
46146
46836
  const explicitHome = process.env.HERMES_HOME?.trim();
46147
- return explicitHome || (0, import_path6.join)((0, import_os3.homedir)(), ".hermes");
46837
+ return explicitHome || (0, import_path7.join)((0, import_os3.homedir)(), ".hermes");
46148
46838
  }
46149
46839
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
46150
46840
  const sourceHome = resolveHermesUserHome();
46151
- const sourceConfigPath = (0, import_path6.join)(sourceHome, "config.yaml");
46841
+ const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
46152
46842
  if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46153
- if ((0, import_path6.resolve)(sourceConfigPath) === (0, import_path6.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46843
+ if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46154
46844
  const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
46155
46845
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
46156
46846
  return { config: baseConfig, sourceHome, sourceConfigPath };
@@ -46184,10 +46874,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46184
46874
  return sanitized;
46185
46875
  }
46186
46876
  function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
46187
- if ((0, import_path6.resolve)(sourceHome) === (0, import_path6.resolve)(targetHome)) return;
46877
+ if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
46188
46878
  for (const fileName of [".env", "auth.json"]) {
46189
- const sourcePath = (0, import_path6.join)(sourceHome, fileName);
46190
- const targetPath = (0, import_path6.join)(targetHome, fileName);
46879
+ const sourcePath = (0, import_path7.join)(sourceHome, fileName);
46880
+ const targetPath = (0, import_path7.join)(targetHome, fileName);
46191
46881
  if (!fs10.existsSync(sourcePath)) continue;
46192
46882
  try {
46193
46883
  fs10.copyFileSync(sourcePath, targetPath);
@@ -46291,30 +46981,97 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46291
46981
  * Allows the MCP server to query mesh data via get_mesh even when
46292
46982
  * the mesh doesn't exist in the local meshes.json file. */
46293
46983
  inlineMeshCache = /* @__PURE__ */ new Map();
46984
+ /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
46985
+ aggregateMeshStatusCache = /* @__PURE__ */ new Map();
46294
46986
  constructor(deps) {
46295
46987
  this.deps = deps;
46296
46988
  }
46989
+ cloneJsonValue(value) {
46990
+ if (typeof structuredClone === "function") return structuredClone(value);
46991
+ return JSON.parse(JSON.stringify(value));
46992
+ }
46993
+ getCachedAggregateMeshStatus(meshId) {
46994
+ const cached2 = this.aggregateMeshStatusCache.get(meshId);
46995
+ if (!cached2?.snapshot || cached2.snapshot.success !== true || !Array.isArray(cached2.snapshot.nodes)) return null;
46996
+ const snapshot = this.cloneJsonValue(cached2.snapshot);
46997
+ const ageMs = Math.max(0, Date.now() - cached2.builtAt);
46998
+ const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
46999
+ snapshot.sourceOfTruth = {
47000
+ ...sourceOfTruth,
47001
+ aggregateSnapshot: {
47002
+ ...sourceOfTruth.aggregateSnapshot && typeof sourceOfTruth.aggregateSnapshot === "object" ? sourceOfTruth.aggregateSnapshot : {},
47003
+ owner: "coordinator_daemon_memory",
47004
+ cached: true,
47005
+ source: "memory",
47006
+ refreshReason: "memory_cache_hit",
47007
+ ageMs,
47008
+ cachedAt: new Date(cached2.builtAt).toISOString(),
47009
+ returnedAt: (/* @__PURE__ */ new Date()).toISOString()
47010
+ }
47011
+ };
47012
+ return snapshot;
47013
+ }
47014
+ rememberAggregateMeshStatus(meshId, snapshot, refreshReason) {
47015
+ if (!snapshot || typeof snapshot !== "object" || snapshot.success !== true || !Array.isArray(snapshot.nodes)) return snapshot;
47016
+ const builtAt = Date.now();
47017
+ const next = this.cloneJsonValue(snapshot);
47018
+ const sourceOfTruth = next.sourceOfTruth && typeof next.sourceOfTruth === "object" ? next.sourceOfTruth : {};
47019
+ next.sourceOfTruth = {
47020
+ ...sourceOfTruth,
47021
+ aggregateSnapshot: {
47022
+ owner: "coordinator_daemon_memory",
47023
+ cached: false,
47024
+ source: "live_refresh",
47025
+ refreshReason,
47026
+ ageMs: 0,
47027
+ cachedAt: new Date(builtAt).toISOString(),
47028
+ returnedAt: new Date(builtAt).toISOString()
47029
+ }
47030
+ };
47031
+ this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next) });
47032
+ return next;
47033
+ }
46297
47034
  getCachedInlineMesh(meshId, inlineMesh) {
46298
47035
  if (inlineMesh && typeof inlineMesh === "object") {
46299
- this.inlineMeshCache.set(meshId, inlineMesh);
46300
- return inlineMesh;
47036
+ return this.warmInlineMeshCache(meshId, inlineMesh);
46301
47037
  }
46302
47038
  return this.inlineMeshCache.get(meshId);
46303
47039
  }
47040
+ warmInlineMeshCache(meshId, inlineMesh) {
47041
+ if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
47042
+ const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
47043
+ const cached2 = this.inlineMeshCache.get(meshId);
47044
+ if (cached2) {
47045
+ const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
47046
+ this.inlineMeshCache.set(meshId, merged);
47047
+ return merged;
47048
+ }
47049
+ this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
47050
+ return sanitizedInlineMesh;
47051
+ }
46304
47052
  async getMeshForCommand(meshId, inlineMesh, options) {
46305
47053
  const preferInline = options?.preferInline === true;
46306
47054
  if (preferInline) {
46307
- const cached22 = this.getCachedInlineMesh(meshId, inlineMesh);
46308
- if (cached22) return { mesh: cached22, inline: true };
47055
+ const cached22 = this.getCachedInlineMesh(meshId);
47056
+ if (cached22) return { mesh: cached22, inline: true, source: "inline_cache" };
47057
+ if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
47058
+ this.warmInlineMeshCache(meshId, inlineMesh);
47059
+ return { mesh: inlineMesh, inline: true, source: "inline_bootstrap" };
47060
+ }
46309
47061
  }
46310
47062
  try {
46311
47063
  const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46312
47064
  const mesh = getMesh3(meshId);
46313
- if (mesh) return { mesh, inline: false };
47065
+ if (mesh) return { mesh, inline: false, source: "local_config" };
46314
47066
  } catch {
46315
47067
  }
46316
- const cached2 = this.getCachedInlineMesh(meshId, inlineMesh);
46317
- return cached2 ? { mesh: cached2, inline: true } : null;
47068
+ const cached2 = this.getCachedInlineMesh(meshId);
47069
+ if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
47070
+ const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
47071
+ return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
47072
+ }
47073
+ invalidateAggregateMeshStatus(meshId) {
47074
+ this.aggregateMeshStatusCache.delete(meshId);
46318
47075
  }
46319
47076
  updateInlineMeshNode(meshId, mesh, node) {
46320
47077
  if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
@@ -46323,6 +47080,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46323
47080
  else mesh.nodes.push(node);
46324
47081
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
46325
47082
  this.inlineMeshCache.set(meshId, mesh);
47083
+ this.invalidateAggregateMeshStatus(meshId);
46326
47084
  }
46327
47085
  removeInlineMeshNode(meshId, mesh, nodeId) {
46328
47086
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
@@ -46331,6 +47089,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46331
47089
  mesh.nodes.splice(idx, 1);
46332
47090
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
46333
47091
  this.inlineMeshCache.set(meshId, mesh);
47092
+ this.invalidateAggregateMeshStatus(meshId);
46334
47093
  return true;
46335
47094
  }
46336
47095
  normalizeMeshSessionCleanupMode(value) {
@@ -46379,7 +47138,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46379
47138
  }
46380
47139
  const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
46381
47140
  const normalizePath = (value) => {
46382
- const resolved = (0, import_path6.resolve)(value);
47141
+ const resolved = (0, import_path7.resolve)(value);
46383
47142
  try {
46384
47143
  return fs10.realpathSync(resolved);
46385
47144
  } catch {
@@ -46543,6 +47302,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46543
47302
  const deletedSessionIds = [];
46544
47303
  const skippedSessionIds = [];
46545
47304
  const skippedLiveSessionIds = [];
47305
+ const skippedCoordinatorSessionIds = [];
46546
47306
  const deleteUnsupportedSessionIds = [];
46547
47307
  const recordsRemainSessionIds = [];
46548
47308
  const errors = [];
@@ -46575,6 +47335,12 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46575
47335
  const completed = this.isCompletedHostedSession(record2);
46576
47336
  const surfaceKind = getSessionHostSurfaceKind(record2);
46577
47337
  const liveRuntime = surfaceKind === "live_runtime";
47338
+ const coordinatorSession = readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId;
47339
+ if (!hasExplicitSessionIds && coordinatorSession) {
47340
+ skippedSessionIds.push(sessionId);
47341
+ skippedCoordinatorSessionIds.push(sessionId);
47342
+ continue;
47343
+ }
46578
47344
  if (!hasExplicitSessionIds && liveRuntime) {
46579
47345
  skippedSessionIds.push(sessionId);
46580
47346
  skippedLiveSessionIds.push(sessionId);
@@ -46640,6 +47406,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46640
47406
  deletedSessionIds,
46641
47407
  skippedSessionIds,
46642
47408
  skippedLiveSessionIds,
47409
+ skippedCoordinatorSessionIds,
46643
47410
  ...deleteUnsupported ? {
46644
47411
  deleteUnsupported: true,
46645
47412
  effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
@@ -46772,7 +47539,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46772
47539
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
46773
47540
  }
46774
47541
  case "get_pending_mesh_events": {
46775
- const events = drainPendingMeshCoordinatorEvents();
47542
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47543
+ const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
46776
47544
  return { success: true, events };
46777
47545
  }
46778
47546
  case "launch_cli":
@@ -47301,15 +48069,39 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47301
48069
  case "get_mesh": {
47302
48070
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47303
48071
  if (!meshId) return { success: false, error: "meshId required" };
47304
- try {
47305
- const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
47306
- const mesh = getMesh3(meshId);
47307
- if (mesh) return { success: true, mesh };
47308
- } catch {
48072
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
48073
+ if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
48074
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
48075
+ const directTruth = await hydrateInlineMeshDirectTruth({
48076
+ mesh: meshRecord.mesh,
48077
+ meshSource: meshRecord.source,
48078
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
48079
+ statusInstanceId: this.deps.statusInstanceId,
48080
+ localMachineId: loadConfig2().machineId || ""
48081
+ });
48082
+ const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
48083
+ const sourceOfTruth = {
48084
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
48085
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
48086
+ directPeerTruth: {
48087
+ required: requireDirectPeerTruth,
48088
+ satisfied: directTruthSatisfied,
48089
+ directEvidenceCount: directTruth.directEvidenceCount,
48090
+ localConfirmedCount: directTruth.localConfirmedCount,
48091
+ peerAttemptedCount: directTruth.peerAttemptedCount,
48092
+ peerConfirmedCount: directTruth.peerConfirmedCount,
48093
+ unavailableNodeIds: directTruth.unavailableNodeIds
48094
+ }
48095
+ };
48096
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
48097
+ return {
48098
+ success: false,
48099
+ code: "mesh_direct_peer_truth_unavailable",
48100
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
48101
+ sourceOfTruth
48102
+ };
47309
48103
  }
47310
- const cached2 = this.inlineMeshCache.get(meshId);
47311
- if (cached2) return { success: true, mesh: cached2 };
47312
- return { success: false, error: "Mesh not found" };
48104
+ return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
47313
48105
  }
47314
48106
  case "create_mesh": {
47315
48107
  const name = typeof args?.name === "string" ? args.name.trim() : "";
@@ -47339,6 +48131,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47339
48131
  const mesh = updateMesh2(meshId, patch);
47340
48132
  if (!mesh) return { success: false, error: "Mesh not found" };
47341
48133
  this.inlineMeshCache.set(meshId, mesh);
48134
+ this.invalidateAggregateMeshStatus(meshId);
47342
48135
  return { success: true, mesh };
47343
48136
  } catch (e) {
47344
48137
  return { success: false, error: e.message };
@@ -47528,26 +48321,41 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47528
48321
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47529
48322
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47530
48323
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
48324
+ const refineStages = [];
47531
48325
  try {
47532
48326
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
47533
48327
  const mesh = meshRecord?.mesh;
47534
48328
  const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
47535
- if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
48329
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
47536
48330
  if (!node.isLocalWorktree || !node.workspace) {
47537
- return { success: false, error: `Refinery requires a local worktree node` };
48331
+ return { success: false, error: `Refinery requires a local worktree node`, refineStages };
47538
48332
  }
47539
48333
  const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
47540
48334
  const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
47541
- if (!repoRoot) return { success: false, error: "Source node repoRoot not found" };
48335
+ if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
47542
48336
  const { execFile: execFile3 } = await import("child_process");
47543
48337
  const { promisify: promisify3 } = await import("util");
47544
48338
  const execFileAsync3 = promisify3(execFile3);
48339
+ const resolveStarted = Date.now();
47545
48340
  const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
47546
48341
  const branch = branchStdout.trim();
47547
- if (!branch) return { success: false, error: "Could not determine branch of the worktree node" };
48342
+ if (!branch) return { success: false, error: "Could not determine branch of the worktree node", refineStages };
47548
48343
  const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
47549
48344
  const baseBranch = baseBranchStdout.trim();
48345
+ const { stdout: baseHeadStdout } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
48346
+ const { stdout: branchHeadStdout } = await execFileAsync3("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
48347
+ const baseHead = baseHeadStdout.trim();
48348
+ const branchHead = branchHeadStdout.trim();
48349
+ recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead });
48350
+ const validationStarted = Date.now();
47550
48351
  const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace);
48352
+ recordMeshRefineStage(
48353
+ refineStages,
48354
+ "validation",
48355
+ validationSummary.status === "passed" ? "passed" : validationSummary.status === "failed" ? "failed" : "skipped",
48356
+ validationStarted,
48357
+ { validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
48358
+ );
47551
48359
  if (validationSummary.status === "failed") {
47552
48360
  return {
47553
48361
  success: false,
@@ -47557,6 +48365,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47557
48365
  branch,
47558
48366
  into: baseBranch,
47559
48367
  validationSummary,
48368
+ refineStages,
47560
48369
  finalBranchConvergenceState: {
47561
48370
  branch,
47562
48371
  baseBranch,
@@ -47576,6 +48385,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47576
48385
  branch,
47577
48386
  into: baseBranch,
47578
48387
  validationSummary,
48388
+ refineStages,
47579
48389
  finalBranchConvergenceState: {
47580
48390
  branch,
47581
48391
  baseBranch,
@@ -47586,37 +48396,121 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47586
48396
  }
47587
48397
  };
47588
48398
  }
48399
+ const patchEquivalenceStarted = Date.now();
48400
+ const patchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
48401
+ recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
48402
+ equivalent: patchEquivalence.equivalent,
48403
+ expectedPatchId: patchEquivalence.expectedPatchId,
48404
+ actualPatchId: patchEquivalence.actualPatchId,
48405
+ error: patchEquivalence.error
48406
+ });
48407
+ if (!patchEquivalence.equivalent) {
48408
+ return {
48409
+ success: false,
48410
+ code: "patch_equivalence_failed",
48411
+ convergenceStatus: "blocked_review",
48412
+ error: "Refinery patch-equivalence preflight failed; merge/refine was not attempted.",
48413
+ branch,
48414
+ into: baseBranch,
48415
+ validationSummary,
48416
+ patchEquivalence,
48417
+ refineStages,
48418
+ finalBranchConvergenceState: {
48419
+ branch,
48420
+ baseBranch,
48421
+ merged: false,
48422
+ removed: false,
48423
+ validation: "passed",
48424
+ patchEquivalence: "failed",
48425
+ status: "blocked_review"
48426
+ }
48427
+ };
48428
+ }
48429
+ let mergeResult;
48430
+ const mergeStarted = Date.now();
47589
48431
  try {
47590
- await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
48432
+ const result = await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
48433
+ mergeResult = {
48434
+ stdout: truncateValidationOutput(result.stdout),
48435
+ stderr: truncateValidationOutput(result.stderr),
48436
+ durationMs: Date.now() - mergeStarted
48437
+ };
48438
+ recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
47591
48439
  } catch (e) {
48440
+ recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
48441
+ error: e?.message || String(e),
48442
+ stdout: truncateValidationOutput(e?.stdout),
48443
+ stderr: truncateValidationOutput(e?.stderr)
48444
+ });
47592
48445
  return {
47593
48446
  success: false,
47594
48447
  error: `Merge failed (conflicts?): ${e.message}`,
47595
48448
  validationSummary,
48449
+ patchEquivalence,
48450
+ refineStages,
47596
48451
  finalBranchConvergenceState: {
47597
48452
  branch,
47598
48453
  baseBranch,
47599
48454
  merged: false,
47600
48455
  removed: false,
47601
48456
  validation: "passed",
48457
+ patchEquivalence: "passed",
47602
48458
  status: "not_mergeable"
47603
48459
  }
47604
48460
  };
47605
48461
  }
48462
+ const cleanupStarted = Date.now();
47606
48463
  const removeResult = await this.execute("remove_mesh_node", {
47607
48464
  meshId,
47608
48465
  nodeId,
47609
- sessionCleanupMode: "kill",
48466
+ sessionCleanupMode: "preserve",
47610
48467
  inlineMesh: args?.inlineMesh
47611
48468
  });
48469
+ recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
48470
+ removed: removeResult?.removed,
48471
+ code: removeResult?.code,
48472
+ error: removeResult?.error
48473
+ });
48474
+ let ledgerError;
48475
+ const ledgerStarted = Date.now();
47612
48476
  try {
47613
48477
  const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
47614
48478
  appendLedgerEntry2(meshId, {
47615
48479
  kind: "node_removed",
47616
48480
  nodeId,
47617
- payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary }
48481
+ payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence }
47618
48482
  });
47619
- } catch {
48483
+ recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
48484
+ } catch (e) {
48485
+ ledgerError = e?.message || String(e);
48486
+ recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
48487
+ }
48488
+ const finalBranchConvergenceState = {
48489
+ branch: baseBranch,
48490
+ mergedBranch: branch,
48491
+ baseBranch,
48492
+ merged: true,
48493
+ removed: removeResult?.success !== false,
48494
+ validation: "passed",
48495
+ patchEquivalence: "passed",
48496
+ status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
48497
+ };
48498
+ if (removeResult?.success === false) {
48499
+ return {
48500
+ success: false,
48501
+ code: "cleanup_failed",
48502
+ error: "Refinery merge completed but worktree cleanup failed; manual cleanup/retry is required.",
48503
+ merged: true,
48504
+ branch,
48505
+ into: baseBranch,
48506
+ removeResult,
48507
+ validationSummary,
48508
+ patchEquivalence,
48509
+ mergeResult,
48510
+ refineStages,
48511
+ ...ledgerError ? { ledgerError } : {},
48512
+ finalBranchConvergenceState
48513
+ };
47620
48514
  }
47621
48515
  return {
47622
48516
  success: true,
@@ -47625,18 +48519,14 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47625
48519
  into: baseBranch,
47626
48520
  removeResult,
47627
48521
  validationSummary,
47628
- finalBranchConvergenceState: {
47629
- branch: baseBranch,
47630
- mergedBranch: branch,
47631
- baseBranch,
47632
- merged: true,
47633
- removed: removeResult?.success !== false,
47634
- validation: "passed",
47635
- status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
47636
- }
48522
+ patchEquivalence,
48523
+ mergeResult,
48524
+ refineStages,
48525
+ ...ledgerError ? { ledgerError } : {},
48526
+ finalBranchConvergenceState
47637
48527
  };
47638
48528
  } catch (e) {
47639
- return { success: false, error: e.message };
48529
+ return { success: false, error: e.message, refineStages };
47640
48530
  }
47641
48531
  }
47642
48532
  case "remove_mesh_node": {
@@ -47677,6 +48567,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47677
48567
  } else {
47678
48568
  const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
47679
48569
  removed = removeNode3(meshId, nodeId);
48570
+ if (removed) this.invalidateAggregateMeshStatus(meshId);
47680
48571
  }
47681
48572
  if (removed) {
47682
48573
  try {
@@ -47755,6 +48646,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47755
48646
  policy: { ...sourceNode.policy || {} }
47756
48647
  });
47757
48648
  if (!node) return { success: false, error: "Failed to register worktree node" };
48649
+ this.invalidateAggregateMeshStatus(meshId);
47758
48650
  }
47759
48651
  const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
47760
48652
  if (initSubmodules) {
@@ -47830,7 +48722,14 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47830
48722
  cliType
47831
48723
  };
47832
48724
  }
47833
- const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
48725
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
48726
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
48727
+ const workspace = readLiveMeshNodeWorkspace({
48728
+ meshId,
48729
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
48730
+ liveSessionRecords: liveMeshSessions,
48731
+ allowCoordinatorSession: true
48732
+ }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
47834
48733
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
47835
48734
  if (!cliType) {
47836
48735
  const resolved = await resolveProviderTypeFromPriority({
@@ -47992,7 +48891,7 @@ ${block}`);
47992
48891
  workspace
47993
48892
  };
47994
48893
  }
47995
- const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
48894
+ const { existsSync: existsSync26, readFileSync: readFileSync18, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
47996
48895
  const { dirname: dirname9 } = await import("path");
47997
48896
  const mcpConfigPath = coordinatorSetup.configPath;
47998
48897
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -48035,14 +48934,14 @@ ${block}`);
48035
48934
  if (hermesManualFallback) return returnManualFallback(message);
48036
48935
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
48037
48936
  }
48038
- const hadExistingMcpConfig = existsSync25(mcpConfigPath);
48937
+ const hadExistingMcpConfig = existsSync26(mcpConfigPath);
48039
48938
  let existingMcpConfig = hermesBaseConfig?.config || {};
48040
48939
  if (hermesBaseConfig) {
48041
48940
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
48042
48941
  }
48043
48942
  if (hadExistingMcpConfig) {
48044
48943
  try {
48045
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
48944
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync18(mcpConfigPath, "utf-8"), configFormat);
48046
48945
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
48047
48946
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
48048
48947
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -48132,110 +49031,264 @@ ${block}`);
48132
49031
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
48133
49032
  const mesh = meshRecord?.mesh;
48134
49033
  if (!mesh) return { success: false, error: "Mesh not found" };
49034
+ const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
49035
+ if (!refreshRequested) {
49036
+ const cachedStatus = this.getCachedAggregateMeshStatus(meshId);
49037
+ if (cachedStatus) return cachedStatus;
49038
+ }
49039
+ const refreshReason = refreshRequested ? "explicit_refresh" : "cold_cache_miss";
48135
49040
  const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
48136
49041
  const queue = getQueue2(meshId);
48137
49042
  const queueSummary = getMeshQueueStats2(meshId);
48138
49043
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48139
49044
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
48140
49045
  const ledgerSummary = getLedgerSummary2(meshId);
49046
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
49047
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
49048
+ const localMachineId = loadConfig2().machineId || "";
49049
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
49050
+ const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
49051
+ mesh,
49052
+ meshSource: meshRecord.source,
49053
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
49054
+ statusInstanceId: this.deps.statusInstanceId,
49055
+ localMachineId
49056
+ }) : {
49057
+ directEvidenceCount: 0,
49058
+ localConfirmedCount: 0,
49059
+ peerAttemptedCount: 0,
49060
+ peerConfirmedCount: 0,
49061
+ unavailableNodeIds: []
49062
+ };
49063
+ const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
49064
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
49065
+ return {
49066
+ success: false,
49067
+ code: "mesh_direct_peer_truth_unavailable",
49068
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct mesh_status probes succeed.",
49069
+ sourceOfTruth: {
49070
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
49071
+ coordinatorOwnsLiveTruth: false,
49072
+ currentStatus: "direct_peer_truth_unavailable",
49073
+ directPeerTruth: {
49074
+ required: true,
49075
+ satisfied: false,
49076
+ directEvidenceCount: directTruth.directEvidenceCount,
49077
+ localConfirmedCount: directTruth.localConfirmedCount,
49078
+ peerAttemptedCount: directTruth.peerAttemptedCount,
49079
+ peerConfirmedCount: directTruth.peerConfirmedCount,
49080
+ unavailableNodeIds: directTruth.unavailableNodeIds
49081
+ }
49082
+ }
49083
+ };
49084
+ }
49085
+ const directTruthUnavailableNodeIds = new Set(directTruth.unavailableNodeIds);
49086
+ const selectedCoordinatorNodeId = readStringValue(
49087
+ mesh.coordinator?.preferredNodeId,
49088
+ mesh.nodes?.[0]?.id,
49089
+ mesh.nodes?.[0]?.nodeId
49090
+ );
49091
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
49092
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
48141
49093
  const nodeStatuses = [];
48142
- for (const node of mesh.nodes || []) {
49094
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
49095
+ const nodeId = String(node.id || node.nodeId || "");
49096
+ const daemonId = readStringValue(node.daemonId);
49097
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
49098
+ const isSelfNode = Boolean(
49099
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
49100
+ ) || Boolean(
49101
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
49102
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
48143
49103
  const status = {
48144
- nodeId: node.id || node.nodeId,
49104
+ nodeId,
48145
49105
  machineLabel: node.machineLabel || node.id || node.nodeId,
48146
49106
  workspace: node.workspace,
48147
49107
  repoRoot: node.repoRoot,
48148
49108
  isLocalWorktree: node.isLocalWorktree,
48149
49109
  worktreeBranch: node.worktreeBranch,
48150
- daemonId: node.daemonId,
49110
+ daemonId,
48151
49111
  machineId: node.machineId,
49112
+ machineStatus: node.machineStatus,
48152
49113
  health: "unknown",
48153
49114
  providers: node.providers || [],
48154
- activeSessions: []
49115
+ providerPriority,
49116
+ activeSessions: [],
49117
+ activeSessionDetails: [],
49118
+ launchReady: false
48155
49119
  };
48156
- if (node.workspace && typeof node.workspace === "string") {
48157
- if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
48158
- nodeStatuses.push(status);
48159
- continue;
49120
+ if (isSelfNode) {
49121
+ status.connection = {
49122
+ perspective: "selected_coordinator",
49123
+ source: "mesh_peer_status",
49124
+ state: "self",
49125
+ transport: "local",
49126
+ reported: true,
49127
+ reason: "Selected coordinator daemon",
49128
+ lastStateChangeAt: refreshedAt
49129
+ };
49130
+ } else if (daemonId) {
49131
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
49132
+ status.connection = connection ?? {
49133
+ perspective: "selected_coordinator",
49134
+ source: "not_reported",
49135
+ state: "unknown",
49136
+ transport: "unknown",
49137
+ reported: false,
49138
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
49139
+ };
49140
+ } else {
49141
+ status.connection = {
49142
+ perspective: "selected_coordinator",
49143
+ source: "not_reported",
49144
+ state: "unknown",
49145
+ transport: "unknown",
49146
+ reported: false,
49147
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
49148
+ };
49149
+ }
49150
+ const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
49151
+ meshId,
49152
+ node,
49153
+ nodeId,
49154
+ liveSessionRecords: liveMeshSessions,
49155
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
49156
+ });
49157
+ const workspace = readLiveMeshNodeWorkspace({
49158
+ meshId,
49159
+ nodeId,
49160
+ liveSessionRecords: matchedLiveSessionRecords,
49161
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
49162
+ }) || (typeof node.workspace === "string" ? node.workspace : "");
49163
+ status.workspace = workspace || node.workspace;
49164
+ if (matchedLiveSessionRecords.length > 0) {
49165
+ const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
49166
+ const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
49167
+ status.activeSessions = sessionIds;
49168
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
49169
+ if (providerTypes.length > 0) {
49170
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
48160
49171
  }
48161
- try {
48162
- const { execFile: execFile3 } = await import("child_process");
48163
- const { promisify: promisify3 } = await import("util");
48164
- const execFileAsync3 = promisify3(execFile3);
48165
- const runGit2 = async (args2) => {
48166
- const result = await execFileAsync3("git", ["-C", node.workspace, ...args2], {
48167
- encoding: "utf8",
48168
- timeout: 1e4
48169
- });
48170
- return result.stdout.trim();
48171
- };
48172
- const branch = await runGit2(["branch", "--show-current"]).catch(() => "");
48173
- const porc = await runGit2(["status", "--porcelain"]).catch(() => "");
48174
- const headCommit = await runGit2(["rev-parse", "--short", "HEAD"]).catch(() => null);
48175
- const headMessage = await runGit2(["log", "-1", "--format=%s"]).catch(() => null);
48176
- const upstream = await runGit2(["rev-parse", "--abbrev-ref", "@{upstream}"]).catch(() => null);
48177
- const aheadBehind = await runGit2(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]).catch(() => "");
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;
49172
+ }
49173
+ if (workspace) {
49174
+ if (!fs10.existsSync(workspace)) {
49175
+ const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
49176
+ let remoteProbeApplied = false;
49177
+ if (inlineTransitGit) {
49178
+ status.git = inlineTransitGit;
49179
+ status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
49180
+ remoteProbeApplied = true;
49181
+ } else if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
49182
+ try {
49183
+ const remoteGit = await probeRemoteMeshGitStatus({
49184
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
49185
+ daemonId,
49186
+ workspace,
49187
+ timeoutMs: 8e3
49188
+ });
49189
+ if (remoteGit) {
49190
+ status.git = remoteGit;
49191
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
49192
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
49193
+ remoteProbeApplied = true;
49194
+ }
49195
+ } catch {
49196
+ const refreshedConnection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
49197
+ const refreshedConnectionState = readStringValue(refreshedConnection?.state);
49198
+ if (refreshedConnection && refreshedConnectionState === "connected") {
49199
+ status.connection = refreshedConnection;
49200
+ try {
49201
+ const remoteGit = await probeRemoteMeshGitStatus({
49202
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
49203
+ daemonId,
49204
+ workspace,
49205
+ timeoutMs: 12e3
49206
+ });
49207
+ if (remoteGit) {
49208
+ status.git = remoteGit;
49209
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
49210
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
49211
+ remoteProbeApplied = true;
49212
+ }
49213
+ } catch {
49214
+ }
49215
+ }
48185
49216
  }
48186
49217
  }
48187
- const dirty = porc.length > 0;
48188
- const lines = porc ? porc.split("\n").filter(Boolean) : [];
48189
- let staged = 0, modified = 0, untracked = 0, deleted = 0, renamed = 0;
48190
- for (const line of lines) {
48191
- const xy = line.slice(0, 2);
48192
- if (xy[0] !== " " && xy[0] !== "?") staged++;
48193
- if (xy[1] === "M") modified++;
48194
- if (xy[1] === "D") deleted++;
48195
- if (xy[0] === "R" || xy[1] === "R") renamed++;
48196
- if (xy === "??") untracked++;
49218
+ if (!remoteProbeApplied) {
49219
+ const connectionState = readStringValue(status.connection?.state);
49220
+ const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
49221
+ if (pendingPeerGitProbe) {
49222
+ status.gitProbePending = true;
49223
+ status.health = "unknown";
49224
+ }
49225
+ if (applyCachedInlineMeshNodeStatus(
49226
+ status,
49227
+ node,
49228
+ pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
49229
+ )) {
49230
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
49231
+ nodeStatuses.push(status);
49232
+ continue;
49233
+ }
49234
+ if (meshRecord?.source === "inline_cache" && !isSelfNode) {
49235
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
49236
+ nodeStatuses.push(status);
49237
+ continue;
49238
+ }
48197
49239
  }
48198
- status.git = {
48199
- workspace: node.workspace,
48200
- repoRoot: node.workspace,
48201
- isGitRepo: true,
48202
- branch: branch || null,
48203
- headCommit,
48204
- headMessage,
48205
- upstream,
48206
- ahead,
48207
- behind,
48208
- staged,
48209
- modified,
48210
- untracked,
48211
- deleted,
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";
49240
+ } else {
49241
+ try {
49242
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
49243
+ status.git = gitStatus;
49244
+ recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
49245
+ if (gitStatus.isGitRepo) {
49246
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
49247
+ } else {
49248
+ status.health = "degraded";
49249
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
49250
+ }
49251
+ } catch {
49252
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
49253
+ status.health = "degraded";
49254
+ }
48222
49255
  }
48223
49256
  }
48224
49257
  } else {
48225
49258
  applyCachedInlineMeshNodeStatus(status, node);
48226
49259
  }
49260
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
48227
49261
  nodeStatuses.push(status);
48228
49262
  }
48229
- return {
49263
+ const statusResult = {
48230
49264
  success: true,
48231
49265
  meshId: mesh.id,
48232
49266
  meshName: mesh.name,
48233
49267
  repoIdentity: mesh.repoIdentity,
48234
49268
  defaultBranch: mesh.defaultBranch,
49269
+ refreshedAt,
49270
+ sourceOfTruth: {
49271
+ membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
49272
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
49273
+ ...requireDirectPeerTruth ? {
49274
+ currentStatus: directTruthSatisfied ? "live_git_and_session_probes" : "direct_peer_truth_unavailable",
49275
+ directPeerTruth: {
49276
+ required: true,
49277
+ satisfied: directTruthSatisfied,
49278
+ directEvidenceCount: directTruth.directEvidenceCount,
49279
+ localConfirmedCount: directTruth.localConfirmedCount,
49280
+ peerAttemptedCount: directTruth.peerAttemptedCount,
49281
+ peerConfirmedCount: directTruth.peerConfirmedCount,
49282
+ unavailableNodeIds: directTruth.unavailableNodeIds
49283
+ }
49284
+ } : {},
49285
+ historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
49286
+ },
48235
49287
  nodes: nodeStatuses,
48236
49288
  queue: { tasks: queue, summary: queueSummary },
48237
49289
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
48238
49290
  };
49291
+ return this.rememberAggregateMeshStatus(meshId, statusResult, refreshReason);
48239
49292
  } catch (e) {
48240
49293
  return { success: false, error: e.message };
48241
49294
  }
@@ -56107,6 +57160,7 @@ data: ${JSON.stringify(msg.data)}
56107
57160
  sessionHostControl: config2.sessionHostControl,
56108
57161
  statusInstanceId: config2.statusInstanceId,
56109
57162
  statusVersion: config2.statusVersion,
57163
+ getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
56110
57164
  getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG2.forComponent(`CDP:${ideType}`).asLogFn())
56111
57165
  });
56112
57166
  poller = new AgentStreamPoller({