@adhdev/daemon-standalone 0.9.82-rc.22 → 0.9.82-rc.24

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,109 @@ 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;
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
+ });
23607
23646
  }
23608
23647
  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") {
23614
- const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
23615
- if (time3 > bestTime) {
23616
- bestTime = time3;
23617
- bestIdx = i;
23618
- }
23619
- }
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];
23648
+ return withQueueLock(meshId, () => {
23649
+ const queue = readQueue(meshId);
23650
+ let bestIdx = -1;
23651
+ let bestTime = 0;
23652
+ for (let i = queue.length - 1; i >= 0; i--) {
23653
+ if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
23654
+ const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
23655
+ if (time3 > bestTime) {
23656
+ bestTime = time3;
23657
+ bestIdx = i;
23658
+ }
23659
+ }
23660
+ }
23661
+ if (bestIdx === -1) return null;
23662
+ queue[bestIdx].status = status;
23663
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23664
+ writeQueue(meshId, queue);
23665
+ return queue[bestIdx];
23666
+ });
23626
23667
  }
23627
23668
  function getMeshQueueStats(meshId) {
23628
23669
  const queue = readQueue(meshId);
@@ -24051,21 +24092,70 @@ Follow these recovery rules:
24051
24092
  triggerMeshQueue: () => triggerMeshQueue,
24052
24093
  tryAssignQueueTask: () => tryAssignQueueTask
24053
24094
  });
24095
+ function sweepExpiredRemoteIdleSessions() {
24096
+ const now = Date.now();
24097
+ for (const [key, session] of remoteIdleSessions) {
24098
+ if (session.expiresAt <= now) remoteIdleSessions.delete(key);
24099
+ }
24100
+ }
24101
+ function getPendingEventsPath(meshId) {
24102
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
24103
+ return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
24104
+ }
24054
24105
  function queuePendingMeshCoordinatorEvent(event) {
24055
- if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
24106
+ try {
24107
+ (0, import_fs6.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
24108
+ return true;
24109
+ } catch (e) {
24110
+ LOG2.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
24056
24111
  return false;
24057
24112
  }
24058
- pendingMeshCoordinatorEvents.push(event);
24059
- return true;
24060
24113
  }
24061
- function drainPendingMeshCoordinatorEvents() {
24062
- return pendingMeshCoordinatorEvents.splice(0);
24114
+ function drainPendingMeshCoordinatorEvents(meshId) {
24115
+ if (!meshId) return [];
24116
+ const path28 = getPendingEventsPath(meshId);
24117
+ if (!(0, import_fs6.existsSync)(path28)) return [];
24118
+ try {
24119
+ const raw = (0, import_fs6.readFileSync)(path28, "utf-8");
24120
+ try {
24121
+ (0, import_fs6.unlinkSync)(path28);
24122
+ } catch {
24123
+ }
24124
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
24125
+ try {
24126
+ return [JSON.parse(line)];
24127
+ } catch {
24128
+ return [];
24129
+ }
24130
+ });
24131
+ } catch {
24132
+ return [];
24133
+ }
24063
24134
  }
24064
- function getPendingMeshCoordinatorEvents() {
24065
- return pendingMeshCoordinatorEvents.slice();
24135
+ function getPendingMeshCoordinatorEvents(meshId) {
24136
+ if (!meshId) return [];
24137
+ const path28 = getPendingEventsPath(meshId);
24138
+ if (!(0, import_fs6.existsSync)(path28)) return [];
24139
+ try {
24140
+ const raw = (0, import_fs6.readFileSync)(path28, "utf-8");
24141
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
24142
+ try {
24143
+ return [JSON.parse(line)];
24144
+ } catch {
24145
+ return [];
24146
+ }
24147
+ });
24148
+ } catch {
24149
+ return [];
24150
+ }
24066
24151
  }
24067
- function clearPendingMeshCoordinatorEvents() {
24068
- pendingMeshCoordinatorEvents.splice(0);
24152
+ function clearPendingMeshCoordinatorEvents(meshId) {
24153
+ if (!meshId) return;
24154
+ const path28 = getPendingEventsPath(meshId);
24155
+ if ((0, import_fs6.existsSync)(path28)) try {
24156
+ (0, import_fs6.unlinkSync)(path28);
24157
+ } catch {
24158
+ }
24069
24159
  }
24070
24160
  function readNonEmptyString(value) {
24071
24161
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -24129,7 +24219,16 @@ Follow these recovery rules:
24129
24219
  message: task.message
24130
24220
  }).catch((e) => {
24131
24221
  LOG2.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
24132
- updateTaskStatus(meshId, task.id, "failed");
24222
+ updateTaskStatus(meshId, task.id, "pending");
24223
+ try {
24224
+ appendLedgerEntry(meshId, {
24225
+ kind: "dispatch_failed",
24226
+ nodeId,
24227
+ sessionId,
24228
+ payload: { taskId: task.id, error: e?.message, retryable: true }
24229
+ });
24230
+ } catch {
24231
+ }
24133
24232
  });
