@adhdev/daemon-core 0.9.82-rc.5 → 0.9.82-rc.51

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
@@ -657,23 +657,97 @@ var init_config = __esm({
657
657
  }
658
658
  });
659
659
 
660
+ // src/mesh/mesh-host-ownership.ts
661
+ function readObject(value) {
662
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
663
+ }
664
+ function readString(value) {
665
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
666
+ }
667
+ function normalizeMeshDaemonRole(value) {
668
+ return value === "host" || value === "member" ? value : void 0;
669
+ }
670
+ function resolveMeshHostStatus(mesh) {
671
+ const meshRecord = readObject(mesh);
672
+ const raw = readObject(meshRecord?.meshHost);
673
+ const role = normalizeMeshDaemonRole(raw?.role) ?? "host";
674
+ const pairing = readObject(raw?.pairing);
675
+ const normalized = {
676
+ role,
677
+ canOwnCoordinator: role === "host",
678
+ canOwnQueue: role === "host",
679
+ defaulted: !raw
680
+ };
681
+ const hostDaemonId = readString(raw?.hostDaemonId);
682
+ const hostNodeId = readString(raw?.hostNodeId);
683
+ const hostAddress = readString(raw?.hostAddress);
684
+ if (hostDaemonId) normalized.hostDaemonId = hostDaemonId;
685
+ if (hostNodeId) normalized.hostNodeId = hostNodeId;
686
+ if (hostAddress) normalized.hostAddress = hostAddress;
687
+ if (pairing) {
688
+ const status = pairing.status === "pairing" || pairing.status === "paired" || pairing.status === "rejected" || pairing.status === "revoked" ? pairing.status : "not_configured";
689
+ normalized.pairing = {
690
+ status,
691
+ ...readString(pairing.tokenId) ? { tokenId: readString(pairing.tokenId) } : {},
692
+ ...readString(pairing.joinedAt) ? { joinedAt: readString(pairing.joinedAt) } : {},
693
+ ...readString(pairing.lastPairedAt) ? { lastPairedAt: readString(pairing.lastPairedAt) } : {},
694
+ ...readString(pairing.lastRejectedAt) ? { lastRejectedAt: readString(pairing.lastRejectedAt) } : {},
695
+ ...readString(pairing.expiresAt) ? { expiresAt: readString(pairing.expiresAt) } : {}
696
+ };
697
+ }
698
+ return normalized;
699
+ }
700
+ function isMeshHostOwner(mesh) {
701
+ return resolveMeshHostStatus(mesh).role === "host";
702
+ }
703
+ function buildMeshHostRequiredFailure(mesh, operation) {
704
+ const meshHost = resolveMeshHostStatus(mesh);
705
+ return {
706
+ success: false,
707
+ code: "mesh_host_required",
708
+ error: `Mesh Host daemon required for ${operation}; member daemons must pair with the host and cannot own coordinator/queue mutations.`,
709
+ meshHost
710
+ };
711
+ }
712
+ function requireMeshHostQueueOwner(opts) {
713
+ if (opts?.ownerRole === "member") {
714
+ throw new Error("Mesh Host daemon required to mutate mesh queue; member daemons must use the host-owned queue.");
715
+ }
716
+ }
717
+ function createDefaultMeshHostMetadata() {
718
+ return {
719
+ role: "host",
720
+ pairing: { status: "not_configured" }
721
+ };
722
+ }
723
+ var init_mesh_host_ownership = __esm({
724
+ "src/mesh/mesh-host-ownership.ts"() {
725
+ "use strict";
726
+ }
727
+ });
728
+
660
729
  // src/config/mesh-config.ts
661
730
  var mesh_config_exports = {};
662
731
  __export(mesh_config_exports, {
663
732
  addNode: () => addNode,
733
+ applyMeshHostJoinRequest: () => applyMeshHostJoinRequest,
734
+ configureMeshHostPairing: () => configureMeshHostPairing,
664
735
  createMesh: () => createMesh,
736
+ createMeshHostPairingToken: () => createMeshHostPairingToken,
665
737
  deleteMesh: () => deleteMesh,
666
738
  getMesh: () => getMesh,
667
739
  getMeshByRepo: () => getMeshByRepo,
668
740
  listMeshes: () => listMeshes,
741
+ markMeshHostPairingJoined: () => markMeshHostPairingJoined,
669
742
  normalizeRepoIdentity: () => normalizeRepoIdentity,
670
743
  removeNode: () => removeNode,
744
+ tokenIdForManualPairing: () => tokenIdForManualPairing,
671
745
  updateMesh: () => updateMesh,
672
746
  updateNode: () => updateNode
673
747
  });
674
748
  import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
675
749
  import { join as join4 } from "path";
676
- import { randomUUID as randomUUID3 } from "crypto";
750
+ import { createHash, randomBytes, randomUUID as randomUUID3 } from "crypto";
677
751
  function getMeshConfigPath() {
678
752
  return join4(getConfigDir(), "meshes.json");
679
753
  }
@@ -746,6 +820,7 @@ function createMesh(opts) {
746
820
  defaultBranch: opts.defaultBranch,
747
821
  policy: mergeMeshPolicy(void 0, opts.policy),
748
822
  coordinator: opts.coordinator || {},
823
+ meshHost: opts.meshHost || createDefaultMeshHostMetadata(),
749
824
  nodes: [],
750
825
  createdAt: now,
751
826
  updatedAt: now
@@ -762,6 +837,7 @@ function updateMesh(meshId, opts) {
762
837
  if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
763
838
  if (opts.policy) mesh.policy = mergeMeshPolicy(mesh.policy, opts.policy);
764
839
  if (opts.coordinator) mesh.coordinator = opts.coordinator;
840
+ if (opts.meshHost) mesh.meshHost = opts.meshHost;
765
841
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
766
842
  saveMeshConfig(config);
767
843
  return mesh;
@@ -774,6 +850,186 @@ function deleteMesh(meshId) {
774
850
  saveMeshConfig(config);
775
851
  return true;
776
852
  }
853
+ function normalizeManualHostAddress(hostAddress) {
854
+ const normalized = hostAddress.trim().replace(/\/+$/, "");
855
+ if (!normalized) throw new Error("hostAddress required");
856
+ let parsed;
857
+ try {
858
+ parsed = new URL(normalized);
859
+ } catch {
860
+ throw new Error("hostAddress must be a valid http(s) or ws(s) URL");
861
+ }
862
+ if (!["http:", "https:", "ws:", "wss:"].includes(parsed.protocol)) {
863
+ throw new Error("hostAddress must use http, https, ws, or wss");
864
+ }
865
+ return normalized;
866
+ }
867
+ function tokenIdForManualPairing(token) {
868
+ return `tok_${createHash("sha256").update(token).digest("hex").slice(0, 16)}`;
869
+ }
870
+ function normalizeTokenExpiry(value) {
871
+ if (typeof value !== "string" || !value.trim()) return void 0;
872
+ const date = new Date(value);
873
+ if (Number.isNaN(date.getTime())) throw new Error("expiresAt must be a valid ISO date");
874
+ return date.toISOString();
875
+ }
876
+ function assertPairingTokenValid(pairing, rawToken, nowIso) {
877
+ const token = rawToken.trim();
878
+ if (!token) return { ok: false, reason: "token required" };
879
+ const presentedTokenId = tokenIdForManualPairing(token);
880
+ const expectedTokenId = pairing?.tokenId;
881
+ if (!expectedTokenId || pairing?.status === "not_configured" || pairing?.status === "revoked") {
882
+ return { ok: false, reason: "host pairing token is not configured", presentedTokenId };
883
+ }
884
+ if (pairing.expiresAt && new Date(pairing.expiresAt).getTime() <= new Date(nowIso).getTime()) {
885
+ return { ok: false, reason: "host pairing token expired", expectedTokenId, presentedTokenId };
886
+ }
887
+ if (presentedTokenId !== expectedTokenId) {
888
+ return { ok: false, reason: "invalid pairing token", expectedTokenId, presentedTokenId };
889
+ }
890
+ return { ok: true, tokenId: presentedTokenId };
891
+ }
892
+ function configureMeshHostPairing(meshId, opts) {
893
+ const hostAddress = normalizeManualHostAddress(opts.hostAddress);
894
+ const token = opts.token.trim();
895
+ if (!token) throw new Error("token required");
896
+ const config = loadMeshConfig();
897
+ const mesh = config.meshes.find((m) => m.id === meshId);
898
+ if (!mesh) return void 0;
899
+ const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
900
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
901
+ const meshHost = {
902
+ ...previous,
903
+ role: "member",
904
+ hostAddress,
905
+ pairing: {
906
+ status: "pairing",
907
+ tokenId: tokenIdForManualPairing(token),
908
+ lastPairedAt: now
909
+ }
910
+ };
911
+ mesh.meshHost = meshHost;
912
+ mesh.updatedAt = now;
913
+ saveMeshConfig(config);
914
+ return { mesh, meshHost, hostAddress };
915
+ }
916
+ function createMeshHostPairingToken(meshId, opts = {}) {
917
+ const config = loadMeshConfig();
918
+ const mesh = config.meshes.find((m) => m.id === meshId);
919
+ if (!mesh) return void 0;
920
+ const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
921
+ const token = (opts.token || `mhj_${randomBytes(24).toString("base64url")}`).trim();
922
+ if (!token) throw new Error("token required");
923
+ const tokenId = tokenIdForManualPairing(token);
924
+ const expiresAt = normalizeTokenExpiry(opts.expiresAt);
925
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
926
+ if (previous.role === "member") {
927
+ throw new Error("Mesh Host daemon required to create host pairing tokens; member daemons cannot mint host join tokens.");
928
+ }
929
+ const meshHost = {
930
+ ...previous,
931
+ role: "host",
932
+ pairing: {
933
+ status: "pairing",
934
+ tokenId,
935
+ lastPairedAt: now,
936
+ ...expiresAt ? { expiresAt } : {}
937
+ }
938
+ };
939
+ mesh.meshHost = meshHost;
940
+ mesh.updatedAt = now;
941
+ saveMeshConfig(config);
942
+ return { mesh, meshHost, token, tokenId, ...expiresAt ? { expiresAt } : {} };
943
+ }
944
+ function applyMeshHostJoinRequest(meshId, opts) {
945
+ const config = loadMeshConfig();
946
+ const mesh = config.meshes.find((m) => m.id === meshId);
947
+ if (!mesh) return void 0;
948
+ const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
949
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
950
+ if (previous.role === "member") {
951
+ return { accepted: false, mesh, meshHost: previous, reason: "Mesh Host daemon required to accept join requests" };
952
+ }
953
+ const meshHost = { ...previous, role: "host" };
954
+ const validation = assertPairingTokenValid(meshHost.pairing, opts.token, now);
955
+ if (!validation.ok) {
956
+ mesh.meshHost = {
957
+ ...meshHost,
958
+ pairing: {
959
+ ...meshHost.pairing || { status: "not_configured" },
960
+ status: "rejected",
961
+ lastRejectedAt: now
962
+ }
963
+ };
964
+ mesh.updatedAt = now;
965
+ saveMeshConfig(config);
966
+ return { accepted: false, mesh, meshHost: mesh.meshHost, tokenId: validation.presentedTokenId, reason: validation.reason };
967
+ }
968
+ const workspace = opts.memberNode.workspace.trim();
969
+ if (!workspace) throw new Error("memberNode.workspace required");
970
+ const memberId = opts.memberNode.id?.trim();
971
+ let node = mesh.nodes.find((n) => memberId && n.id === memberId || n.workspace === workspace);
972
+ if (node) {
973
+ node.workspace = workspace;
974
+ node.repoRoot = opts.memberNode.repoRoot;
975
+ node.daemonId = opts.memberNode.daemonId;
976
+ node.machineId = opts.memberNode.machineId;
977
+ node.userOverrides = opts.memberNode.userOverrides || node.userOverrides || {};
978
+ node.policy = { ...node.policy || {}, ...opts.memberNode.policy || {} };
979
+ node.role = "member";
980
+ } else {
981
+ if (mesh.nodes.length >= 10) throw new Error("Maximum 10 nodes per mesh");
982
+ node = {
983
+ id: memberId || `node_${randomUUID3().replace(/-/g, "")}`,
984
+ workspace,
985
+ repoRoot: opts.memberNode.repoRoot,
986
+ daemonId: opts.memberNode.daemonId,
987
+ machineId: opts.memberNode.machineId,
988
+ userOverrides: opts.memberNode.userOverrides || {},
989
+ policy: opts.memberNode.policy || {},
990
+ role: "member"
991
+ };
992
+ mesh.nodes.push(node);
993
+ }
994
+ mesh.meshHost = {
995
+ ...meshHost,
996
+ pairing: {
997
+ ...meshHost.pairing || {},
998
+ status: "paired",
999
+ tokenId: validation.tokenId,
1000
+ joinedAt: now,
1001
+ lastPairedAt: meshHost.pairing?.lastPairedAt || now,
1002
+ ...meshHost.pairing?.expiresAt ? { expiresAt: meshHost.pairing.expiresAt } : {}
1003
+ }
1004
+ };
1005
+ mesh.updatedAt = now;
1006
+ saveMeshConfig(config);
1007
+ return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
1008
+ }
1009
+ function markMeshHostPairingJoined(meshId, opts) {
1010
+ const config = loadMeshConfig();
1011
+ const mesh = config.meshes.find((m) => m.id === meshId);
1012
+ if (!mesh) return void 0;
1013
+ const now = opts.joinedAt || (/* @__PURE__ */ new Date()).toISOString();
1014
+ const previous = mesh.meshHost || createDefaultMeshHostMetadata();
1015
+ const tokenId = opts.tokenId || (opts.token ? tokenIdForManualPairing(opts.token) : previous.pairing?.tokenId);
1016
+ mesh.meshHost = {
1017
+ ...previous,
1018
+ role: "member",
1019
+ ...opts.hostDaemonId ? { hostDaemonId: opts.hostDaemonId } : {},
1020
+ ...opts.hostNodeId ? { hostNodeId: opts.hostNodeId } : {},
1021
+ pairing: {
1022
+ ...previous.pairing || {},
1023
+ status: "paired",
1024
+ ...tokenId ? { tokenId } : {},
1025
+ joinedAt: now,
1026
+ lastPairedAt: previous.pairing?.lastPairedAt || now
1027
+ }
1028
+ };
1029
+ mesh.updatedAt = now;
1030
+ saveMeshConfig(config);
1031
+ return { mesh, meshHost: mesh.meshHost };
1032
+ }
777
1033
  function addNode(meshId, opts) {
778
1034
  const config = loadMeshConfig();
779
1035
  const mesh = config.meshes.find((m) => m.id === meshId);
@@ -794,7 +1050,8 @@ function addNode(meshId, opts) {
794
1050
  policy: opts.policy || {},
795
1051
  isLocalWorktree: opts.isLocalWorktree,
796
1052
  worktreeBranch: opts.worktreeBranch,
797
- clonedFromNodeId: opts.clonedFromNodeId
1053
+ clonedFromNodeId: opts.clonedFromNodeId,
1054
+ role: opts.role
798
1055
  };
799
1056
  mesh.nodes.push(node);
800
1057
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -830,6 +1087,7 @@ var init_mesh_config = __esm({
830
1087
  "use strict";
831
1088
  init_config();
832
1089
  init_repo_mesh_types();
1090
+ init_mesh_host_ownership();
833
1091
  SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set(["preserve", "stop", "delete_stopped", "stop_and_delete"]);
834
1092
  SPAWNED_SESSION_VISIBILITY_MODES = /* @__PURE__ */ new Set(["visible", "hidden"]);
835
1093
  }
@@ -1007,8 +1265,8 @@ __export(mesh_ledger_exports, {
1007
1265
  readLedgerEntries: () => readLedgerEntries,
1008
1266
  readLedgerSlice: () => readLedgerSlice
1009
1267
  });
1010
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, appendFileSync, statSync as statSync2, renameSync } from "fs";
1011
- import { join as join5 } from "path";
1268
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, appendFileSync, statSync as statSync2, renameSync } from "fs";
1269
+ import { join as join6 } from "path";
1012
1270
  import { randomUUID as randomUUID4 } from "crypto";
1013
1271
  import { EventEmitter } from "events";
1014
1272
  function isIntentionalCleanupStopEntry(entry) {
@@ -1017,19 +1275,19 @@ function isIntentionalCleanupStopEntry(entry) {
1017
1275
  return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
1018
1276
  }
1019
1277
  function getLedgerDir() {
1020
- const dir = join5(getConfigDir(), LEDGER_DIR_NAME);
1021
- if (!existsSync5(dir)) {
1278
+ const dir = join6(getConfigDir(), LEDGER_DIR_NAME);
1279
+ if (!existsSync6(dir)) {
1022
1280
  mkdirSync3(dir, { recursive: true, mode: 448 });
1023
1281
  }
1024
1282
  return dir;
1025
1283
  }
1026
1284
  function getLedgerPath(meshId) {
1027
1285
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1028
- return join5(getLedgerDir(), `${safe}.jsonl`);
1286
+ return join6(getLedgerDir(), `${safe}.jsonl`);
1029
1287
  }
1030
1288
  function getRotatedPath(meshId, index) {
1031
1289
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1032
- return join5(getLedgerDir(), `${safe}.${index}.jsonl`);
1290
+ return join6(getLedgerDir(), `${safe}.${index}.jsonl`);
1033
1291
  }
1034
1292
  function buildTaskCompletionEvidence(opts) {
1035
1293
  const providerSessionId = opts.providerSessionId?.trim() || void 0;
@@ -1070,7 +1328,7 @@ function appendLedgerEntry(meshId, partial) {
1070
1328
  ...partial
1071
1329
  };
1072
1330
  const filePath = getLedgerPath(meshId);
1073
- if (existsSync5(filePath)) {
1331
+ if (existsSync6(filePath)) {
1074
1332
  try {
1075
1333
  const stat2 = statSync2(filePath);
1076
1334
  if (stat2.size >= MAX_FILE_SIZE_BYTES) {
@@ -1137,10 +1395,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
1137
1395
  }
1138
1396
  function readLedgerEntries(meshId, opts) {
1139
1397
  const filePath = getLedgerPath(meshId);
1140
- if (!existsSync5(filePath)) return [];
1398
+ if (!existsSync6(filePath)) return [];
1141
1399
  let content;
1142
1400
  try {
1143
- content = readFileSync3(filePath, "utf-8");
1401
+ content = readFileSync4(filePath, "utf-8");
1144
1402
  } catch {
1145
1403
  return [];
1146
1404
  }
@@ -1312,7 +1570,7 @@ function getSessionRecoveryContext(meshId, opts) {
1312
1570
  }
1313
1571
  function rotateLedgerFile(meshId, currentPath) {
1314
1572
  let index = 1;
1315
- while (existsSync5(getRotatedPath(meshId, index))) {
1573
+ while (existsSync6(getRotatedPath(meshId, index))) {
1316
1574
  index++;
1317
1575
  if (index > 10) break;
1318
1576
  }
@@ -1351,18 +1609,48 @@ __export(mesh_work_queue_exports, {
1351
1609
  updateSessionTaskStatus: () => updateSessionTaskStatus,
1352
1610
  updateTaskStatus: () => updateTaskStatus
1353
1611
  });
1354
- import { existsSync as existsSync6, writeFileSync as writeFileSync3, readFileSync as readFileSync4 } from "fs";
1355
- import { join as join6 } from "path";
1612
+ import { existsSync as existsSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync5, openSync, closeSync, unlinkSync } from "fs";
1613
+ import { join as join7 } from "path";
1356
1614
  import { randomUUID as randomUUID5 } from "crypto";
1357
1615
  function getQueuePath(meshId) {
1358
1616
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1359
- return join6(getLedgerDir(), `${safe}.queue.json`);
1617
+ return join7(getLedgerDir(), `${safe}.queue.json`);
1618
+ }
1619
+ function getLockPath(meshId) {
1620
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
1621
+ return join7(getLedgerDir(), `${safe}.queue.lock`);
1622
+ }
1623
+ function withQueueLock(meshId, fn) {
1624
+ const lockPath = getLockPath(meshId);
1625
+ let fd = -1;
1626
+ for (let i = 0; i < 10; i++) {
1627
+ try {
1628
+ fd = openSync(lockPath, "wx");
1629
+ break;
1630
+ } catch {
1631
+ const deadline = Date.now() + 30;
1632
+ while (Date.now() < deadline) {
1633
+ }
1634
+ }
1635
+ }
1636
+ try {
1637
+ return fn();
1638
+ } finally {
1639
+ if (fd !== -1) try {
1640
+ closeSync(fd);
1641
+ } catch {
1642
+ }
1643
+ try {
1644
+ unlinkSync(lockPath);
1645
+ } catch {
1646
+ }
1647
+ }
1360
1648
  }
1361
1649
  function readQueue(meshId) {
1362
1650
  const path28 = getQueuePath(meshId);
1363
- if (!existsSync6(path28)) return [];
1651
+ if (!existsSync7(path28)) return [];
1364
1652
  try {
1365
- const content = readFileSync4(path28, "utf-8");
1653
+ const content = readFileSync5(path28, "utf-8");
1366
1654
  return JSON.parse(content);
1367
1655
  } catch {
1368
1656
  return [];
@@ -1373,20 +1661,23 @@ function writeQueue(meshId, queue) {
1373
1661
  writeFileSync3(path28, JSON.stringify(queue, null, 2), "utf-8");
1374
1662
  }
1375
1663
  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;
1664
+ requireMeshHostQueueOwner(opts);
1665
+ return withQueueLock(meshId, () => {
1666
+ const queue = readQueue(meshId);
1667
+ const entry = {
1668
+ id: randomUUID5(),
1669
+ meshId,
1670
+ message,
1671
+ status: "pending",
1672
+ targetNodeId: opts?.targetNodeId,
1673
+ targetSessionId: opts?.targetSessionId,
1674
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1675
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1676
+ };
1677
+ queue.push(entry);
1678
+ writeQueue(meshId, queue);
1679
+ return entry;
1680
+ });
1390
1681
  }
1391
1682
  function getQueue(meshId, opts) {
1392
1683
  let queue = readQueue(meshId);
@@ -1397,100 +1688,114 @@ function getQueue(meshId, opts) {
1397
1688
  return queue;
1398
1689
  }
1399
1690
  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;
1419
- }
1420
- 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];
1691
+ return withQueueLock(meshId, () => {
1692
+ const queue = readQueue(meshId);
1693
+ const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
1694
+ if (hasActiveAssignment) return null;
1695
+ let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
1696
+ if (targetIdx === -1) {
1697
+ targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
1698
+ }
1699
+ if (targetIdx === -1) {
1700
+ targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
1701
+ }
1702
+ if (targetIdx === -1) return null;
1703
+ const entry = queue[targetIdx];
1704
+ entry.status = "assigned";
1705
+ entry.assignedNodeId = nodeId;
1706
+ entry.assignedSessionId = sessionId;
1707
+ entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
1708
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1709
+ writeQueue(meshId, queue);
1710
+ return entry;
1711
+ });
1712
+ }
1713
+ function updateTaskStatus(meshId, taskId, status, opts) {
1714
+ requireMeshHostQueueOwner(opts);
1715
+ return withQueueLock(meshId, () => {
1716
+ const queue = readQueue(meshId);
1717
+ const idx = queue.findIndex((q) => q.id === taskId);
1718
+ if (idx === -1) return null;
1719
+ queue[idx].status = status;
1720
+ queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1721
+ writeQueue(meshId, queue);
1722
+ return queue[idx];
1723
+ });
1428
1724
  }
1429
1725
  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];
1726
+ return withQueueLock(meshId, () => {
1727
+ const queue = readQueue(meshId);
1728
+ const idx = queue.findIndex((q) => q.id === taskId);
1729
+ if (idx === -1) return null;
1730
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1731
+ queue[idx].autoLaunch = { ...autoLaunch, updatedAt: now };
1732
+ queue[idx].updatedAt = now;
1733
+ writeQueue(meshId, queue);
1734
+ return queue[idx];
1735
+ });
1441
1736
  }
1442
1737
  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];
1738
+ requireMeshHostQueueOwner(opts);
1739
+ return withQueueLock(meshId, () => {
1740
+ const queue = readQueue(meshId);
1741
+ const idx = queue.findIndex((q) => q.id === taskId);
1742
+ if (idx === -1) return null;
1743
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1744
+ queue[idx].status = "cancelled";
1745
+ queue[idx].updatedAt = now;
1746
+ queue[idx].cancelledAt = now;
1747
+ if (opts?.reason) queue[idx].cancelReason = opts.reason;
1748
+ writeQueue(meshId, queue);
1749
+ return queue[idx];
1750
+ });
1453
1751
  }
1454
1752
  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;
1475
- }
1476
- 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") {
1753
+ requireMeshHostQueueOwner(opts);
1754
+ return withQueueLock(meshId, () => {
1755
+ const queue = readQueue(meshId);
1756
+ const idx = queue.findIndex((q) => q.id === taskId);
1757
+ if (idx === -1) return null;
1758
+ const entry = queue[idx];
1759
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1760
+ entry.status = "pending";
1761
+ delete entry.assignedNodeId;
1762
+ delete entry.assignedSessionId;
1763
+ delete entry.cancelledAt;
1764
+ delete entry.cancelReason;
1765
+ if (opts?.clearTargetNode) delete entry.targetNodeId;
1766
+ if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
1767
+ if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
1768
+ if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
1769
+ entry.updatedAt = now;
1770
+ entry.requeuedAt = now;
1771
+ entry.requeueCount = (entry.requeueCount || 0) + 1;
1772
+ if (opts?.reason) entry.requeueReason = opts.reason;
1773
+ writeQueue(meshId, queue);
1774
+ return entry;
1775
+ });
1776
+ }
1777
+ function updateSessionTaskStatus(meshId, sessionId, status, opts) {
1778
+ return withQueueLock(meshId, () => {
1779
+ const queue = readQueue(meshId);
1780
+ const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
1781
+ const hasOccurredAt = Number.isFinite(occurredAtTime);
1782
+ let bestIdx = -1;
1783
+ let bestTime = 0;
1784
+ for (let i = queue.length - 1; i >= 0; i--) {
1785
+ if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
1482
1786
  const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1787
+ if (hasOccurredAt && Number.isFinite(time) && time > occurredAtTime) continue;
1483
1788
  if (time > bestTime) {
1484
1789
  bestTime = time;
1485
1790
  bestIdx = i;
1486
1791
  }
1487
1792
  }
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];
1793
+ if (bestIdx === -1) return null;
1794
+ queue[bestIdx].status = status;
1795
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1796
+ writeQueue(meshId, queue);
1797
+ return queue[bestIdx];
1798
+ });
1494
1799
  }
1495
1800
  function getMeshQueueStats(meshId) {
1496
1801
  const queue = readQueue(meshId);
@@ -1530,6 +1835,7 @@ var init_mesh_work_queue = __esm({
1530
1835
  "src/mesh/mesh-work-queue.ts"() {
1531
1836
  "use strict";
1532
1837
  init_mesh_ledger();
1838
+ init_mesh_host_ownership();
1533
1839
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
1534
1840
  HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
1535
1841
  }
@@ -1539,7 +1845,7 @@ var init_mesh_work_queue = __esm({
1539
1845
  import { exec } from "child_process";
1540
1846
  import * as os2 from "os";
1541
1847
  import * as path8 from "path";
1542
- import { existsSync as existsSync7 } from "fs";
1848
+ import { existsSync as existsSync8 } from "fs";
1543
1849
  function parseVersion(raw) {
1544
1850
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
1545
1851
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
@@ -1563,7 +1869,7 @@ function resolveCommandPath(command) {
1563
1869
  if (isExplicitCommandPath(trimmed)) {
1564
1870
  const expanded = expandHome(trimmed);
1565
1871
  const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
1566
- return existsSync7(candidate) ? candidate : null;
1872
+ return existsSync8(candidate) ? candidate : null;
1567
1873
  }
1568
1874
  return null;
1569
1875
  }
@@ -1890,18 +2196,77 @@ __export(mesh_events_exports, {
1890
2196
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
1891
2197
  getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
1892
2198
  handleMeshForwardEvent: () => handleMeshForwardEvent,
2199
+ queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
1893
2200
  setupMeshEventForwarding: () => setupMeshEventForwarding,
1894
2201
  triggerMeshQueue: () => triggerMeshQueue,
1895
2202
  tryAssignQueueTask: () => tryAssignQueueTask
1896
2203
  });
1897
- function drainPendingMeshCoordinatorEvents() {
1898
- return pendingMeshCoordinatorEvents.splice(0);
2204
+ import { appendFileSync as appendFileSync3, existsSync as existsSync10, readFileSync as readFileSync6, unlinkSync as unlinkSync3 } from "fs";
2205
+ import { join as join10 } from "path";
2206
+ function sweepExpiredRemoteIdleSessions() {
2207
+ const now = Date.now();
2208
+ for (const [key, session] of remoteIdleSessions) {
2209
+ if (session.expiresAt <= now) remoteIdleSessions.delete(key);
2210
+ }
2211
+ }
2212
+ function getPendingEventsPath(meshId) {
2213
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2214
+ return join10(getLedgerDir(), `${safe}.pending-events.jsonl`);
2215
+ }
2216
+ function queuePendingMeshCoordinatorEvent(event) {
2217
+ try {
2218
+ appendFileSync3(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
2219
+ return true;
2220
+ } catch (e) {
2221
+ LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
2222
+ return false;
2223
+ }
2224
+ }
2225
+ function drainPendingMeshCoordinatorEvents(meshId) {
2226
+ if (!meshId) return [];
2227
+ const path28 = getPendingEventsPath(meshId);
2228
+ if (!existsSync10(path28)) return [];
2229
+ try {
2230
+ const raw = readFileSync6(path28, "utf-8");
2231
+ try {
2232
+ unlinkSync3(path28);
2233
+ } catch {
2234
+ }
2235
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
2236
+ try {
2237
+ return [JSON.parse(line)];
2238
+ } catch {
2239
+ return [];
2240
+ }
2241
+ });
2242
+ } catch {
2243
+ return [];
2244
+ }
1899
2245
  }
1900
- function getPendingMeshCoordinatorEvents() {
1901
- return pendingMeshCoordinatorEvents.slice();
2246
+ function getPendingMeshCoordinatorEvents(meshId) {
2247
+ if (!meshId) return [];
2248
+ const path28 = getPendingEventsPath(meshId);
2249
+ if (!existsSync10(path28)) return [];
2250
+ try {
2251
+ const raw = readFileSync6(path28, "utf-8");
2252
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
2253
+ try {
2254
+ return [JSON.parse(line)];
2255
+ } catch {
2256
+ return [];
2257
+ }
2258
+ });
2259
+ } catch {
2260
+ return [];
2261
+ }
1902
2262
  }
1903
- function clearPendingMeshCoordinatorEvents() {
1904
- pendingMeshCoordinatorEvents.splice(0);
2263
+ function clearPendingMeshCoordinatorEvents(meshId) {
2264
+ if (!meshId) return;
2265
+ const path28 = getPendingEventsPath(meshId);
2266
+ if (existsSync10(path28)) try {
2267
+ unlinkSync3(path28);
2268
+ } catch {
2269
+ }
1905
2270
  }
1906
2271
  function readNonEmptyString(value) {
1907
2272
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -1947,6 +2312,38 @@ function shouldSuppressIntentionalCleanupStop(args) {
1947
2312
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
1948
2313
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
1949
2314
  }
2315
+ function readEventTimestamp(value) {
2316
+ if (typeof value === "number" && Number.isFinite(value)) return value;
2317
+ if (typeof value === "string" && value.trim()) {
2318
+ const numeric = Number(value);
2319
+ if (Number.isFinite(numeric)) return numeric;
2320
+ const parsed = Date.parse(value);
2321
+ if (Number.isFinite(parsed)) return parsed;
2322
+ }
2323
+ return null;
2324
+ }
2325
+ function buildMeshCompletionFingerprint(args) {
2326
+ const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
2327
+ return [
2328
+ args.meshId,
2329
+ args.event,
2330
+ args.sessionId,
2331
+ args.providerType || "",
2332
+ args.providerSessionId || "",
2333
+ timestampPart
2334
+ ].join("::");
2335
+ }
2336
+ function isDuplicateMeshCompletionEvent(args) {
2337
+ const fingerprint = buildMeshCompletionFingerprint(args);
2338
+ if (!fingerprint) return false;
2339
+ const now = Date.now();
2340
+ for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
2341
+ if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
2342
+ }
2343
+ if (recentCompletionFingerprints.has(fingerprint)) return true;
2344
+ recentCompletionFingerprints.set(fingerprint, now);
2345
+ return false;
2346
+ }
1950
2347
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
1951
2348
  const task = claimNextTask(meshId, nodeId, sessionId);
1952
2349
  if (!task) {
@@ -1965,7 +2362,16 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
1965
2362
  message: task.message
1966
2363
  }).catch((e) => {
1967
2364
  LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
1968
- updateTaskStatus(meshId, task.id, "failed");
2365
+ updateTaskStatus(meshId, task.id, "pending");
2366
+ try {
2367
+ appendLedgerEntry(meshId, {
2368
+ kind: "dispatch_failed",
2369
+ nodeId,
2370
+ sessionId,
2371
+ payload: { taskId: task.id, error: e?.message, retryable: true }
2372
+ });
2373
+ } catch {
2374
+ }
1969
2375
  });
1970
2376
  return true;
1971
2377
  }
@@ -2299,18 +2705,36 @@ function injectMeshSystemMessage(components, args) {
2299
2705
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
2300
2706
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
2301
2707
  }
2708
+ const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
2709
+ if (args.event === "agent:generating_completed" && eventSessionId) {
2710
+ const duplicateCompletion = isDuplicateMeshCompletionEvent({
2711
+ meshId: args.meshId,
2712
+ event: args.event,
2713
+ sessionId: eventSessionId,
2714
+ providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
2715
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
2716
+ timestamp: eventTimestamp,
2717
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
2718
+ });
2719
+ if (duplicateCompletion) {
2720
+ LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
2721
+ return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
2722
+ }
2723
+ }
2302
2724
  let completedTaskForLedger = null;
2303
2725
  if (args.event === "agent:generating_completed") {
2304
2726
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
2305
2727
  const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
2306
2728
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
2307
2729
  if (sessionId) {
2308
- const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
2730
+ const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
2731
+ occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
2732
+ });
2309
2733
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
2310
2734
  if (nodeId && providerType) {
2311
- setTimeout(() => {
2735
+ setImmediate(() => {
2312
2736
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
2313
- }, 500);
2737
+ });
2314
2738
  }
2315
2739
  }
2316
2740
  } else if (args.event === "agent:ready") {
@@ -2348,13 +2772,17 @@ function injectMeshSystemMessage(components, args) {
2348
2772
  }
2349
2773
  }
2350
2774
  if (sessionId && nodeId && providerType) {
2351
- remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
2352
- setTimeout(() => {
2775
+ sweepExpiredRemoteIdleSessions();
2776
+ remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
2777
+ nodeId,
2778
+ sessionId,
2779
+ providerType,
2780
+ expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
2781
+ });
2782
+ setImmediate(() => {
2353
2783
  const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
2354
- if (assigned) {
2355
- remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
2356
- }
2357
- }, 500);
2784
+ if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
2785
+ });
2358
2786
  }
2359
2787
  } else if (args.event === "agent:generating_started") {
2360
2788
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
@@ -2465,17 +2893,18 @@ function injectMeshSystemMessage(components, args) {
2465
2893
  return true;
2466
2894
  });
2467
2895
  if (coordinatorInstances.length === 0) {
2468
- if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
2469
- pendingMeshCoordinatorEvents.push({
2470
- event: args.event,
2471
- meshId: args.meshId,
2472
- nodeLabel: args.nodeLabel,
2473
- metadataEvent: {
2474
- ...args.metadataEvent,
2475
- ...recoveryContext ? { recoveryContext } : {}
2476
- },
2477
- queuedAt: Date.now()
2478
- });
2896
+ if (queuePendingMeshCoordinatorEvent({
2897
+ event: args.event,
2898
+ meshId: args.meshId,
2899
+ nodeLabel: args.nodeLabel,
2900
+ nodeId: args.nodeId || void 0,
2901
+ workspace: readNonEmptyString(args.metadataEvent.workspace),
2902
+ metadataEvent: {
2903
+ ...args.metadataEvent,
2904
+ ...recoveryContext ? { recoveryContext } : {}
2905
+ },
2906
+ queuedAt: Date.now()
2907
+ })) {
2479
2908
  LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
2480
2909
  }
2481
2910
  return { success: true, forwarded: 0 };
@@ -2514,6 +2943,7 @@ function handleMeshForwardEvent(components, payload) {
2514
2943
  providerType: readNonEmptyString(payload.providerType),
2515
2944
  providerSessionId: readNonEmptyString(payload.providerSessionId),
2516
2945
  finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
2946
+ ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
2517
2947
  intentional: payload.intentional === true,
2518
2948
  intentionalStop: payload.intentionalStop === true,
2519
2949
  operatorCleanup: payload.operatorCleanup === true,
@@ -2556,7 +2986,7 @@ function setupMeshEventForwarding(components) {
2556
2986
  });
2557
2987
  });
2558
2988
  }
