@adhdev/daemon-core 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.mjs CHANGED
@@ -1351,13 +1351,43 @@ __export(mesh_work_queue_exports, {
1351
1351
  updateSessionTaskStatus: () => updateSessionTaskStatus,
1352
1352
  updateTaskStatus: () => updateTaskStatus
1353
1353
  });
1354
- import { existsSync as existsSync6, writeFileSync as writeFileSync3, readFileSync as readFileSync4 } from "fs";
1354
+ import { existsSync as existsSync6, writeFileSync as writeFileSync3, readFileSync as readFileSync4, openSync, closeSync, unlinkSync } from "fs";
1355
1355
  import { join as join6 } from "path";
1356
1356
  import { randomUUID as randomUUID5 } from "crypto";
1357
1357
  function getQueuePath(meshId) {
1358
1358
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1359
1359
  return join6(getLedgerDir(), `${safe}.queue.json`);
1360
1360
  }
1361
+ function getLockPath(meshId) {
1362
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1363
+ return join6(getLedgerDir(), `${safe}.queue.lock`);
1364
+ }
1365
+ function withQueueLock(meshId, fn) {
1366
+ const lockPath = getLockPath(meshId);
1367
+ let fd = -1;
1368
+ for (let i = 0; i < 10; i++) {
1369
+ try {
1370
+ fd = openSync(lockPath, "wx");
1371
+ break;
1372
+ } catch {
1373
+ const deadline = Date.now() + 30;
1374
+ while (Date.now() < deadline) {
1375
+ }
1376
+ }
1377
+ }
1378
+ try {
1379
+ return fn();
1380
+ } finally {
1381
+ if (fd !== -1) try {
1382
+ closeSync(fd);
1383
+ } catch {
1384
+ }
1385
+ try {
1386
+ unlinkSync(lockPath);
1387
+ } catch {
1388
+ }
1389
+ }
1390
+ }
1361
1391
  function readQueue(meshId) {
1362
1392
  const path28 = getQueuePath(meshId);
1363
1393
  if (!existsSync6(path28)) return [];
@@ -1373,20 +1403,22 @@ function writeQueue(meshId, queue) {
1373
1403
  writeFileSync3(path28, JSON.stringify(queue, null, 2), "utf-8");
1374
1404
  }
1375
1405
  function enqueueTask(meshId, message, opts) {
1376
- const queue = readQueue(meshId);
1377
- const entry = {
1378
- id: randomUUID5(),
1379
- meshId,
1380
- message,
1381
- status: "pending",
1382
- targetNodeId: opts?.targetNodeId,
1383
- targetSessionId: opts?.targetSessionId,
1384
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1385
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1386
- };
1387
- queue.push(entry);
1388
- writeQueue(meshId, queue);
1389
- return entry;
1406
+ return withQueueLock(meshId, () => {
1407
+ const queue = readQueue(meshId);
1408
+ const entry = {
1409
+ id: randomUUID5(),
1410
+ meshId,
1411
+ message,
1412
+ status: "pending",
1413
+ targetNodeId: opts?.targetNodeId,
1414
+ targetSessionId: opts?.targetSessionId,
1415
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1416
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1417
+ };
1418
+ queue.push(entry);
1419
+ writeQueue(meshId, queue);
1420
+ return entry;
1421
+ });
1390
1422
  }
1391
1423
  function getQueue(meshId, opts) {
1392
1424
  let queue = readQueue(meshId);
@@ -1397,100 +1429,109 @@ function getQueue(meshId, opts) {
1397
1429
  return queue;
1398
1430
  }
1399
1431
  function claimNextTask(meshId, nodeId, sessionId) {
1400
- const queue = readQueue(meshId);
1401
- const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
1402
- if (hasActiveAssignment) return null;
1403
- let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
1404
- if (targetIdx === -1) {
1405
- targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
1406
- }
1407
- if (targetIdx === -1) {
1408
- targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
1409
- }
1410
- if (targetIdx === -1) return null;
1411
- const entry = queue[targetIdx];
1412
- entry.status = "assigned";
1413
- entry.assignedNodeId = nodeId;
1414
- entry.assignedSessionId = sessionId;
1415
- entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
1416
- entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1417
- writeQueue(meshId, queue);
1418
- return entry;
1432
+ return withQueueLock(meshId, () => {
1433
+ const queue = readQueue(meshId);
1434
+ const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
1435
+ if (hasActiveAssignment) return null;
1436
+ let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
1437
+ if (targetIdx === -1) {
1438
+ targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
1439
+ }
1440
+ if (targetIdx === -1) {
1441
+ targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
1442
+ }
1443
+ if (targetIdx === -1) return null;
1444
+ const entry = queue[targetIdx];
1445
+ entry.status = "assigned";
1446
+ entry.assignedNodeId = nodeId;
1447
+ entry.assignedSessionId = sessionId;
1448
+ entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
1449
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1450
+ writeQueue(meshId, queue);
1451
+ return entry;
1452
+ });
1419
1453
  }
1420
1454
  function updateTaskStatus(meshId, taskId, status) {
1421
- const queue = readQueue(meshId);
1422
- const idx = queue.findIndex((q) => q.id === taskId);
1423
- if (idx === -1) return null;
1424
- queue[idx].status = status;
1425
- queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1426
- writeQueue(meshId, queue);
1427
- return queue[idx];
1455
+ return withQueueLock(meshId, () => {
1456
+ const queue = readQueue(meshId);
1457
+ const idx = queue.findIndex((q) => q.id === taskId);
1458
+ if (idx === -1) return null;
1459
+ queue[idx].status = status;
1460
+ queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1461
+ writeQueue(meshId, queue);
1462
+ return queue[idx];
1463
+ });
1428
1464
  }
1429
1465
  function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
1430
- const queue = readQueue(meshId);
1431
- const idx = queue.findIndex((q) => q.id === taskId);
1432
- if (idx === -1) return null;
1433
- const now = (/* @__PURE__ */ new Date()).toISOString();
1434
- queue[idx].autoLaunch = {
1435
- ...autoLaunch,
1436
- updatedAt: now
1437
- };
1438
- queue[idx].updatedAt = now;
1439
- writeQueue(meshId, queue);
1440
- return queue[idx];
1466
+ return withQueueLock(meshId, () => {
1467
+ const queue = readQueue(meshId);
1468
+ const idx = queue.findIndex((q) => q.id === taskId);
1469
+ if (idx === -1) return null;
1470
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1471
+ queue[idx].autoLaunch = { ...autoLaunch, updatedAt: now };
1472
+ queue[idx].updatedAt = now;
1473
+ writeQueue(meshId, queue);
1474
+ return queue[idx];
1475
+ });
1441
1476
  }
1442
1477
  function cancelTask(meshId, taskId, opts) {
1443
- const queue = readQueue(meshId);
1444
- const idx = queue.findIndex((q) => q.id === taskId);
1445
- if (idx === -1) return null;
1446
- const now = (/* @__PURE__ */ new Date()).toISOString();
1447
- queue[idx].status = "cancelled";
1448
- queue[idx].updatedAt = now;
1449
- queue[idx].cancelledAt = now;
1450
- if (opts?.reason) queue[idx].cancelReason = opts.reason;
1451
- writeQueue(meshId, queue);
1452
- return queue[idx];
1478
+ return withQueueLock(meshId, () => {
1479
+ const queue = readQueue(meshId);
1480
+ const idx = queue.findIndex((q) => q.id === taskId);
1481
+ if (idx === -1) return null;
1482
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1483
+ queue[idx].status = "cancelled";
1484
+ queue[idx].updatedAt = now;
1485
+ queue[idx].cancelledAt = now;
1486
+ if (opts?.reason) queue[idx].cancelReason = opts.reason;
1487
+ writeQueue(meshId, queue);
1488
+ return queue[idx];
1489
+ });
1453
1490
  }
1454
1491
  function requeueTask(meshId, taskId, opts) {
1455
- const queue = readQueue(meshId);
1456
- const idx = queue.findIndex((q) => q.id === taskId);
1457
- if (idx === -1) return null;
1458
- const entry = queue[idx];
1459
- const now = (/* @__PURE__ */ new Date()).toISOString();
1460
- entry.status = "pending";
1461
- delete entry.assignedNodeId;
1462
- delete entry.assignedSessionId;
1463
- delete entry.cancelledAt;
1464
- delete entry.cancelReason;
1465
- if (opts?.clearTargetNode) delete entry.targetNodeId;
1466
- if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
1467
- if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
1468
- if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
1469
- entry.updatedAt = now;
1470
- entry.requeuedAt = now;
1471
- entry.requeueCount = (entry.requeueCount || 0) + 1;
1472
- if (opts?.reason) entry.requeueReason = opts.reason;
1473
- writeQueue(meshId, queue);
1474
- return entry;
1492
+ return withQueueLock(meshId, () => {
1493
+ const queue = readQueue(meshId);
1494
+ const idx = queue.findIndex((q) => q.id === taskId);
1495
+ if (idx === -1) return null;
1496
+ const entry = queue[idx];
1497
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1498
+ entry.status = "pending";
1499
+ delete entry.assignedNodeId;
1500
+ delete entry.assignedSessionId;
1501
+ delete entry.cancelledAt;
1502
+ delete entry.cancelReason;
1503
+ if (opts?.clearTargetNode) delete entry.targetNodeId;
1504
+ if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
1505
+ if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
1506
+ if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
1507
+ entry.updatedAt = now;
1508
+ entry.requeuedAt = now;
1509
+ entry.requeueCount = (entry.requeueCount || 0) + 1;
1510
+ if (opts?.reason) entry.requeueReason = opts.reason;
1511
+ writeQueue(meshId, queue);
1512
+ return entry;
1513
+ });
1475
1514
  }
1476
1515
  function updateSessionTaskStatus(meshId, sessionId, status) {
1477
- const queue = readQueue(meshId);
1478
- let bestIdx = -1;
1479
- let bestTime = 0;
1480
- for (let i = queue.length - 1; i >= 0; i--) {
1481
- if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
1482
- const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1483
- if (time > bestTime) {
1484
- bestTime = time;
1485
- bestIdx = i;
1486
- }
1487
- }
1488
- }
1489
- if (bestIdx === -1) return null;
1490
- queue[bestIdx].status = status;
1491
- queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1492
- writeQueue(meshId, queue);
1493
- return queue[bestIdx];
1516
+ return withQueueLock(meshId, () => {
1517
+ const queue = readQueue(meshId);
1518
+ let bestIdx = -1;
1519
+ let bestTime = 0;
1520
+ for (let i = queue.length - 1; i >= 0; i--) {
1521
+ if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
1522
+ const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1523
+ if (time > bestTime) {
1524
+ bestTime = time;
1525
+ bestIdx = i;
1526
+ }
1527
+ }
1528
+ }
1529
+ if (bestIdx === -1) return null;
1530
+ queue[bestIdx].status = status;
1531
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1532
+ writeQueue(meshId, queue);
1533
+ return queue[bestIdx];
1534
+ });
1494
1535
  }