24134
24233
  return true;
24135
24234
  }
@@ -24472,9 +24571,9 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
24472
24571
  const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
24473
24572
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
24474
24573
  if (nodeId && providerType) {
24475
- setTimeout(() => {
24574
+ setImmediate(() => {
24476
24575
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
24477
- }, 500);
24576
+ });
24478
24577
  }
24479
24578
  }
24480
24579
  } else if (args.event === "agent:ready") {
@@ -24512,13 +24611,17 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
24512
24611
  }
24513
24612
  }
24514
24613
  if (sessionId && nodeId && providerType) {
24515
- remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
24516
- setTimeout(() => {
24614
+ sweepExpiredRemoteIdleSessions();
24615
+ remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
24616
+ nodeId,
24617
+ sessionId,
24618
+ providerType,
24619
+ expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
24620
+ });
24621
+ setImmediate(() => {
24517
24622
  const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
24518
- if (assigned) {
24519
- remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
24520
- }
24521
- }, 500);
24623
+ if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
24624
+ });
24522
24625
  }
24523
24626
  } else if (args.event === "agent:generating_started") {
24524
24627
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
@@ -24721,9 +24824,10 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
24721
24824
  });
24722
24825
  });
24723
24826
  }
24827
+ var import_fs6;
24828
+ var import_path5;
24829
+ var REMOTE_IDLE_SESSION_TTL_MS;
24724
24830
  var remoteIdleSessions;
24725
- var MAX_PENDING_EVENTS;
24726
- var pendingMeshCoordinatorEvents;
24727
24831
  var MESH_COORDINATOR_EVENTS;
24728
24832
  var EVENT_TO_LEDGER_KIND;
24729
24833
  var INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS;