2559
- var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2989
+ var REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2560
2990
  var init_mesh_events = __esm({
2561
2991
  "src/mesh/mesh-events.ts"() {
2562
2992
  "use strict";
@@ -2566,9 +2996,8 @@ var init_mesh_events = __esm({
2566
2996
  init_logger();
2567
2997
  init_mesh_ledger();
2568
2998
  init_mesh_work_queue();
2999
+ REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
2569
3000
  remoteIdleSessions = /* @__PURE__ */ new Map();
2570
- MAX_PENDING_EVENTS = 50;
2571
- pendingMeshCoordinatorEvents = [];
2572
3001
  MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
2573
3002
  "agent:generating_started",
2574
3003
  "agent:generating_completed",
@@ -2584,6 +3013,8 @@ var init_mesh_events = __esm({
2584
3013
  "monitor:long_generating": "task_stalled"
2585
3014
  };
2586
3015
  INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
3016
+ RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
3017
+ recentCompletionFingerprints = /* @__PURE__ */ new Map();
2587
3018
  autoLaunchInProgress = /* @__PURE__ */ new Set();
2588
3019
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
2589
3020
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
@@ -5676,8 +6107,14 @@ async function getGitRepoStatus(workspace, options = {}) {
5676
6107
  const includeSubmodules = options.includeSubmodules !== false;
5677
6108
  try {
5678
6109
  const repo = await resolveGitRepository(workspace, options);
5679
- const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
5680
- const parsed = parsePorcelainV2Status(statusOutput.stdout);
6110
+ let parsed = await readPorcelainStatus(repo, options);
6111
+ let upstreamProbe = getInitialUpstreamProbe(parsed);
6112
+ if (options.refreshUpstream) {
6113
+ upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
6114
+ if (upstreamProbe.upstreamStatus === "fresh") {
6115
+ parsed = await readPorcelainStatus(repo, options);
6116
+ }
6117
+ }
5681
6118
  const head = await readHead(repo, options);
5682
6119
  const stashCount = await readStashCount(repo, options);
5683
6120
  let submodules;
@@ -5692,6 +6129,9 @@ async function getGitRepoStatus(workspace, options = {}) {
5692
6129
  headCommit: head.commit,
5693
6130
  headMessage: head.message,
5694
6131
  upstream: parsed.upstream,
6132
+ upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
6133
+ upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
6134
+ upstreamFetchError: upstreamProbe.upstreamFetchError,
5695
6135
  ahead: parsed.ahead,
5696
6136
  behind: parsed.behind,
5697
6137
  staged: parsed.staged,
@@ -5716,6 +6156,60 @@ async function getGitRepoStatus(workspace, options = {}) {
5716
6156
  );
5717
6157
  }
5718
6158
  }
6159
+ async function readPorcelainStatus(repo, options) {
6160
+ const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
6161
+ return parsePorcelainV2Status(statusOutput.stdout);
6162
+ }
6163
+ function getInitialUpstreamProbe(parsed) {
6164
+ return {
6165
+ upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
6166
+ };
6167
+ }
6168
+ async function refreshTrackedUpstream(repo, parsed, options) {
6169
+ if (!parsed.upstream || !parsed.branch) {
6170
+ return { upstreamStatus: "no_upstream" };
6171
+ }
6172
+ const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
6173
+ if (!remoteName) {
6174
+ return {
6175
+ upstreamStatus: "stale",
6176
+ upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
6177
+ };
6178
+ }
6179
+ try {
6180
+ await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
6181
+ return {
6182
+ upstreamStatus: "fresh",
6183
+ upstreamFetchedAt: Date.now()
6184
+ };
6185
+ } catch (error) {
6186
+ return {
6187
+ upstreamStatus: "stale",
6188
+ upstreamFetchError: formatGitError(error)
6189
+ };
6190
+ }
6191
+ }
6192
+ async function readBranchRemote(repo, branch, options) {
6193
+ try {
6194
+ const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
6195
+ return result.stdout.trim() || null;
6196
+ } catch {
6197
+ return null;
6198
+ }
6199
+ }
6200
+ function inferRemoteName(upstream) {
6201
+ const [remoteName] = upstream.split("/");
6202
+ return remoteName?.trim() || null;
6203
+ }
6204
+ function formatGitError(error) {
6205
+ if (error instanceof GitCommandError) {
6206
+ return error.stderr || error.message;
6207
+ }
6208
+ if (error instanceof Error) {
6209
+ return error.message;
6210
+ }
6211
+ return String(error);
6212
+ }
5719
6213
  function parsePorcelainV2Status(output) {
5720
6214
  const parsed = {
5721
6215
  branch: null,
@@ -5810,6 +6304,7 @@ function emptyStatus(workspace, lastCheckedAt, error) {
5810
6304
  headCommit: null,
5811
6305
  headMessage: null,
5812
6306
  upstream: null,
6307
+ upstreamStatus: "unavailable",
5813
6308
  ahead: 0,
5814
6309
  behind: 0,
5815
6310
  staged: 0,
@@ -6090,6 +6585,9 @@ function createGitCompactSummary(status, diffSummary) {
6090
6585
  isGitRepo: status.isGitRepo,
6091
6586
  repoRoot: status.repoRoot,
6092
6587
  branch: status.branch,
6588
+ upstreamStatus: status.upstreamStatus,
6589
+ upstreamFetchedAt: status.upstreamFetchedAt,
6590
+ upstreamFetchError: status.upstreamFetchError,
6093
6591
  dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
6094
6592
  changedFiles,
6095
6593
  ahead: status.ahead,
@@ -6434,7 +6932,7 @@ var defaultSnapshotStore = createGitSnapshotStore({
6434
6932
  });
6435
6933
  function createDefaultGitCommandServices() {
6436
6934
  return {
6437
- getStatus: ({ workspace }) => getGitRepoStatus(workspace),
6935
+ getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
6438
6936
  getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
6439
6937
  getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
6440
6938
  createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
@@ -6520,7 +7018,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
6520
7018
  switch (command) {
6521
7019
  case "git_status": {
6522
7020
  if (!services.getStatus) return serviceNotImplemented(command);
6523
- const status = await runService(() => services.getStatus({ workspace }));
7021
+ const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
6524
7022
  return "success" in status ? status : { success: true, status };
6525
7023
  }
6526
7024
  case "git_diff_summary": {
@@ -7326,6 +7824,238 @@ function getSavedProviderSessions(state, filters) {
7326
7824
  init_mesh_config();
7327
7825
  init_coordinator_prompt();
7328
7826
 
7827
+ // src/mesh/refine-config.ts
7828
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
7829
+ import { join as join5 } from "path";
7830
+ import * as yaml from "js-yaml";
7831
+ var MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
7832
+ var MESH_REFINE_CONFIG_LOCATIONS = [
7833
+ ".adhdev/refine.json",
7834
+ ".adhdev/refine.yaml",
7835
+ ".adhdev/refine.yml",
7836
+ ".adhdev/repo-mesh-refine.json",
7837
+ ".adhdev/repo-mesh-refine.yaml",
7838
+ ".adhdev/repo-mesh-refine.yml",
7839
+ "repo-mesh.refine.json",
7840
+ "repo-mesh.refine.yaml",
7841
+ "repo-mesh.refine.yml"
7842
+ ];
7843
+ var MESH_REFINE_CONFIG_SCHEMA = {
7844
+ $schema: "https://json-schema.org/draft/2020-12/schema",
7845
+ title: "ADHDev Repo Mesh Refinery Config",
7846
+ type: "object",
7847
+ additionalProperties: false,
7848
+ required: ["version"],
7849
+ properties: {
7850
+ version: { const: 1 },
7851
+ validation: {
7852
+ type: "object",
7853
+ additionalProperties: false,
7854
+ properties: {
7855
+ required: { type: "boolean", default: true },
7856
+ commands: {
7857
+ type: "array",
7858
+ minItems: 1,
7859
+ maxItems: 8,
7860
+ items: {
7861
+ type: "object",
7862
+ additionalProperties: false,
7863
+ required: ["command"],
7864
+ properties: {
7865
+ command: { type: "string", minLength: 1 },
7866
+ args: { type: "array", items: { type: "string" } },
7867
+ category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
7868
+ cwd: { type: "string" },
7869
+ timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
7870
+ env: { type: "object", additionalProperties: { type: "string" } }
7871
+ }
7872
+ }
7873
+ }
7874
+ }
7875
+ }
7876
+ }
7877
+ };
7878
+ function isRecord(value) {
7879
+ return !!value && typeof value === "object" && !Array.isArray(value);
7880
+ }
7881
+ function tokenizeCommandString(command) {
7882
+ const trimmed = command.trim();
7883
+ if (!trimmed) return null;
7884
+ if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
7885
+ const tokens = trimmed.split(/\s+/).filter(Boolean);
7886
+ if (!tokens.length) return null;
7887
+ if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
7888
+ return tokens;
7889
+ }
7890
+ function validateCategory(value) {
7891
+ return typeof value === "string" && [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"].includes(value) ? value : "custom";
7892
+ }
7893
+ function normalizeCommandConfig(entry, source) {
7894
+ if (!isRecord(entry) || typeof entry.command !== "string") {
7895
+ return { rejected: { source, reason: "validation command must be an object with a command string" } };
7896
+ }
7897
+ const commandText = entry.command.trim();
7898
+ const explicitArgs = Array.isArray(entry.args) ? entry.args : void 0;
7899
+ if (explicitArgs && !explicitArgs.every((arg) => typeof arg === "string")) {
7900
+ return { rejected: { source, command: commandText, reason: "args must be an array of strings" } };
7901
+ }
7902
+ let command = commandText;
7903
+ let args = explicitArgs ? [...explicitArgs] : [];
7904
+ if (!explicitArgs) {
7905
+ const tokens = tokenizeCommandString(commandText);
7906
+ if (!tokens) return { rejected: { source, command: commandText, reason: "unsafe command string is not allowlisted" } };
7907
+ command = tokens[0];
7908
+ args = tokens.slice(1);
7909
+ } else if (!tokenizeCommandString(command)) {
7910
+ return { rejected: { source, command: commandText, reason: "unsafe executable name is not allowlisted" } };
7911
+ }
7912
+ if (args.some((arg) => /[\n\r\0]/.test(arg))) {
7913
+ return { rejected: { source, command: commandText, reason: "args cannot contain control characters" } };
7914
+ }
7915
+ if (entry.cwd !== void 0 && typeof entry.cwd !== "string") {
7916
+ return { rejected: { source, command: commandText, reason: "cwd must be a string when provided" } };
7917
+ }
7918
+ if (entry.timeoutMs !== void 0 && (typeof entry.timeoutMs !== "number" || !Number.isFinite(entry.timeoutMs) || entry.timeoutMs < 1e3 || entry.timeoutMs > 6e5)) {
7919
+ return { rejected: { source, command: commandText, reason: "timeoutMs must be between 1000 and 600000" } };
7920
+ }
7921
+ if (entry.env !== void 0 && (!isRecord(entry.env) || !Object.values(entry.env).every((value) => typeof value === "string"))) {
7922
+ return { rejected: { source, command: commandText, reason: "env must be an object of string values" } };
7923
+ }
7924
+ return {
7925
+ command: {
7926
+ command,
7927
+ args,
7928
+ displayCommand: [command, ...args].join(" "),
7929
+ category: validateCategory(entry.category),
7930
+ source,
7931
+ ...typeof entry.cwd === "string" && entry.cwd.trim() ? { cwd: entry.cwd.trim() } : {},
7932
+ ...typeof entry.timeoutMs === "number" ? { timeoutMs: entry.timeoutMs } : {},
7933
+ ...isRecord(entry.env) ? { env: entry.env } : {}
7934
+ }
7935
+ };
7936
+ }
7937
+ function validateMeshRefineConfig(config, source = "inline") {
7938
+ const errors = [];
7939
+ const commands = [];
7940
+ const rejectedCommands = [];
7941
+ if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], commands, rejectedCommands };
7942
+ if (config.version !== 1) errors.push("version must be 1");
7943
+ const validation = config.validation;
7944
+ if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
7945
+ const rawCommands = isRecord(validation) ? validation.commands : void 0;
7946
+ if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
7947
+ if (Array.isArray(rawCommands)) {
7948
+ rawCommands.forEach((entry, index) => {
7949
+ const normalized = normalizeCommandConfig(entry, `${source}:validation.commands[${index}]`);
7950
+ if (normalized.command) commands.push(normalized.command);
7951
+ if (normalized.rejected) rejectedCommands.push(normalized.rejected);
7952
+ });
7953
+ }
7954
+ if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
7955
+ return { valid: errors.length === 0, errors, commands, rejectedCommands };
7956
+ }
7957
+ function parseConfigText(path28, text) {
7958
+ if (/\.json$/i.test(path28)) return JSON.parse(text);
7959
+ return yaml.load(text);
7960
+ }
7961
+ function loadMeshRefineConfig(mesh, workspace) {
7962
+ const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
7963
+ const inline = mesh?.refineConfig || policy.refineConfig || policy.refine;
7964
+ if (inline !== void 0) {
7965
+ const validation = validateMeshRefineConfig(inline, "mesh.policy.refineConfig");
7966
+ if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
7967
+ return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
7968
+ }
7969
+ for (const relative3 of MESH_REFINE_CONFIG_LOCATIONS) {
7970
+ const configPath = join5(workspace, relative3);
7971
+ if (!existsSync5(configPath)) continue;
7972
+ try {
7973
+ const parsed = parseConfigText(configPath, readFileSync3(configPath, "utf-8"));
7974
+ const validation = validateMeshRefineConfig(parsed, relative3);
7975
+ if (!validation.valid) return { source: relative3, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
7976
+ return { config: parsed, source: relative3, sourceType: "repo_file", path: configPath };
7977
+ } catch (error) {
7978
+ return { source: relative3, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
7979
+ }
7980
+ }
7981
+ return {
7982
+ source: "unavailable",
7983
+ sourceType: "unavailable",
7984
+ error: `No repo mesh/refine config found. Checked: ${MESH_REFINE_CONFIG_LOCATIONS.join(", ")}`
7985
+ };
7986
+ }
7987
+ function readPackageScripts(workspace) {
7988
+ try {
7989
+ const parsed = JSON.parse(readFileSync3(join5(workspace, "package.json"), "utf-8"));
7990
+ return isRecord(parsed?.scripts) ? parsed.scripts : {};
7991
+ } catch {
7992
+ return {};
7993
+ }
7994
+ }
7995
+ function collectProjectContextSuggestions(mesh) {
7996
+ const commands = mesh?.projectContext?.commands;
7997
+ if (!isRecord(commands)) return [];
7998
+ const suggestions = [];
7999
+ for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
8000
+ const entries = Array.isArray(commands[category]) ? commands[category] : [];
8001
+ for (const entry of entries) {
8002
+ if (isRecord(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
8003
+ }
8004
+ }
8005
+ return suggestions;
8006
+ }
8007
+ function collectPackageScriptSuggestions(workspace) {
8008
+ const scripts = readPackageScripts(workspace);
8009
+ const suggestions = [];
8010
+ for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
8011
+ for (const scriptName of Object.keys(scripts)) {
8012
+ if (scriptName === category || scriptName.startsWith(`${category}:`)) {
8013
+ suggestions.push({ command: "npm", args: ["run", scriptName], category });
8014
+ }
8015
+ }
8016
+ }
8017
+ return suggestions;
8018
+ }
8019
+ function suggestMeshRefineConfig(mesh, workspace) {
8020
+ const seen = /* @__PURE__ */ new Set();
8021
+ const suggestions = [];
8022
+ for (const entry of [...collectProjectContextSuggestions(mesh), ...collectPackageScriptSuggestions(workspace)]) {
8023
+ const key = `${entry.command} ${(entry.args || []).join(" ")}`.trim();
8024
+ if (seen.has(key)) continue;
8025
+ seen.add(key);
8026
+ suggestions.push(entry);
8027
+ }
8028
+ return {
8029
+ suggestions,
8030
+ suggestedConfig: suggestions.length ? { version: 1, validation: { required: true, commands: suggestions.slice(0, 4) } } : void 0
8031
+ };
8032
+ }
8033
+ function resolveMeshRefineValidationPlan(mesh, workspace) {
8034
+ const loaded = loadMeshRefineConfig(mesh, workspace);
8035
+ const suggestion = suggestMeshRefineConfig(mesh, workspace);
8036
+ if (!loaded.config) {
8037
+ return {
8038
+ source: loaded.source,
8039
+ sourceType: loaded.sourceType,
8040
+ commands: [],
8041
+ rejectedCommands: loaded.error ? [{ source: loaded.source, reason: loaded.error }] : [],
8042
+ suggestions: suggestion.suggestions,
8043
+ suggestedConfig: suggestion.suggestedConfig,
8044
+ unavailableReason: loaded.error || "validation_unavailable: repo mesh/refine config missing"
8045
+ };
8046
+ }
8047
+ const validation = validateMeshRefineConfig(loaded.config, loaded.source);
8048
+ return {
8049
+ source: loaded.path || loaded.source,
8050
+ sourceType: loaded.sourceType,
8051
+ commands: validation.commands,
8052
+ rejectedCommands: validation.rejectedCommands,
8053
+ suggestions: suggestion.suggestions,
8054
+ suggestedConfig: suggestion.suggestedConfig,
8055
+ unavailableReason: validation.commands.length ? void 0 : "validation_unavailable: repo mesh/refine config has no validation.commands"
8056
+ };
8057
+ }
8058
+
7329
8059
  // src/mesh/mesh-sync.ts
7330
8060
  init_mesh_config();
7331
8061
  async function syncMeshes(transport) {
@@ -7445,6 +8175,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
7445
8175
 
7446
8176
  // src/index.ts
7447
8177
  init_mesh_work_queue();
8178
+ init_mesh_host_ownership();
7448
8179
  init_mesh_events();
7449
8180
 
7450
8181
  // src/mesh/p2p-relay-failure.ts
@@ -7559,8 +8290,8 @@ var P2pRelayFailureError = class extends Error {
7559
8290
 
7560
8291
  // src/config/state-store.ts
7561
8292
  init_config();
7562
- import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
7563
- import { join as join9 } from "path";
8293
+ import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
8294
+ import { join as join11 } from "path";
7564
8295
  var DEFAULT_STATE = {
7565
8296
  recentActivity: [],
7566
8297
  savedProviderSessions: [],
@@ -7573,7 +8304,7 @@ function isPlainObject2(value) {
7573
8304
  return !!value && typeof value === "object" && !Array.isArray(value);
7574
8305
  }
7575
8306
  function getStatePath() {
7576
- return join9(getConfigDir(), "state.json");
8307
+ return join11(getConfigDir(), "state.json");
7577
8308
  }
7578
8309
  function normalizeState(raw) {
7579
8310
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -7609,11 +8340,11 @@ function normalizeState(raw) {
7609
8340
  }
7610
8341
  function loadState() {
7611
8342
  const statePath = getStatePath();
7612
- if (!existsSync9(statePath)) {
8343
+ if (!existsSync11(statePath)) {
7613
8344
  return { ...DEFAULT_STATE };
7614
8345
  }
7615
8346
  try {
7616
- const raw = readFileSync5(statePath, "utf-8");
8347
+ const raw = readFileSync7(statePath, "utf-8");
7617
8348
  return normalizeState(JSON.parse(raw));
7618
8349
  } catch {
7619
8350
  return { ...DEFAULT_STATE };
@@ -7630,7 +8361,7 @@ function resetState() {
7630
8361
 
7631
8362
  // src/detection/ide-detector.ts
7632
8363
  import { execSync } from "child_process";
7633
- import { existsSync as existsSync10 } from "fs";
8364
+ import { existsSync as existsSync12 } from "fs";
7634
8365
  import { platform as platform2, homedir as homedir5 } from "os";
7635
8366
  import * as path10 from "path";
7636
8367
  var BUILTIN_IDE_DEFINITIONS = [];
@@ -7654,7 +8385,7 @@ function findCliCommand(command) {
7654
8385
  if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
7655
8386
  const candidate = trimmed.startsWith("~") ? path10.join(homedir5(), trimmed.slice(1)) : trimmed;
7656
8387
  const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
7657
- return existsSync10(resolved) ? resolved : null;
8388
+ return existsSync12(resolved) ? resolved : null;
7658
8389
  }
7659
8390
  try {
7660
8391
  const result = execSync(
@@ -7685,9 +8416,9 @@ function checkPathExists(paths) {
7685
8416
  if (normalized.includes("*")) {
7686
8417
  const username = home.split(/[\\/]/).pop() || "";
7687
8418
  const resolved = normalized.replace("*", username);
7688
- if (existsSync10(resolved)) return resolved;
8419
+ if (existsSync12(resolved)) return resolved;
7689
8420
  } else {
7690
- if (existsSync10(normalized)) return normalized;
8421
+ if (existsSync12(normalized)) return normalized;
7691
8422
  }
7692
8423
  }
7693
8424
  return null;
@@ -7701,7 +8432,7 @@ async function detectIDEs(providerLoader) {
7701
8432
  let resolvedCli = cliPath;
7702
8433
  if (!resolvedCli && appPath && os22 === "darwin") {
7703
8434
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
7704
- if (existsSync10(bundledCli)) resolvedCli = bundledCli;
8435
+ if (existsSync12(bundledCli)) resolvedCli = bundledCli;
7705
8436
  }
7706
8437
  if (!resolvedCli && appPath && os22 === "win32") {
7707
8438
  const { dirname: dirname9 } = await import("path");
@@ -7714,7 +8445,7 @@ async function detectIDEs(providerLoader) {
7714
8445
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
7715
8446
  ];
7716
8447
  for (const c of candidates) {
7717
- if (existsSync10(c)) {
8448
+ if (existsSync12(c)) {
7718
8449
  resolvedCli = c;
7719
8450
  break;
7720
8451
  }
@@ -9606,7 +10337,8 @@ var StatusMonitor = class {
9606
10337
  };
9607
10338
 
9608
10339
  // src/providers/chat-message-normalization.ts
9609
- function extractFinalSummaryFromMessages(messages, maxChars = 500) {
10340
+ var DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
10341
+ function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
9610
10342
  if (!Array.isArray(messages) || messages.length === 0) return "";
9611
10343
  for (let i = messages.length - 1; i >= 0; i--) {
9612
10344
  const msg = messages[i];
@@ -16869,7 +17601,7 @@ init_config();
16869
17601
  import * as os13 from "os";
16870
17602
  import * as path18 from "path";
16871
17603
  import * as crypto4 from "crypto";
16872
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
17604
+ import { existsSync as existsSync16, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
16873
17605
  import { execFileSync } from "child_process";
16874
17606
  import chalk from "chalk";
16875
17607
 
@@ -19343,7 +20075,7 @@ function commandExists(command) {
19343
20075
  const trimmed = command.trim();
19344
20076
  if (!trimmed) return false;
19345
20077
  if (isExplicitCommand(trimmed)) {
19346
- return existsSync14(expandExecutable(trimmed));
20078
+ return existsSync16(expandExecutable(trimmed));
19347
20079
  }
19348
20080
  try {
19349
20081
  execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -22607,15 +23339,15 @@ cleanOldFiles();
22607
23339
 
22608
23340
  // src/commands/router.ts
22609
23341
  init_logger();
22610
- import * as yaml from "js-yaml";
23342
+ import * as yaml2 from "js-yaml";
22611
23343
 
22612
23344
  // src/commands/mesh-coordinator.ts
22613
23345
  import { execFileSync as execFileSync2 } from "child_process";
22614
- import { createHash as createHash2 } from "crypto";
22615
- import { existsSync as existsSync17, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
23346
+ import { createHash as createHash3 } from "crypto";
23347
+ import { existsSync as existsSync19, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
22616
23348
  import { createRequire as createRequire2 } from "module";
22617
23349
  import * as os17 from "os";
22618
- import { dirname as dirname4, isAbsolute as isAbsolute11, join as join20, resolve as resolve13 } from "path";
23350
+ import { dirname as dirname4, isAbsolute as isAbsolute11, join as join22, resolve as resolve13 } from "path";
22619
23351
  var DEFAULT_SERVER_NAME = "adhdev-mesh";
22620
23352
  var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
22621
23353
  var HERMES_CLI_TYPE = "hermes-cli";
@@ -22638,7 +23370,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
22638
23370
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
22639
23371
  };
22640
23372
  }
22641
- const configPath = join20(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
23373
+ const configPath = join22(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
22642
23374
  if (!configPath.trim()) {
22643
23375
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
22644
23376
  }
@@ -22758,15 +23490,15 @@ function renderMeshCoordinatorTemplate(template, values) {
22758
23490
  function resolveHermesCoordinatorHome(meshId, workspace) {
22759
23491
  const key = `${meshId || "mesh"}
22760
23492
  ${resolve13(workspace || os17.tmpdir())}`;
22761
- const hash = createHash2("sha256").update(key).digest("hex").slice(0, 16);
22762
- return join20(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
23493
+ const hash = createHash3("sha256").update(key).digest("hex").slice(0, 16);
23494
+ return join22(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
22763
23495
  }
22764
23496
  function resolveMcpConfigPath(configPath, workspace) {
22765
23497
  const trimmed = configPath.trim();
22766
23498
  if (trimmed === "~") return os17.homedir();
22767
- if (trimmed.startsWith("~/")) return join20(os17.homedir(), trimmed.slice(2));
23499
+ if (trimmed.startsWith("~/")) return join22(os17.homedir(), trimmed.slice(2));
22768
23500
  if (isAbsolute11(trimmed)) return trimmed;
22769
- return join20(workspace, trimmed);
23501
+ return join22(workspace, trimmed);
22770
23502
  }
22771
23503
  function resolveAdhdevMcpServerLaunch(options) {
22772
23504
  const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
@@ -22822,15 +23554,15 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
22822
23554
  for (const entry of (pathValue || "").split(":")) {
22823
23555
  const dir = entry.trim();
22824
23556
  if (!dir) continue;
22825
- addCandidate(join20(dir, "node"));
23557
+ addCandidate(join22(dir, "node"));
22826
23558
  }
22827
23559
  }
22828
23560
  function addNodeCandidatesFromNvm(homeDir, addCandidate) {
22829
- const versionsDir = join20(homeDir, ".nvm", "versions", "node");
23561
+ const versionsDir = join22(homeDir, ".nvm", "versions", "node");
22830
23562
  try {
22831
23563
  const versionDirs = readdirSync7(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
22832
23564
  for (const versionDir of versionDirs) {
22833
- addCandidate(join20(versionsDir, versionDir, "bin", "node"));
23565
+ addCandidate(join22(versionsDir, versionDir, "bin", "node"));
22834
23566
  }
22835
23567
  } catch {
22836
23568
  }
@@ -22881,7 +23613,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
22881
23613
  if (normalized) return normalized;
22882
23614
  }
22883
23615
  try {
22884
- const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join20(process.cwd(), "adhdev-daemon.js");
23616
+ const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join22(process.cwd(), "adhdev-daemon.js");
22885
23617
  const req = createRequire2(requireBase);
22886
23618
  const resolvedModule = req.resolve("@adhdev/mcp-server");
22887
23619
  return normalizeExistingPath(resolvedModule) || resolvedModule;
@@ -22891,7 +23623,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
22891
23623
  }
22892
23624
  function normalizeExistingPath(filePath) {
22893
23625
  try {
22894
- if (!existsSync17(filePath)) return null;
23626
+ if (!existsSync19(filePath)) return null;
22895
23627
  return realpathSync2.native(filePath);
22896
23628
  } catch {
22897
23629
  return null;
@@ -22900,6 +23632,7 @@ function normalizeExistingPath(filePath) {
22900
23632
 
22901
23633
  // src/commands/router.ts
22902
23634
  init_mesh_events();
23635
+ init_mesh_host_ownership();
22903
23636
 
22904
23637
  // src/status/snapshot.ts
22905
23638
  init_config();
@@ -23603,13 +24336,85 @@ function readBooleanValue(...values) {
23603
24336
  }
23604
24337
  return void 0;
23605
24338
  }
23606
- function readGitSubmodules(value) {
24339
+ function summarizeRepoMeshDebugGit(git) {
24340
+ const record = readObjectRecord(git);
24341
+ if (!Object.keys(record).length) return null;
24342
+ const submodules = Array.isArray(record.submodules) ? record.submodules.map((entry) => ({
24343
+ path: readStringValue(entry?.path) ?? null,
24344
+ commit: readStringValue(entry?.commit)?.slice(0, 12) ?? null,
24345
+ dirty: readBooleanValue(entry?.dirty) ?? false,
24346
+ outOfSync: readBooleanValue(entry?.outOfSync, entry?.out_of_sync) ?? false
24347
+ })) : [];
24348
+ return {
24349
+ isGitRepo: readBooleanValue(record.isGitRepo),
24350
+ workspace: readStringValue(record.workspace) ?? null,
24351
+ repoRoot: readStringValue(record.repoRoot, record.repo_root) ?? null,
24352
+ branch: readStringValue(record.branch) ?? null,
24353
+ upstream: readStringValue(record.upstream) ?? null,
24354
+ upstreamStatus: readStringValue(record.upstreamStatus, record.upstream_status) ?? null,
24355
+ headCommit: readStringValue(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,
24356
+ ahead: readNumberValue(record.ahead) ?? null,
24357
+ behind: readNumberValue(record.behind) ?? null,
24358
+ dirtyCounts: {
24359
+ staged: readNumberValue(record.staged) ?? 0,
24360
+ modified: readNumberValue(record.modified) ?? 0,
24361
+ untracked: readNumberValue(record.untracked) ?? 0,
24362
+ deleted: readNumberValue(record.deleted) ?? 0,
24363
+ renamed: readNumberValue(record.renamed) ?? 0
24364
+ },
24365
+ lastCheckedAt: readNumberValue(record.lastCheckedAt, record.last_checked_at) ?? null,
24366
+ submoduleCount: submodules.length,
24367
+ submodules
24368
+ };
24369
+ }
24370
+ function summarizeRepoMeshStatusDebug(status) {
24371
+ const nodes = Array.isArray(status?.nodes) ? status.nodes : [];
24372
+ return {
24373
+ success: status?.success,
24374
+ meshId: readStringValue(status?.meshId, status?.mesh_id) ?? null,
24375
+ refreshedAt: readStringValue(status?.refreshedAt, status?.refreshed_at) ?? null,
24376
+ sourceOfTruth: status?.sourceOfTruth ?? null,
24377
+ nodeCount: nodes.length,
24378
+ nodes: nodes.map((node) => ({
24379
+ nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
24380
+ daemonId: readStringValue(node?.daemonId, node?.daemon_id) ?? null,
24381
+ workspace: readStringValue(node?.workspace, node?.git?.workspace) ?? null,
24382
+ health: readStringValue(node?.health) ?? null,
24383
+ machineStatus: readStringValue(node?.machineStatus, node?.machine_status) ?? null,
24384
+ connection: node?.connection && typeof node.connection === "object" ? {
24385
+ state: readStringValue(node.connection.state) ?? null,
24386
+ transport: readStringValue(node.connection.transport) ?? null,
24387
+ source: readStringValue(node.connection.source) ?? null,
24388
+ reported: readBooleanValue(node.connection.reported) ?? null
24389
+ } : null,
24390
+ gitProbePending: node?.gitProbePending === true,
24391
+ launchReady: node?.launchReady === true,
24392
+ git: summarizeRepoMeshDebugGit(node?.git)
24393
+ }))
24394
+ };
24395
+ }
24396
+ function logRepoMeshStatusDebug(event, fields) {
24397
+ try {
24398
+ LOG.info("MeshStatusDebug", `[RepoMeshStatusDebug] ${JSON.stringify({ event, ...fields })}`);
24399
+ } catch {
24400
+ LOG.info("MeshStatusDebug", `[RepoMeshStatusDebug] ${event}`);
24401
+ }
24402
+ }
24403
+ function joinRepoPath(root, relativePath) {
24404
+ const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
24405
+ const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
24406
+ if (!normalizedPath) return void 0;
24407
+ if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
24408
+ if (!normalizedRoot) return void 0;
24409
+ return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
24410
+ }
24411
+ function readGitSubmodules(value, parentRepoRoot) {
23607
24412
  if (!Array.isArray(value)) return void 0;
23608
24413
  const submodules = value.map((entry) => {
23609
24414
  const submodule = readObjectRecord(entry);
23610
24415
  const path28 = readStringValue(submodule.path);
23611
24416
  const commit = readStringValue(submodule.commit);
23612
- const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
24417
+ const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path28);
23613
24418
  if (!path28 || !commit || !repoPath) return null;
23614
24419
  return {
23615
24420
  path: path28,
@@ -23623,58 +24428,17 @@ function readGitSubmodules(value) {
23623
24428
  }).filter((entry) => entry !== null);
23624
24429
  return submodules.length > 0 ? submodules : void 0;
23625
24430
  }
23626
- function buildCachedInlineMeshGitStatus(node) {
23627
- const cachedStatus = readObjectRecord(node?.cachedStatus);
23628
- const cachedGit = readObjectRecord(cachedStatus.git);
23629
- if (Object.keys(cachedGit).length) {
23630
- const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
23631
- const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
23632
- const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
23633
- const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
23634
- if (isGitRepo2 !== void 0) {
23635
- const submodules2 = readGitSubmodules(cachedGit.submodules);
23636
- return {
23637
- workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
23638
- repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
23639
- isGitRepo: isGitRepo2,
23640
- branch: readStringValue(cachedGit.branch) ?? null,
23641
- headCommit: readStringValue(cachedGit.headCommit) ?? null,
23642
- headMessage: readStringValue(cachedGit.headMessage) ?? null,
23643
- upstream: readStringValue(cachedGit.upstream) ?? null,
23644
- ahead: readNumberValue(cachedGit.ahead) ?? 0,
23645
- behind: readNumberValue(cachedGit.behind) ?? 0,
23646
- staged: readNumberValue(cachedGit.staged) ?? 0,
23647
- modified: readNumberValue(cachedGit.modified) ?? 0,
23648
- untracked: readNumberValue(cachedGit.untracked) ?? 0,
23649
- deleted: readNumberValue(cachedGit.deleted) ?? 0,
23650
- renamed: readNumberValue(cachedGit.renamed) ?? 0,
23651
- hasConflicts: hasConflicts2,
23652
- conflictFiles: conflictFiles2,
23653
- stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
23654
- lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
23655
- ...submodules2 ? { submodules: submodules2 } : {}
23656
- };
23657
- }
23658
- }
23659
- const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
23660
- const gitResult = readObjectRecord(rawGit.result);
23661
- const directStatus = readObjectRecord(rawGit.status);
23662
- const nestedStatus = readObjectRecord(gitResult.status);
23663
- const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
23664
- const probeGit = readObjectRecord(rawProbe.git);
23665
- const probeGitResult = readObjectRecord(probeGit.result);
23666
- const probeDirectStatus = readObjectRecord(probeGit.status);
23667
- const probeNestedStatus = readObjectRecord(probeGitResult.status);
23668
- const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
24431
+ function normalizeInlineMeshGitStatus(status, node, options) {
23669
24432
  const isGitRepo = readBooleanValue(status.isGitRepo);
23670
24433
  if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
23671
24434
  const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
23672
24435
  const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
23673
24436
  const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
23674
- const submodules = readGitSubmodules(status.submodules);
24437
+ const repoRoot = readStringValue(status.repoRoot, status.repo_root, node?.repoRoot, node?.repo_root, status.workspace, node?.workspace) || void 0;
24438
+ const submodules = readGitSubmodules(status.submodules, repoRoot);
23675
24439
  return {
23676
24440
  workspace: readStringValue(status.workspace, node?.workspace) || "",
23677
- repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
24441
+ repoRoot: repoRoot ?? null,
23678
24442
  isGitRepo,
23679
24443
  branch: readStringValue(status.branch) ?? null,
23680
24444
  headCommit: readStringValue(status.headCommit) ?? null,
@@ -23690,30 +24454,456 @@ function buildCachedInlineMeshGitStatus(node) {
23690
24454
  hasConflicts,
23691
24455
  conflictFiles,
23692
24456
  stashCount: readNumberValue(status.stashCount) ?? 0,
23693
- lastCheckedAt: Date.now(),
24457
+ lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
23694
24458
  ...submodules ? { submodules } : {}
23695
24459
  };
23696
24460
  }
23697
- function applyCachedInlineMeshNodeStatus(status, node) {
24461
+ function scoreInlineMeshGitStatus(git) {
24462
+ if (!git) return Number.NEGATIVE_INFINITY;
24463
+ let score = 0;
24464
+ if (readBooleanValue(git.isGitRepo) === true) score += 50;
24465
+ if (readBooleanValue(git.isGitRepo) === false) score -= 10;
24466
+ if (readStringValue(git.branch)) score += 20;
24467
+ if (readStringValue(git.headCommit)) score += 20;
24468
+ if (readStringValue(git.upstream)) score += 10;
24469
+ if (readStringValue(git.upstreamStatus)) score += 5;
24470
+ if (readNumberValue(git.ahead) !== void 0) score += 2;
24471
+ if (readNumberValue(git.behind) !== void 0) score += 2;
24472
+ if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
24473
+ if (readStringValue(git.error)) score -= 20;
24474
+ return score;
24475
+ }
24476
+ function buildInlineMeshTransitGitStatus(node) {
24477
+ const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
24478
+ const gitResult = readObjectRecord(rawGit.result);
24479
+ const directStatus = readObjectRecord(rawGit.status);
24480
+ const nestedStatus = readObjectRecord(gitResult.status);
24481
+ const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
24482
+ const probeGit = readObjectRecord(rawProbe.git);
24483
+ const probeGitResult = readObjectRecord(probeGit.result);
24484
+ const probeDirectStatus = readObjectRecord(probeGit.status);
24485
+ const probeNestedStatus = readObjectRecord(probeGitResult.status);
24486
+ const candidates = [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus];
24487
+ let best = null;
24488
+ for (const status of candidates) {
24489
+ const normalized = normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
24490
+ if (!normalized) continue;
24491
+ const score = scoreInlineMeshGitStatus(normalized);
24492
+ if (!best || score > best.score) best = { git: normalized, score };
24493
+ }
24494
+ return best?.git;
24495
+ }
24496
+ function shouldRefreshStalePendingAggregate(snapshot, options) {
24497
+ if (options?.requireDirectPeerTruth !== true || !Array.isArray(snapshot?.nodes)) return false;
24498
+ return snapshot.nodes.some((node) => {
24499
+ if (node?.gitProbePending !== true) return false;
24500
+ const git = readObjectRecord(node?.git);
24501
+ return !readBooleanValue(git.isGitRepo) && !readStringValue(git.branch, git.headCommit, git.upstream);
24502
+ });
24503
+ }
24504
+ function buildLivePeerGitConnection(connection, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
24505
+ const source = readStringValue(connection.source);
24506
+ const transport = readStringValue(connection.transport);
24507
+ return {
24508
+ ...connection,
24509
+ perspective: readStringValue(connection.perspective) ?? "selected_coordinator",
24510
+ source: source && source !== "not_reported" ? source : "mesh_peer_status",
24511
+ state: "connected",
24512
+ transport: transport && transport !== "unknown" ? transport : "direct",
24513
+ reported: true,
24514
+ reason: "Live peer git snapshot reported by the selected coordinator.",
24515
+ lastStateChangeAt: readStringValue(connection.lastStateChangeAt) ?? timestamp
24516
+ };
24517
+ }
24518
+ function recordInlineMeshDirectGitTruth(node, git, source) {
24519
+ if (!node || typeof node !== "object" || Array.isArray(node)) return;
24520
+ const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
24521
+ const updatedAt = new Date(checkedAt).toISOString();
24522
+ const nextGit = {
24523
+ ...git,
24524
+ lastCheckedAt: checkedAt
24525
+ };
24526
+ node.lastGit = {
24527
+ source,
24528
+ checkedAt,
24529
+ status: nextGit
24530
+ };
24531
+ node.last_git = node.lastGit;
24532
+ node.machineStatus = "online";
24533
+ node.updatedAt = updatedAt;
24534
+ node.lastSeenAt = updatedAt;
24535
+ const repoRoot = readStringValue(nextGit.repoRoot);
24536
+ if (repoRoot && !readStringValue(node.repoRoot)) node.repoRoot = repoRoot;
24537
+ }
24538
+ function buildCachedInlineMeshGitStatus(node) {
24539
+ const liveGit = buildInlineMeshTransitGitStatus(node);
24540
+ if (liveGit) return liveGit;
24541
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
24542
+ const cachedGit = readObjectRecord(cachedStatus.git);
24543
+ if (!Object.keys(cachedGit).length) return void 0;
24544
+ return normalizeInlineMeshGitStatus(cachedGit, node);
24545
+ }
24546
+ function shouldDiscardCachedInlineMeshStatus(node) {
24547
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
24548
+ if (!Object.keys(cachedStatus).length) return false;
24549
+ const cachedGit = readObjectRecord(cachedStatus.git);
24550
+ const workspaceError = readStringValue(cachedStatus.error, node?.error);
24551
+ if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
24552
+ const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
24553
+ const branch = readStringValue(cachedGit.branch);
24554
+ const headCommit = readStringValue(cachedGit.headCommit);
24555
+ return isGitRepo === false && !branch && !headCommit;
24556
+ }
24557
+ function stripInlineMeshTransientNodeState(node) {
24558
+ if (!node || typeof node !== "object" || Array.isArray(node)) return node;
24559
+ const {
24560
+ cachedStatus,
24561
+ lastGit: _lastGit,
24562
+ last_git: _lastGitLegacy,
24563
+ lastProbe: _lastProbe,
24564
+ last_probe: _lastProbeLegacy,
24565
+ error: _error,
24566
+ health: _health,
24567
+ machineStatus: _machineStatus,
24568
+ lastSeenAt: _lastSeenAt,
24569
+ last_seen_at: _lastSeenAtLegacy,
24570
+ updatedAt: _updatedAt,
24571
+ updated_at: _updatedAtLegacy,
24572
+ activeSession: _activeSession,
24573
+ active_session: _activeSessionLegacy,
24574
+ activeSessionId: _activeSessionId,
24575
+ active_session_id: _activeSessionIdLegacy,
24576
+ sessionId: _sessionId,
24577
+ session_id: _sessionIdLegacy,
24578
+ providerType: _providerType,
24579
+ provider_type: _providerTypeLegacy,
24580
+ ...rest
24581
+ } = node;
24582
+ if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
24583
+ return { ...rest, cachedStatus };
24584
+ }
24585
+ return rest;
24586
+ }
24587
+ function hasInlineMeshTransientNodeState(node) {
24588
+ if (!node || typeof node !== "object" || Array.isArray(node)) return false;
24589
+ 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;
24590
+ }
24591
+ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
24592
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return false;
24593
+ if (!Array.isArray(inlineMesh.nodes) || inlineMesh.nodes.length === 0) return false;
24594
+ return inlineMesh.nodes.some((node) => hasInlineMeshTransientNodeState(node));
24595
+ }
24596
+ function readInlineMeshNodeId(node) {
24597
+ return readStringValue(node?.id, node?.nodeId) || "";
24598
+ }
24599
+ function sanitizeInlineMesh(inlineMesh) {
24600
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
24601
+ if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
24602
+ let changed = false;
24603
+ const nodes = inlineMesh.nodes.map((node) => {
24604
+ if (!hasInlineMeshTransientNodeState(node)) return node;
24605
+ changed = true;
24606
+ return stripInlineMeshTransientNodeState(node);
24607
+ });
24608
+ if (!changed) return inlineMesh;
24609
+ return {
24610
+ ...inlineMesh,
24611
+ nodes
24612
+ };
24613
+ }
24614
+ function reconcileInlineMeshCache(cached, incoming) {
24615
+ if (!cached || typeof cached !== "object" || Array.isArray(cached)) return incoming;
24616
+ if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached;
24617
+ const cachedNodes = Array.isArray(cached.nodes) ? cached.nodes : [];
24618
+ const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
24619
+ if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
24620
+ const incomingById = /* @__PURE__ */ new Map();
24621
+ for (const node of incomingNodes) {
24622
+ const nodeId = readInlineMeshNodeId(node);
24623
+ if (nodeId) incomingById.set(nodeId, node);
24624
+ }
24625
+ const nodes = cachedNodes.map((cachedNode) => {
24626
+ const nodeId = readInlineMeshNodeId(cachedNode);
24627
+ const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
24628
+ if (!incomingNode) return cachedNode;
24629
+ if (hasInlineMeshTransientNodeState(incomingNode)) {
24630
+ return { ...cachedNode, ...incomingNode };
24631
+ }
24632
+ return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
24633
+ });
24634
+ return {
24635
+ ...cached,
24636
+ ...incoming,
24637
+ nodes
24638
+ };
24639
+ }
24640
+ function hasGitWorktreeChanges(git) {
24641
+ if (!git) return false;
24642
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
24643
+ }
24644
+ function getGitSubmoduleDriftState(git) {
24645
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
24646
+ let dirty = false;
24647
+ let outOfSync = false;
24648
+ for (const entry of submodules) {
24649
+ const submodule = readObjectRecord(entry);
24650
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
24651
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
24652
+ }
24653
+ return { dirty, outOfSync };
24654
+ }
24655
+ function deriveMeshNodeHealthFromGit(git) {
24656
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
24657
+ const branch = readStringValue(git.branch);
24658
+ if (!branch) return "degraded";
24659
+ const submoduleDrift = getGitSubmoduleDriftState(git);
24660
+ if (submoduleDrift.outOfSync) return "degraded";
24661
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
24662
+ return "online";
24663
+ }
24664
+ function readCachedInlineMeshActiveSessions(node) {
24665
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
24666
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
24667
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
24668
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
24669
+ return sessionId ? [sessionId] : [];
24670
+ }
24671
+ function readCachedInlineMeshActiveSessionDetails(node) {
24672
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
24673
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
24674
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
24675
+ const sessionId = readStringValue(
24676
+ fallbackSession.id,
24677
+ fallbackSession.sessionId,
24678
+ fallbackSession.session_id,
24679
+ node?.activeSessionId,
24680
+ node?.active_session_id,
24681
+ node?.sessionId,
24682
+ node?.session_id
24683
+ );
24684
+ if (!sessionId) return [];
24685
+ return [{
24686
+ sessionId,
24687
+ providerType: readStringValue(
24688
+ fallbackSession.providerType,
24689
+ fallbackSession.provider_type,
24690
+ fallbackSession.cliType,
24691
+ fallbackSession.cli_type,
24692
+ fallbackSession.provider,
24693
+ node?.providerType,
24694
+ node?.provider_type
24695
+ ),
24696
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
24697
+ lifecycle: readStringValue(fallbackSession.lifecycle),
24698
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
24699
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
24700
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
24701
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
24702
+ isCached: true
24703
+ }];
24704
+ }
24705
+ function readLiveMeshSessionState(record) {
24706
+ return readStringValue(
24707
+ record?.meta?.sessionStatus,
24708
+ record?.meta?.status,
24709
+ record?.meta?.providerStatus,
24710
+ record?.status,
24711
+ record?.state,
24712
+ record?.lifecycle
24713
+ );
24714
+ }
24715
+ function toIsoTimestamp(value) {
24716
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
24717
+ const stringValue = readStringValue(value);
24718
+ return stringValue || null;
24719
+ }
24720
+ function synthesizeMeshNodeFreshnessFromConnection(status) {
24721
+ const connection = readObjectRecord(status.connection);
24722
+ const connectionFreshAt = toIsoTimestamp(connection.lastCommandAt ?? connection.lastConnectedAt ?? connection.lastStateChangeAt);
24723
+ const git = readObjectRecord(status.git);
24724
+ const gitCheckedAt = toIsoTimestamp(git.lastCheckedAt);
24725
+ if (!status.lastSeenAt && connectionFreshAt) status.lastSeenAt = connectionFreshAt;
24726
+ if (!status.updatedAt && (gitCheckedAt || connectionFreshAt)) {
24727
+ status.updatedAt = gitCheckedAt ?? connectionFreshAt;
24728
+ }
24729
+ }
24730
+ function finalizeMeshNodeStatus(args) {
24731
+ const { status, node, daemonId, isSelfNode } = args;
24732
+ if (!readStringValue(status.machineStatus)) {
24733
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
24734
+ const machineStatus = readStringValue(cachedStatus.machineStatus, cachedStatus.machine_status, node?.machineStatus);
24735
+ if (machineStatus) status.machineStatus = machineStatus;
24736
+ }
24737
+ synthesizeMeshNodeFreshnessFromConnection(status);
24738
+ const connectionState = readStringValue(readObjectRecord(status.connection).state);
24739
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
24740
+ }
24741
+ async function probeRemoteMeshGitStatus(args) {
24742
+ if (!args.dispatchMeshCommand) return null;
24743
+ const remoteResult = await Promise.race([
24744
+ args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
24745
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
24746
+ ]);
24747
+ const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
24748
+ return remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean" ? remoteGit : null;
24749
+ }
24750
+ async function hydrateInlineMeshDirectTruth(args) {
24751
+ const nodes = Array.isArray(args.mesh?.nodes) ? args.mesh.nodes : [];
24752
+ if (!nodes.length) {
24753
+ return {
24754
+ directEvidenceCount: 0,
24755
+ localConfirmedCount: 0,
24756
+ peerAttemptedCount: 0,
24757
+ peerConfirmedCount: 0,
24758
+ unavailableNodeIds: []
24759
+ };
24760
+ }
24761
+ const selectedCoordinatorNodeId = readStringValue(
24762
+ args.mesh?.coordinator?.preferredNodeId,
24763
+ nodes[0]?.id,
24764
+ nodes[0]?.nodeId
24765
+ );
24766
+ let localConfirmedCount = 0;
24767
+ let peerAttemptedCount = 0;
24768
+ let peerConfirmedCount = 0;
24769
+ const unavailableNodeIds = [];
24770
+ for (const [nodeIndex, node] of nodes.entries()) {
24771
+ const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
24772
+ const workspace = readStringValue(node?.workspace);
24773
+ const daemonId = readStringValue(node?.daemonId);
24774
+ const isSelfNode = Boolean(
24775
+ nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
24776
+ ) || Boolean(
24777
+ daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
24778
+ ) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
24779
+ if (!workspace) {
24780
+ if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
24781
+ continue;
24782
+ }
24783
+ if (isSelfNode && fs10.existsSync(workspace)) {
24784
+ try {
24785
+ const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
24786
+ if (localGit?.isGitRepo) {
24787
+ recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
24788
+ localConfirmedCount += 1;
24789
+ continue;
24790
+ }
24791
+ } catch {
24792
+ }
24793
+ }
24794
+ if (!daemonId || !args.dispatchMeshCommand) {
24795
+ if (!isSelfNode) unavailableNodeIds.push(nodeId);
24796
+ continue;
24797
+ }
24798
+ peerAttemptedCount += 1;
24799
+ try {
24800
+ const remoteGit = await probeRemoteMeshGitStatus({
24801
+ dispatchMeshCommand: args.dispatchMeshCommand,
24802
+ daemonId,
24803
+ workspace,
24804
+ timeoutMs: 8e3
24805
+ });
24806
+ if (remoteGit) {
24807
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
24808
+ peerConfirmedCount += 1;
24809
+ continue;
24810
+ }
24811
+ } catch {
24812
+ }
24813
+ unavailableNodeIds.push(nodeId);
24814
+ }
24815
+ return {
24816
+ directEvidenceCount: localConfirmedCount + peerConfirmedCount,
24817
+ localConfirmedCount,
24818
+ peerAttemptedCount,
24819
+ peerConfirmedCount,
24820
+ unavailableNodeIds
24821
+ };
24822
+ }
24823
+ function summarizeMeshSessionRecord(record) {
24824
+ return {
24825
+ sessionId: readStringValue(record?.sessionId) || "unknown",
24826
+ providerType: readStringValue(record?.providerType),
24827
+ state: readLiveMeshSessionState(record),
24828
+ lifecycle: readStringValue(record?.lifecycle),
24829
+ surfaceKind: getSessionHostSurfaceKind(record),
24830
+ recoveryState: readStringValue(record?.meta?.runtimeRecoveryState) ?? null,
24831
+ workspace: readStringValue(record?.workspace) ?? null,
24832
+ title: readStringValue(record?.displayName, record?.workspaceLabel) ?? null,
24833
+ lastActivityAt: toIsoTimestamp(record?.updatedAt ?? record?.lastActivityAt ?? record?.last_activity_at),
24834
+ isCached: false
24835
+ };
24836
+ }
24837
+ function liveSessionRecordMatchesMeshNode(record, meshId, nodeId) {
24838
+ const recordNodeId = readStringValue(record?.meta?.meshNodeId);
24839
+ if (!recordNodeId || recordNodeId !== nodeId) return false;
24840
+ const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
24841
+ return !recordMeshId || recordMeshId === meshId;
24842
+ }
24843
+ function liveSessionRecordMatchesMeshWorkspace(record, meshId, workspace) {
24844
+ const recordWorkspace = readStringValue(record?.workspace);
24845
+ if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
24846
+ const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
24847
+ if (recordMeshId) return recordMeshId === meshId;
24848
+ return record?.meta?.launchedByCoordinator === true || !!readStringValue(record?.meta?.meshNodeId);
24849
+ }
24850
+ function readLiveMeshNodeWorkspace(args) {
24851
+ const directNodeWorkspace = args.liveSessionRecords.find((record) => liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId) && readStringValue(record?.workspace));
24852
+ if (directNodeWorkspace) {
24853
+ return readStringValue(directNodeWorkspace.workspace) || "";
24854
+ }
24855
+ if (args.allowCoordinatorSession) {
24856
+ const coordinatorWorkspace = args.liveSessionRecords.find((record) => readStringValue(record?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record?.workspace));
24857
+ if (coordinatorWorkspace) {
24858
+ return readStringValue(coordinatorWorkspace.workspace) || "";
24859
+ }
24860
+ }
24861
+ return "";
24862
+ }
24863
+ function collectLiveMeshSessionRecords(args) {
24864
+ const matches = args.liveSessionRecords.filter((record) => {
24865
+ const nodeWorkspace = readStringValue(args.node?.workspace);
24866
+ if (liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId)) return true;
24867
+ return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record, args.meshId, nodeWorkspace);
24868
+ });
24869
+ if (args.allowCoordinatorSession) {
24870
+ for (const record of args.liveSessionRecords) {
24871
+ if (readStringValue(record?.meta?.meshCoordinatorFor) !== args.meshId) continue;
24872
+ const sessionId = readStringValue(record?.sessionId);
24873
+ if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
24874
+ matches.push(record);
24875
+ }
24876
+ }
24877
+ return matches;
24878
+ }
24879
+ function applyCachedInlineMeshNodeStatus(status, node, options) {
23698
24880
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23699
- const git = buildCachedInlineMeshGitStatus(node);
23700
- const error = readStringValue(cachedStatus.error, node?.error);
23701
- const health = readStringValue(cachedStatus.health, node?.health);
24881
+ const liveGit = buildInlineMeshTransitGitStatus(node);
24882
+ const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
24883
+ const error = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
24884
+ const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
23702
24885
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
23703
- if (!git && !error && !health) return false;
23704
- if (!machineStatus && !git && !error) return false;
24886
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
24887
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
24888
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
24889
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
24890
+ if (!git && !error && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
23705
24891
  if (git) status.git = git;
23706
24892
  if (error) status.error = error;
24893
+ if (machineStatus) status.machineStatus = machineStatus;
24894
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
24895
+ if (updatedAt) status.updatedAt = updatedAt;
24896
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
24897
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
23707
24898
  if (health) {
23708
24899
  status.health = health;
23709
24900
  return true;
23710
24901
  }
23711
24902
  if (git) {
23712
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
23713
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
24903
+ status.health = deriveMeshNodeHealthFromGit(git);
23714
24904
  return true;
23715
24905
  }
23716
- return false;
24906
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
23717
24907
  }
23718
24908
  async function resolveProviderTypeFromPriority(args) {
23719
24909
  if (!args.providerPriority.length) {
@@ -23738,152 +24928,116 @@ async function resolveProviderTypeFromPriority(args) {
23738
24928
  }
23739
24929
  return { error: `No usable provider detected for node '${args.nodeId}' from providerPriority: ${failed.join("; ")}` };
23740
24930
  }
23741
- var REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
23742
24931
  var REFINE_VALIDATION_TIMEOUT_MS = 12e4;
23743
24932
  var REFINE_VALIDATION_OUTPUT_LIMIT_BYTES = 128 * 1024;
23744
24933
  var REFINE_VALIDATION_SUMMARY_CHARS = 2e3;
23745
- var REFINE_VALIDATION_MAX_COMMANDS = 4;
24934
+ var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
23746
24935
  function truncateValidationOutput(value) {
23747
24936
  const text = typeof value === "string" ? value : value == null ? "" : String(value);
23748
24937
  if (text.length <= REFINE_VALIDATION_SUMMARY_CHARS) return text;
23749
24938
  return `${text.slice(0, REFINE_VALIDATION_SUMMARY_CHARS)}
23750
24939
  [truncated ${text.length - REFINE_VALIDATION_SUMMARY_CHARS} chars]`;
23751
24940
  }
23752
- function readPackageScripts(workspace) {
23753
- try {
23754
- const packageJsonPath = pathJoin(workspace, "package.json");
23755
- const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
23756
- return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
23757
- } catch {
23758
- return {};
23759
- }
23760
- }
23761
- function tokenizeValidationCommand(command) {
23762
- const trimmed = command.trim();
23763
- if (!trimmed) return null;
23764
- if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
23765
- const tokens = trimmed.split(/\s+/).filter(Boolean);
23766
- if (!tokens.length) return null;
23767
- if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
23768
- return tokens;
23769
- }
23770
- function scriptMatchesValidationCategory(scriptName, category) {
23771
- return scriptName === category || scriptName.startsWith(`${category}:`);
23772
- }
23773
- function parsePackageManagerValidationCommand(rawCommand, category, scripts, source) {
23774
- const tokens = tokenizeValidationCommand(rawCommand);
23775
- if (!tokens) {
23776
- return { rejected: { command: rawCommand, category, source, reason: "unsafe command string is not allowlisted" } };
23777
- }
23778
- const [binary, second, third, ...rest] = tokens;
23779
- let scriptName = "";
23780
- let command = binary;
23781
- let args = [];
23782
- if ((binary === "npm" || binary === "pnpm" || binary === "bun") && second === "run" && third) {
23783
- scriptName = third;
23784
- args = ["run", scriptName, ...rest];
23785
- } else if (binary === "npm" && second === "test" && !third) {
23786
- scriptName = "test";
23787
- args = ["test"];
23788
- } else if (binary === "yarn" && second === "run" && third) {
23789
- scriptName = third;
23790
- args = ["run", scriptName, ...rest];
23791
- } else if (binary === "yarn" && second && !third) {
23792
- scriptName = second;
23793
- args = [scriptName];
23794
- } else {
23795
- return { rejected: { command: rawCommand, category, source, reason: "command is not a supported package-manager script invocation" } };
23796
- }
23797
- if (!scriptName || !Object.prototype.hasOwnProperty.call(scripts, scriptName)) {
23798
- return { rejected: { command: rawCommand, category, source, script: scriptName, reason: "script is not declared in package.json" } };
23799
- }
23800
- if (!scriptMatchesValidationCategory(scriptName, category)) {
23801
- return { rejected: { command: rawCommand, category, source, script: scriptName, reason: "script name is outside the validation category allowlist" } };
23802
- }
23803
- return {
23804
- command: {
23805
- command,
23806
- args,
23807
- displayCommand: [command, ...args].join(" "),
23808
- category,
23809
- source
23810
- }
23811
- };
24941
+ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
24942
+ stages.push({
24943
+ stage,
24944
+ status,
24945
+ durationMs: Date.now() - startedAt,
24946
+ ...details || {}
24947
+ });
23812
24948
  }
23813
- function collectProjectContextValidationCandidates(mesh) {
23814
- const commands = mesh?.projectContext?.commands;
23815
- if (!commands || typeof commands !== "object" || Array.isArray(commands)) return [];
23816
- const candidates = [];
23817
- for (const category of REFINE_VALIDATION_CATEGORIES) {
23818
- const entries = Array.isArray(commands[category]) ? commands[category] : [];
23819
- for (const entry of entries) {
23820
- if (typeof entry?.command !== "string") continue;
23821
- candidates.push({
23822
- command: entry.command,
23823
- category,
23824
- source: typeof entry.sourcePath === "string" ? entry.sourcePath : "projectContext.commands",
23825
- confidence: typeof entry.confidence === "string" ? entry.confidence : void 0
23826
- });
23827
- }
23828
- }
23829
- return candidates.sort((a, b) => {
23830
- const rank = (value) => value === "high" ? 0 : value === "medium" ? 1 : 2;
23831
- return rank(a.confidence) - rank(b.confidence);
24949
+ async function computeGitPatchId(cwd, fromRef, toRef) {
24950
+ const { execFileSync: execFileSync4 } = await import("child_process");
24951
+ const diff = execFileSync4("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
24952
+ cwd,
24953
+ encoding: "utf8",
24954
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
23832
24955
  });
24956
+ if (!diff.trim()) return "";
24957
+ const patchId = execFileSync4("git", ["patch-id", "--stable"], {
24958
+ cwd,
24959
+ input: diff,
24960
+ encoding: "utf8",
24961
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
24962
+ }).trim();
24963
+ return patchId.split(/\s+/)[0] || "";
23833
24964
  }
23834
- function collectPolicyValidationCandidates(mesh) {
23835
- const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
23836
- const configured = Array.isArray(policy.validationCommands) ? policy.validationCommands : Array.isArray(policy.validationGate?.commands) ? policy.validationGate.commands : [];
23837
- return configured.map((entry) => typeof entry === "string" ? { command: entry, category: "", source: "mesh.policy.validationCommands" } : entry).filter((entry) => entry && typeof entry.command === "string").map((entry) => {
23838
- const commandText = entry.command.trim();
23839
- const category = REFINE_VALIDATION_CATEGORIES.find((cat) => commandText.includes(` ${cat}`)) ?? "";
23840
- return { command: commandText, category, source: "mesh.policy.validationCommands" };
23841
- }).filter((entry) => !!entry.category);
23842
- }
23843
- function selectMeshRefineValidationCommands(mesh, workspace) {
23844
- const scripts = readPackageScripts(workspace);
23845
- const rejectedCommands = [];
23846
- const selected = [];
23847
- const seen = /* @__PURE__ */ new Set();
23848
- const candidates = [
23849
- ...collectPolicyValidationCandidates(mesh),
23850
- ...collectProjectContextValidationCandidates(mesh)
23851
- ];
23852
- for (const candidate of candidates) {
23853
- const parsed = parsePackageManagerValidationCommand(candidate.command, candidate.category, scripts, candidate.source);
23854
- if (parsed.rejected) {
23855
- rejectedCommands.push(parsed.rejected);
23856
- continue;
23857
- }
23858
- if (!parsed.command || seen.has(parsed.command.displayCommand)) continue;
23859
- selected.push(parsed.command);
23860
- seen.add(parsed.command.displayCommand);
23861
- if (selected.length >= REFINE_VALIDATION_MAX_COMMANDS) break;
23862
- }
23863
- if (!selected.length && candidates.length === 0) {
23864
- for (const category of REFINE_VALIDATION_CATEGORIES) {
23865
- if (!Object.prototype.hasOwnProperty.call(scripts, category)) continue;
23866
- const fallback = parsePackageManagerValidationCommand(`npm run ${category}`, category, scripts, "package.json:scripts");
23867
- if (fallback.command && !seen.has(fallback.command.displayCommand)) {
23868
- selected.push(fallback.command);
23869
- seen.add(fallback.command.displayCommand);
23870
- } else if (fallback.rejected) {
23871
- rejectedCommands.push(fallback.rejected);
23872
- }
23873
- if (selected.length >= 2) break;
24965
+ async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
24966
+ const startedAt = Date.now();
24967
+ try {
24968
+ const { execFileSync: execFileSync4 } = await import("child_process");
24969
+ const git = (args) => execFileSync4("git", args, {
24970
+ cwd: repoRoot,
24971
+ encoding: "utf8",
24972
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
24973
+ });
24974
+ const mergeBase = git(["merge-base", baseHead, branchHead]).trim();
24975
+ const mergeTreeStdout = git(["merge-tree", "--write-tree", baseHead, branchHead]);
24976
+ const mergedTree = mergeTreeStdout.trim().split(/\s+/)[0] || "";
24977
+ if (!mergeBase || !mergedTree) {
24978
+ return {
24979
+ status: "failed",
24980
+ equivalent: false,
24981
+ baseHead,
24982
+ branchHead,
24983
+ mergeBase: mergeBase || void 0,
24984
+ mergedTree: mergedTree || void 0,
24985
+ durationMs: Date.now() - startedAt,
24986
+ error: "patch equivalence preflight could not resolve merge-base or synthetic merge tree",
24987
+ stdout: truncateValidationOutput(mergeTreeStdout)
24988
+ };
23874
24989
  }
24990
+ const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead);
24991
+ const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree);
24992
+ const equivalent = expectedPatchId === actualPatchId;
24993
+ return {
24994
+ status: equivalent ? "passed" : "failed",
24995
+ equivalent,
24996
+ baseHead,
24997
+ branchHead,
24998
+ mergeBase,
24999
+ mergedTree,
25000
+ expectedPatchId,
25001
+ actualPatchId,
25002
+ durationMs: Date.now() - startedAt
25003
+ };
25004
+ } catch (e) {
25005
+ return {
25006
+ status: "failed",
25007
+ equivalent: false,
25008
+ baseHead,
25009
+ branchHead,
25010
+ durationMs: Date.now() - startedAt,
25011
+ error: e?.message || String(e),
25012
+ stdout: truncateValidationOutput(e?.stdout),
25013
+ stderr: truncateValidationOutput(e?.stderr)
25014
+ };
23875
25015
  }
25016
+ }
25017
+ function buildMeshRefineValidationPlan(mesh, workspace) {
25018
+ const plan = resolveMeshRefineValidationPlan(mesh, workspace);
23876
25019
  return {
23877
- commands: selected,
23878
- rejectedCommands,
23879
- source: selected.some((command) => command.source === "mesh.policy.validationCommands") ? "mesh_policy" : selected.some((command) => command.source !== "package.json:scripts") ? "project_context" : selected.length ? "package_json_scripts" : "unavailable"
25020
+ source: plan.source,
25021
+ sourceType: plan.sourceType,
25022
+ commands: plan.commands.map((command) => ({
25023
+ displayCommand: command.displayCommand,
25024
+ category: command.category,
25025
+ source: command.source,
25026
+ cwd: command.cwd,
25027
+ timeoutMs: command.timeoutMs
25028
+ })),
25029
+ unavailableReason: plan.unavailableReason,
25030
+ rejectedCommands: plan.rejectedCommands,
25031
+ suggestions: plan.suggestions,
25032
+ suggestedConfig: plan.suggestedConfig,
25033
+ note: plan.sourceType === "unavailable" ? "No validation command will be executed until a repo mesh/refine config is provided. Heuristics are suggestions only." : "Validation commands are resolved from repo mesh/refine config; heuristics are suggestions only."
23880
25034
  };
23881
25035
  }
23882
25036
  async function runMeshRefineValidationGate(mesh, workspace) {
23883
25037
  const { execFile: execFile3 } = await import("child_process");
23884
25038
  const { promisify: promisify3 } = await import("util");
23885
25039
  const execFileAsync3 = promisify3(execFile3);
23886
- const selection = selectMeshRefineValidationCommands(mesh, workspace);
25040
+ const selection = resolveMeshRefineValidationPlan(mesh, workspace);
23887
25041
  const summary = {
23888
25042
  status: "skipped",
23889
25043
  required: true,
@@ -23891,21 +25045,27 @@ async function runMeshRefineValidationGate(mesh, workspace) {
23891
25045
  rejectedCommands: selection.rejectedCommands,
23892
25046
  skippedReason: void 0,
23893
25047
  timeoutMs: REFINE_VALIDATION_TIMEOUT_MS,
23894
- outputLimitBytes: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES
25048
+ outputLimitBytes: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
25049
+ configSource: selection.source,
25050
+ configSourceType: selection.sourceType,
25051
+ suggestions: selection.suggestions,
25052
+ suggestedConfig: selection.suggestedConfig
23895
25053
  };
23896
25054
  if (!selection.commands.length) {
23897
- summary.skippedReason = "validation_unavailable: no allowlisted projectContext, mesh policy, or package.json build/test/typecheck/lint command was available";
25055
+ summary.skippedReason = selection.unavailableReason || "validation_unavailable: repo mesh/refine config did not provide executable validation.commands";
23898
25056
  return summary;
23899
25057
  }
23900
25058
  for (const candidate of selection.commands) {
23901
25059
  const startedAt = Date.now();
25060
+ const cwd = candidate.cwd ? pathResolve(workspace, candidate.cwd) : workspace;
25061
+ const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
23902
25062
  try {
23903
25063
  const result = await execFileAsync3(candidate.command, candidate.args, {
23904
- cwd: workspace,
25064
+ cwd,
23905
25065
  encoding: "utf8",
23906
- timeout: REFINE_VALIDATION_TIMEOUT_MS,
25066
+ timeout,
23907
25067
  maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
23908
- env: { ...process.env, CI: process.env.CI || "1" }
25068
+ env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
23909
25069
  });
23910
25070
  summary.commandsRun.push({
23911
25071
  command: candidate.command,
@@ -23913,6 +25073,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
23913
25073
  displayCommand: candidate.displayCommand,
23914
25074
  category: candidate.category,
23915
25075
  source: candidate.source,
25076
+ cwd,
23916
25077
  passed: true,
23917
25078
  exitCode: 0,
23918
25079
  durationMs: Date.now() - startedAt,
@@ -23926,6 +25087,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
23926
25087
  displayCommand: candidate.displayCommand,
23927
25088
  category: candidate.category,
23928
25089
  source: candidate.source,
25090
+ cwd,
23929
25091
  passed: false,
23930
25092
  exitCode: typeof error?.code === "number" ? error.code : null,
23931
25093
  signal: typeof error?.signal === "string" ? error.signal : null,
@@ -23942,7 +25104,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
23942
25104
  return summary;
23943
25105
  }
23944
25106
  function loadYamlModule() {
23945
- return yaml;
25107
+ return yaml2;
23946
25108
  }
23947
25109
  function getMcpServersKey(format) {
23948
25110
  return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
@@ -24100,36 +25262,216 @@ function summarizeSessionHostPruneResult(result) {
24100
25262
  keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
24101
25263
  };
24102
25264
  }
25265
+ function normalizeStandaloneHostCommandUrl(hostAddress) {
25266
+ const raw = hostAddress.trim();
25267
+ if (!raw) throw new Error("hostAddress required");
25268
+ const url = new URL(raw.replace(/^ws:/, "http:").replace(/^wss:/, "https:"));
25269
+ url.pathname = "/api/v1/command";
25270
+ url.search = "";
25271
+ url.hash = "";
25272
+ return url.toString();
25273
+ }
25274
+ function buildMemberJoinNode(mesh, args, fallbackDaemonId) {
25275
+ const requestedNodeId = typeof args?.memberNodeId === "string" ? args.memberNodeId.trim() : "";
25276
+ const explicit = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
25277
+ const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => node?.id === requestedNodeId || node?.nodeId === requestedNodeId) : mesh.nodes[0] : null;
25278
+ const source = explicit || configured;
25279
+ const workspace = typeof source?.workspace === "string" && source.workspace.trim() ? source.workspace.trim() : typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
25280
+ if (!workspace) return null;
25281
+ const nodeId = typeof source?.id === "string" && source.id.trim() ? source.id.trim() : typeof source?.nodeId === "string" && source.nodeId.trim() ? source.nodeId.trim() : void 0;
25282
+ return {
25283
+ ...nodeId ? { id: nodeId } : {},
25284
+ workspace,
25285
+ ...typeof source?.repoRoot === "string" && source.repoRoot.trim() ? { repoRoot: source.repoRoot.trim() } : {},
25286
+ ...typeof source?.daemonId === "string" && source.daemonId.trim() ? { daemonId: source.daemonId.trim() } : fallbackDaemonId ? { daemonId: fallbackDaemonId } : {},
25287
+ ...typeof source?.machineId === "string" && source.machineId.trim() ? { machineId: source.machineId.trim() } : {},
25288
+ userOverrides: source?.userOverrides && typeof source.userOverrides === "object" && !Array.isArray(source.userOverrides) ? source.userOverrides : {},
25289
+ policy: source?.policy && typeof source.policy === "object" && !Array.isArray(source.policy) ? source.policy : {},
25290
+ role: "member"
25291
+ };
25292
+ }
24103
25293
  var DaemonCommandRouter = class {
24104
25294
  deps;
24105
25295
  /** In-memory cache for cloud-originating meshes passed via inlineMesh.
24106
25296
  * Allows the MCP server to query mesh data via get_mesh even when
24107
25297
  * the mesh doesn't exist in the local meshes.json file. */
24108
25298
  inlineMeshCache = /* @__PURE__ */ new Map();
25299
+ /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
25300
+ aggregateMeshStatusCache = /* @__PURE__ */ new Map();
24109
25301
  constructor(deps) {
24110
25302
  this.deps = deps;
24111
25303
  }
25304
+ cloneJsonValue(value) {
25305
+ if (typeof structuredClone === "function") return structuredClone(value);
25306
+ return JSON.parse(JSON.stringify(value));
25307
+ }
25308
+ hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options) {
25309
+ if (!mesh || typeof mesh !== "object" || !Array.isArray(mesh.nodes) || !Array.isArray(snapshot?.nodes)) return snapshot;
25310
+ const inlineNodesById = /* @__PURE__ */ new Map();
25311
+ for (const node of mesh.nodes) {
25312
+ const nodeId = readInlineMeshNodeId(node);
25313
+ if (nodeId) inlineNodesById.set(nodeId, node);
25314
+ }
25315
+ if (!inlineNodesById.size) return snapshot;
25316
+ let changed = false;
25317
+ const unavailableNodeIds = /* @__PURE__ */ new Set();
25318
+ const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
25319
+ const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
25320
+ for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
25321
+ const nodeId = readStringValue(entry);
25322
+ if (nodeId) unavailableNodeIds.add(nodeId);
25323
+ }
25324
+ const nodes = snapshot.nodes.map((statusNode) => {
25325
+ const nodeId = readStringValue(statusNode?.nodeId, statusNode?.id);
25326
+ const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
25327
+ if (!inlineNode) return statusNode;
25328
+ const liveGit = buildInlineMeshTransitGitStatus(inlineNode);
25329
+ if (!liveGit) return statusNode;
25330
+ const nextStatus = { ...statusNode };
25331
+ nextStatus.git = liveGit;
25332
+ nextStatus.health = deriveMeshNodeHealthFromGit(liveGit);
25333
+ nextStatus.launchReady = readBooleanValue(nextStatus.launchReady) ?? true;
25334
+ const connection = readObjectRecord(nextStatus.connection);
25335
+ const connectionState = readStringValue(connection.state);
25336
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
25337
+ if (!connectionReported || connectionState === "unknown") {
25338
+ nextStatus.connection = buildLivePeerGitConnection(connection);
25339
+ }
25340
+ delete nextStatus.gitProbePending;
25341
+ const error = readStringValue(nextStatus.error);
25342
+ if (error && /pending_git|git probe|live peer git snapshot|no peer git snapshot/i.test(error)) delete nextStatus.error;
25343
+ if (!readStringValue(nextStatus.machineStatus)) nextStatus.machineStatus = "online";
25344
+ if (nodeId) unavailableNodeIds.delete(nodeId);
25345
+ changed = true;
25346
+ return nextStatus;
25347
+ });
25348
+ if (!changed && !(options?.requireDirectPeerTruth && unavailableNodeIds.size > 0)) return snapshot;
25349
+ const nextSourceOfTruth = {
25350
+ ...sourceOfTruth,
25351
+ ...Object.keys(directPeerTruth).length ? {
25352
+ directPeerTruth: {
25353
+ ...directPeerTruth,
25354
+ satisfied: options?.requireDirectPeerTruth === true ? unavailableNodeIds.size === 0 : directPeerTruth.satisfied,
25355
+ unavailableNodeIds: [...unavailableNodeIds]
25356
+ },
25357
+ ...options?.requireDirectPeerTruth === true ? {
25358
+ coordinatorOwnsLiveTruth: unavailableNodeIds.size === 0,
25359
+ currentStatus: unavailableNodeIds.size === 0 ? "live_git_and_session_probes" : "direct_peer_truth_unavailable"
25360
+ } : {}
25361
+ } : {}
25362
+ };
25363
+ return {
25364
+ ...snapshot,
25365
+ ...options?.requireDirectPeerTruth === true && unavailableNodeIds.size > 0 ? {
25366
+ success: false,
25367
+ code: "mesh_direct_peer_truth_unavailable",
25368
+ error: "Selected coordinator could not confirm direct mesh truth for every remote node yet."
25369
+ } : {},
25370
+ sourceOfTruth: nextSourceOfTruth,
25371
+ nodes
25372
+ };
25373
+ }
25374
+ getCachedAggregateMeshStatus(meshId, mesh, options) {
25375
+ const cached = this.aggregateMeshStatusCache.get(meshId);
25376
+ if (!cached?.snapshot || cached.snapshot.success !== true || !Array.isArray(cached.snapshot.nodes)) return null;
25377
+ let snapshot = this.cloneJsonValue(cached.snapshot);
25378
+ snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
25379
+ if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
25380
+ const ageMs = Math.max(0, Date.now() - cached.builtAt);
25381
+ const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
25382
+ snapshot.sourceOfTruth = {
25383
+ ...sourceOfTruth,
25384
+ aggregateSnapshot: {
25385
+ ...sourceOfTruth.aggregateSnapshot && typeof sourceOfTruth.aggregateSnapshot === "object" ? sourceOfTruth.aggregateSnapshot : {},
25386
+ owner: "coordinator_daemon_memory",
25387
+ cached: true,
25388
+ source: "memory",
25389
+ refreshReason: "memory_cache_hit",
25390
+ ageMs,
25391
+ cachedAt: new Date(cached.builtAt).toISOString(),
25392
+ returnedAt: (/* @__PURE__ */ new Date()).toISOString()
25393
+ }
25394
+ };
25395
+ return snapshot;
25396
+ }
25397
+ rememberAggregateMeshStatus(meshId, snapshot, refreshReason) {
25398
+ if (!snapshot || typeof snapshot !== "object" || snapshot.success !== true || !Array.isArray(snapshot.nodes)) return snapshot;
25399
+ const builtAt = Date.now();
25400
+ const next = this.cloneJsonValue(snapshot);
25401
+ const sourceOfTruth = next.sourceOfTruth && typeof next.sourceOfTruth === "object" ? next.sourceOfTruth : {};
25402
+ next.sourceOfTruth = {
25403
+ ...sourceOfTruth,
25404
+ aggregateSnapshot: {
25405
+ owner: "coordinator_daemon_memory",
25406
+ cached: false,
25407
+ source: "live_refresh",
25408
+ refreshReason,
25409
+ ageMs: 0,
25410
+ cachedAt: new Date(builtAt).toISOString(),
25411
+ returnedAt: new Date(builtAt).toISOString()
25412
+ }
25413
+ };
25414
+ this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next) });
25415
+ return next;
25416
+ }
24112
25417
  getCachedInlineMesh(meshId, inlineMesh) {
24113
25418
  if (inlineMesh && typeof inlineMesh === "object") {
24114
- this.inlineMeshCache.set(meshId, inlineMesh);
24115
- return inlineMesh;
25419
+ return this.warmInlineMeshCache(meshId, inlineMesh);
24116
25420
  }
24117
25421
  return this.inlineMeshCache.get(meshId);
24118
25422
  }
25423
+ warmInlineMeshCache(meshId, inlineMesh) {
25424
+ if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
25425
+ const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
25426
+ const cached = this.inlineMeshCache.get(meshId);
25427
+ if (cached) {
25428
+ const merged = reconcileInlineMeshCache(cached, sanitizedInlineMesh);
25429
+ this.inlineMeshCache.set(meshId, merged);
25430
+ return merged;
25431
+ }
25432
+ this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
25433
+ return sanitizedInlineMesh;
25434
+ }
24119
25435
  async getMeshForCommand(meshId, inlineMesh, options) {
24120
25436
  const preferInline = options?.preferInline === true;
24121
25437
  if (preferInline) {
24122
- const cached2 = this.getCachedInlineMesh(meshId, inlineMesh);
24123
- if (cached2) return { mesh: cached2, inline: true };
25438
+ const cached2 = this.getCachedInlineMesh(meshId);
25439
+ if (cached2) {
25440
+ if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
25441
+ const merged = reconcileInlineMeshCache(cached2, inlineMesh);
25442
+ this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
25443
+ return { mesh: merged, inline: true, source: "inline_cache" };
25444
+ }
25445
+ return { mesh: cached2, inline: true, source: "inline_cache" };
25446
+ }
25447
+ if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
25448
+ this.warmInlineMeshCache(meshId, inlineMesh);
25449
+ return { mesh: inlineMesh, inline: true, source: "inline_bootstrap" };
25450
+ }
24124
25451
  }
24125
25452
  try {
24126
25453
  const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
24127
25454
  const mesh = getMesh3(meshId);
24128
- if (mesh) return { mesh, inline: false };
25455
+ if (mesh) return { mesh, inline: false, source: "local_config" };
24129
25456
  } catch {
24130
25457
  }
24131
- const cached = this.getCachedInlineMesh(meshId, inlineMesh);
24132
- return cached ? { mesh: cached, inline: true } : null;
25458
+ const cached = this.getCachedInlineMesh(meshId);
25459
+ if (cached) return { mesh: cached, inline: true, source: "inline_cache" };
25460
+ const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
25461
+ return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
25462
+ }
25463
+ invalidateAggregateMeshStatus(meshId) {
25464
+ this.aggregateMeshStatusCache.delete(meshId);
25465
+ }
25466
+ async requireMeshHostMutationOwner(meshId, inlineMesh, operation) {
25467
+ const meshRecord = await this.getMeshForCommand(meshId, inlineMesh, { preferInline: true });
25468
+ const mesh = meshRecord?.mesh;
25469
+ if (!mesh) return { success: false, error: "Mesh not found" };
25470
+ const meshHost = resolveMeshHostStatus(mesh);
25471
+ if (!meshHost.canOwnCoordinator || !meshHost.canOwnQueue) {
25472
+ return { ...buildMeshHostRequiredFailure(mesh, operation), success: false, meshId };
25473
+ }
25474
+ return null;
24133
25475
  }
24134
25476
  updateInlineMeshNode(meshId, mesh, node) {
24135
25477
  if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
@@ -24138,6 +25480,7 @@ var DaemonCommandRouter = class {
24138
25480
  else mesh.nodes.push(node);
24139
25481
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24140
25482
  this.inlineMeshCache.set(meshId, mesh);
25483
+ this.invalidateAggregateMeshStatus(meshId);
24141
25484
  }
24142
25485
  removeInlineMeshNode(meshId, mesh, nodeId) {
24143
25486
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
@@ -24146,6 +25489,7 @@ var DaemonCommandRouter = class {
24146
25489
  mesh.nodes.splice(idx, 1);
24147
25490
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
24148
25491
  this.inlineMeshCache.set(meshId, mesh);
25492
+ this.invalidateAggregateMeshStatus(meshId);
24149
25493
  return true;
24150
25494
  }
24151
25495
  normalizeMeshSessionCleanupMode(value) {
@@ -24358,6 +25702,7 @@ var DaemonCommandRouter = class {
24358
25702
  const deletedSessionIds = [];
24359
25703
  const skippedSessionIds = [];
24360
25704
  const skippedLiveSessionIds = [];
25705
+ const skippedCoordinatorSessionIds = [];
24361
25706
  const deleteUnsupportedSessionIds = [];
24362
25707
  const recordsRemainSessionIds = [];
24363
25708
  const errors = [];
@@ -24390,6 +25735,12 @@ var DaemonCommandRouter = class {
24390
25735
  const completed = this.isCompletedHostedSession(record);
24391
25736
  const surfaceKind = getSessionHostSurfaceKind(record);
24392
25737
  const liveRuntime = surfaceKind === "live_runtime";
25738
+ const coordinatorSession = readStringValue(record?.meta?.meshCoordinatorFor) === args.meshId;
25739
+ if (!hasExplicitSessionIds && coordinatorSession) {
25740
+ skippedSessionIds.push(sessionId);
25741
+ skippedCoordinatorSessionIds.push(sessionId);
25742
+ continue;
25743
+ }
24393
25744
  if (!hasExplicitSessionIds && liveRuntime) {
24394
25745
  skippedSessionIds.push(sessionId);
24395
25746
  skippedLiveSessionIds.push(sessionId);
@@ -24455,6 +25806,7 @@ var DaemonCommandRouter = class {
24455
25806
  deletedSessionIds,
24456
25807
  skippedSessionIds,
24457
25808
  skippedLiveSessionIds,
25809
+ skippedCoordinatorSessionIds,
24458
25810
  ...deleteUnsupported ? {
24459
25811
  deleteUnsupported: true,
24460
25812
  effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
@@ -24587,7 +25939,8 @@ var DaemonCommandRouter = class {
24587
25939
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
24588
25940
  }
24589
25941
  case "get_pending_mesh_events": {
24590
- const events = drainPendingMeshCoordinatorEvents();
25942
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25943
+ const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
24591
25944
  return { success: true, events };
24592
25945
  }
24593
25946
  case "launch_cli":
@@ -25116,15 +26469,39 @@ var DaemonCommandRouter = class {
25116
26469
  case "get_mesh": {
25117
26470
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25118
26471
  if (!meshId) return { success: false, error: "meshId required" };
25119
- try {
25120
- const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25121
- const mesh = getMesh3(meshId);
25122
- if (mesh) return { success: true, mesh };
25123
- } catch {
26472
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
26473
+ if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
26474
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
26475
+ const directTruth = await hydrateInlineMeshDirectTruth({
26476
+ mesh: meshRecord.mesh,
26477
+ meshSource: meshRecord.source,
26478
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
26479
+ statusInstanceId: this.deps.statusInstanceId,
26480
+ localMachineId: loadConfig().machineId || ""
26481
+ });
26482
+ const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
26483
+ const sourceOfTruth = {
26484
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
26485
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
26486
+ directPeerTruth: {
26487
+ required: requireDirectPeerTruth,
26488
+ satisfied: directTruthSatisfied,
26489
+ directEvidenceCount: directTruth.directEvidenceCount,
26490
+ localConfirmedCount: directTruth.localConfirmedCount,
26491
+ peerAttemptedCount: directTruth.peerAttemptedCount,
26492
+ peerConfirmedCount: directTruth.peerConfirmedCount,
26493
+ unavailableNodeIds: directTruth.unavailableNodeIds
26494
+ }
26495
+ };
26496
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
26497
+ return {
26498
+ success: false,
26499
+ code: "mesh_direct_peer_truth_unavailable",
26500
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
26501
+ sourceOfTruth
26502
+ };
25124
26503
  }
25125
- const cached = this.inlineMeshCache.get(meshId);
25126
- if (cached) return { success: true, mesh: cached };
25127
- return { success: false, error: "Mesh not found" };
26504
+ return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
25128
26505
  }
25129
26506
  case "create_mesh": {
25130
26507
  const name = typeof args?.name === "string" ? args.name.trim() : "";
@@ -25134,7 +26511,8 @@ var DaemonCommandRouter = class {
25134
26511
  if (!name) return { success: false, error: "name required" };
25135
26512
  try {
25136
26513
  const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25137
- const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy });
26514
+ const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
26515
+ const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy, meshHost });
25138
26516
  return { success: true, mesh };
25139
26517
  } catch (e) {
25140
26518
  return { success: false, error: e.message };
@@ -25150,15 +26528,226 @@ var DaemonCommandRouter = class {
25150
26528
  if (typeof args?.defaultBranch === "string") patch.defaultBranch = args.defaultBranch;
25151
26529
  if (args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy)) patch.policy = args.policy;
25152
26530
  if (args?.coordinator && typeof args.coordinator === "object" && !Array.isArray(args.coordinator)) patch.coordinator = args.coordinator;
26531
+ if (args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost)) patch.meshHost = args.meshHost;
25153
26532
  if (!Object.keys(patch).length) return { success: false, error: "No updates provided" };
25154
26533
  const mesh = updateMesh2(meshId, patch);
25155
26534
  if (!mesh) return { success: false, error: "Mesh not found" };
25156
26535
  this.inlineMeshCache.set(meshId, mesh);
26536
+ this.invalidateAggregateMeshStatus(meshId);
25157
26537
  return { success: true, mesh };
25158
26538
  } catch (e) {
25159
26539
  return { success: false, error: e.message };
25160
26540
  }
25161
26541
  }
26542
+ case "get_mesh_host_pairing": {
26543
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26544
+ if (!meshId) return { success: false, error: "meshId required" };
26545
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
26546
+ const mesh = meshRecord?.mesh;
26547
+ if (!mesh) return { success: false, error: "Mesh not found" };
26548
+ const meshHost = resolveMeshHostStatus(mesh);
26549
+ const pairingStatus = meshHost.pairing?.status || "not_configured";
26550
+ return {
26551
+ success: true,
26552
+ code: pairingStatus === "not_configured" ? "mesh_host_pairing_not_configured" : "mesh_host_pairing_pending",
26553
+ meshId,
26554
+ hostAddress: meshHost.hostAddress,
26555
+ meshHost,
26556
+ manualPairing: {
26557
+ status: pairingStatus,
26558
+ joinImplemented: true,
26559
+ protocol: "standalone_command_direct_v1",
26560
+ description: "Standalone manual pairing can save address/token metadata, apply a host join over direct standalone command HTTP or injected mesh command dispatch, and check persisted status. P2P signaling remains outside this slice."
26561
+ }
26562
+ };
26563
+ }
26564
+ case "configure_mesh_host_pairing": {
26565
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26566
+ const hostAddress = typeof args?.hostAddress === "string" ? args.hostAddress.trim() : "";
26567
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
26568
+ if (!meshId) return { success: false, error: "meshId required" };
26569
+ if (!hostAddress || !token) return { success: false, error: "hostAddress and token required" };
26570
+ try {
26571
+ const { configureMeshHostPairing: configureMeshHostPairing2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
26572
+ const configured = configureMeshHostPairing2(meshId, { hostAddress, token });
26573
+ if (!configured) return { success: false, error: "Mesh not found" };
26574
+ this.inlineMeshCache.set(meshId, configured.mesh);
26575
+ const meshHost = resolveMeshHostStatus(configured.mesh);
26576
+ return {
26577
+ success: true,
26578
+ code: "mesh_host_pairing_pending",
26579
+ meshId,
26580
+ hostAddress: configured.hostAddress,
26581
+ meshHost,
26582
+ manualPairing: {
26583
+ status: meshHost.pairing?.status || "pairing",
26584
+ joinImplemented: true,
26585
+ protocol: "standalone_command_direct_v1",
26586
+ description: "Manual Mesh Host pairing config was saved locally. Use join_mesh_host_pairing to apply it to the host. Raw token was not persisted."
26587
+ }
26588
+ };
26589
+ } catch (e) {
26590
+ return { success: false, code: "mesh_host_pairing_invalid", meshId, hostAddress, error: e.message };
26591
+ }
26592
+ }
26593
+ case "create_mesh_host_pairing_token": {
26594
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26595
+ if (!meshId) return { success: false, error: "meshId required" };
26596
+ try {
26597
+ const { createMeshHostPairingToken: createMeshHostPairingToken2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
26598
+ const created = createMeshHostPairingToken2(meshId, {
26599
+ token: typeof args?.token === "string" ? args.token : void 0,
26600
+ expiresAt: typeof args?.expiresAt === "string" ? args.expiresAt : void 0
26601
+ });
26602
+ if (!created) return { success: false, error: "Mesh not found" };
26603
+ this.inlineMeshCache.set(meshId, created.mesh);
26604
+ this.invalidateAggregateMeshStatus(meshId);
26605
+ return {
26606
+ success: true,
26607
+ code: "mesh_host_pairing_token_created",
26608
+ meshId,
26609
+ token: created.token,
26610
+ tokenId: created.tokenId,
26611
+ expiresAt: created.expiresAt,
26612
+ meshHost: resolveMeshHostStatus(created.mesh),
26613
+ warning: "Raw token is returned once and is not persisted; share it with member daemons over a trusted channel."
26614
+ };
26615
+ } catch (e) {
26616
+ return { success: false, code: "mesh_host_pairing_token_invalid", meshId, error: e.message };
26617
+ }
26618
+ }
26619
+ case "apply_mesh_host_join": {
26620
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26621
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
26622
+ const memberNode = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
26623
+ if (!meshId) return { success: false, error: "meshId required" };
26624
+ if (!token || !memberNode) return { success: false, error: "token and memberNode required" };
26625
+ try {
26626
+ const { applyMeshHostJoinRequest: applyMeshHostJoinRequest2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
26627
+ const applied = applyMeshHostJoinRequest2(meshId, {
26628
+ token,
26629
+ memberNode,
26630
+ memberMeshId: typeof args?.memberMeshId === "string" ? args.memberMeshId : void 0
26631
+ });
26632
+ if (!applied) return { success: false, error: "Mesh not found" };
26633
+ if (!applied.accepted) {
26634
+ return {
26635
+ success: false,
26636
+ code: "mesh_host_join_rejected",
26637
+ meshId,
26638
+ tokenId: applied.tokenId,
26639
+ meshHost: applied.meshHost ? resolveMeshHostStatus({ meshHost: applied.meshHost }) : void 0,
26640
+ error: applied.reason
26641
+ };
26642
+ }
26643
+ this.inlineMeshCache.set(meshId, applied.mesh);
26644
+ this.invalidateAggregateMeshStatus(meshId);
26645
+ try {
26646
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
26647
+ appendLedgerEntry2(meshId, {
26648
+ kind: "node_joined",
26649
+ nodeId: applied.node.id,
26650
+ payload: { role: "member", tokenId: applied.tokenId, workspace: applied.node.workspace }
26651
+ });
26652
+ } catch {
26653
+ }
26654
+ return {
26655
+ success: true,
26656
+ code: "mesh_host_join_accepted",
26657
+ meshId,
26658
+ node: applied.node,
26659
+ tokenId: applied.tokenId,
26660
+ meshHost: resolveMeshHostStatus(applied.mesh)
26661
+ };
26662
+ } catch (e) {
26663
+ return { success: false, code: "mesh_host_join_failed", meshId, error: e.message };
26664
+ }
26665
+ }
26666
+ case "join_mesh_host_pairing": {
26667
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26668
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
26669
+ if (!meshId) return { success: false, error: "meshId required" };
26670
+ if (!token) return { success: false, error: "token required because raw pairing tokens are not persisted" };
26671
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
26672
+ const mesh = meshRecord?.mesh;
26673
+ if (!mesh) return { success: false, error: "Mesh not found" };
26674
+ const meshHost = resolveMeshHostStatus(mesh);
26675
+ if (meshHost.role !== "member") {
26676
+ return { success: false, code: "mesh_host_join_not_member", meshId, meshHost, error: "join_mesh_host_pairing must run from a member daemon configured with a Mesh Host address/token." };
26677
+ }
26678
+ try {
26679
+ const { tokenIdForManualPairing: tokenIdForManualPairing2, markMeshHostPairingJoined: markMeshHostPairingJoined2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
26680
+ const tokenId = tokenIdForManualPairing2(token);
26681
+ if (meshHost.pairing?.tokenId && meshHost.pairing.tokenId !== tokenId) {
26682
+ return { success: false, code: "mesh_host_join_rejected", meshId, tokenId, meshHost, error: "invalid pairing token" };
26683
+ }
26684
+ const memberNode = buildMemberJoinNode(mesh, args, this.deps.statusInstanceId);
26685
+ if (!memberNode) return { success: false, error: "member node metadata unavailable" };
26686
+ const hostMeshId = typeof args?.hostMeshId === "string" && args.hostMeshId.trim() ? args.hostMeshId.trim() : meshId;
26687
+ const hostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : meshHost.hostDaemonId;
26688
+ let hostResult;
26689
+ let transport;
26690
+ if (hostDaemonId && this.deps.dispatchMeshCommand) {
26691
+ transport = "mesh_command_dispatch";
26692
+ hostResult = await this.deps.dispatchMeshCommand(hostDaemonId, "apply_mesh_host_join", {
26693
+ meshId: hostMeshId,
26694
+ token,
26695
+ memberMeshId: meshId,
26696
+ memberNode
26697
+ });
26698
+ } else if (meshHost.hostAddress) {
26699
+ transport = "standalone_http_command";
26700
+ const commandUrl = normalizeStandaloneHostCommandUrl(meshHost.hostAddress);
26701
+ const response = await fetch(commandUrl, {
26702
+ method: "POST",
26703
+ headers: { "Content-Type": "application/json" },
26704
+ body: JSON.stringify({ type: "apply_mesh_host_join", payload: { meshId: hostMeshId, token, memberMeshId: meshId, memberNode } })
26705
+ });
26706
+ hostResult = await response.json().catch(() => ({ success: false, error: `Host returned HTTP ${response.status}` }));
26707
+ if (!response.ok && hostResult?.success !== false) hostResult = { success: false, error: `Host returned HTTP ${response.status}` };
26708
+ } else {
26709
+ return {
26710
+ success: false,
26711
+ code: "mesh_host_join_transport_unavailable",
26712
+ meshId,
26713
+ meshHost,
26714
+ error: "No hostDaemonId dispatch path or hostAddress HTTP command path is available. P2P signaling join is not implemented in this slice."
26715
+ };
26716
+ }
26717
+ if (!hostResult?.success) {
26718
+ return { success: false, code: hostResult?.code || "mesh_host_join_rejected", meshId, meshHost, transport, error: hostResult?.error || "Mesh Host rejected join request", hostResult };
26719
+ }
26720
+ const joined = meshRecord.inline ? null : markMeshHostPairingJoined2(meshId, {
26721
+ tokenId: hostResult.tokenId || tokenId,
26722
+ hostDaemonId: hostResult.meshHost?.hostDaemonId || hostDaemonId,
26723
+ hostNodeId: hostResult.meshHost?.hostNodeId,
26724
+ joinedAt: hostResult.meshHost?.pairing?.joinedAt
26725
+ });
26726
+ if (joined) {
26727
+ this.inlineMeshCache.set(meshId, joined.mesh);
26728
+ this.invalidateAggregateMeshStatus(meshId);
26729
+ }
26730
+ return {
26731
+ success: true,
26732
+ code: "mesh_host_join_applied",
26733
+ meshId,
26734
+ hostMeshId,
26735
+ transport,
26736
+ node: hostResult.node,
26737
+ tokenId: hostResult.tokenId || tokenId,
26738
+ meshHost: joined ? resolveMeshHostStatus(joined.mesh) : { ...meshHost, pairing: { ...meshHost.pairing || {}, status: "paired", tokenId: hostResult.tokenId || tokenId } },
26739
+ hostResult,
26740
+ manualPairing: {
26741
+ status: "paired",
26742
+ joinImplemented: true,
26743
+ protocol: "standalone_command_direct_v1",
26744
+ description: "Mesh Host accepted the join and local member pairing status was marked paired. P2P runtime signaling remains outside this slice."
26745
+ }
26746
+ };
26747
+ } catch (e) {
26748
+ return { success: false, code: "mesh_host_join_failed", meshId, meshHost, error: e.message };
26749
+ }
26750
+ }
25162
26751
  case "delete_mesh": {
25163
26752
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25164
26753
  if (!meshId) return { success: false, error: "meshId required" };
@@ -25241,6 +26830,8 @@ var DaemonCommandRouter = class {
25241
26830
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25242
26831
  const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
25243
26832
  if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
26833
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue cancellation");
26834
+ if (ownerFailure) return ownerFailure;
25244
26835
  try {
25245
26836
  const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
25246
26837
  const reason = typeof args?.reason === "string" ? args.reason : void 0;
@@ -25255,6 +26846,8 @@ var DaemonCommandRouter = class {
25255
26846
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25256
26847
  const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
25257
26848
  if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
26849
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue requeue");
26850
+ if (ownerFailure) return ownerFailure;
25258
26851
  try {
25259
26852
  const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
25260
26853
  const task = requeueTask2(meshId, taskId, {
@@ -25275,6 +26868,8 @@ var DaemonCommandRouter = class {
25275
26868
  const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
25276
26869
  if (!meshId) return { success: false, error: "meshId required" };
25277
26870
  if (!workspace) return { success: false, error: "workspace required" };
26871
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node addition");
26872
+ if (ownerFailure) return ownerFailure;
25278
26873
  try {
25279
26874
  const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25280
26875
  const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
@@ -25283,7 +26878,8 @@ var DaemonCommandRouter = class {
25283
26878
  ...readOnly ? { readOnly: true } : {},
25284
26879
  ...providerPriority.length ? { providerPriority } : {}
25285
26880
  };
25286
- const node = addNode3(meshId, { workspace, ...policy ? { policy } : {} });
26881
+ const role = normalizeMeshDaemonRole(args?.role);
26882
+ const node = addNode3(meshId, { workspace, ...policy ? { policy } : {}, ...role ? { role } : {} });
25287
26883
  if (!node) return { success: false, error: "Mesh not found" };
25288
26884
  return { success: true, node };
25289
26885
  } catch (e) {
@@ -25294,6 +26890,8 @@ var DaemonCommandRouter = class {
25294
26890
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25295
26891
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
25296
26892
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
26893
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
26894
+ if (ownerFailure) return ownerFailure;
25297
26895
  try {
25298
26896
  const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25299
26897
  const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
@@ -25317,6 +26915,8 @@ var DaemonCommandRouter = class {
25317
26915
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25318
26916
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
25319
26917
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
26918
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node removal");
26919
+ if (ownerFailure) return ownerFailure;
25320
26920
  try {
25321
26921
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
25322
26922
  const mesh = meshRecord?.mesh;
@@ -25339,30 +26939,88 @@ var DaemonCommandRouter = class {
25339
26939
  return { success: false, error: e.message };
25340
26940
  }
25341
26941
  }
26942
+ case "get_mesh_refine_config_schema": {
26943
+ return {
26944
+ success: true,
26945
+ schema: MESH_REFINE_CONFIG_SCHEMA,
26946
+ locations: MESH_REFINE_CONFIG_LOCATIONS,
26947
+ sourceOfTruth: "repo mesh/refine config",
26948
+ heuristicRole: "suggestions_only_not_execution_path"
26949
+ };
26950
+ }
26951
+ case "validate_mesh_refine_config": {
26952
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
26953
+ const mesh = args?.inlineMesh || {};
26954
+ const loaded = args?.config !== void 0 ? { config: args.config, source: "inline", sourceType: "mesh_policy" } : loadMeshRefineConfig(mesh, workspace);
26955
+ const validation = loaded.config ? validateMeshRefineConfig(loaded.config, loaded.source) : { valid: false, errors: [loaded.error || "repo mesh/refine config unavailable"], commands: [], rejectedCommands: [] };
26956
+ return { success: validation.valid, ...loaded, ...validation };
26957
+ }
26958
+ case "suggest_mesh_refine_config": {
26959
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
26960
+ const mesh = args?.inlineMesh || {};
26961
+ return {
26962
+ success: true,
26963
+ ...suggestMeshRefineConfig(mesh, workspace),
26964
+ note: "Suggestions are heuristic scaffold only; Refinery will not execute them until saved into repo mesh/refine config."
26965
+ };
26966
+ }
26967
+ case "plan_mesh_refine_node": {
26968
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
26969
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
26970
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
26971
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
26972
+ const mesh = meshRecord?.mesh;
26973
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
26974
+ if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
26975
+ return {
26976
+ success: true,
26977
+ dryRun: true,
26978
+ nodeId,
26979
+ workspace: node.workspace,
26980
+ validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
26981
+ mergeWillRun: false,
26982
+ cleanupWillRun: false
26983
+ };
26984
+ }
25342
26985
  case "refine_mesh_node": {
25343
26986
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25344
26987
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
25345
26988
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
26989
+ const refineStages = [];
25346
26990
  try {
25347
26991
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
25348
26992
  const mesh = meshRecord?.mesh;
25349
26993
  const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
25350
- if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
26994
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
25351
26995
  if (!node.isLocalWorktree || !node.workspace) {
25352
- return { success: false, error: `Refinery requires a local worktree node` };
26996
+ return { success: false, error: `Refinery requires a local worktree node`, refineStages };
25353
26997
  }
25354
26998
  const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
25355
26999
  const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
25356
- if (!repoRoot) return { success: false, error: "Source node repoRoot not found" };
27000
+ if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
25357
27001
  const { execFile: execFile3 } = await import("child_process");
25358
27002
  const { promisify: promisify3 } = await import("util");
25359
27003
  const execFileAsync3 = promisify3(execFile3);
27004
+ const resolveStarted = Date.now();
25360
27005
  const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
25361
27006
  const branch = branchStdout.trim();
25362
- if (!branch) return { success: false, error: "Could not determine branch of the worktree node" };
27007
+ if (!branch) return { success: false, error: "Could not determine branch of the worktree node", refineStages };
25363
27008
  const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
25364
27009
  const baseBranch = baseBranchStdout.trim();
27010
+ const { stdout: baseHeadStdout } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
27011
+ const { stdout: branchHeadStdout } = await execFileAsync3("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
27012
+ const baseHead = baseHeadStdout.trim();
27013
+ const branchHead = branchHeadStdout.trim();
27014
+ recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead });
27015
+ const validationStarted = Date.now();
25365
27016
  const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace);
27017
+ recordMeshRefineStage(
27018
+ refineStages,
27019
+ "validation",
27020
+ validationSummary.status === "passed" ? "passed" : validationSummary.status === "failed" ? "failed" : "skipped",
27021
+ validationStarted,
27022
+ { validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
27023
+ );
25366
27024
  if (validationSummary.status === "failed") {
25367
27025
  return {
25368
27026
  success: false,
@@ -25372,6 +27030,7 @@ var DaemonCommandRouter = class {
25372
27030
  branch,
25373
27031
  into: baseBranch,
25374
27032
  validationSummary,
27033
+ refineStages,
25375
27034
  finalBranchConvergenceState: {
25376
27035
  branch,
25377
27036
  baseBranch,
@@ -25391,6 +27050,7 @@ var DaemonCommandRouter = class {
25391
27050
  branch,
25392
27051
  into: baseBranch,
25393
27052
  validationSummary,
27053
+ refineStages,
25394
27054
  finalBranchConvergenceState: {
25395
27055
  branch,
25396
27056
  baseBranch,
@@ -25401,37 +27061,121 @@ var DaemonCommandRouter = class {
25401
27061
  }
25402
27062
  };
25403
27063
  }
27064
+ const patchEquivalenceStarted = Date.now();
27065
+ const patchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
27066
+ recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
27067
+ equivalent: patchEquivalence.equivalent,
27068
+ expectedPatchId: patchEquivalence.expectedPatchId,
27069
+ actualPatchId: patchEquivalence.actualPatchId,
27070
+ error: patchEquivalence.error
27071
+ });
27072
+ if (!patchEquivalence.equivalent) {
27073
+ return {
27074
+ success: false,
27075
+ code: "patch_equivalence_failed",
27076
+ convergenceStatus: "blocked_review",
27077
+ error: "Refinery patch-equivalence preflight failed; merge/refine was not attempted.",
27078
+ branch,
27079
+ into: baseBranch,
27080
+ validationSummary,
27081
+ patchEquivalence,
27082
+ refineStages,
27083
+ finalBranchConvergenceState: {
27084
+ branch,
27085
+ baseBranch,
27086
+ merged: false,
27087
+ removed: false,
27088
+ validation: "passed",
27089
+ patchEquivalence: "failed",
27090
+ status: "blocked_review"
27091
+ }
27092
+ };
27093
+ }
27094
+ let mergeResult;
27095
+ const mergeStarted = Date.now();
25404
27096
  try {
25405
- await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
27097
+ const result = await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
27098
+ mergeResult = {
27099
+ stdout: truncateValidationOutput(result.stdout),
27100
+ stderr: truncateValidationOutput(result.stderr),
27101
+ durationMs: Date.now() - mergeStarted
27102
+ };
27103
+ recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
25406
27104
  } catch (e) {
27105
+ recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
27106
+ error: e?.message || String(e),
27107
+ stdout: truncateValidationOutput(e?.stdout),
27108
+ stderr: truncateValidationOutput(e?.stderr)
27109
+ });
25407
27110
  return {
25408
27111
  success: false,
25409
27112
  error: `Merge failed (conflicts?): ${e.message}`,
25410
27113
  validationSummary,
27114
+ patchEquivalence,
27115
+ refineStages,
25411
27116
  finalBranchConvergenceState: {
25412
27117
  branch,
25413
27118
  baseBranch,
25414
27119
  merged: false,
25415
27120
  removed: false,
25416
27121
  validation: "passed",
27122
+ patchEquivalence: "passed",
25417
27123
  status: "not_mergeable"
25418
27124
  }
25419
27125
  };
25420
27126
  }
27127
+ const cleanupStarted = Date.now();
25421
27128
  const removeResult = await this.execute("remove_mesh_node", {
25422
27129
  meshId,
25423
27130
  nodeId,
25424
- sessionCleanupMode: "kill",
27131
+ sessionCleanupMode: "preserve",
25425
27132
  inlineMesh: args?.inlineMesh
25426
27133
  });
27134
+ recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
27135
+ removed: removeResult?.removed,
27136
+ code: removeResult?.code,
27137
+ error: removeResult?.error
27138
+ });
27139
+ let ledgerError;
27140
+ const ledgerStarted = Date.now();
25427
27141
  try {
25428
27142
  const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
25429
27143
  appendLedgerEntry2(meshId, {
25430
27144
  kind: "node_removed",
25431
27145
  nodeId,
25432
- payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary }
27146
+ payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence }
25433
27147
  });
25434
- } catch {
27148
+ recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
27149
+ } catch (e) {
27150
+ ledgerError = e?.message || String(e);
27151
+ recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
27152
+ }
27153
+ const finalBranchConvergenceState = {
27154
+ branch: baseBranch,
27155
+ mergedBranch: branch,
27156
+ baseBranch,
27157
+ merged: true,
27158
+ removed: removeResult?.success !== false,
27159
+ validation: "passed",
27160
+ patchEquivalence: "passed",
27161
+ status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
27162
+ };
27163
+ if (removeResult?.success === false) {
27164
+ return {
27165
+ success: false,
27166
+ code: "cleanup_failed",
27167
+ error: "Refinery merge completed but worktree cleanup failed; manual cleanup/retry is required.",
27168
+ merged: true,
27169
+ branch,
27170
+ into: baseBranch,
27171
+ removeResult,
27172
+ validationSummary,
27173
+ patchEquivalence,
27174
+ mergeResult,
27175
+ refineStages,
27176
+ ...ledgerError ? { ledgerError } : {},
27177
+ finalBranchConvergenceState
27178
+ };
25435
27179
  }
25436
27180
  return {
25437
27181
  success: true,
@@ -25440,18 +27184,14 @@ var DaemonCommandRouter = class {
25440
27184
  into: baseBranch,
25441
27185
  removeResult,
25442
27186
  validationSummary,
25443
- finalBranchConvergenceState: {
25444
- branch: baseBranch,
25445
- mergedBranch: branch,
25446
- baseBranch,
25447
- merged: true,
25448
- removed: removeResult?.success !== false,
25449
- validation: "passed",
25450
- status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
25451
- }
27187
+ patchEquivalence,
27188
+ mergeResult,
27189
+ refineStages,
27190
+ ...ledgerError ? { ledgerError } : {},
27191
+ finalBranchConvergenceState
25452
27192
  };
25453
27193
  } catch (e) {
25454
- return { success: false, error: e.message };
27194
+ return { success: false, error: e.message, refineStages };
25455
27195
  }
25456
27196
  }
25457
27197
  case "remove_mesh_node": {
@@ -25492,6 +27232,7 @@ var DaemonCommandRouter = class {
25492
27232
  } else {
25493
27233
  const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25494
27234
  removed = removeNode3(meshId, nodeId);
27235
+ if (removed) this.invalidateAggregateMeshStatus(meshId);
25495
27236
  }
25496
27237
  if (removed) {
25497
27238
  try {
@@ -25526,6 +27267,8 @@ var DaemonCommandRouter = class {
25526
27267
  if (!meshId) return { success: false, error: "meshId required" };
25527
27268
  if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
25528
27269
  if (!branch) return { success: false, error: "branch required" };
27270
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "worktree clone");
27271
+ if (ownerFailure) return ownerFailure;
25529
27272
  try {
25530
27273
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
25531
27274
  const mesh = meshRecord?.mesh;
@@ -25570,6 +27313,7 @@ var DaemonCommandRouter = class {
25570
27313
  policy: { ...sourceNode.policy || {} }
25571
27314
  });
25572
27315
  if (!node) return { success: false, error: "Failed to register worktree node" };
27316
+ this.invalidateAggregateMeshStatus(meshId);
25573
27317
  }
25574
27318
  const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
25575
27319
  if (initSubmodules) {
@@ -25606,6 +27350,8 @@ var DaemonCommandRouter = class {
25606
27350
  case "trigger_mesh_queue": {
25607
27351
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25608
27352
  if (!meshId) return { success: false, error: "meshId required" };
27353
+ const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue trigger");
27354
+ if (ownerFailure) return ownerFailure;
25609
27355
  try {
25610
27356
  const { triggerMeshQueue: triggerMeshQueue2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
25611
27357
  if (meshId) {
@@ -25632,6 +27378,15 @@ var DaemonCommandRouter = class {
25632
27378
  mesh = getMesh3(meshId);
25633
27379
  }
25634
27380
  if (!mesh) return { success: false, error: "Mesh not found" };
27381
+ const meshHost = resolveMeshHostStatus(mesh);
27382
+ if (!meshHost.canOwnCoordinator) {
27383
+ return {
27384
+ success: false,
27385
+ ...buildMeshHostRequiredFailure(mesh, "coordinator launch"),
27386
+ meshId,
27387
+ cliType
27388
+ };
27389
+ }
25635
27390
  if (!Array.isArray(mesh.nodes) || mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
25636
27391
  const requestedCoordinatorNodeId = typeof args?.coordinatorNodeId === "string" ? args.coordinatorNodeId.trim() : "";
25637
27392
  const preferredCoordinatorNodeId = requestedCoordinatorNodeId || (typeof mesh.coordinator?.preferredNodeId === "string" ? mesh.coordinator.preferredNodeId.trim() : "");
@@ -25645,7 +27400,14 @@ var DaemonCommandRouter = class {
25645
27400
  cliType
25646
27401
  };
25647
27402
  }
25648
- const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
27403
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
27404
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
27405
+ const workspace = readLiveMeshNodeWorkspace({
27406
+ meshId,
27407
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
27408
+ liveSessionRecords: liveMeshSessions,
27409
+ allowCoordinatorSession: true
27410
+ }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
25649
27411
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
25650
27412
  if (!cliType) {
25651
27413
  const resolved = await resolveProviderTypeFromPriority({
@@ -25807,7 +27569,7 @@ ${block}`);
25807
27569
  workspace
25808
27570
  };
25809
27571
  }
25810
- const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
27572
+ const { existsSync: existsSync27, readFileSync: readFileSync19, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
25811
27573
  const { dirname: dirname9 } = await import("path");
25812
27574
  const mcpConfigPath = coordinatorSetup.configPath;
25813
27575
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -25850,14 +27612,14 @@ ${block}`);
25850
27612
  if (hermesManualFallback) return returnManualFallback(message);
25851
27613
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
25852
27614
  }
25853
- const hadExistingMcpConfig = existsSync25(mcpConfigPath);
27615
+ const hadExistingMcpConfig = existsSync27(mcpConfigPath);
25854
27616
  let existingMcpConfig = hermesBaseConfig?.config || {};
25855
27617
  if (hermesBaseConfig) {
25856
27618
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
25857
27619
  }
25858
27620
  if (hadExistingMcpConfig) {
25859
27621
  try {
25860
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
27622
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync19(mcpConfigPath, "utf-8"), configFormat);
25861
27623
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
25862
27624
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
25863
27625
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -25947,62 +27709,321 @@ ${block}`);
25947
27709
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
25948
27710
  const mesh = meshRecord?.mesh;
25949
27711
  if (!mesh) return { success: false, error: "Mesh not found" };
27712
+ const meshHost = resolveMeshHostStatus(mesh);
27713
+ const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
27714
+ const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
27715
+ if (!refreshRequested) {
27716
+ const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
27717
+ if (cachedStatus) {
27718
+ logRepoMeshStatusDebug("return_cached", {
27719
+ meshId,
27720
+ command: "mesh_status",
27721
+ refreshRequested,
27722
+ summary: summarizeRepoMeshStatusDebug(cachedStatus)
27723
+ });
27724
+ return cachedStatus;
27725
+ }
27726
+ }
27727
+ const refreshReason = refreshRequested ? "explicit_refresh" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
25950
27728
  const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
25951
27729
  const queue = getQueue2(meshId);
25952
27730
  const queueSummary = getMeshQueueStats2(meshId);
25953
27731
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
25954
27732
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
25955
27733
  const ledgerSummary = getLedgerSummary2(meshId);
27734
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
27735
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
27736
+ const localMachineId = loadConfig().machineId || "";
27737
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
27738
+ const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
27739
+ mesh,
27740
+ meshSource: meshRecord.source,
27741
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
27742
+ statusInstanceId: this.deps.statusInstanceId,
27743
+ localMachineId
27744
+ }) : {
27745
+ directEvidenceCount: 0,
27746
+ localConfirmedCount: 0,
27747
+ peerAttemptedCount: 0,
27748
+ peerConfirmedCount: 0,
27749
+ unavailableNodeIds: []
27750
+ };
27751
+ const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
27752
+ const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
27753
+ const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && effectiveDirectTruth.unavailableNodeIds.length === 0;
27754
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
27755
+ const failureResult = {
27756
+ success: false,
27757
+ code: "mesh_direct_peer_truth_unavailable",
27758
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct mesh_status probes succeed.",
27759
+ sourceOfTruth: {
27760
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
27761
+ coordinatorOwnsLiveTruth: false,
27762
+ currentStatus: "direct_peer_truth_unavailable",
27763
+ directPeerTruth: {
27764
+ required: true,
27765
+ satisfied: false,
27766
+ directEvidenceCount: directTruth.directEvidenceCount,
27767
+ localConfirmedCount: directTruth.localConfirmedCount,
27768
+ peerAttemptedCount: directTruth.peerAttemptedCount,
27769
+ peerConfirmedCount: directTruth.peerConfirmedCount,
27770
+ unavailableNodeIds: directTruth.unavailableNodeIds
27771
+ }
27772
+ }
27773
+ };
27774
+ logRepoMeshStatusDebug("direct_truth_unavailable", {
27775
+ meshId,
27776
+ command: "mesh_status",
27777
+ refreshRequested,
27778
+ meshSource: meshRecord.source,
27779
+ directTruth
27780
+ });
27781
+ return failureResult;
27782
+ }
27783
+ const directTruthUnavailableNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
27784
+ const selectedCoordinatorNodeId = readStringValue(
27785
+ mesh.coordinator?.preferredNodeId,
27786
+ mesh.nodes?.[0]?.id,
27787
+ mesh.nodes?.[0]?.nodeId
27788
+ );
27789
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
27790
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
25956
27791
  const nodeStatuses = [];
25957
- for (const node of mesh.nodes || []) {
27792
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
27793
+ const nodeId = String(node.id || node.nodeId || "");
27794
+ const daemonId = readStringValue(node.daemonId);
27795
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
27796
+ const isSelfNode = Boolean(
27797
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
27798
+ ) || Boolean(
27799
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
27800
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
25958
27801
  const status = {
25959
- nodeId: node.id || node.nodeId,
27802
+ nodeId,
25960
27803
  machineLabel: node.machineLabel || node.id || node.nodeId,
25961
27804
  workspace: node.workspace,
25962
27805
  repoRoot: node.repoRoot,
25963
27806
  isLocalWorktree: node.isLocalWorktree,
25964
27807
  worktreeBranch: node.worktreeBranch,
25965
- daemonId: node.daemonId,
27808
+ role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? "host" : void 0),
27809
+ daemonId,
25966
27810
  machineId: node.machineId,
27811
+ machineStatus: node.machineStatus,
25967
27812
  health: "unknown",
25968
27813
  providers: node.providers || [],
25969
- activeSessions: []
27814
+ providerPriority,
27815
+ activeSessions: [],
27816
+ activeSessionDetails: [],
27817
+ launchReady: false
25970
27818
  };
25971
- if (node.workspace && typeof node.workspace === "string") {
25972
- if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
25973
- nodeStatuses.push(status);
25974
- continue;
27819
+ if (isSelfNode) {
27820
+ status.connection = {
27821
+ perspective: "selected_coordinator",
27822
+ source: "mesh_peer_status",
27823
+ state: "self",
27824
+ transport: "local",
27825
+ reported: true,
27826
+ reason: "Selected coordinator daemon",
27827
+ lastStateChangeAt: refreshedAt
27828
+ };
27829
+ } else if (daemonId) {
27830
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
27831
+ status.connection = connection ?? {
27832
+ perspective: "selected_coordinator",
27833
+ source: "not_reported",
27834
+ state: "unknown",
27835
+ transport: "unknown",
27836
+ reported: false,
27837
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
27838
+ };
27839
+ } else {
27840
+ status.connection = {
27841
+ perspective: "selected_coordinator",
27842
+ source: "not_reported",
27843
+ state: "unknown",
27844
+ transport: "unknown",
27845
+ reported: false,
27846
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
27847
+ };
27848
+ }
27849
+ const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
27850
+ meshId,
27851
+ node,
27852
+ nodeId,
27853
+ liveSessionRecords: liveMeshSessions,
27854
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
27855
+ });
27856
+ const workspace = readLiveMeshNodeWorkspace({
27857
+ meshId,
27858
+ nodeId,
27859
+ liveSessionRecords: matchedLiveSessionRecords,
27860
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
27861
+ }) || (typeof node.workspace === "string" ? node.workspace : "");
27862
+ status.workspace = workspace || node.workspace;
27863
+ if (matchedLiveSessionRecords.length > 0) {
27864
+ const sessionIds = matchedLiveSessionRecords.map((record) => typeof record?.sessionId === "string" ? record.sessionId : "").filter(Boolean);
27865
+ const providerTypes = matchedLiveSessionRecords.map((record) => readStringValue(record?.providerType)).filter(Boolean);
27866
+ status.activeSessions = sessionIds;
27867
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
27868
+ if (providerTypes.length > 0) {
27869
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
25975
27870
  }
25976
- try {
25977
- const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4 });
25978
- status.git = gitStatus;
25979
- if (gitStatus.isGitRepo) {
25980
- const dirty = gitStatus.staged + gitStatus.modified + gitStatus.untracked + gitStatus.deleted + gitStatus.renamed > 0;
25981
- status.health = gitStatus.branch ? dirty ? "dirty" : "online" : "degraded";
25982
- } else {
25983
- status.health = "degraded";
25984
- if (gitStatus.error && !status.error) status.error = gitStatus.error;
27871
+ }
27872
+ if (workspace) {
27873
+ if (!fs10.existsSync(workspace)) {
27874
+ const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
27875
+ let remoteProbeApplied = false;
27876
+ if (inlineTransitGit) {
27877
+ status.git = inlineTransitGit;
27878
+ status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
27879
+ const connection = readObjectRecord(status.connection);
27880
+ const connectionState = readStringValue(connection.state);
27881
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
27882
+ if (!connectionReported || connectionState === "unknown") {
27883
+ status.connection = buildLivePeerGitConnection(connection, refreshedAt);
27884
+ }
27885
+ remoteProbeApplied = true;
27886
+ } else if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
27887
+ try {
27888
+ const remoteGit = await probeRemoteMeshGitStatus({
27889
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
27890
+ daemonId,
27891
+ workspace,
27892
+ timeoutMs: 8e3
27893
+ });
27894
+ if (remoteGit) {
27895
+ status.git = remoteGit;
27896
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
27897
+ const connection = readObjectRecord(status.connection);
27898
+ const connectionState = readStringValue(connection.state);
27899
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
27900
+ if (!connectionReported || connectionState === "unknown") {
27901
+ status.connection = buildLivePeerGitConnection(connection, refreshedAt);
27902
+ }
27903
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
27904
+ remoteProbeApplied = true;
27905
+ }
27906
+ } catch {
27907
+ const refreshedConnection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
27908
+ const refreshedConnectionState = readStringValue(refreshedConnection?.state);
27909
+ if (refreshedConnection && refreshedConnectionState === "connected") {
27910
+ status.connection = refreshedConnection;
27911
+ try {
27912
+ const remoteGit = await probeRemoteMeshGitStatus({
27913
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
27914
+ daemonId,
27915
+ workspace,
27916
+ timeoutMs: 12e3
27917
+ });
27918
+ if (remoteGit) {
27919
+ status.git = remoteGit;
27920
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
27921
+ const connection = readObjectRecord(status.connection);
27922
+ const connectionState = readStringValue(connection.state);
27923
+ const connectionReported = readBooleanValue(connection.reported) ?? false;
27924
+ if (!connectionReported || connectionState === "unknown") {
27925
+ status.connection = buildLivePeerGitConnection(connection, refreshedAt);
27926
+ }
27927
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
27928
+ remoteProbeApplied = true;
27929
+ }
27930
+ } catch {
27931
+ }
27932
+ }
27933
+ }
25985
27934
  }
25986
- } catch {
25987
- if (!applyCachedInlineMeshNodeStatus(status, node)) {
25988
- status.health = "degraded";
27935
+ if (!remoteProbeApplied) {
27936
+ const connectionState = readStringValue(status.connection?.state);
27937
+ const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
27938
+ if (pendingPeerGitProbe) {
27939
+ status.gitProbePending = true;
27940
+ status.health = "unknown";
27941
+ }
27942
+ if (applyCachedInlineMeshNodeStatus(
27943
+ status,
27944
+ node,
27945
+ pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
27946
+ )) {
27947
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
27948
+ nodeStatuses.push(status);
27949
+ continue;
27950
+ }
27951
+ if (meshRecord?.source === "inline_cache" && !isSelfNode) {
27952
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
27953
+ nodeStatuses.push(status);
27954
+ continue;
27955
+ }
27956
+ }
27957
+ } else {
27958
+ try {
27959
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
27960
+ status.git = gitStatus;
27961
+ recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
27962
+ if (gitStatus.isGitRepo) {
27963
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
27964
+ } else {
27965
+ status.health = "degraded";
27966
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
27967
+ }
27968
+ } catch {
27969
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
27970
+ status.health = "degraded";
27971
+ }
25989
27972
  }
25990
27973
  }
25991
27974
  } else {
25992
27975
  applyCachedInlineMeshNodeStatus(status, node);
25993
27976
  }
27977
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
25994
27978
  nodeStatuses.push(status);
25995
27979
  }
25996
- return {
27980
+ const statusResult = {
25997
27981
  success: true,
25998
27982
  meshId: mesh.id,
25999
27983
  meshName: mesh.name,
26000
27984
  repoIdentity: mesh.repoIdentity,
26001
27985
  defaultBranch: mesh.defaultBranch,
27986
+ refreshedAt,
27987
+ meshHost,
27988
+ sourceOfTruth: {
27989
+ membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
27990
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
27991
+ meshHost: {
27992
+ owner: "mesh_host_daemon",
27993
+ localRole: meshHost.role,
27994
+ hostDaemonId: meshHost.hostDaemonId,
27995
+ hostNodeId: meshHost.hostNodeId,
27996
+ hostAddress: meshHost.hostAddress
27997
+ },
27998
+ ...requireDirectPeerTruth ? {
27999
+ currentStatus: directTruthSatisfied ? "live_git_and_session_probes" : "direct_peer_truth_unavailable",
28000
+ directPeerTruth: {
28001
+ required: true,
28002
+ satisfied: directTruthSatisfied,
28003
+ directEvidenceCount: effectiveDirectTruth.directEvidenceCount,
28004
+ localConfirmedCount: effectiveDirectTruth.localConfirmedCount,
28005
+ peerAttemptedCount: effectiveDirectTruth.peerAttemptedCount,
28006
+ peerConfirmedCount: effectiveDirectTruth.peerConfirmedCount,
28007
+ unavailableNodeIds: effectiveDirectTruth.unavailableNodeIds
28008
+ }
28009
+ } : {},
28010
+ historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
28011
+ },
26002
28012
  nodes: nodeStatuses,
26003
28013
  queue: { tasks: queue, summary: queueSummary },
26004
28014
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
26005
28015
  };
28016
+ const rememberedStatus = this.rememberAggregateMeshStatus(meshId, statusResult, refreshReason);
28017
+ logRepoMeshStatusDebug("return_live", {
28018
+ meshId,
28019
+ command: "mesh_status",
28020
+ refreshRequested,
28021
+ refreshReason,
28022
+ meshSource: meshRecord.source,
28023
+ directTruth,
28024
+ summary: summarizeRepoMeshStatusDebug(rememberedStatus)
28025
+ });
28026
+ return rememberedStatus;
26006
28027
  } catch (e) {
26007
28028
  return { success: false, error: e.message };
26008
28029
  }
@@ -33933,6 +35954,8 @@ async function initDaemonComponents(config) {
33933
35954
  sessionHostControl: config.sessionHostControl,
33934
35955
  statusInstanceId: config.statusInstanceId,
33935
35956
  statusVersion: config.statusVersion,
35957
+ getMeshPeerConnectionStatus: config.getMeshPeerConnectionStatus,
35958
+ dispatchMeshCommand: config.dispatchMeshCommand,
33936
35959
  getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
33937
35960
  });
33938
35961
  poller = new AgentStreamPoller({
@@ -34060,6 +36083,8 @@ export {
34060
36083
  InMemoryGitSnapshotStore,
34061
36084
  LOG,
34062
36085
  MAX_LEDGER_SLICE_LIMIT,
36086
+ MESH_REFINE_CONFIG_LOCATIONS,
36087
+ MESH_REFINE_CONFIG_SCHEMA,
34063
36088
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
34064
36089
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
34065
36090
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
@@ -34082,6 +36107,7 @@ export {
34082
36107
  buildChatTailDeliverySignature,
34083
36108
  buildCoordinatorSystemPrompt,
34084
36109
  buildMachineInfo,
36110
+ buildMeshHostRequiredFailure,
34085
36111
  buildMeshLedgerReconciliationEvidence,
34086
36112
  buildMeshLedgerReplicaEvidence,
34087
36113
  buildP2pRelayFailurePayload,
@@ -34107,6 +36133,7 @@ export {
34107
36133
  connectCdpManager,
34108
36134
  createDebugTraceStore,
34109
36135
  createDefaultGitCommandServices,
36136
+ createDefaultMeshHostMetadata,
34110
36137
  createGitCompactSummary,
34111
36138
  createGitSnapshotStore,
34112
36139
  createGitWorkspaceMonitor,
@@ -34170,6 +36197,7 @@ export {
34170
36197
  isInternalChatMessage,
34171
36198
  isManagedStatusWaiting,
34172
36199
  isManagedStatusWorking,
36200
+ isMeshHostOwner,
34173
36201
  isP2pRelayTransportFailure,
34174
36202
  isPathInside,
34175
36203
  isSessionHostLiveRuntime,
@@ -34183,6 +36211,7 @@ export {
34183
36211
  listMeshes,
34184
36212
  listWorktrees,
34185
36213
  loadConfig,
36214
+ loadMeshRefineConfig,
34186
36215
  loadState,
34187
36216
  logCommand,
34188
36217
  markSetupComplete,
@@ -34196,6 +36225,7 @@ export {
34196
36225
  normalizeGitWorkspaceSubscriptionParams,
34197
36226
  normalizeInputEnvelope,
34198
36227
  normalizeManagedStatus,
36228
+ normalizeMeshDaemonRole,
34199
36229
  normalizeMessageParts,
34200
36230
  normalizeRepoIdentity,
34201
36231
  normalizeSessionModalFields,
@@ -34207,6 +36237,7 @@ export {
34207
36237
  prepareSessionChatTailUpdate,
34208
36238
  prepareSessionModalUpdate,
34209
36239
  probeCdpPort,
36240
+ queuePendingMeshCoordinatorEvent,
34210
36241
  readChatHistory,
34211
36242
  readLedgerEntries,
34212
36243
  readLedgerSlice,
@@ -34215,6 +36246,7 @@ export {
34215
36246
  removeNode,
34216
36247
  removeWorktree,
34217
36248
  requeueTask,
36249
+ requireMeshHostQueueOwner,
34218
36250
  resetConfig,
34219
36251
  resetDebugRuntimeConfig,
34220
36252
  resetState,
@@ -34222,6 +36254,8 @@ export {
34222
36254
  resolveCurrentGlobalInstallSurface,
34223
36255
  resolveDebugRuntimeConfig,
34224
36256
  resolveGitRepository,
36257
+ resolveMeshHostStatus,
36258
+ resolveMeshRefineValidationPlan,
34225
36259
  resolveSessionHostAppName,
34226
36260
  resolveSessionHostAppNameResolution,
34227
36261
  resolveWorktreePath,
@@ -34237,6 +36271,7 @@ export {
34237
36271
  shutdownDaemonComponents,
34238
36272
  spawnDetachedDaemonUpgradeHelper,
34239
36273
  startDaemonDevSupport,
36274
+ suggestMeshRefineConfig,
34240
36275
  summarizeGitStatus,
34241
36276
  syncMeshes,
34242
36277
  triggerMeshQueue,
@@ -34245,6 +36280,7 @@ export {
34245
36280
  updateNode,
34246
36281
  updateSessionTaskStatus,
34247
36282
  updateTaskStatus,
34248
- upsertSavedProviderSession
36283
+ upsertSavedProviderSession,
36284
+ validateMeshRefineConfig
34249
36285
  };
34250
36286
  //# sourceMappingURL=index.mjs.map