1495
1536
  function getMeshQueueStats(meshId) {
1496
1537
  const queue = readQueue(meshId);
@@ -1895,21 +1936,72 @@ __export(mesh_events_exports, {
1895
1936
  triggerMeshQueue: () => triggerMeshQueue,
1896
1937
  tryAssignQueueTask: () => tryAssignQueueTask
1897
1938
  });
1939
+ import { appendFileSync as appendFileSync3, existsSync as existsSync9, readFileSync as readFileSync5, unlinkSync as unlinkSync3 } from "fs";
1940
+ import { join as join9 } from "path";
1941
+ function sweepExpiredRemoteIdleSessions() {
1942
+ const now = Date.now();
1943
+ for (const [key, session] of remoteIdleSessions) {
1944
+ if (session.expiresAt <= now) remoteIdleSessions.delete(key);
1945
+ }
1946
+ }
1947
+ function getPendingEventsPath(meshId) {
1948
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1949
+ return join9(getLedgerDir(), `${safe}.pending-events.jsonl`);
1950
+ }
1898
1951
  function queuePendingMeshCoordinatorEvent(event) {
1899
- if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
1952
+ try {
1953
+ appendFileSync3(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
1954
+ return true;
1955
+ } catch (e) {
1956
+ LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
1900
1957
  return false;
1901
1958
  }
1902
- pendingMeshCoordinatorEvents.push(event);
1903
- return true;
1904
1959
  }
1905
- function drainPendingMeshCoordinatorEvents() {
1906
- return pendingMeshCoordinatorEvents.splice(0);
1960
+ function drainPendingMeshCoordinatorEvents(meshId) {
1961
+ if (!meshId) return [];
1962
+ const path28 = getPendingEventsPath(meshId);
1963
+ if (!existsSync9(path28)) return [];
1964
+ try {
1965
+ const raw = readFileSync5(path28, "utf-8");
1966
+ try {
1967
+ unlinkSync3(path28);
1968
+ } catch {
1969
+ }
1970
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
1971
+ try {
1972
+ return [JSON.parse(line)];
1973
+ } catch {
1974
+ return [];
1975
+ }
1976
+ });
1977
+ } catch {
1978
+ return [];
1979
+ }
1907
1980
  }
1908
- function getPendingMeshCoordinatorEvents() {
1909
- return pendingMeshCoordinatorEvents.slice();
1981
+ function getPendingMeshCoordinatorEvents(meshId) {
1982
+ if (!meshId) return [];
1983
+ const path28 = getPendingEventsPath(meshId);
1984
+ if (!existsSync9(path28)) return [];
1985
+ try {
1986
+ const raw = readFileSync5(path28, "utf-8");
1987
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
1988
+ try {
1989
+ return [JSON.parse(line)];
1990
+ } catch {
1991
+ return [];
1992
+ }
1993
+ });
1994
+ } catch {
1995
+ return [];
1996
+ }
1910
1997
  }