@@ -24733,15 +24837,16 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
24733
24837
  var init_mesh_events = __esm2({
24734
24838
  "src/mesh/mesh-events.ts"() {
24735
24839
  "use strict";
24840
+ import_fs6 = require("fs");
24841
+ import_path5 = require("path");
24736
24842
  init_config();
24737
24843
  init_mesh_config();
24738
24844
  init_cli_detector();
24739
24845
  init_logger();
24740
24846
  init_mesh_ledger();
24741
24847
  init_mesh_work_queue();
24848
+ REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
24742
24849
  remoteIdleSessions = /* @__PURE__ */ new Map();
24743
- MAX_PENDING_EVENTS = 50;
24744
- pendingMeshCoordinatorEvents = [];
24745
24850
  MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
24746
24851
  "agent:generating_started",
24747
24852
  "agent:generating_completed",
@@ -29981,8 +30086,8 @@ ${lastSnapshot}`;
29981
30086
  this.targetDaemonId = context.targetDaemonId;
29982
30087
  }
29983
30088
  };
29984
- var import_fs6 = require("fs");
29985
- var import_path5 = require("path");
30089
+ var import_fs7 = require("fs");
30090
+ var import_path6 = require("path");
29986
30091
  init_config();
29987
30092
  var DEFAULT_STATE = {
29988
30093
  recentActivity: [],
@@ -29996,7 +30101,7 @@ ${lastSnapshot}`;
29996
30101
  return !!value && typeof value === "object" && !Array.isArray(value);
29997
30102
  }
29998
30103
  function getStatePath() {
29999
- return (0, import_path5.join)(getConfigDir(), "state.json");
30104
+ return (0, import_path6.join)(getConfigDir(), "state.json");
30000
30105
  }
30001
30106
  function normalizeState(raw) {
30002
30107
  const parsed = isPlainObject22(raw) ? raw : {};
@@ -30032,11 +30137,11 @@ ${lastSnapshot}`;
30032
30137
  }
30033
30138
  function loadState() {
30034
30139
  const statePath = getStatePath();
30035
- if (!(0, import_fs6.existsSync)(statePath)) {
30140
+ if (!(0, import_fs7.existsSync)(statePath)) {
30036
30141
  return { ...DEFAULT_STATE };
30037
30142
  }
30038
30143
  try {
30039
- const raw = (0, import_fs6.readFileSync)(statePath, "utf-8");
30144
+ const raw = (0, import_fs7.readFileSync)(statePath, "utf-8");
30040
30145
  return normalizeState(JSON.parse(raw));
30041
30146
  } catch {
30042
30147
  return { ...DEFAULT_STATE };
@@ -30045,13 +30150,13 @@ ${lastSnapshot}`;
30045
30150
  function saveState(state) {
30046
30151
  const statePath = getStatePath();
30047
30152
  const normalized = normalizeState(state);
30048
- (0, import_fs6.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
30153
+ (0, import_fs7.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
30049
30154
  }
30050
30155
  function resetState() {
30051
30156
  saveState({ ...DEFAULT_STATE });
30052
30157
  }
30053
30158
  var import_child_process2 = require("child_process");
30054
- var import_fs7 = require("fs");
30159
+ var import_fs8 = require("fs");
30055
30160
  var import_os22 = require("os");
30056
30161
  var path10 = __toESM2(require("path"));
30057
30162
  var BUILTIN_IDE_DEFINITIONS = [];
@@ -30075,7 +30180,7 @@ ${lastSnapshot}`;
30075
30180
  if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
30076
30181
  const candidate = trimmed.startsWith("~") ? path10.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
30077
30182
  const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
30078
- return (0, import_fs7.existsSync)(resolved) ? resolved : null;
30183
+ return (0, import_fs8.existsSync)(resolved) ? resolved : null;
30079
30184
  }
30080
30185
  try {
30081
30186
  const result = (0, import_child_process2.execSync)(
@@ -30106,9 +30211,9 @@ ${lastSnapshot}`;
30106
30211
  if (normalized.includes("*")) {
30107
30212
  const username = home.split(/[\\/]/).pop() || "";
30108
30213
  const resolved = normalized.replace("*", username);
30109
- if ((0, import_fs7.existsSync)(resolved)) return resolved;
30214
+ if ((0, import_fs8.existsSync)(resolved)) return resolved;
30110
30215
  } else {
30111
- if ((0, import_fs7.existsSync)(normalized)) return normalized;
30216
+ if ((0, import_fs8.existsSync)(normalized)) return normalized;
30112
30217
  }
30113
30218
  }
30114
30219
  return null;
@@ -30122,7 +30227,7 @@ ${lastSnapshot}`;
30122
30227
  let resolvedCli = cliPath;
30123
30228
  if (!resolvedCli && appPath && os222 === "darwin") {
30124
30229
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
30125
- if ((0, import_fs7.existsSync)(bundledCli)) resolvedCli = bundledCli;
30230
+ if ((0, import_fs8.existsSync)(bundledCli)) resolvedCli = bundledCli;
30126
30231
  }
30127
30232
  if (!resolvedCli && appPath && os222 === "win32") {
30128
30233
  const { dirname: dirname9 } = await import("path");
@@ -30135,7 +30240,7 @@ ${lastSnapshot}`;
30135
30240
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
30136
30241
  ];
30137
30242
  for (const c of candidates) {
30138
- if ((0, import_fs7.existsSync)(c)) {
30243
+ if ((0, import_fs8.existsSync)(c)) {
30139
30244
  resolvedCli = c;
30140
30245
  break;
30141
30246
  }
@@ -39200,7 +39305,7 @@ ${effect.notification.body || ""}`.trim();
39200
39305
  var os13 = __toESM2(require("os"));
39201
39306
  var path18 = __toESM2(require("path"));
39202
39307
  var crypto4 = __toESM2(require("crypto"));
39203
- var import_fs8 = require("fs");
39308
+ var import_fs9 = require("fs");
39204
39309
  var import_child_process6 = require("child_process");
39205
39310
  var import_chalk = __toESM2((init_source(), __toCommonJS(source_exports)));
39206
39311
  init_provider_cli_adapter();
@@ -41658,7 +41763,7 @@ ${rawInput}` : rawInput;
41658
41763
  const trimmed = command.trim();
41659
41764
  if (!trimmed) return false;
41660
41765
  if (isExplicitCommand(trimmed)) {
41661
- return (0, import_fs8.existsSync)(expandExecutable(trimmed));
41766
+ return (0, import_fs9.existsSync)(expandExecutable(trimmed));
41662
41767
  }
41663
41768
  try {
41664
41769
  (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -41687,10 +41792,10 @@ ${rawInput}` : rawInput;
41687
41792
  }
41688
41793
  function ensureEmptyDelegatedMcpConfig(workspace) {
41689
41794
  const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
41690
- (0, import_fs8.mkdirSync)(baseDir, { recursive: true });
41795
+ (0, import_fs9.mkdirSync)(baseDir, { recursive: true });
41691
41796
  const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
41692
41797
  const filePath = path18.join(baseDir, `${workspaceHash}.json`);
41693
- (0, import_fs8.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
41798
+ (0, import_fs9.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
41694
41799
  return filePath;
41695
41800
  }
41696
41801
  function buildCoordinatorDelegatedCliLaunchOptions(input) {
@@ -45841,7 +45946,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
45841
45946
  }
45842
45947
  }
45843
45948
  var import_os3 = require("os");
45844
- var import_path6 = require("path");
45949
+ var import_path7 = require("path");
45845
45950
  var fs10 = __toESM2(require("fs"));
45846
45951
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
45847
45952
  var CHANNEL_SERVER_URL = {
@@ -46165,8 +46270,21 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46165
46270
  isCached: false
46166
46271
  };
46167
46272
  }
46273
+ function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
46274
+ const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
46275
+ if (!recordNodeId || recordNodeId !== nodeId) return false;
46276
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46277
+ return !recordMeshId || recordMeshId === meshId;
46278
+ }
46279
+ function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
46280
+ const recordWorkspace = readStringValue(record2?.workspace);
46281
+ if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
46282
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46283
+ if (recordMeshId) return recordMeshId === meshId;
46284
+ return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
46285
+ }
46168
46286
  function readLiveMeshNodeWorkspace(args) {
46169
- const directNodeWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshNodeId) === args.nodeId && readStringValue(record2?.workspace));
46287
+ const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
46170
46288
  if (directNodeWorkspace) {
46171
46289
  return readStringValue(directNodeWorkspace.workspace) || "";
46172
46290
  }
@@ -46180,10 +46298,9 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46180
46298
  }
46181
46299
  function collectLiveMeshSessionRecords(args) {
46182
46300
  const matches = args.liveSessionRecords.filter((record2) => {
46183
- if (readStringValue(record2?.meta?.meshNodeId) === args.nodeId) return true;
46184
- const recordWorkspace = readStringValue(record2?.workspace);
46185
46301
  const nodeWorkspace = readStringValue(args.node?.workspace);
46186
- return !!recordWorkspace && !!nodeWorkspace && recordWorkspace === nodeWorkspace;
46302
+ if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
46303
+ return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
46187
46304
  });
46188
46305
  if (args.allowCoordinatorSession) {
46189
46306
  for (const record2 of args.liveSessionRecords) {
@@ -46259,7 +46376,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46259
46376
  }
46260
46377
  function readPackageScripts(workspace) {
46261
46378
  try {
46262
- const packageJsonPath = (0, import_path6.join)(workspace, "package.json");
46379
+ const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
46263
46380
  const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
46264
46381
  return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
46265
46382
  } catch {
@@ -46467,13 +46584,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46467
46584
  }
46468
46585
  function resolveHermesUserHome() {
46469
46586
  const explicitHome = process.env.HERMES_HOME?.trim();
46470
- return explicitHome || (0, import_path6.join)((0, import_os3.homedir)(), ".hermes");
46587
+ return explicitHome || (0, import_path7.join)((0, import_os3.homedir)(), ".hermes");
46471
46588
  }
46472
46589
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
46473
46590
  const sourceHome = resolveHermesUserHome();
46474
- const sourceConfigPath = (0, import_path6.join)(sourceHome, "config.yaml");
46591
+ const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
46475
46592
  if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46476
- if ((0, import_path6.resolve)(sourceConfigPath) === (0, import_path6.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46593
+ if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46477
46594
  const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
46478
46595
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
46479
46596
  return { config: baseConfig, sourceHome, sourceConfigPath };
@@ -46507,10 +46624,10 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46507
46624
  return sanitized;
46508
46625
  }
46509
46626
  function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
46510
- if ((0, import_path6.resolve)(sourceHome) === (0, import_path6.resolve)(targetHome)) return;
46627
+ if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
46511
46628
  for (const fileName of [".env", "auth.json"]) {
46512
- const sourcePath = (0, import_path6.join)(sourceHome, fileName);
46513
- const targetPath = (0, import_path6.join)(targetHome, fileName);
46629
+ const sourcePath = (0, import_path7.join)(sourceHome, fileName);
46630
+ const targetPath = (0, import_path7.join)(targetHome, fileName);
46514
46631
  if (!fs10.existsSync(sourcePath)) continue;
46515
46632
  try {
46516
46633
  fs10.copyFileSync(sourcePath, targetPath);
@@ -46717,7 +46834,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
46717
46834
  }
46718
46835
  const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
46719
46836
  const normalizePath = (value) => {
46720
- const resolved = (0, import_path6.resolve)(value);
46837
+ const resolved = (0, import_path7.resolve)(value);
46721
46838
  try {
46722
46839
  return fs10.realpathSync(resolved);
46723
46840
  } catch {
@@ -47118,7 +47235,8 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
47118
47235
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
47119
47236
  }
47120
47237
  case "get_pending_mesh_events": {
47121
- const events = drainPendingMeshCoordinatorEvents();
47238
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47239
+ const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
47122
47240
  return { success: true, events };
47123
47241
  }
47124
47242
  case "launch_cli":
@@ -48339,7 +48457,7 @@ ${block}`);
48339
48457
  workspace
48340
48458
  };
48341
48459
  }
48342
- const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
48460
+ const { existsSync: existsSync26, readFileSync: readFileSync18, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
48343
48461
  const { dirname: dirname9 } = await import("path");
48344
48462
  const mcpConfigPath = coordinatorSetup.configPath;
48345
48463
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -48382,14 +48500,14 @@ ${block}`);
48382
48500
  if (hermesManualFallback) return returnManualFallback(message);
48383
48501
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
48384
48502
  }
48385
- const hadExistingMcpConfig = existsSync25(mcpConfigPath);
48503
+ const hadExistingMcpConfig = existsSync26(mcpConfigPath);
48386
48504
  let existingMcpConfig = hermesBaseConfig?.config || {};
48387
48505
  if (hermesBaseConfig) {
48388
48506
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
48389
48507
  }
48390
48508
  if (hadExistingMcpConfig) {
48391
48509
  try {
48392
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
48510
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync18(mcpConfigPath, "utf-8"), configFormat);
48393
48511
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
48394
48512
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
48395
48513
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -48577,29 +48695,48 @@ ${block}`);
48577
48695
  }
48578
48696
  if (workspace) {
48579
48697
  if (!fs10.existsSync(workspace)) {
48580
- if (applyCachedInlineMeshNodeStatus(status, node)) {
48581
- status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48582
- nodeStatuses.push(status);
48583
- continue;
48584
- }
48585
- if (meshRecord?.source === "inline_cache" && !isSelfNode) {
48586
- status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48587
- nodeStatuses.push(status);
48588
- continue;
48698
+ let remoteProbeApplied = false;
48699
+ if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
48700
+ try {
48701
+ const remoteResult = await Promise.race([
48702
+ this.deps.dispatchMeshCommand(daemonId, "git_status", { workspace }),
48703
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 8e3))
48704
+ ]);
48705
+ const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
48706
+ if (remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean") {
48707
+ status.git = remoteGit;
48708
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
48709
+ remoteProbeApplied = true;
48710
+ }
48711
+ } catch {
48712
+ }
48589
48713
  }
48590
- }
48591
- try {
48592
- const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
48593
- status.git = gitStatus;
48594
- if (gitStatus.isGitRepo) {
48595
- status.health = deriveMeshNodeHealthFromGit(gitStatus);
48596
- } else {
48597
- status.health = "degraded";
48598
- if (gitStatus.error && !status.error) status.error = gitStatus.error;
48714
+ if (!remoteProbeApplied) {
48715
+ if (applyCachedInlineMeshNodeStatus(status, node)) {
48716
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48717
+ nodeStatuses.push(status);
48718
+ continue;
48719
+ }
48720
+ if (meshRecord?.source === "inline_cache" && !isSelfNode) {
48721
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48722
+ nodeStatuses.push(status);
48723
+ continue;
48724
+ }
48599
48725
  }
48600
- } catch {
48601
- if (!applyCachedInlineMeshNodeStatus(status, node)) {
48602
- status.health = "degraded";
48726
+ } else {
48727
+ try {
48728
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
48729
+ status.git = gitStatus;
48730
+ if (gitStatus.isGitRepo) {
48731
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
48732
+ } else {
48733
+ status.health = "degraded";
48734
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
48735
+ }
48736
+ } catch {
48737
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
48738
+ status.health = "degraded";
48739
+ }
48603
48740
  }
48604
48741
  }
48605
48742
  } else {