1911
- function clearPendingMeshCoordinatorEvents() {
1912
- pendingMeshCoordinatorEvents.splice(0);
1998
+ function clearPendingMeshCoordinatorEvents(meshId) {
1999
+ if (!meshId) return;
2000
+ const path28 = getPendingEventsPath(meshId);
2001
+ if (existsSync9(path28)) try {
2002
+ unlinkSync3(path28);
2003
+ } catch {
2004
+ }
1913
2005
  }
1914
2006
  function readNonEmptyString(value) {
1915
2007
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -1973,7 +2065,16 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
1973
2065
  message: task.message
1974
2066
  }).catch((e) => {
1975
2067
  LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
1976
- updateTaskStatus(meshId, task.id, "failed");
2068
+ updateTaskStatus(meshId, task.id, "pending");
2069
+ try {
2070
+ appendLedgerEntry(meshId, {
2071
+ kind: "dispatch_failed",
2072
+ nodeId,
2073
+ sessionId,
2074
+ payload: { taskId: task.id, error: e?.message, retryable: true }
2075
+ });
2076
+ } catch {
2077
+ }
1977
2078
  });
1978
2079
  return true;
1979
2080
  }
@@ -2316,9 +2417,9 @@ function injectMeshSystemMessage(components, args) {
2316
2417
  const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
2317
2418
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
2318
2419
  if (nodeId && providerType) {
2319
- setTimeout(() => {
2420
+ setImmediate(() => {
2320
2421
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
2321
- }, 500);
2422
+ });
2322
2423
  }
2323
2424
  }
2324
2425
  } else if (args.event === "agent:ready") {
@@ -2356,13 +2457,17 @@ function injectMeshSystemMessage(components, args) {
2356
2457
  }
2357
2458
  }
2358
2459
  if (sessionId && nodeId && providerType) {
2359
- remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
2360
- setTimeout(() => {
2460
+ sweepExpiredRemoteIdleSessions();
2461
+ remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
2462
+ nodeId,
2463
+ sessionId,
2464
+ providerType,
2465
+ expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
2466
+ });
2467
+ setImmediate(() => {
2361
2468
  const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
2362
- if (assigned) {
2363
- remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
2364
- }
2365
- }, 500);
2469
+ if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
2470
+ });
2366
2471
  }
2367
2472
  } else if (args.event === "agent:generating_started") {
2368
2473
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
@@ -2565,7 +2670,7 @@ function setupMeshEventForwarding(components) {
2565
2670
  });
2566
2671
  });
2567
2672
  }
2568
- var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2673
+ var REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2569
2674
  var init_mesh_events = __esm({
2570
2675
  "src/mesh/mesh-events.ts"() {
2571
2676
  "use strict";
@@ -2575,9 +2680,8 @@ var init_mesh_events = __esm({
2575
2680
  init_logger();
2576
2681
  init_mesh_ledger();
2577
2682
  init_mesh_work_queue();
2683
+ REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
2578
2684
  remoteIdleSessions = /* @__PURE__ */ new Map();
2579
- MAX_PENDING_EVENTS = 50;
2580
- pendingMeshCoordinatorEvents = [];
2581
2685
  MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
2582
2686
  "agent:generating_started",
2583
2687
  "agent:generating_completed",
@@ -7635,8 +7739,8 @@ var P2pRelayFailureError = class extends Error {
7635
7739
 
7636
7740
  // src/config/state-store.ts
7637
7741
  init_config();
7638
- import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
7639
- import { join as join9 } from "path";
7742
+ import { existsSync as existsSync10, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
7743
+ import { join as join10 } from "path";
7640
7744
  var DEFAULT_STATE = {
7641
7745
  recentActivity: [],
7642
7746
  savedProviderSessions: [],
@@ -7649,7 +7753,7 @@ function isPlainObject2(value) {
7649
7753
  return !!value && typeof value === "object" && !Array.isArray(value);
7650
7754
  }
7651
7755
  function getStatePath() {
7652
- return join9(getConfigDir(), "state.json");
7756
+ return join10(getConfigDir(), "state.json");
7653
7757
  }
7654
7758
  function normalizeState(raw) {
7655
7759
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -7685,11 +7789,11 @@ function normalizeState(raw) {
7685
7789
  }
7686
7790
  function loadState() {
7687
7791
  const statePath = getStatePath();
7688
- if (!existsSync9(statePath)) {
7792
+ if (!existsSync10(statePath)) {
7689
7793
  return { ...DEFAULT_STATE };
7690
7794
  }
7691
7795
  try {
7692
- const raw = readFileSync5(statePath, "utf-8");
7796
+ const raw = readFileSync6(statePath, "utf-8");
7693
7797
  return normalizeState(JSON.parse(raw));
7694
7798
  } catch {
7695
7799
  return { ...DEFAULT_STATE };
@@ -7706,7 +7810,7 @@ function resetState() {
7706
7810
 
7707
7811
  // src/detection/ide-detector.ts
7708
7812
  import { execSync } from "child_process";
7709
- import { existsSync as existsSync10 } from "fs";
7813
+ import { existsSync as existsSync11 } from "fs";
7710
7814
  import { platform as platform2, homedir as homedir5 } from "os";
7711
7815
  import * as path10 from "path";
7712
7816
  var BUILTIN_IDE_DEFINITIONS = [];
@@ -7730,7 +7834,7 @@ function findCliCommand(command) {
7730
7834
  if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
7731
7835
  const candidate = trimmed.startsWith("~") ? path10.join(homedir5(), trimmed.slice(1)) : trimmed;
7732
7836
  const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
7733
- return existsSync10(resolved) ? resolved : null;
7837
+ return existsSync11(resolved) ? resolved : null;
7734
7838
  }
7735
7839
  try {
7736
7840
  const result = execSync(
@@ -7761,9 +7865,9 @@ function checkPathExists(paths) {
7761
7865
  if (normalized.includes("*")) {
7762
7866
  const username = home.split(/[\\/]/).pop() || "";
7763
7867
  const resolved = normalized.replace("*", username);
7764
- if (existsSync10(resolved)) return resolved;
7868
+ if (existsSync11(resolved)) return resolved;
7765
7869
  } else {
7766
- if (existsSync10(normalized)) return normalized;
7870
+ if (existsSync11(normalized)) return normalized;
7767
7871
  }
7768
7872
  }
7769
7873
  return null;
@@ -7777,7 +7881,7 @@ async function detectIDEs(providerLoader) {
7777
7881
  let resolvedCli = cliPath;
7778
7882
  if (!resolvedCli && appPath && os22 === "darwin") {
7779
7883
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
7780
- if (existsSync10(bundledCli)) resolvedCli = bundledCli;
7884
+ if (existsSync11(bundledCli)) resolvedCli = bundledCli;
7781
7885
  }
7782
7886
  if (!resolvedCli && appPath && os22 === "win32") {
7783
7887
  const { dirname: dirname9 } = await import("path");
@@ -7790,7 +7894,7 @@ async function detectIDEs(providerLoader) {
7790
7894
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
7791
7895
  ];
7792
7896
  for (const c of candidates) {
7793
- if (existsSync10(c)) {
7897
+ if (existsSync11(c)) {
7794
7898
  resolvedCli = c;
7795
7899
  break;
7796
7900
  }
@@ -16946,7 +17050,7 @@ init_config();
16946
17050
  import * as os13 from "os";
16947
17051
  import * as path18 from "path";
16948
17052
  import * as crypto4 from "crypto";
16949
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
17053
+ import { existsSync as existsSync15, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
16950
17054
  import { execFileSync } from "child_process";
16951
17055
  import chalk from "chalk";
16952
17056
 
@@ -19420,7 +19524,7 @@ function commandExists(command) {
19420
19524
  const trimmed = command.trim();
19421
19525
  if (!trimmed) return false;
19422
19526
  if (isExplicitCommand(trimmed)) {
19423
- return existsSync14(expandExecutable(trimmed));
19527
+ return existsSync15(expandExecutable(trimmed));
19424
19528
  }
19425
19529
  try {
19426
19530
  execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -22689,10 +22793,10 @@ import * as yaml from "js-yaml";
22689
22793
  // src/commands/mesh-coordinator.ts
22690
22794
  import { execFileSync as execFileSync2 } from "child_process";
22691
22795
  import { createHash as createHash2 } from "crypto";
22692
- import { existsSync as existsSync17, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
22796
+ import { existsSync as existsSync18, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
22693
22797
  import { createRequire as createRequire2 } from "module";
22694
22798
  import * as os17 from "os";
22695
- import { dirname as dirname4, isAbsolute as isAbsolute11, join as join20, resolve as resolve13 } from "path";
22799
+ import { dirname as dirname4, isAbsolute as isAbsolute11, join as join21, resolve as resolve13 } from "path";
22696
22800
  var DEFAULT_SERVER_NAME = "adhdev-mesh";
22697
22801
  var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
22698
22802
  var HERMES_CLI_TYPE = "hermes-cli";
@@ -22715,7 +22819,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
22715
22819
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
22716
22820
  };
22717
22821
  }
22718
- const configPath = join20(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
22822
+ const configPath = join21(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
22719
22823
  if (!configPath.trim()) {
22720
22824
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
22721
22825
  }
@@ -22836,14 +22940,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
22836
22940
  const key = `${meshId || "mesh"}
22837
22941
  ${resolve13(workspace || os17.tmpdir())}`;
22838
22942
  const hash = createHash2("sha256").update(key).digest("hex").slice(0, 16);
22839
- return join20(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
22943
+ return join21(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
22840
22944
  }
22841
22945
  function resolveMcpConfigPath(configPath, workspace) {
22842
22946
  const trimmed = configPath.trim();
22843
22947
  if (trimmed === "~") return os17.homedir();
22844
- if (trimmed.startsWith("~/")) return join20(os17.homedir(), trimmed.slice(2));
22948
+ if (trimmed.startsWith("~/")) return join21(os17.homedir(), trimmed.slice(2));
22845
22949
  if (isAbsolute11(trimmed)) return trimmed;
22846
- return join20(workspace, trimmed);
22950
+ return join21(workspace, trimmed);
22847
22951
  }
22848
22952
  function resolveAdhdevMcpServerLaunch(options) {
22849
22953
  const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
@@ -22899,15 +23003,15 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
22899
23003
  for (const entry of (pathValue || "").split(":")) {
22900
23004
  const dir = entry.trim();
22901
23005
  if (!dir) continue;
22902
- addCandidate(join20(dir, "node"));
23006
+ addCandidate(join21(dir, "node"));
22903
23007
  }
22904
23008
  }
22905
23009
  function addNodeCandidatesFromNvm(homeDir, addCandidate) {
22906
- const versionsDir = join20(homeDir, ".nvm", "versions", "node");
23010
+ const versionsDir = join21(homeDir, ".nvm", "versions", "node");
22907
23011
  try {
22908
23012
  const versionDirs = readdirSync7(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
22909
23013
  for (const versionDir of versionDirs) {
22910
- addCandidate(join20(versionsDir, versionDir, "bin", "node"));
23014
+ addCandidate(join21(versionsDir, versionDir, "bin", "node"));
22911
23015
  }
22912
23016
  } catch {
22913
23017
  }
@@ -22958,7 +23062,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
22958
23062
  if (normalized) return normalized;
22959
23063
  }
22960
23064
  try {
22961
- const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join20(process.cwd(), "adhdev-daemon.js");
23065
+ const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join21(process.cwd(), "adhdev-daemon.js");
22962
23066
  const req = createRequire2(requireBase);
22963
23067
  const resolvedModule = req.resolve("@adhdev/mcp-server");
22964
23068
  return normalizeExistingPath(resolvedModule) || resolvedModule;
@@ -22968,7 +23072,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
22968
23072
  }
22969
23073
  function normalizeExistingPath(filePath) {
22970
23074
  try {
22971
- if (!existsSync17(filePath)) return null;
23075
+ if (!existsSync18(filePath)) return null;
22972
23076
  return realpathSync2.native(filePath);
22973
23077
  } catch {
22974
23078
  return null;
@@ -23955,8 +24059,21 @@ function summarizeMeshSessionRecord(record) {
23955
24059
  isCached: false
23956
24060
  };
23957
24061
  }
24062
+ function liveSessionRecordMatchesMeshNode(record, meshId, nodeId) {
24063
+ const recordNodeId = readStringValue(record?.meta?.meshNodeId);
24064
+ if (!recordNodeId || recordNodeId !== nodeId) return false;
24065
+ const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
24066
+ return !recordMeshId || recordMeshId === meshId;
24067
+ }
24068
+ function liveSessionRecordMatchesMeshWorkspace(record, meshId, workspace) {
24069
+ const recordWorkspace = readStringValue(record?.workspace);
24070
+ if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
24071
+ const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
24072
+ if (recordMeshId) return recordMeshId === meshId;
24073
+ return record?.meta?.launchedByCoordinator === true || !!readStringValue(record?.meta?.meshNodeId);
24074
+ }
23958
24075
  function readLiveMeshNodeWorkspace(args) {
23959
- const directNodeWorkspace = args.liveSessionRecords.find((record) => readStringValue(record?.meta?.meshNodeId) === args.nodeId && readStringValue(record?.workspace));
24076
+ const directNodeWorkspace = args.liveSessionRecords.find((record) => liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId) && readStringValue(record?.workspace));
23960
24077
  if (directNodeWorkspace) {
23961
24078
  return readStringValue(directNodeWorkspace.workspace) || "";
23962
24079
  }
@@ -23970,10 +24087,9 @@ function readLiveMeshNodeWorkspace(args) {
23970
24087
  }
23971
24088
  function collectLiveMeshSessionRecords(args) {
23972
24089
  const matches = args.liveSessionRecords.filter((record) => {
23973
- if (readStringValue(record?.meta?.meshNodeId) === args.nodeId) return true;
23974
- const recordWorkspace = readStringValue(record?.workspace);
23975
24090
  const nodeWorkspace = readStringValue(args.node?.workspace);
23976
- return !!recordWorkspace && !!nodeWorkspace && recordWorkspace === nodeWorkspace;
24091
+ if (liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId)) return true;
24092
+ return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record, args.meshId, nodeWorkspace);
23977
24093
  });
23978
24094
  if (args.allowCoordinatorSession) {
23979
24095
  for (const record of args.liveSessionRecords) {
@@ -24908,7 +25024,8 @@ var DaemonCommandRouter = class {
24908
25024
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
24909
25025
  }
24910
25026
  case "get_pending_mesh_events": {
24911
- const events = drainPendingMeshCoordinatorEvents();
25027
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25028
+ const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
24912
25029
  return { success: true, events };
24913
25030
  }
24914
25031
  case "launch_cli":
@@ -26129,7 +26246,7 @@ ${block}`);
26129
26246
  workspace
26130
26247
  };
26131
26248
  }
26132
- const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
26249
+ const { existsSync: existsSync26, readFileSync: readFileSync18, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
26133
26250
  const { dirname: dirname9 } = await import("path");
26134
26251
  const mcpConfigPath = coordinatorSetup.configPath;
26135
26252
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -26172,14 +26289,14 @@ ${block}`);
26172
26289
  if (hermesManualFallback) return returnManualFallback(message);
26173
26290
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
26174
26291
  }
26175
- const hadExistingMcpConfig = existsSync25(mcpConfigPath);
26292
+ const hadExistingMcpConfig = existsSync26(mcpConfigPath);
26176
26293
  let existingMcpConfig = hermesBaseConfig?.config || {};
26177
26294
  if (hermesBaseConfig) {
26178
26295
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
26179
26296
  }
26180
26297
  if (hadExistingMcpConfig) {
26181
26298
  try {
26182
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
26299
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync18(mcpConfigPath, "utf-8"), configFormat);
26183
26300
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
26184
26301
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
26185
26302
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -26367,29 +26484,48 @@ ${block}`);
26367
26484
  }
26368
26485
  if (workspace) {
26369
26486
  if (!fs10.existsSync(workspace)) {
26370
- if (applyCachedInlineMeshNodeStatus(status, node)) {
26371
- status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26372
- nodeStatuses.push(status);
26373
- continue;
26374
- }
26375
- if (meshRecord?.source === "inline_cache" && !isSelfNode) {
26376
- status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26377
- nodeStatuses.push(status);
26378
- continue;
26487
+ let remoteProbeApplied = false;
26488
+ if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
26489
+ try {
26490
+ const remoteResult = await Promise.race([
26491
+ this.deps.dispatchMeshCommand(daemonId, "git_status", { workspace }),
26492
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 8e3))
26493
+ ]);
26494
+ const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
26495
+ if (remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean") {
26496
+ status.git = remoteGit;
26497
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
26498
+ remoteProbeApplied = true;
26499
+ }
26500
+ } catch {
26501
+ }
26379
26502
  }
26380
- }
26381
- try {
26382
- const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
26383
- status.git = gitStatus;
26384
- if (gitStatus.isGitRepo) {
26385
- status.health = deriveMeshNodeHealthFromGit(gitStatus);
26386
- } else {
26387
- status.health = "degraded";
26388
- if (gitStatus.error && !status.error) status.error = gitStatus.error;
26503
+ if (!remoteProbeApplied) {
26504
+ if (applyCachedInlineMeshNodeStatus(status, node)) {
26505
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26506
+ nodeStatuses.push(status);
26507
+ continue;
26508
+ }
26509
+ if (meshRecord?.source === "inline_cache" && !isSelfNode) {
26510
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26511
+ nodeStatuses.push(status);
26512
+ continue;
26513
+ }
26389
26514
  }
26390
- } catch {
26391
- if (!applyCachedInlineMeshNodeStatus(status, node)) {
26392
- status.health = "degraded";
26515
+ } else {
26516
+ try {
26517
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
26518
+ status.git = gitStatus;
26519
+ if (gitStatus.isGitRepo) {
26520
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
26521
+ } else {
26522
+ status.health = "degraded";
26523
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
26524
+ }
26525
+ } catch {
26526
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
26527
+ status.health = "degraded";
26528
+ }
26393
26529
  }
26394
26530
  }
26395
26531
  } else {