@adhdev/daemon-core 0.9.82-rc.310 → 0.9.82-rc.312

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
@@ -26,6 +26,18 @@ var __copyProps = (to, from, except, desc) => {
26
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
27
 
28
28
  // src/repo-mesh-types.ts
29
+ function normalizeMeshSchedulingStrategy(value) {
30
+ if (typeof value !== "string") return DEFAULT_MESH_SCHEDULING_STRATEGY;
31
+ const trimmed = value.trim();
32
+ return MESH_SCHEDULING_STRATEGIES.includes(trimmed) ? trimmed : DEFAULT_MESH_SCHEDULING_STRATEGY;
33
+ }
34
+ function resolveNodeSchedulingPriority(nodePolicy) {
35
+ const raw = Number(nodePolicy?.schedulingPriority);
36
+ return Number.isFinite(raw) ? raw : 0;
37
+ }
38
+ function resolveAutoConvergeCodeChange(policy) {
39
+ return policy?.autoConvergeCodeChange === true;
40
+ }
29
41
  function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
30
42
  if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
31
43
  return nodePolicy.delegatedWorkerAutoApprove;
@@ -53,10 +65,19 @@ function resolveProviderMaxParallel(nodePolicy, providerType) {
53
65
  if (!Number.isFinite(raw) || raw < 0) return void 0;
54
66
  return Math.floor(raw);
55
67
  }
56
- var DEFAULT_MESH_POLICY;
68
+ var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, DEFAULT_MESH_POLICY;
57
69
  var init_repo_mesh_types = __esm({
58
70
  "src/repo-mesh-types.ts"() {
59
71
  "use strict";
72
+ MESH_SCHEDULING_STRATEGIES = [
73
+ "first_eligible",
74
+ "least_loaded",
75
+ "round_robin",
76
+ "priority_only"
77
+ ];
78
+ DEFAULT_MESH_SCHEDULING_STRATEGY = "first_eligible";
79
+ MESH_CONVERGE_REFINE_TAG = "converge=refine";
80
+ MESH_CONVERGE_FAST_FORWARD_TAG = "converge=fast_forward";
60
81
  DEFAULT_MESH_POLICY = {
61
82
  requirePreTaskCheckpoint: false,
62
83
  requirePostTaskCheckpoint: true,
@@ -290,10 +311,10 @@ function readInjected(value) {
290
311
  }
291
312
  function getDaemonBuildInfo() {
292
313
  if (cached) return cached;
293
- const commit = readInjected(true ? "33fe83f72a43bccb1b4bec7744ee5c6d8c11a325" : void 0) ?? "unknown";
294
- const commitShort = readInjected(true ? "33fe83f7" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
295
- const version = readInjected(true ? "0.9.82-rc.310" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
296
- const builtAt = readInjected(true ? "2026-06-17T09:34:54.806Z" : void 0);
314
+ const commit = readInjected(true ? "35facf0367dbbe37f25a3b5589287dc757ee6213" : void 0) ?? "unknown";
315
+ const commitShort = readInjected(true ? "35facf03" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
+ const version = readInjected(true ? "0.9.82-rc.312" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
+ const builtAt = readInjected(true ? "2026-06-17T22:48:50.124Z" : void 0);
297
318
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
298
319
  return cached;
299
320
  }
@@ -1543,6 +1564,17 @@ function mergeMeshPolicy(base, patch) {
1543
1564
  if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
1544
1565
  policy.spawnedSessionVisibility = "visible";
1545
1566
  }
1567
+ const normalizedStrategy = normalizeMeshSchedulingStrategy(policy.schedulingStrategy);
1568
+ if (normalizedStrategy === "first_eligible") {
1569
+ delete policy.schedulingStrategy;
1570
+ } else {
1571
+ policy.schedulingStrategy = normalizedStrategy;
1572
+ }
1573
+ if (policy.autoConvergeCodeChange === true) {
1574
+ policy.autoConvergeCodeChange = true;
1575
+ } else {
1576
+ delete policy.autoConvergeCodeChange;
1577
+ }
1546
1578
  return policy;
1547
1579
  }
1548
1580
  function normalizeAutoFastForwardPolicy(value) {
@@ -2081,6 +2113,7 @@ var init_coordinator_prompt = __esm({
2081
2113
  | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
2082
2114
  | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
2083
2115
  | \`mesh_git_status\` | Check git status on a specific node |
2116
+ | \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) \u2014 no session/PowerShell needed to debug a node's daemon |
2084
2117
  | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
2085
2118
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
2086
2119
  | \`mesh_approve\` | Approve/reject a pending agent action |
@@ -2833,6 +2866,7 @@ __export(mesh_work_queue_exports, {
2833
2866
  recordMeshToolCall: () => recordMeshToolCall,
2834
2867
  recordTaskAutoLaunch: () => recordTaskAutoLaunch,
2835
2868
  requeueTask: () => requeueTask,
2869
+ resolveConvergeRequiredTags: () => resolveConvergeRequiredTags,
2836
2870
  updateDirectDispatchStatus: () => updateDirectDispatchStatus,
2837
2871
  updateSessionTaskStatus: () => updateSessionTaskStatus,
2838
2872
  updateTaskStatus: () => updateTaskStatus,
@@ -2907,6 +2941,21 @@ function firstProviderPriority(policy) {
2907
2941
  if (!Array.isArray(raw)) return void 0;
2908
2942
  return raw.find((type) => typeof type === "string" && type.trim())?.trim();
2909
2943
  }
2944
+ function roleCapabilityTags(policy, providerType) {
2945
+ const roles = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerRoles : void 0;
2946
+ if (!Array.isArray(roles)) return [];
2947
+ const wantedProvider = typeof providerType === "string" && providerType.trim() ? providerType.trim().toLowerCase() : "";
2948
+ const out = [];
2949
+ for (const entry of roles) {
2950
+ if (!entry || typeof entry !== "object") continue;
2951
+ const type = typeof entry.providerType === "string" ? entry.providerType.trim().toLowerCase() : "";
2952
+ const role = typeof entry.role === "string" ? entry.role.trim().toLowerCase() : "";
2953
+ if (!role) continue;
2954
+ if (wantedProvider && type && type !== wantedProvider) continue;
2955
+ out.push(`role=${role}`);
2956
+ }
2957
+ return out;
2958
+ }
2910
2959
  function buildMeshNodeCapabilityTags(node, providerType) {
2911
2960
  const provider = typeof providerType === "string" && providerType.trim() ? providerType.trim() : firstProviderPriority(node?.policy);
2912
2961
  const worktreeBranch = typeof node?.worktreeBranch === "string" && node.worktreeBranch.trim() ? node.worktreeBranch.trim() : null;
@@ -2918,7 +2967,25 @@ function buildMeshNodeCapabilityTags(node, providerType) {
2918
2967
  // Worktree nodes automatically expose a "worktree=<branch>" tag so that
2919
2968
  // mesh_enqueue_task with required_tags: ["worktree=<branch>"] routes
2920
2969
  // only to the matching worktree node.
2921
- ...node?.isLocalWorktree === true && worktreeBranch ? [`worktree=${worktreeBranch}`] : []
2970
+ ...node?.isLocalWorktree === true && worktreeBranch ? [`worktree=${worktreeBranch}`] : [],
2971
+ // Convergence routing: advertise how this node can land its work onto base.
2972
+ // - converge=refine: local worktree nodes (on ANY machine — refine_mesh_node
2973
+ // now forwards to the owning daemon) can run the Refinery merge → push →
2974
+ // cleanup against their own checkout, so they accept code_change tasks.
2975
+ // - converge=fast_forward: non-worktree nodes (the machine itself) can only
2976
+ // ff/push an already-converged branch; they are NOT a destination for
2977
+ // code_change work (a worktree is created first, and that worktree node
2978
+ // receives the task instead). Reuses the ordinary required-tags filter —
2979
+ // the load-balancing scheduler auto-injects converge=refine for code_change
2980
+ // so such work is hard-filtered onto refine-capable nodes.
2981
+ ...node?.isLocalWorktree === true ? ["converge=refine"] : ["converge=fast_forward"],
2982
+ // Role-based routing: advertise role=<x> for each (node, provider) role
2983
+ // declared in policy.providerRoles. Narrowed to the selected provider when
2984
+ // one is given so the chosen provider must match a task's required role;
2985
+ // when no provider is selected, all declared roles are advertised for the
2986
+ // node-level eligibility scan. Reuses the ordinary required-tags filter —
2987
+ // no separate role field/gate.
2988
+ ...roleCapabilityTags(node?.policy, providerType)
2922
2989
  ]);
2923
2990
  }
2924
2991
  function nodeSatisfiesRequiredTags(requiredTags, capabilityTags) {
@@ -2927,6 +2994,18 @@ function nodeSatisfiesRequiredTags(requiredTags, capabilityTags) {
2927
2994
  const available = new Set(normalizeMeshCapabilityTags(capabilityTags));
2928
2995
  return required.every((tag) => available.has(tag));
2929
2996
  }
2997
+ function resolveConvergeRequiredTags(meshId, taskMode, explicitRequiredTags, opts) {
2998
+ if (taskMode !== "code_change") return explicitRequiredTags;
2999
+ if (typeof opts?.targetNodeId === "string" && opts.targetNodeId.trim()) return explicitRequiredTags;
3000
+ let optedIn = false;
3001
+ try {
3002
+ optedIn = resolveAutoConvergeCodeChange(getMesh(meshId)?.policy);
3003
+ } catch {
3004
+ optedIn = false;
3005
+ }
3006
+ if (!optedIn) return explicitRequiredTags;
3007
+ return normalizeMeshCapabilityTags([...explicitRequiredTags, MESH_CONVERGE_REFINE_TAG]);
3008
+ }
2930
3009
  function withQueueLock(_meshId, fn) {
2931
3010
  return MeshRuntimeStore.getInstance().transaction(fn);
2932
3011
  }
@@ -2985,7 +3064,15 @@ function enqueueTask(meshId, message, opts) {
2985
3064
  taskMode: modeValidation.taskMode,
2986
3065
  targetNodeId: opts?.targetNodeId,
2987
3066
  targetSessionId: opts?.targetSessionId,
2988
- requiredTags: normalizeMeshCapabilityTags(opts?.requiredTags),
3067
+ // Convergence routing (opt-in): auto-inject converge=refine for code_change
3068
+ // tasks so they hard-filter onto refine-capable worktree nodes. No-op unless
3069
+ // the mesh opts in; explicit target_node_id / required_tags are preserved.
3070
+ requiredTags: resolveConvergeRequiredTags(
3071
+ meshId,
3072
+ modeValidation.taskMode,
3073
+ normalizeMeshCapabilityTags(opts?.requiredTags),
3074
+ { targetNodeId: opts?.targetNodeId }
3075
+ ),
2989
3076
  ...dependsOn.length > 0 ? { dependsOn } : {},
2990
3077
  ...typeof opts?.missionId === "string" && opts.missionId.trim() ? { missionId: opts.missionId.trim() } : {},
2991
3078
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -3245,6 +3332,7 @@ var init_mesh_work_queue = __esm({
3245
3332
  "src/mesh/mesh-work-queue.ts"() {
3246
3333
  "use strict";
3247
3334
  init_mesh_host_ownership();
3335
+ init_repo_mesh_types();
3248
3336
  init_mesh_runtime_store();
3249
3337
  init_mesh_config();
3250
3338
  ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
@@ -3538,6 +3626,17 @@ var init_mesh_runtime_store = __esm({
3538
3626
 
3539
3627
  CREATE INDEX IF NOT EXISTS idx_mesh_missions_mesh_status
3540
3628
  ON mesh_missions(mesh_id, status, updated_at);
3629
+
3630
+ -- Load-balancing scheduler: per-mesh round-robin rotation cursor. When
3631
+ -- the schedulingStrategy is 'round_robin', several eligible nodes tied at
3632
+ -- the least load are rotated by this cursor so the tie-break winner cycles
3633
+ -- across scheduling passes instead of always favouring the same array-order
3634
+ -- node. Persisted (not a module Map) so rotation survives daemon restarts
3635
+ -- and stays a single source of truth across scheduling entry points.
3636
+ CREATE TABLE IF NOT EXISTS mesh_scheduler_cursor (
3637
+ mesh_id TEXT PRIMARY KEY,
3638
+ cursor INTEGER NOT NULL DEFAULT 0
3639
+ );
3541
3640
  `);
3542
3641
  }
3543
3642
  hasCompletionFingerprint(fingerprint) {
@@ -3715,6 +3814,44 @@ var init_mesh_runtime_store = __esm({
3715
3814
  `).get(meshId, nodeId);
3716
3815
  return row !== void 0;
3717
3816
  }
3817
+ /**
3818
+ * Count active (status='assigned') tasks on a node, regardless of provider or
3819
+ * task mode. This is the load metric for least-loaded / round-robin ranking:
3820
+ * the scheduler prefers the node with the fewest active assignments so
3821
+ * untargeted work spreads instead of piling onto whichever node asks first.
3822
+ */
3823
+ nodeActiveAssignmentCount(meshId, nodeId) {
3824
+ const row = this.db.prepare(`
3825
+ SELECT COUNT(*) as count FROM mesh_queue
3826
+ WHERE mesh_id = ? AND status = 'assigned' AND assigned_node_id = ?
3827
+ `).get(meshId, nodeId);
3828
+ return row?.count ?? 0;
3829
+ }
3830
+ /**
3831
+ * Read the current per-mesh round-robin cursor (0 when unset). Used to rotate
3832
+ * the tie-break winner among nodes tied at the least load.
3833
+ */
3834
+ getSchedulerCursor(meshId) {
3835
+ const row = this.db.prepare(
3836
+ "SELECT cursor FROM mesh_scheduler_cursor WHERE mesh_id = ?"
3837
+ ).get(meshId);
3838
+ return row?.cursor ?? 0;
3839
+ }
3840
+ /**
3841
+ * Atomically advance the per-mesh round-robin cursor by one and return the
3842
+ * value that was current BEFORE the bump (the value the caller should rotate
3843
+ * by for this pass). UPSERT keeps it lock-free across concurrent passes.
3844
+ */
3845
+ bumpSchedulerCursor(meshId) {
3846
+ return this.transaction(() => {
3847
+ const current = this.getSchedulerCursor(meshId);
3848
+ this.db.prepare(`
3849
+ INSERT INTO mesh_scheduler_cursor (mesh_id, cursor) VALUES (?, ?)
3850
+ ON CONFLICT(mesh_id) DO UPDATE SET cursor = excluded.cursor
3851
+ `).run(meshId, current + 1);
3852
+ return current;
3853
+ });
3854
+ }
3718
3855
  /**
3719
3856
  * Count active (status='assigned') tasks on a (node, provider) combination,
3720
3857
  * matched by the assignedProviderType stamped on the payload at claim time.
@@ -5688,8 +5825,8 @@ function stripCoordinatorWrapperFile(filePath) {
5688
5825
  const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
5689
5826
  if (!remaining.trim()) {
5690
5827
  try {
5691
- const fs30 = __require("fs");
5692
- fs30.unlinkSync(filePath);
5828
+ const fs31 = __require("fs");
5829
+ fs31.unlinkSync(filePath);
5693
5830
  } catch {
5694
5831
  }
5695
5832
  } else {
@@ -8286,6 +8423,33 @@ function activeReadonlyAssignedCount(meshId) {
8286
8423
  function nodeHasActiveAssignment(meshId, nodeId) {
8287
8424
  return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedNodeId === nodeId);
8288
8425
  }
8426
+ function nodeActiveLoad(meshId, nodeId) {
8427
+ return MeshRuntimeStore.getInstance().nodeActiveAssignmentCount(meshId, nodeId);
8428
+ }
8429
+ function resolveSchedulingStrategy(mesh) {
8430
+ return normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
8431
+ }
8432
+ function orderEligibleNodes(meshId, strategy, nodes, opts) {
8433
+ if (strategy === "first_eligible" || nodes.length <= 1) {
8434
+ return nodes;
8435
+ }
8436
+ const priorityOf = (n) => resolveNodeSchedulingPriority(n.node?.policy);
8437
+ let rotation = 0;
8438
+ if (strategy === "round_robin") {
8439
+ const cursor = opts?.bumpCursor ? MeshRuntimeStore.getInstance().bumpSchedulerCursor(meshId) : MeshRuntimeStore.getInstance().getSchedulerCursor(meshId);
8440
+ rotation = (cursor % nodes.length + nodes.length) % nodes.length;
8441
+ }
8442
+ const rotationRank = (index) => (index - rotation + nodes.length) % nodes.length;
8443
+ return [...nodes].sort((a, b) => {
8444
+ const prioDelta = priorityOf(b) - priorityOf(a);
8445
+ if (prioDelta !== 0) return prioDelta;
8446
+ if (strategy === "least_loaded" || strategy === "round_robin") {
8447
+ const loadDelta = nodeActiveLoad(meshId, a.nodeId) - nodeActiveLoad(meshId, b.nodeId);
8448
+ if (loadDelta !== 0) return loadDelta;
8449
+ }
8450
+ return rotationRank(a.index) - rotationRank(b.index);
8451
+ });
8452
+ }
8289
8453
  function activeProviderAssignedCount(meshId, nodeId, providerType) {
8290
8454
  return getQueue(meshId, { status: ["assigned"] }).filter((task) => task.assignedNodeId === nodeId && task.assignedProviderType === providerType).length;
8291
8455
  }
@@ -8422,7 +8586,14 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
8422
8586
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "no_node_satisfies_required_tags", nodeId: task.targetNodeId });
8423
8587
  continue;
8424
8588
  }
8425
- for (const node of candidateNodes) {
8589
+ const strategy = resolveSchedulingStrategy(mesh);
8590
+ const orderedCandidateNodes = strategy === "first_eligible" ? candidateNodes : orderEligibleNodes(
8591
+ meshId,
8592
+ strategy,
8593
+ candidateNodes.map((node, index) => ({ nodeId: readMeshNodeId(node), node, index })).filter((c) => c.nodeId),
8594
+ { bumpCursor: true }
8595
+ ).map((c) => c.node);
8596
+ for (const node of orderedCandidateNodes) {
8426
8597
  const nodeId = readMeshNodeId(node);
8427
8598
  if (!nodeId) continue;
8428
8599
  const launchKey = `${meshId}:${nodeId}`;
@@ -8549,6 +8720,8 @@ async function triggerMeshQueue(components, meshId) {
8549
8720
  noIdleMeshSessionAvailable: true
8550
8721
  };
8551
8722
  }
8723
+ const strategy = resolveSchedulingStrategy(mesh);
8724
+ const localCandidates = [];
8552
8725
  const cliInstances = components.instanceManager.getByCategory("cli");
8553
8726
  for (const inst of cliInstances) {
8554
8727
  const state = inst.getState();
@@ -8571,7 +8744,7 @@ async function triggerMeshQueue(components, meshId) {
8571
8744
  const providerType = state.type || readNonEmptyString2(settings.providerType);
8572
8745
  if (providerType) {
8573
8746
  localIdleSessionsChecked += 1;
8574
- tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
8747
+ localCandidates.push({ nodeId, sessionId, providerType, origin: "local", node: mesh.nodes.find((n) => readMeshNodeId(n) === nodeId) });
8575
8748
  } else {
8576
8749
  skippedSessions.push({
8577
8750
  nodeId,
@@ -8585,18 +8758,49 @@ async function triggerMeshQueue(components, meshId) {
8585
8758
  remoteSessions = MeshRuntimeStore.getInstance().getRemoteIdleSessions();
8586
8759
  } catch {
8587
8760
  }
8761
+ const remoteCandidates = [];
8588
8762
  for (const idle of remoteSessions) {
8589
8763
  const node = mesh.nodes.find((n) => n.id === idle.nodeId);
8590
8764
  if (node) {
8591
8765
  remoteIdleSessionsChecked += 1;
8592
- const assigned = tryAssignQueueTask(components, meshId, idle.nodeId, idle.sessionId, idle.providerType);
8593
- if (assigned) {
8594
- try {
8595
- MeshRuntimeStore.getInstance().deleteRemoteIdleSession(idle.nodeId, idle.sessionId);
8596
- } catch {
8597
- }
8766
+ remoteCandidates.push({ nodeId: idle.nodeId, sessionId: idle.sessionId, providerType: idle.providerType, origin: "remote", node });
8767
+ }
8768
+ }
8769
+ const assignIdleCandidate = (candidate) => {
8770
+ const assigned = tryAssignQueueTask(components, meshId, candidate.nodeId, candidate.sessionId, candidate.providerType);
8771
+ if (assigned && candidate.origin === "remote") {
8772
+ try {
8773
+ MeshRuntimeStore.getInstance().deleteRemoteIdleSession(candidate.nodeId, candidate.sessionId);
8774
+ } catch {
8598
8775
  }
8599
8776
  }
8777
+ };
8778
+ if (strategy === "first_eligible") {
8779
+ for (const candidate of localCandidates) assignIdleCandidate(candidate);
8780
+ for (const candidate of remoteCandidates) assignIdleCandidate(candidate);
8781
+ } else {
8782
+ const pool = [...localCandidates, ...remoteCandidates];
8783
+ const baseIndex = /* @__PURE__ */ new Map();
8784
+ pool.forEach((c, i) => {
8785
+ if (!baseIndex.has(c.nodeId)) baseIndex.set(c.nodeId, i);
8786
+ });
8787
+ const uniqueNodes = [...new Set(pool.map((c) => c.nodeId))].map((nodeId, index) => ({ nodeId, node: pool.find((c) => c.nodeId === nodeId)?.node, index }));
8788
+ const ranked = orderEligibleNodes(meshId, strategy, uniqueNodes, { bumpCursor: true });
8789
+ const rankIndex = new Map(ranked.map((r, i) => [r.nodeId, i]));
8790
+ const remaining = [...pool];
8791
+ while (remaining.length > 0) {
8792
+ remaining.sort((a, b) => {
8793
+ const aPrio = resolveNodeSchedulingPriority(a.node?.policy);
8794
+ const bPrio = resolveNodeSchedulingPriority(b.node?.policy);
8795
+ if (aPrio !== bPrio) return bPrio - aPrio;
8796
+ if (strategy === "least_loaded" || strategy === "round_robin") {
8797
+ const loadDelta = nodeActiveLoad(meshId, a.nodeId) - nodeActiveLoad(meshId, b.nodeId);
8798
+ if (loadDelta !== 0) return loadDelta;
8799
+ }
8800
+ return (rankIndex.get(a.nodeId) ?? 0) - (rankIndex.get(b.nodeId) ?? 0);
8801
+ });
8802
+ assignIdleCandidate(remaining.shift());
8803
+ }
8600
8804
  }
8601
8805
  autoLaunchStarted = await maybeAutoLaunchOneQueueSession(components, meshId, mesh);
8602
8806
  const afterQueue = getQueue(meshId);
@@ -10651,8 +10855,8 @@ var init_pty_transport = __esm({
10651
10855
  let cwd = options.cwd;
10652
10856
  if (cwd) {
10653
10857
  try {
10654
- const fs30 = __require("fs");
10655
- const stat2 = fs30.statSync(cwd);
10858
+ const fs31 = __require("fs");
10859
+ const stat2 = fs31.statSync(cwd);
10656
10860
  if (!stat2.isDirectory()) cwd = os11.homedir();
10657
10861
  } catch {
10658
10862
  cwd = os11.homedir();
@@ -10761,9 +10965,9 @@ function findBinary(name) {
10761
10965
  for (const ext of exes) {
10762
10966
  const fullPath = path17.join(p, trimmed + ext);
10763
10967
  try {
10764
- const fs30 = __require("fs");
10765
- if (fs30.existsSync(fullPath)) {
10766
- const stat2 = fs30.statSync(fullPath);
10968
+ const fs31 = __require("fs");
10969
+ if (fs31.existsSync(fullPath)) {
10970
+ const stat2 = fs31.statSync(fullPath);
10767
10971
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
10768
10972
  return fullPath;
10769
10973
  }
@@ -10777,12 +10981,12 @@ function findBinary(name) {
10777
10981
  function isScriptBinary(binaryPath) {
10778
10982
  if (!path17.isAbsolute(binaryPath)) return false;
10779
10983
  try {
10780
- const fs30 = __require("fs");
10781
- const resolved = fs30.realpathSync(binaryPath);
10984
+ const fs31 = __require("fs");
10985
+ const resolved = fs31.realpathSync(binaryPath);
10782
10986
  const head = Buffer.alloc(8);
10783
- const fd = fs30.openSync(resolved, "r");
10784
- fs30.readSync(fd, head, 0, 8, 0);
10785
- fs30.closeSync(fd);
10987
+ const fd = fs31.openSync(resolved, "r");
10988
+ fs31.readSync(fd, head, 0, 8, 0);
10989
+ fs31.closeSync(fd);
10786
10990
  let i = 0;
10787
10991
  if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
10788
10992
  return head[i] === 35 && head[i + 1] === 33;
@@ -10793,12 +10997,12 @@ function isScriptBinary(binaryPath) {
10793
10997
  function looksLikeMachOOrElf(filePath) {
10794
10998
  if (!path17.isAbsolute(filePath)) return false;
10795
10999
  try {
10796
- const fs30 = __require("fs");
10797
- const resolved = fs30.realpathSync(filePath);
11000
+ const fs31 = __require("fs");
11001
+ const resolved = fs31.realpathSync(filePath);
10798
11002
  const buf = Buffer.alloc(8);
10799
- const fd = fs30.openSync(resolved, "r");
10800
- fs30.readSync(fd, buf, 0, 8, 0);
10801
- fs30.closeSync(fd);
11003
+ const fd = fs31.openSync(resolved, "r");
11004
+ fs31.readSync(fd, buf, 0, 8, 0);
11005
+ fs31.closeSync(fd);
10802
11006
  let i = 0;
10803
11007
  if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
10804
11008
  const b = buf.subarray(i);
@@ -11972,7 +12176,7 @@ var init_cli_state_engine = __esm({
11972
12176
  scheduleSettle() {
11973
12177
  if (this.settleTimer) clearTimeout(this.settleTimer);
11974
12178
  const epoch = this.responseEpoch;
11975
- const delay = Math.max(
12179
+ const delay2 = Math.max(
11976
12180
  this.timeouts.outputSettle,
11977
12181
  this.submitPendingUntil > Date.now() ? this.submitPendingUntil - Date.now() + this.timeouts.outputSettle : 0
11978
12182
  );
@@ -11980,7 +12184,7 @@ var init_cli_state_engine = __esm({
11980
12184
  this.settleTimer = null;
11981
12185
  if (epoch !== this.responseEpoch) return;
11982
12186
  this.evaluateSettled(this.transport.getSnapshot());
11983
- }, delay);
12187
+ }, delay2);
11984
12188
  }
11985
12189
  /** Called from sendMessage in transport once a turn scope is established. */
11986
12190
  onTurnStarted(turnScope) {
@@ -17795,9 +17999,9 @@ function readString6(value) {
17795
17999
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
17796
18000
  }
17797
18001
  function summarizeMessage(message) {
17798
- const oneLine = message.replace(/\s+/g, " ").trim();
17799
- const title = oneLine.length > 96 ? `${oneLine.slice(0, 93)}...` : oneLine;
17800
- return { title: title || "(untitled task)", summary: oneLine };
18002
+ const oneLine2 = message.replace(/\s+/g, " ").trim();
18003
+ const title = oneLine2.length > 96 ? `${oneLine2.slice(0, 93)}...` : oneLine2;
18004
+ return { title: title || "(untitled task)", summary: oneLine2 };
17801
18005
  }
17802
18006
  function elapsedSince(value, now) {
17803
18007
  const started = value ? new Date(value).getTime() : Number.NaN;
@@ -20903,6 +21107,11 @@ function collapseReplayAssistantTurns(messages, historyBehavior) {
20903
21107
  continue;
20904
21108
  }
20905
21109
  if (message.role === "assistant") {
21110
+ const isActivity = message.kind === "tool" || message.kind === "terminal" || message.kind === "thought";
21111
+ if (isActivity) {
21112
+ collapsed.push(message);
21113
+ continue;
21114
+ }
20906
21115
  if (sawAssistantSinceLastUser) continue;
20907
21116
  sawAssistantSinceLastUser = true;
20908
21117
  collapsed.push(message);
@@ -26046,7 +26255,8 @@ function buildReadChatCommandResult(payload, args, h) {
26046
26255
  const sessionIdHint = typeof args?.targetSessionId === "string" ? args.targetSessionId : typeof args?.sessionId === "string" ? args.sessionId : "";
26047
26256
  const providerHint = typeof args?.cliType === "string" ? args.cliType : typeof args?.providerType === "string" ? args.providerType : typeof args?.agentType === "string" ? args.agentType : "";
26048
26257
  const filteredMessages = h ? maybeHideCoordinatorPromptMessage(h, providerHint, sessionIdHint, messages) : messages;
26049
- const visibleMessages = filterUserFacingChatMessages(filteredMessages);
26258
+ const includeActivity = args?.includeActivity === true || args?.includeActivity === "true";
26259
+ const visibleMessages = includeActivity ? filteredMessages.filter((m) => isUserFacingChatMessage(m) || isActivityChatMessage(m)) : filterUserFacingChatMessages(filteredMessages);
26050
26260
  const sync = buildFullTail(visibleMessages, normalizeReadChatTailLimit(args));
26051
26261
  const hiddenMsgCount = Math.max(0, messages.length - visibleMessages.length);
26052
26262
  const preservedPayloadFields = Object.fromEntries(Object.entries(payload).filter(([key]) => shouldPreserveReadChatPayloadField(key)));
@@ -28415,6 +28625,9 @@ function normalizeProviderScriptArgs(args, scriptName) {
28415
28625
  }
28416
28626
  function buildControlScriptResult(scriptName, payload) {
28417
28627
  if (!payload || typeof payload !== "object") return {};
28628
+ if (payload.controlResult && typeof payload.controlResult === "object") {
28629
+ return { controlResult: payload.controlResult };
28630
+ }
28418
28631
  const legacyListPayload = (() => {
28419
28632
  if (Array.isArray(payload.options)) return payload;
28420
28633
  if (/^listmodels$/i.test(scriptName) && Array.isArray(payload.models)) {
@@ -29277,7 +29490,7 @@ var DaemonCommandHandler = class {
29277
29490
  return { success: false, error: "invalid type" };
29278
29491
  }
29279
29492
  const https = __require("https");
29280
- const fs30 = __require("fs");
29493
+ const fs31 = __require("fs");
29281
29494
  const path41 = __require("path");
29282
29495
  const crypto6 = __require("crypto");
29283
29496
  const REGISTRY = "https://api.adhf.dev/api/v1/registry";
@@ -29321,7 +29534,7 @@ var DaemonCommandHandler = class {
29321
29534
  if (!targetDir.startsWith(installRootResolved + path41.sep)) {
29322
29535
  return { success: false, error: "install path escaped upstream root" };
29323
29536
  }
29324
- fs30.mkdirSync(targetDir, { recursive: true });
29537
+ fs31.mkdirSync(targetDir, { recursive: true });
29325
29538
  let manifestProbe = {};
29326
29539
  try {
29327
29540
  manifestProbe = JSON.parse(manifestBody);
@@ -29346,7 +29559,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29346
29559
  }
29347
29560
  const targetFile = isV1 ? "provider.v1.json" : "provider.json";
29348
29561
  const targetPath = path41.join(targetDir, targetFile);
29349
- fs30.writeFileSync(targetPath, manifestBody, "utf-8");
29562
+ fs31.writeFileSync(targetPath, manifestBody, "utf-8");
29350
29563
  const manifestJson = JSON.parse(manifestBody);
29351
29564
  const scriptFetch = await this.fetchProviderSources(
29352
29565
  manifestJson,
@@ -29416,7 +29629,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29416
29629
  const repo = source.repo;
29417
29630
  const ref = source.ref;
29418
29631
  const https = __require("https");
29419
- const fs30 = __require("fs");
29632
+ const fs31 = __require("fs");
29420
29633
  const path41 = __require("path");
29421
29634
  function fetchJson(url, timeoutMs) {
29422
29635
  return new Promise((resolve24, reject) => {
@@ -29500,8 +29713,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29500
29713
  const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
29501
29714
  const outPath = path41.resolve(path41.join(sharedTargetDir, relInside));
29502
29715
  if (!outPath.startsWith(path41.resolve(sharedTargetDir) + path41.sep)) continue;
29503
- fs30.mkdirSync(path41.dirname(outPath), { recursive: true });
29504
- fs30.writeFileSync(outPath, body);
29716
+ fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
29717
+ fs31.writeFileSync(outPath, body);
29505
29718
  fetchedCount++;
29506
29719
  } catch (e) {
29507
29720
  errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
@@ -29539,8 +29752,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29539
29752
  errors.push(`refusing to write outside targetDir: ${entry.path}`);
29540
29753
  continue;
29541
29754
  }
29542
- fs30.mkdirSync(path41.dirname(outPath), { recursive: true });
29543
- fs30.writeFileSync(outPath, body);
29755
+ fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
29756
+ fs31.writeFileSync(outPath, body);
29544
29757
  fetchedCount++;
29545
29758
  } catch (e) {
29546
29759
  errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
@@ -29568,7 +29781,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29568
29781
  if (!["cli", "ide", "extension", "acp"].includes(category)) {
29569
29782
  return { success: false, error: `unknown category: ${category}` };
29570
29783
  }
29571
- const fs30 = __require("fs");
29784
+ const fs31 = __require("fs");
29572
29785
  const path41 = __require("path");
29573
29786
  try {
29574
29787
  const installRoot = this.getUpstreamInstallRoot();
@@ -29577,10 +29790,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29577
29790
  if (!targetDir.startsWith(installRootResolved + path41.sep)) {
29578
29791
  return { success: false, error: "refusing to delete outside upstream root" };
29579
29792
  }
29580
- if (!fs30.existsSync(targetDir)) {
29793
+ if (!fs31.existsSync(targetDir)) {
29581
29794
  return { success: false, error: "not installed" };
29582
29795
  }
29583
- fs30.rmSync(targetDir, { recursive: true, force: true });
29796
+ fs31.rmSync(targetDir, { recursive: true, force: true });
29584
29797
  if (this._ctx.providerLoader) {
29585
29798
  this._ctx.providerLoader.reload();
29586
29799
  this._ctx.providerLoader.registerToDetector();
@@ -29596,28 +29809,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29596
29809
  * the UI and by the update checker.
29597
29810
  */
29598
29811
  handleListInstalledProviders(_args) {
29599
- const fs30 = __require("fs");
29812
+ const fs31 = __require("fs");
29600
29813
  const path41 = __require("path");
29601
29814
  const installRoot = this.getUpstreamInstallRoot();
29602
- if (!fs30.existsSync(installRoot)) return { success: true, providers: [] };
29815
+ if (!fs31.existsSync(installRoot)) return { success: true, providers: [] };
29603
29816
  const CATEGORIES = ["cli", "ide", "extension", "acp"];
29604
29817
  const items = [];
29605
29818
  for (const category of CATEGORIES) {
29606
29819
  const categoryDir = path41.join(installRoot, category);
29607
- if (!fs30.existsSync(categoryDir)) continue;
29820
+ if (!fs31.existsSync(categoryDir)) continue;
29608
29821
  let entries;
29609
29822
  try {
29610
- entries = fs30.readdirSync(categoryDir);
29823
+ entries = fs31.readdirSync(categoryDir);
29611
29824
  } catch {
29612
29825
  continue;
29613
29826
  }
29614
29827
  for (const type of entries) {
29615
29828
  const v1Path = path41.join(categoryDir, type, "provider.v1.json");
29616
29829
  const v0Path = path41.join(categoryDir, type, "provider.json");
29617
- const manifestPath = fs30.existsSync(v1Path) ? v1Path : fs30.existsSync(v0Path) ? v0Path : null;
29830
+ const manifestPath = fs31.existsSync(v1Path) ? v1Path : fs31.existsSync(v0Path) ? v0Path : null;
29618
29831
  if (!manifestPath) continue;
29619
29832
  try {
29620
- const m = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
29833
+ const m = JSON.parse(fs31.readFileSync(manifestPath, "utf-8"));
29621
29834
  items.push({
29622
29835
  type,
29623
29836
  category,
@@ -29728,7 +29941,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29728
29941
  if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
29729
29942
  return { success: false, error: "name must match @[a-z0-9_-]+" };
29730
29943
  }
29731
- const fs30 = __require("fs");
29944
+ const fs31 = __require("fs");
29732
29945
  const path41 = __require("path");
29733
29946
  const { spawnSync: spawnSync2 } = __require("child_process");
29734
29947
  const file = ext.loadExternalSources();
@@ -29739,8 +29952,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29739
29952
  return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
29740
29953
  }
29741
29954
  const sourceDir = path41.join(ext.externalRoot(), requestedName);
29742
- if (!fs30.existsSync(ext.externalRoot())) fs30.mkdirSync(ext.externalRoot(), { recursive: true });
29743
- if (fs30.existsSync(sourceDir)) {
29955
+ if (!fs31.existsSync(ext.externalRoot())) fs31.mkdirSync(ext.externalRoot(), { recursive: true });
29956
+ if (fs31.existsSync(sourceDir)) {
29744
29957
  return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
29745
29958
  }
29746
29959
  const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
@@ -29750,7 +29963,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29750
29963
  });
29751
29964
  if (clone.status !== 0) {
29752
29965
  try {
29753
- fs30.rmSync(sourceDir, { recursive: true, force: true });
29966
+ fs31.rmSync(sourceDir, { recursive: true, force: true });
29754
29967
  } catch {
29755
29968
  }
29756
29969
  return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
@@ -29794,15 +30007,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
29794
30007
  const name = typeof args?.name === "string" ? args.name.trim() : "";
29795
30008
  if (!name) return { success: false, error: "name is required" };
29796
30009
  const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
29797
- const fs30 = __require("fs");
30010
+ const fs31 = __require("fs");
29798
30011
  const path41 = __require("path");
29799
30012
  const file = ext.loadExternalSources();
29800
30013
  const match = file.sources.find((s) => s.name === name);
29801
30014
  if (!match) return { success: false, error: `source "${name}" not registered` };
29802
30015
  const sourceDir = path41.join(ext.externalRoot(), name);
29803
- if (fs30.existsSync(sourceDir)) {
30016
+ if (fs31.existsSync(sourceDir)) {
29804
30017
  try {
29805
- fs30.rmSync(sourceDir, { recursive: true, force: true });
30018
+ fs31.rmSync(sourceDir, { recursive: true, force: true });
29806
30019
  } catch (e) {
29807
30020
  return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
29808
30021
  }
@@ -30265,12 +30478,12 @@ var FsmDriver = class {
30265
30478
  scheduleSpawnPrime() {
30266
30479
  const seqs = this.spec.send_on_spawn;
30267
30480
  if (!Array.isArray(seqs) || seqs.length === 0) return;
30268
- const delay = Math.max(0, this.spec.send_on_spawn_delay_ms ?? 250);
30481
+ const delay2 = Math.max(0, this.spec.send_on_spawn_delay_ms ?? 250);
30269
30482
  setTimeout(() => {
30270
30483
  for (const seq of seqs) {
30271
30484
  if (typeof seq === "string" && seq.length > 0) this.adapter.send_keys(seq);
30272
30485
  }
30273
- }, delay);
30486
+ }, delay2);
30274
30487
  }
30275
30488
  dispatch(cmd) {
30276
30489
  switch (cmd.kind) {
@@ -30636,11 +30849,11 @@ var FsmDriver = class {
30636
30849
  const armed = this.delegateTimers.has(d.id);
30637
30850
  const shouldFire = d.when_state === currentStateId;
30638
30851
  if (shouldFire && !armed) {
30639
- const delay = d.after_duration_ms ?? 0;
30852
+ const delay2 = d.after_duration_ms ?? 0;
30640
30853
  const t = setTimeout(() => {
30641
30854
  this.fireDelegate(d);
30642
30855
  this.delegateTimers.delete(d.id);
30643
- }, delay);
30856
+ }, delay2);
30644
30857
  this.delegateTimers.set(d.id, t);
30645
30858
  } else if (!shouldFire && armed) {
30646
30859
  clearTimeout(this.delegateTimers.get(d.id));
@@ -30694,7 +30907,15 @@ var FsmDriver = class {
30694
30907
  this.adapter.send_keys(a.keys);
30695
30908
  return;
30696
30909
  case "open_picker":
30697
- this.adapter.send_keys(a.trigger_keys);
30910
+ {
30911
+ const m = /^([\s\S]*?)([\r\n]+)$/.exec(a.trigger_keys);
30912
+ if (m && m[1]) {
30913
+ this.adapter.send_keys(m[1]);
30914
+ setTimeout(() => this.adapter.send_keys(m[2]), 200);
30915
+ } else {
30916
+ this.adapter.send_keys(a.trigger_keys);
30917
+ }
30918
+ }
30698
30919
  this.pickerInProgress = { control_id: ctl.id, spec: ctl };
30699
30920
  return;
30700
30921
  case "attach_image": {
@@ -30879,8 +31100,7 @@ function executeJsonl(src, input) {
30879
31100
  for (let i = 0; i < lines.length; i += 1) {
30880
31101
  const rec = lines[i];
30881
31102
  if (filter && !filter(rec)) continue;
30882
- const msg = projectMessage(rec, src.message_map, i, lines.length, mtime);
30883
- if (msg) {
31103
+ for (const msg of projectMessages(rec, src.message_map, i, lines.length, mtime)) {
30884
31104
  if (transcriptWorkspace) msg.workspace = transcriptWorkspace;
30885
31105
  messages.push(msg);
30886
31106
  }
@@ -30960,8 +31180,9 @@ function executeSqlite(src, input) {
30960
31180
  const mtime = safeMtimeMs(resolved);
30961
31181
  const messages = [];
30962
31182
  for (let i = 0; i < messageRows.length; i += 1) {
30963
- const msg = projectMessage(messageRows[i], src.message_map, i, messageRows.length, mtime);
30964
- if (msg) messages.push(msg);
31183
+ for (const msg of projectMessages(messageRows[i], src.message_map, i, messageRows.length, mtime)) {
31184
+ messages.push(msg);
31185
+ }
30965
31186
  }
30966
31187
  if (messages.length === 0) return null;
30967
31188
  return {
@@ -31359,11 +31580,42 @@ function jsonPathGet(record, expr) {
31359
31580
  }
31360
31581
  return cur;
31361
31582
  }
31362
- function projectMessage(record, map, index, total, sourceMtimeMs) {
31583
+ function projectMessages(record, map, index, total, sourceMtimeMs) {
31363
31584
  const roleRaw = jsonPathGet(record, map.role);
31364
- const contentRaw = jsonPathGet(record, map.content);
31365
31585
  const role = normalizeRole(roleRaw);
31366
- let content = stringifyContent(contentRaw);
31586
+ let receivedAt = sourceMtimeMs - (total - 1 - index) * 1e3;
31587
+ if (map.timestamp_ms) {
31588
+ const tsRaw = jsonPathGet(record, map.timestamp_ms);
31589
+ const parsed = parseTimestamp(tsRaw);
31590
+ if (parsed != null) receivedAt = parsed;
31591
+ }
31592
+ const kindRaw = map.kind ? jsonPathGet(record, map.kind) : void 0;
31593
+ const kind = typeof kindRaw === "string" && kindRaw ? kindRaw : "standard";
31594
+ const out = [];
31595
+ if (map.tools) {
31596
+ const recordTool = projectToolBlock(record, role, map.tools);
31597
+ if (recordTool) {
31598
+ out.push({ ...recordTool, receivedAt });
31599
+ return out;
31600
+ }
31601
+ }
31602
+ const contentRaw = jsonPathGet(record, map.content);
31603
+ const content = cleanContent(stringifyContent(contentRaw), map);
31604
+ if (content) out.push({ role, content, receivedAt, kind });
31605
+ if (map.tools && Array.isArray(contentRaw)) {
31606
+ let nudge = 1;
31607
+ for (const block2 of contentRaw) {
31608
+ const tool = projectToolBlock(block2, role, map.tools);
31609
+ if (tool) {
31610
+ out.push({ ...tool, receivedAt: receivedAt + nudge });
31611
+ nudge += 1;
31612
+ }
31613
+ }
31614
+ }
31615
+ return out;
31616
+ }
31617
+ function cleanContent(input, map) {
31618
+ let content = input;
31367
31619
  if (content && map.content_strip) {
31368
31620
  for (const tag of map.content_strip) {
31369
31621
  const safeTag = tag.replace(/[.+^${}()|[\]\\]/g, "\\$&");
@@ -31379,17 +31631,33 @@ function projectMessage(record, map, index, total, sourceMtimeMs) {
31379
31631
  content = content.replace(open, "").replace(close, "");
31380
31632
  }
31381
31633
  }
31382
- if (content) content = content.trim();
31383
- if (!content) return null;
31384
- let receivedAt = sourceMtimeMs - (total - 1 - index) * 1e3;
31385
- if (map.timestamp_ms) {
31386
- const tsRaw = jsonPathGet(record, map.timestamp_ms);
31387
- const parsed = parseTimestamp(tsRaw);
31388
- if (parsed != null) receivedAt = parsed;
31634
+ return content ? content.trim() : "";
31635
+ }
31636
+ var DEFAULT_TOOL_CALL_TYPES = ["tool_use", "function_call", "custom_tool_call"];
31637
+ var DEFAULT_TOOL_RESULT_TYPES = ["tool_result", "function_call_output", "custom_tool_call_output"];
31638
+ function projectToolBlock(block2, role, tmap) {
31639
+ void role;
31640
+ if (block2 == null || typeof block2 !== "object") return null;
31641
+ const typeVal = String(jsonPathGet(block2, tmap.block_type || "$.type") ?? "");
31642
+ if (!typeVal) return null;
31643
+ const callTypes = tmap.call_types ?? DEFAULT_TOOL_CALL_TYPES;
31644
+ const resultTypes = tmap.result_types ?? DEFAULT_TOOL_RESULT_TYPES;
31645
+ if (callTypes.includes(typeVal)) {
31646
+ const name = String(jsonPathGet(block2, tmap.call_name || "$.name") ?? "tool").trim() || "tool";
31647
+ const args = oneLine(stringifyContent(jsonPathGet(block2, tmap.call_args || "$.input")), 240);
31648
+ const content = args ? `\u2197 ${name}: ${args}` : `\u2197 ${name}`;
31649
+ return { role: "assistant", content, receivedAt: 0, kind: "tool" };
31650
+ }
31651
+ if (resultTypes.includes(typeVal)) {
31652
+ const result = oneLine(stringifyContent(jsonPathGet(block2, tmap.result_content || "$.content")), 600);
31653
+ if (!result) return null;
31654
+ return { role: "assistant", content: `\u2198 ${result}`, receivedAt: 0, kind: "tool" };
31389
31655
  }
31390
- const kindRaw = map.kind ? jsonPathGet(record, map.kind) : void 0;
31391
- const kind = typeof kindRaw === "string" && kindRaw ? kindRaw : "standard";
31392
- return { role, content, receivedAt, kind };
31656
+ return null;
31657
+ }
31658
+ function oneLine(s, max) {
31659
+ const flat = s.replace(/\s+/g, " ").trim();
31660
+ return flat.length > max ? flat.slice(0, max - 1) + "\u2026" : flat;
31393
31661
  }
31394
31662
  function parseTimestamp(v) {
31395
31663
  if (v == null) return null;
@@ -31530,6 +31798,9 @@ import * as fs13 from "fs";
31530
31798
  function stripAnsi3(text) {
31531
31799
  return String(text || "").replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
31532
31800
  }
31801
+ function delay(ms) {
31802
+ return new Promise((resolve24) => setTimeout(resolve24, ms));
31803
+ }
31533
31804
  var SpecCliAdapter = class _SpecCliAdapter {
31534
31805
  cliType;
31535
31806
  cliName;
@@ -31751,9 +32022,15 @@ var SpecCliAdapter = class _SpecCliAdapter {
31751
32022
  * drives the dispatch:
31752
32023
  *
31753
32024
  * send_keys → click_control (e.g. stop)
31754
- * open_picker → click_control then resolve when extract_choices
31755
- * surface; choice index comes from args.choiceIndex
31756
- * or args.choice (string label match), defaulting to 0
32025
+ * open_picker → two roles, driven by the screen, not a hardcoded list:
32026
+ * - LIST (no choice arg): open the picker, wait for it
32027
+ * to render, parse the on-screen options via
32028
+ * `extract_choices`, and return them as
32029
+ * `controlResult.options` (+ `currentValue`). This is
32030
+ * how the dashboard's Model/Mode controls learn what is
32031
+ * actually selectable in this CLI right now.
32032
+ * - SELECT (args.choiceIndex / args.choiceLabel): drive
32033
+ * the picker to that option using `submit_key`.
31757
32034
  * attach_image → attach_image dispatch; expects args.blob (data url
31758
32035
  * or base64) and args.mime
31759
32036
  *
@@ -31778,11 +32055,128 @@ var SpecCliAdapter = class _SpecCliAdapter {
31778
32055
  this.driver.dispatch({ kind: "attach_image", blob, mime });
31779
32056
  return Promise.resolve({ ok: true, effects: [{ type: "attached_image", controlId: ctl.id }] });
31780
32057
  }
32058
+ if (action.type === "open_picker") {
32059
+ const choiceIndex = typeof flat.choiceIndex === "number" ? flat.choiceIndex : typeof flat.choiceIndex === "string" && flat.choiceIndex.trim() ? Number(flat.choiceIndex) : void 0;
32060
+ const choiceLabel = typeof flat.choiceLabel === "string" ? flat.choiceLabel : typeof flat.choice === "string" ? flat.choice : void 0;
32061
+ if (typeof choiceIndex === "number" && Number.isFinite(choiceIndex) || choiceLabel && choiceLabel.trim()) {
32062
+ return this.selectPickerChoice(ctl, action, choiceIndex, choiceLabel);
32063
+ }
32064
+ return this.openPickerAndListChoices(ctl, action);
32065
+ }
31781
32066
  this.driver.dispatch({ kind: "click_control", control_id: ctl.id, payload: flat });
31782
- const effects = [];
31783
- if (action.type === "open_picker") effects.push({ type: "opened_picker", controlId: ctl.id });
31784
- else if (action.type === "send_keys") effects.push({ type: "sent_keys", controlId: ctl.id });
31785
- return Promise.resolve({ ok: true, effects });
32067
+ return Promise.resolve({ ok: true, effects: [{ type: "sent_keys", controlId: ctl.id }] });
32068
+ }
32069
+ /**
32070
+ * Open an `open_picker` control and return the options the CLI is showing,
32071
+ * parsed live from the screen via `extract_choices`. Nothing is selected —
32072
+ * the picker is left open so a follow-up SELECT invoke can commit a choice.
32073
+ */
32074
+ async openPickerAndListChoices(ctl, action) {
32075
+ this.driver.dispatch({ kind: "click_control", control_id: ctl.id });
32076
+ const ready = await this.waitForPickerRendered(action);
32077
+ const options = this.extractPickerChoices(action);
32078
+ const currentValue = options.find((o) => o.current)?.label;
32079
+ return {
32080
+ ok: true,
32081
+ effects: [{ type: "opened_picker", controlId: ctl.id }],
32082
+ controlResult: {
32083
+ options: options.map((o) => ({ value: o.label, label: o.label, current: o.current })),
32084
+ ...currentValue ? { currentValue } : {},
32085
+ source: "screen-parse",
32086
+ ...ready ? {} : { warning: "picker_render_timeout" }
32087
+ }
32088
+ };
32089
+ }
32090
+ /**
32091
+ * Drive an already-listable picker to a specific option. The option can be
32092
+ * named (choiceLabel — matched against the parsed on-screen labels) or
32093
+ * positional (choiceIndex — the on-screen number). The actual keystrokes
32094
+ * come from the spec's `submit_key` with `{index}` substituted, so the spec
32095
+ * — not this code — decides how a selection is keyed for each CLI.
32096
+ */
32097
+ async selectPickerChoice(ctl, action, choiceIndex, choiceLabel) {
32098
+ this.driver.dispatch({ kind: "click_control", control_id: ctl.id });
32099
+ await this.waitForPickerRendered(action);
32100
+ const options = this.extractPickerChoices(action);
32101
+ let index = choiceIndex;
32102
+ if ((index == null || !Number.isFinite(index)) && choiceLabel) {
32103
+ const needle = choiceLabel.trim().toLowerCase();
32104
+ const match = options.find((o) => o.label.toLowerCase().includes(needle));
32105
+ if (!match) {
32106
+ return { ok: false, error: `choice not found on screen: ${choiceLabel}`, controlResult: { options: options.map((o) => ({ value: o.label, label: o.label })) } };
32107
+ }
32108
+ index = match.index;
32109
+ }
32110
+ if (index == null || !Number.isFinite(index)) {
32111
+ return { ok: false, error: "choiceIndex or choiceLabel required to select" };
32112
+ }
32113
+ const keys = (action.submit_key || "{index}\r").replace(/\{index\}/g, String(index));
32114
+ this.driver.dispatch({ kind: "pty_write", data: keys });
32115
+ const selected = options.find((o) => o.index === index);
32116
+ return {
32117
+ ok: true,
32118
+ effects: [{ type: "selected_choice", controlId: ctl.id }],
32119
+ controlResult: {
32120
+ ok: true,
32121
+ ...selected ? { currentValue: selected.label } : {},
32122
+ selectedIndex: index
32123
+ }
32124
+ };
32125
+ }
32126
+ /** Poll the live screen until the picker's `wait_for` condition matches,
32127
+ * up to a short budget. Returns true if it rendered, false on timeout. */
32128
+ async waitForPickerRendered(action) {
32129
+ const wf = action.wait_for;
32130
+ if (!wf?.regex) {
32131
+ await delay(250);
32132
+ return true;
32133
+ }
32134
+ const re = new RegExp(wf.regex, wf.flags ?? "i");
32135
+ const deadline = Date.now() + 2500;
32136
+ while (Date.now() < deadline) {
32137
+ await delay(120);
32138
+ const hay = this.readScreenSectionText(wf.section);
32139
+ if (re.test(hay)) return true;
32140
+ }
32141
+ return false;
32142
+ }
32143
+ /** Parse the picker's `extract_choices` pattern against the live screen.
32144
+ * Each match yields { index, label, current }. `current` is true for the
32145
+ * line the CLI marks with its cursor glyph (❯ ›). Purely screen-driven —
32146
+ * no model/mode names are baked in. */
32147
+ extractPickerChoices(action) {
32148
+ const ec = action.extract_choices;
32149
+ if (!ec?.pattern) return [];
32150
+ const text = this.readScreenSectionText(ec.section);
32151
+ const out = [];
32152
+ const seen = /* @__PURE__ */ new Set();
32153
+ for (const rawLine of text.split("\n")) {
32154
+ const line = rawLine.replace(/\r$/, "");
32155
+ const m = new RegExp(ec.pattern, ec.flags ?? "").exec(line);
32156
+ if (!m) continue;
32157
+ const idx = Number(m[1]);
32158
+ if (!Number.isFinite(idx) || seen.has(idx)) continue;
32159
+ const label = (m[2] ?? "").replace(/\s+/g, " ").trim();
32160
+ if (!label) continue;
32161
+ const current = /^\s*[❯›>]/.test(line) || /[✔✓●]\s*$/.test(label);
32162
+ seen.add(idx);
32163
+ out.push({ index: idx, label, current });
32164
+ }
32165
+ return out;
32166
+ }
32167
+ /** Live text of a named screen section (or the whole screen when no
32168
+ * section is named), resolved from the driver's current sections. */
32169
+ readScreenSectionText(sectionId) {
32170
+ try {
32171
+ const sections = this.driver.getSections();
32172
+ if (sectionId && sections) {
32173
+ const hit = sections.find((s) => s.id === sectionId);
32174
+ if (hit) return hit.text;
32175
+ }
32176
+ return this.driver.getScreen();
32177
+ } catch {
32178
+ return "";
32179
+ }
31786
32180
  }
31787
32181
  getDebugSnapshot() {
31788
32182
  let screen = "";
@@ -38738,7 +39132,7 @@ var ProviderLoader = class _ProviderLoader {
38738
39132
  }
38739
39133
  if (providerDir) {
38740
39134
  try {
38741
- const fs30 = __require("fs");
39135
+ const fs31 = __require("fs");
38742
39136
  const path41 = __require("path");
38743
39137
  const candidates = [];
38744
39138
  if (Array.isArray(base.compatibility)) {
@@ -38750,13 +39144,13 @@ var ProviderLoader = class _ProviderLoader {
38750
39144
  }
38751
39145
  candidates.push(path41.join(providerDir, "specs", "default.json"));
38752
39146
  candidates.push(path41.join(providerDir, "spec.json"));
38753
- const specPath = candidates.find((p) => fs30.existsSync(p));
39147
+ const specPath = candidates.find((p) => fs31.existsSync(p));
38754
39148
  if (specPath) {
38755
39149
  resolved._resolvedSpecPath = specPath;
38756
39150
  let specControls;
38757
39151
  let nh;
38758
39152
  try {
38759
- const rawSpec = JSON.parse(fs30.readFileSync(specPath, "utf8"));
39153
+ const rawSpec = JSON.parse(fs31.readFileSync(specPath, "utf8"));
38760
39154
  specControls = rawSpec.control_bar;
38761
39155
  nh = rawSpec.native_history;
38762
39156
  } catch {
@@ -38781,7 +39175,7 @@ var ProviderLoader = class _ProviderLoader {
38781
39175
  reader = (input) => executeNativeHistory(nh, input);
38782
39176
  } else if (nh.override_path) {
38783
39177
  const overrideFile = path41.resolve(providerDir, nh.override_path);
38784
- if (fs30.existsSync(overrideFile)) {
39178
+ if (fs31.existsSync(overrideFile)) {
38785
39179
  try {
38786
39180
  registerProviderScriptRootSafely(path41.dirname(path41.dirname(providerDir)));
38787
39181
  delete __require.cache[__require.resolve(overrideFile)];
@@ -39966,7 +40360,7 @@ async function detectCurrentWorkspace(ideId) {
39966
40360
  }
39967
40361
  } else if (plat === "win32") {
39968
40362
  try {
39969
- const fs30 = __require("fs");
40363
+ const fs31 = __require("fs");
39970
40364
  const appNameMap = getMacAppIdentifiers();
39971
40365
  const appName = appNameMap[ideId];
39972
40366
  if (appName) {
@@ -39975,8 +40369,8 @@ async function detectCurrentWorkspace(ideId) {
39975
40369
  appName,
39976
40370
  "storage.json"
39977
40371
  );
39978
- if (fs30.existsSync(storagePath)) {
39979
- const data = JSON.parse(fs30.readFileSync(storagePath, "utf-8"));
40372
+ if (fs31.existsSync(storagePath)) {
40373
+ const data = JSON.parse(fs31.readFileSync(storagePath, "utf-8"));
39980
40374
  const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
39981
40375
  if (workspaces.length > 0) {
39982
40376
  const recent = workspaces[0];
@@ -40308,6 +40702,210 @@ cleanOldFiles();
40308
40702
  // src/commands/router.ts
40309
40703
  init_logger();
40310
40704
  import * as yaml3 from "js-yaml";
40705
+
40706
+ // src/logging/log-tail-reader.ts
40707
+ init_logger();
40708
+ import * as fs23 from "fs";
40709
+ var DEFAULT_TAIL_BYTES = 64 * 1024;
40710
+ var MAX_TAIL_BYTES = 128 * 1024;
40711
+ var READ_CHUNK_BYTES = 64 * 1024;
40712
+ function resolveLogPath(date) {
40713
+ if (date instanceof Date) return getCurrentDaemonLogPath(date);
40714
+ if (typeof date === "string" && date.trim()) {
40715
+ const parsed = /* @__PURE__ */ new Date(`${date.trim()}T00:00:00.000Z`);
40716
+ if (!Number.isNaN(parsed.getTime())) return getCurrentDaemonLogPath(parsed);
40717
+ }
40718
+ return getCurrentDaemonLogPath();
40719
+ }
40720
+ function clampTailBytes(tailBytes) {
40721
+ if (!Number.isFinite(tailBytes) || tailBytes <= 0) return DEFAULT_TAIL_BYTES;
40722
+ return Math.min(Math.floor(tailBytes), MAX_TAIL_BYTES);
40723
+ }
40724
+ function readByteBoundedTail(filePath, limitBytes) {
40725
+ const fd = fs23.openSync(filePath, "r");
40726
+ try {
40727
+ const stat2 = fs23.fstatSync(fd);
40728
+ const size = stat2.size;
40729
+ if (size === 0) return { text: "", truncated: false, bytesReturned: 0 };
40730
+ const want = Math.min(limitBytes, size);
40731
+ let start = size - want;
40732
+ const truncated = start > 0;
40733
+ const buffers = [];
40734
+ let position = start;
40735
+ while (position < size) {
40736
+ const chunkSize = Math.min(READ_CHUNK_BYTES, size - position);
40737
+ const chunk = Buffer.alloc(chunkSize);
40738
+ fs23.readSync(fd, chunk, 0, chunkSize, position);
40739
+ buffers.push(chunk);
40740
+ position += chunkSize;
40741
+ }
40742
+ let buf = Buffer.concat(buffers);
40743
+ if (truncated) {
40744
+ const firstNewline = buf.indexOf(10);
40745
+ if (firstNewline >= 0) {
40746
+ buf = buf.subarray(firstNewline + 1);
40747
+ }
40748
+ }
40749
+ return { text: buf.toString("utf-8"), truncated, bytesReturned: buf.length };
40750
+ } finally {
40751
+ fs23.closeSync(fd);
40752
+ }
40753
+ }
40754
+ function parseLineEpochMs(line, fileDate) {
40755
+ const m = line.match(/^\[(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?\]/);
40756
+ if (!m) {
40757
+ const iso = line.match(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?/);
40758
+ if (iso) {
40759
+ const t = Date.parse(iso[0].replace(" ", "T"));
40760
+ return Number.isNaN(t) ? null : t;
40761
+ }
40762
+ return null;
40763
+ }
40764
+ const d = new Date(fileDate);
40765
+ d.setHours(Number(m[1]), Number(m[2]), Number(m[3]), m[4] ? Number(m[4].padEnd(3, "0")) : 0);
40766
+ return d.getTime();
40767
+ }
40768
+ function readDaemonLogTail(args = {}) {
40769
+ const platform10 = process.platform;
40770
+ const limitBytes = clampTailBytes(args.tailBytes);
40771
+ let logPath = resolveLogPath(args.date);
40772
+ if (!fs23.existsSync(logPath)) {
40773
+ const backup = logPath.replace(/\.log$/, ".1.log");
40774
+ if (fs23.existsSync(backup)) {
40775
+ logPath = backup;
40776
+ } else {
40777
+ return {
40778
+ success: false,
40779
+ error: `No daemon log file at ${logPath} (dir: ${getDaemonLogDir()})`,
40780
+ lines: [],
40781
+ truncated: false,
40782
+ logPath,
40783
+ platform: platform10,
40784
+ bytesReturned: 0,
40785
+ filtered: false
40786
+ };
40787
+ }
40788
+ }
40789
+ let raw;
40790
+ try {
40791
+ raw = readByteBoundedTail(logPath, limitBytes);
40792
+ } catch (e) {
40793
+ return {
40794
+ success: false,
40795
+ error: `Failed to read ${logPath}: ${e?.message ?? String(e)}`,
40796
+ lines: [],
40797
+ truncated: false,
40798
+ logPath,
40799
+ platform: platform10,
40800
+ bytesReturned: 0,
40801
+ filtered: false
40802
+ };
40803
+ }
40804
+ let lines = raw.text.split("\n");
40805
+ if (lines.length && lines[lines.length - 1] === "") lines.pop();
40806
+ const rawCount = lines.length;
40807
+ if (Number.isFinite(args.sinceMs)) {
40808
+ const fileDate = args.date instanceof Date ? args.date : typeof args.date === "string" && args.date.trim() ? /* @__PURE__ */ new Date(`${args.date.trim()}T00:00:00.000Z`) : /* @__PURE__ */ new Date();
40809
+ const floor = args.sinceMs;
40810
+ lines = lines.filter((line) => {
40811
+ const ts2 = parseLineEpochMs(line, fileDate);
40812
+ return ts2 === null || ts2 >= floor;
40813
+ });
40814
+ }
40815
+ let appliedGrep;
40816
+ if (typeof args.grep === "string" && args.grep.trim()) {
40817
+ appliedGrep = args.grep.trim();
40818
+ let re = null;
40819
+ try {
40820
+ re = new RegExp(appliedGrep, "i");
40821
+ } catch {
40822
+ re = null;
40823
+ }
40824
+ if (re) {
40825
+ const compiled = re;
40826
+ lines = lines.filter((line) => compiled.test(line));
40827
+ } else {
40828
+ const needle = appliedGrep.toLowerCase();
40829
+ lines = lines.filter((line) => line.toLowerCase().includes(needle));
40830
+ }
40831
+ }
40832
+ return {
40833
+ success: true,
40834
+ lines,
40835
+ truncated: raw.truncated,
40836
+ logPath,
40837
+ platform: platform10,
40838
+ bytesReturned: raw.bytesReturned,
40839
+ filtered: lines.length !== rawCount,
40840
+ ...appliedGrep ? { grep: appliedGrep } : {}
40841
+ };
40842
+ }
40843
+
40844
+ // src/logging/log-redactor.ts
40845
+ var MASK = "\u2022\u2022\u2022\u2022redacted";
40846
+ function maskKeepTail(token) {
40847
+ if (token.length <= 8) return MASK;
40848
+ return `${MASK}${token.slice(-4)}`;
40849
+ }
40850
+ var RULES = [
40851
+ // `JWT_SECRET=...`, `TOKEN=...`, `API_KEY=...`, `password: ...` env/config dumps.
40852
+ // Captures the key + delimiter and masks only the value.
40853
+ {
40854
+ name: "key_value_secret",
40855
+ pattern: /\b([A-Z0-9_]*(?:SECRET|TOKEN|API[_-]?KEY|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CREDENTIAL|CLIENT[_-]?SECRET)[A-Z0-9_]*)(\s*[:=]\s*)(["']?)([^\s"',;]+)\3/gi,
40856
+ replace: (_m, key, delim, quote) => `${key}${delim}${quote}${MASK}${quote}`
40857
+ },
40858
+ // Authorization: Bearer <token>
40859
+ {
40860
+ name: "bearer_token",
40861
+ pattern: /\b(Bearer\s+)([A-Za-z0-9._\-+/=]{8,})/g,
40862
+ replace: (_m, prefix, token) => `${prefix}${maskKeepTail(token)}`
40863
+ },
40864
+ // ADHDev credential prefixes: API key (adk_), machine secret (adm_), provider key (adp_).
40865
+ {
40866
+ name: "adhdev_prefixed_secret",
40867
+ pattern: /\b(ad[kmp]_)([A-Za-z0-9]{6,})/g,
40868
+ replace: (_m, prefix, token) => `${prefix}${maskKeepTail(prefix + token)}`
40869
+ },
40870
+ // JWT: three base64url segments separated by dots, header starts with eyJ.
40871
+ {
40872
+ name: "jwt",
40873
+ pattern: /\beyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}/g,
40874
+ replace: () => MASK
40875
+ },
40876
+ // TURN credential: a long credential value following a `credential` key in
40877
+ // any common shape — `credential: x`, `credential=x`, or `credential "x"`.
40878
+ // Mask the credential value only, preserving the key + delimiter/quote.
40879
+ {
40880
+ name: "turn_credential",
40881
+ pattern: /\b(credential["']?\s*(?:[:=]\s*)?["']?)([^\s"',;]{6,})/gi,
40882
+ replace: (_m, prefix) => `${prefix}${MASK}`
40883
+ },
40884
+ // TURN REST username:credential of the form `<expiry-ts>:<base64hmac>`,
40885
+ // where the hmac part is long base64. Mask the hmac.
40886
+ {
40887
+ name: "turn_rest_pair",
40888
+ pattern: /\b(\d{10,}:)([A-Za-z0-9+/]{20,}={0,2})\b/g,
40889
+ replace: (_m, prefix) => `${prefix}${MASK}`
40890
+ }
40891
+ ];
40892
+ function redactLogLine(line) {
40893
+ if (!line) return line;
40894
+ let out = line;
40895
+ for (const rule of RULES) {
40896
+ try {
40897
+ out = out.replace(rule.pattern, rule.replace);
40898
+ } catch {
40899
+ }
40900
+ }
40901
+ return out;
40902
+ }
40903
+ function redactLogLines(lines) {
40904
+ return lines.map((line) => redactLogLine(line));
40905
+ }
40906
+ var LOG_REDACTION_RULE_NAMES = RULES.map((r) => r.name);
40907
+
40908
+ // src/commands/router.ts
40311
40909
  init_mesh_coordinator();
40312
40910
  init_mesh_events();
40313
40911
  init_mesh_routing();
@@ -40404,7 +41002,7 @@ function orderMeshRefineBatchNodes(changeAreas) {
40404
41002
 
40405
41003
  // src/mesh/preview-freshness.ts
40406
41004
  import { execFileSync as execFileSync4 } from "child_process";
40407
- import { existsSync as existsSync33, readFileSync as readFileSync25 } from "fs";
41005
+ import { existsSync as existsSync34, readFileSync as readFileSync25 } from "fs";
40408
41006
  import { resolve as resolve19 } from "path";
40409
41007
  var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
40410
41008
  function runGit2(repoRoot, args) {
@@ -40421,7 +41019,7 @@ function runGit2(repoRoot, args) {
40421
41019
  }
40422
41020
  function readRecord6(repoRoot) {
40423
41021
  const path41 = resolve19(repoRoot, PREVIEW_DEPLOY_RECORD);
40424
- if (!existsSync33(path41)) return null;
41022
+ if (!existsSync34(path41)) return null;
40425
41023
  try {
40426
41024
  const parsed = JSON.parse(readFileSync25(path41, "utf8"));
40427
41025
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
@@ -40488,7 +41086,7 @@ function buildPreviewFreshness(repoRoot) {
40488
41086
  init_mesh_refine_status();
40489
41087
 
40490
41088
  // src/mesh/mesh-init.ts
40491
- import { existsSync as existsSync34, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
41089
+ import { existsSync as existsSync35, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
40492
41090
  import { dirname as dirname7, join as join37 } from "path";
40493
41091
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
40494
41092
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
@@ -40511,14 +41109,14 @@ function writeConfigFile(workspace, relativePath, config) {
40511
41109
  }
40512
41110
  function suggestMeshWorktreeBootstrapConfig(workspace) {
40513
41111
  const commands = [];
40514
- const hasPackageJson = existsSync34(join37(workspace, "package.json"));
40515
- const hasNpmLock = existsSync34(join37(workspace, "package-lock.json"));
41112
+ const hasPackageJson = existsSync35(join37(workspace, "package.json"));
41113
+ const hasNpmLock = existsSync35(join37(workspace, "package-lock.json"));
40516
41114
  if (hasPackageJson) {
40517
41115
  commands.push(
40518
41116
  hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
40519
41117
  );
40520
41118
  }
40521
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync34(join37(workspace, relative5)));
41119
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync35(join37(workspace, relative5)));
40522
41120
  if (!commands.length) {
40523
41121
  return { commands, staleInputs };
40524
41122
  }
@@ -40952,21 +41550,21 @@ init_build_info();
40952
41550
  // src/commands/upgrade-helper.ts
40953
41551
  import { execFileSync as execFileSync5 } from "child_process";
40954
41552
  import { spawn as spawn3 } from "child_process";
40955
- import * as fs23 from "fs";
41553
+ import * as fs24 from "fs";
40956
41554
  import * as os27 from "os";
40957
41555
  import * as path35 from "path";
40958
41556
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
40959
41557
  function getUpgradeLogPath() {
40960
41558
  const home = os27.homedir();
40961
41559
  const dir = path35.join(home, ".adhdev");
40962
- fs23.mkdirSync(dir, { recursive: true });
41560
+ fs24.mkdirSync(dir, { recursive: true });
40963
41561
  return path35.join(dir, "daemon-upgrade.log");
40964
41562
  }
40965
41563
  function appendUpgradeLog(message) {
40966
41564
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
40967
41565
  `;
40968
41566
  try {
40969
- fs23.appendFileSync(getUpgradeLogPath(), line, "utf8");
41567
+ fs24.appendFileSync(getUpgradeLogPath(), line, "utf8");
40970
41568
  } catch {
40971
41569
  }
40972
41570
  }
@@ -40974,12 +41572,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
40974
41572
  const binDir = path35.dirname(nodeExecutable);
40975
41573
  if (platform10 === "win32") {
40976
41574
  const npmCliPath = path35.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
40977
- if (fs23.existsSync(npmCliPath)) {
41575
+ if (fs24.existsSync(npmCliPath)) {
40978
41576
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
40979
41577
  }
40980
41578
  for (const candidate of ["npm.exe", "npm"]) {
40981
41579
  const candidatePath = path35.join(binDir, candidate);
40982
- if (fs23.existsSync(candidatePath)) {
41580
+ if (fs24.existsSync(candidatePath)) {
40983
41581
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
40984
41582
  }
40985
41583
  }
@@ -40987,7 +41585,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
40987
41585
  }
40988
41586
  for (const candidate of ["npm"]) {
40989
41587
  const candidatePath = path35.join(binDir, candidate);
40990
- if (fs23.existsSync(candidatePath)) {
41588
+ if (fs24.existsSync(candidatePath)) {
40991
41589
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
40992
41590
  }
40993
41591
  }
@@ -40997,12 +41595,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
40997
41595
  if (!currentCliPath) return null;
40998
41596
  let resolvedPath = currentCliPath;
40999
41597
  try {
41000
- resolvedPath = fs23.realpathSync.native(currentCliPath);
41598
+ resolvedPath = fs24.realpathSync.native(currentCliPath);
41001
41599
  } catch {
41002
41600
  }
41003
41601
  let currentDir = resolvedPath;
41004
41602
  try {
41005
- if (fs23.statSync(resolvedPath).isFile()) {
41603
+ if (fs24.statSync(resolvedPath).isFile()) {
41006
41604
  currentDir = path35.dirname(resolvedPath);
41007
41605
  }
41008
41606
  } catch {
@@ -41011,8 +41609,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
41011
41609
  while (true) {
41012
41610
  const packageJsonPath = path35.join(currentDir, "package.json");
41013
41611
  try {
41014
- if (fs23.existsSync(packageJsonPath)) {
41015
- const parsed = JSON.parse(fs23.readFileSync(packageJsonPath, "utf8"));
41612
+ if (fs24.existsSync(packageJsonPath)) {
41613
+ const parsed = JSON.parse(fs24.readFileSync(packageJsonPath, "utf8"));
41016
41614
  if (parsed?.name === packageName) {
41017
41615
  const normalized = currentDir.replace(/\\/g, "/");
41018
41616
  return normalized.includes("/node_modules/") ? currentDir : null;
@@ -41161,8 +41759,8 @@ async function waitForPidExit(pid, timeoutMs) {
41161
41759
  function stopSessionHostProcesses(appName) {
41162
41760
  const pidFile = path35.join(os27.homedir(), ".adhdev", `${appName}-session-host.pid`);
41163
41761
  try {
41164
- if (fs23.existsSync(pidFile)) {
41165
- const pid = Number.parseInt(fs23.readFileSync(pidFile, "utf8").trim(), 10);
41762
+ if (fs24.existsSync(pidFile)) {
41763
+ const pid = Number.parseInt(fs24.readFileSync(pidFile, "utf8").trim(), 10);
41166
41764
  if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
41167
41765
  killPid(pid);
41168
41766
  }
@@ -41170,7 +41768,7 @@ function stopSessionHostProcesses(appName) {
41170
41768
  } catch {
41171
41769
  } finally {
41172
41770
  try {
41173
- fs23.unlinkSync(pidFile);
41771
+ fs24.unlinkSync(pidFile);
41174
41772
  } catch {
41175
41773
  }
41176
41774
  }
@@ -41178,7 +41776,7 @@ function stopSessionHostProcesses(appName) {
41178
41776
  function removeDaemonPidFile() {
41179
41777
  const pidFile = path35.join(os27.homedir(), ".adhdev", "daemon.pid");
41180
41778
  try {
41181
- fs23.unlinkSync(pidFile);
41779
+ fs24.unlinkSync(pidFile);
41182
41780
  } catch {
41183
41781
  }
41184
41782
  }
@@ -41196,23 +41794,23 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
41196
41794
  if (pkgName.startsWith("@")) {
41197
41795
  const [scope, name] = pkgName.split("/");
41198
41796
  const scopeDir = path35.join(npmRoot, scope);
41199
- if (!fs23.existsSync(scopeDir)) return;
41200
- for (const entry of fs23.readdirSync(scopeDir)) {
41797
+ if (!fs24.existsSync(scopeDir)) return;
41798
+ for (const entry of fs24.readdirSync(scopeDir)) {
41201
41799
  if (!entry.startsWith(`.${name}-`)) continue;
41202
- fs23.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
41800
+ fs24.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
41203
41801
  appendUpgradeLog(`Removed stale scoped staging dir: ${path35.join(scopeDir, entry)}`);
41204
41802
  }
41205
41803
  } else {
41206
- for (const entry of fs23.readdirSync(npmRoot)) {
41804
+ for (const entry of fs24.readdirSync(npmRoot)) {
41207
41805
  if (!entry.startsWith(`.${pkgName}-`)) continue;
41208
- fs23.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
41806
+ fs24.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
41209
41807
  appendUpgradeLog(`Removed stale staging dir: ${path35.join(npmRoot, entry)}`);
41210
41808
  }
41211
41809
  }
41212
- if (fs23.existsSync(binDir)) {
41213
- for (const entry of fs23.readdirSync(binDir)) {
41810
+ if (fs24.existsSync(binDir)) {
41811
+ for (const entry of fs24.readdirSync(binDir)) {
41214
41812
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
41215
- fs23.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
41813
+ fs24.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
41216
41814
  appendUpgradeLog(`Removed stale bin staging entry: ${path35.join(binDir, entry)}`);
41217
41815
  }
41218
41816
  }
@@ -41303,7 +41901,7 @@ init_mesh_work_queue();
41303
41901
  init_repo_mesh_types();
41304
41902
  import { homedir as homedir26, hostname as osHostname } from "os";
41305
41903
  import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
41306
- import * as fs24 from "fs";
41904
+ import * as fs25 from "fs";
41307
41905
  import { execFileSync as execFileSync6 } from "child_process";
41308
41906
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
41309
41907
  var CHANNEL_SERVER_URL = {
@@ -41629,6 +42227,12 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
41629
42227
  function readInlineMeshNodeId(node) {
41630
42228
  return normalizeMeshNodeId(node) ?? "";
41631
42229
  }
42230
+ function isDeadLocalWorktreeNode(node) {
42231
+ if (node?.isLocalWorktree !== true) return false;
42232
+ const workspace = readStringValue(node?.workspace);
42233
+ if (!workspace) return false;
42234
+ return !fs25.existsSync(workspace);
42235
+ }
41632
42236
  function foldMeshNodeIdentityToCanonical(node) {
41633
42237
  if (!node || typeof node !== "object" || Array.isArray(node)) return node;
41634
42238
  const canonical = normalizeMeshNodeId(node);
@@ -41875,7 +42479,7 @@ function summarizeInlineMeshBranchConvergence(nodes) {
41875
42479
  const followUps = nodes.filter((node) => {
41876
42480
  if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
41877
42481
  const workspace = typeof node.workspace === "string" ? node.workspace : "";
41878
- if (workspace && !fs24.existsSync(workspace)) return false;
42482
+ if (workspace && !fs25.existsSync(workspace)) return false;
41879
42483
  return true;
41880
42484
  }).map((node) => {
41881
42485
  const convergence = readObjectRecord(node.branchConvergence);
@@ -42003,6 +42607,43 @@ function readMeshTimeoutEnvMs(name, defaultMs) {
42003
42607
  }
42004
42608
  var MESH_DIRECT_PROBE_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_TIMEOUT_MS", 25e3);
42005
42609
  var MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS", 25e3);
42610
+ var MESH_DIRECT_PROBE_REUSE_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_REUSE_MS", 12e3);
42611
+ var MeshGitProbeCache = class {
42612
+ constructor(reuseMs, now = Date.now) {
42613
+ this.reuseMs = reuseMs;
42614
+ this.now = now;
42615
+ }
42616
+ inflight = /* @__PURE__ */ new Map();
42617
+ recent = /* @__PURE__ */ new Map();
42618
+ key(daemonId, workspace) {
42619
+ return `${daemonId}::${workspace}`;
42620
+ }
42621
+ /**
42622
+ * Run `probe` for this peer, but reuse a fresh recent result or an in-flight
42623
+ * probe for the same key when one is available. `probe` is only invoked when
42624
+ * neither gate is satisfied.
42625
+ */
42626
+ async probe(daemonId, workspace, probe) {
42627
+ const key = this.key(daemonId, workspace);
42628
+ const cached2 = this.recent.get(key);
42629
+ if (cached2 && this.now() - cached2.at < this.reuseMs) {
42630
+ return cached2.value;
42631
+ }
42632
+ const existing = this.inflight.get(key);
42633
+ if (existing) return existing;
42634
+ const pending = (async () => {
42635
+ const result = await probe();
42636
+ if (result) this.recent.set(key, { at: this.now(), value: result });
42637
+ return result;
42638
+ })();
42639
+ this.inflight.set(key, pending);
42640
+ try {
42641
+ return await pending;
42642
+ } finally {
42643
+ if (this.inflight.get(key) === pending) this.inflight.delete(key);
42644
+ }
42645
+ }
42646
+ };
42006
42647
  async function probeRemoteMeshGitStatus(args) {
42007
42648
  if (!args.dispatchMeshCommand) return null;
42008
42649
  const remoteResult = await Promise.race([
@@ -42046,7 +42687,8 @@ async function hydrateInlineMeshDirectTruth(args) {
42046
42687
  peerAttemptedCount: 0,
42047
42688
  peerConfirmedCount: 0,
42048
42689
  standingEvidenceCount: 0,
42049
- unavailableNodeIds: []
42690
+ unavailableNodeIds: [],
42691
+ deadNodeIds: []
42050
42692
  };
42051
42693
  }
42052
42694
  const selectedCoordinatorNodeId = readStringValue(
@@ -42059,6 +42701,7 @@ async function hydrateInlineMeshDirectTruth(args) {
42059
42701
  let peerConfirmedCount = 0;
42060
42702
  let standingEvidenceCount = 0;
42061
42703
  const unavailableNodeIds = [];
42704
+ const deadNodeIds = [];
42062
42705
  for (const [nodeIndex, node] of nodes.entries()) {
42063
42706
  const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
42064
42707
  const workspace = readStringValue(node?.workspace);
@@ -42068,11 +42711,18 @@ async function hydrateInlineMeshDirectTruth(args) {
42068
42711
  ) || Boolean(
42069
42712
  daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
42070
42713
  ) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
42714
+ const isSelfDaemonNode = Boolean(
42715
+ daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
42716
+ );
42717
+ if ((isSelfNode || isSelfDaemonNode) && isDeadLocalWorktreeNode(node)) {
42718
+ deadNodeIds.push(nodeId);
42719
+ continue;
42720
+ }
42071
42721
  if (!workspace) {
42072
42722
  if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
42073
42723
  continue;
42074
42724
  }
42075
- if (fs24.existsSync(workspace)) {
42725
+ if (fs25.existsSync(workspace)) {
42076
42726
  try {
42077
42727
  const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
42078
42728
  if (localGit?.isGitRepo) {
@@ -42096,7 +42746,7 @@ async function hydrateInlineMeshDirectTruth(args) {
42096
42746
  continue;
42097
42747
  }
42098
42748
  peerAttemptedCount += 1;
42099
- const remoteGit = await probeRemoteMeshGitStatusWithRetry({
42749
+ const runProbe = () => probeRemoteMeshGitStatusWithRetry({
42100
42750
  dispatchMeshCommand: args.dispatchMeshCommand,
42101
42751
  daemonId,
42102
42752
  workspace,
@@ -42104,6 +42754,7 @@ async function hydrateInlineMeshDirectTruth(args) {
42104
42754
  retryTimeoutMs: MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
42105
42755
  getConnection: args.getMeshPeerConnectionStatus
42106
42756
  });
42757
+ const remoteGit = args.probeCache ? await args.probeCache.probe(daemonId, workspace, runProbe) : await runProbe();
42107
42758
  if (remoteGit) {
42108
42759
  recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
42109
42760
  peerConfirmedCount += 1;
@@ -42117,7 +42768,8 @@ async function hydrateInlineMeshDirectTruth(args) {
42117
42768
  peerAttemptedCount,
42118
42769
  peerConfirmedCount,
42119
42770
  standingEvidenceCount,
42120
- unavailableNodeIds
42771
+ unavailableNodeIds,
42772
+ deadNodeIds
42121
42773
  };
42122
42774
  }
42123
42775
  function summarizeMeshSessionRecord(record) {
@@ -42176,7 +42828,7 @@ function readLiveMeshNodeWorkspace(args) {
42176
42828
  }
42177
42829
  function collectLiveMeshSessionRecords(args) {
42178
42830
  const nodeWorkspace = readStringValue(args.node?.workspace);
42179
- const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs24.existsSync(nodeWorkspace);
42831
+ const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs25.existsSync(nodeWorkspace);
42180
42832
  const matches = args.liveSessionRecords.filter((record) => {
42181
42833
  const recordNodeId = readStringValue(record?.meta?.meshNodeId);
42182
42834
  if (recordNodeId && recordNodeId !== args.nodeId) return false;
@@ -42203,7 +42855,7 @@ function buildHistoricalMeshSessions(args) {
42203
42855
  const workspace = readStringValue(node?.workspace);
42204
42856
  if (nodeId) liveNodeIds.add(nodeId);
42205
42857
  if (workspace) liveWorkspaces.add(workspace);
42206
- if (nodeId && node?.isLocalWorktree === true && workspace && !fs24.existsSync(workspace)) {
42858
+ if (nodeId && node?.isLocalWorktree === true && workspace && !fs25.existsSync(workspace)) {
42207
42859
  missingLocalWorktreeNodeIds.add(nodeId);
42208
42860
  }
42209
42861
  }
@@ -42563,7 +43215,7 @@ function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
42563
43215
  if (!baseCommit || !branchCommit) return false;
42564
43216
  if (baseCommit === branchCommit) return true;
42565
43217
  try {
42566
- if (!fs24.existsSync(submoduleRepoPath)) return false;
43218
+ if (!fs25.existsSync(submoduleRepoPath)) return false;
42567
43219
  execFileSync6("git", ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
42568
43220
  execFileSync6("git", ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
42569
43221
  execFileSync6("git", ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
@@ -42680,7 +43332,7 @@ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderC
42680
43332
  return newTree || void 0;
42681
43333
  } finally {
42682
43334
  try {
42683
- fs24.rmSync(tmpIndex, { force: true });
43335
+ fs25.rmSync(tmpIndex, { force: true });
42684
43336
  } catch {
42685
43337
  }
42686
43338
  }
@@ -42755,7 +43407,7 @@ function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, g
42755
43407
  return newTree || void 0;
42756
43408
  } finally {
42757
43409
  try {
42758
- fs24.rmSync(tmpIndex, { force: true });
43410
+ fs25.rmSync(tmpIndex, { force: true });
42759
43411
  } catch {
42760
43412
  }
42761
43413
  }
@@ -42861,7 +43513,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
42861
43513
  return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
42862
43514
  };
42863
43515
  const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
42864
- if (!fs24.existsSync(worktreeSubmodulePath)) return false;
43516
+ if (!fs25.existsSync(worktreeSubmodulePath)) return false;
42865
43517
  try {
42866
43518
  await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
42867
43519
  } catch {
@@ -42884,7 +43536,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
42884
43536
  reachable: false
42885
43537
  };
42886
43538
  try {
42887
- if (!fs24.existsSync(submodulePath)) {
43539
+ if (!fs25.existsSync(submodulePath)) {
42888
43540
  entry.error = `Submodule checkout missing at ${gitlink.path}`;
42889
43541
  entry.publishRequired = true;
42890
43542
  if (options.allowAutoPublishSubmoduleMainCommits === true) {
@@ -43121,9 +43773,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
43121
43773
  return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
43122
43774
  };
43123
43775
  const dependenciesLikelyMissing = (cwd) => {
43124
- if (!fs24.existsSync(pathJoin(cwd, "package.json"))) return false;
43125
- if (fs24.existsSync(pathJoin(cwd, "node_modules"))) return false;
43126
- return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs24.existsSync(pathJoin(cwd, lock)));
43776
+ if (!fs25.existsSync(pathJoin(cwd, "package.json"))) return false;
43777
+ if (fs25.existsSync(pathJoin(cwd, "node_modules"))) return false;
43778
+ return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs25.existsSync(pathJoin(cwd, lock)));
43127
43779
  };
43128
43780
  if (runLegacyBootstrapCommands) {
43129
43781
  summary.bootstrap = { stage: "legacy" };
@@ -43225,9 +43877,9 @@ function resolveHermesUserHome() {
43225
43877
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
43226
43878
  const sourceHome = resolveHermesUserHome();
43227
43879
  const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
43228
- if (!fs24.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
43880
+ if (!fs25.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
43229
43881
  if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
43230
- const parsed = parseMeshCoordinatorMcpConfig(fs24.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
43882
+ const parsed = parseMeshCoordinatorMcpConfig(fs25.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
43231
43883
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
43232
43884
  return { config: baseConfig, sourceHome, sourceConfigPath };
43233
43885
  }
@@ -43264,9 +43916,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
43264
43916
  for (const fileName of [".env", "auth.json"]) {
43265
43917
  const sourcePath = pathJoin(sourceHome, fileName);
43266
43918
  const targetPath = pathJoin(targetHome, fileName);
43267
- if (!fs24.existsSync(sourcePath)) continue;
43919
+ if (!fs25.existsSync(sourcePath)) continue;
43268
43920
  try {
43269
- fs24.copyFileSync(sourcePath, targetPath);
43921
+ fs25.copyFileSync(sourcePath, targetPath);
43270
43922
  } catch (error) {
43271
43923
  LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
43272
43924
  }
@@ -43424,8 +44076,21 @@ var DaemonCommandRouter = class {
43424
44076
  * Allows the MCP server to query mesh data via get_mesh even when
43425
44077
  * the mesh doesn't exist in the local meshes.json file. */
43426
44078
  inlineMeshCache = /* @__PURE__ */ new Map();
44079
+ /** Tombstones for inline mesh nodes removed via remove_mesh_node, keyed by
44080
+ * meshId → set of removed nodeIds. The dashboard keeps echoing the removed
44081
+ * node in the inlineMesh it attaches to every command; without a tombstone,
44082
+ * reconcileInlineMeshCache MERGEs it straight back (resurrection). A
44083
+ * tombstoned node is skipped during reconcile only while its workspace is
44084
+ * absent from disk — a genuine re-registration (same nodeId, workspace back
44085
+ * on disk) clears the tombstone and merges normally, preserving clone
44086
+ * worktree visibility and legitimate node re-creation. */
44087
+ removedInlineMeshNodeIds = /* @__PURE__ */ new Map();
43427
44088
  /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
43428
44089
  aggregateMeshStatusCache = /* @__PURE__ */ new Map();
44090
+ /** Shared per-peer git_status probe dedup + recently-probed reuse gate.
44091
+ * Spans separate mesh_status/get_mesh calls so the dashboard auto-retry
44092
+ * loop cannot storm a slow peer with back-to-back refreshUpstream probes. */
44093
+ meshGitProbeCache = new MeshGitProbeCache(MESH_DIRECT_PROBE_REUSE_MS);
43429
44094
  /** In-memory async Refinery jobs keyed by meshId:nodeId to reject/return duplicate in-flight requests. */
43430
44095
  runningRefineJobs = /* @__PURE__ */ new Map();
43431
44096
  /** Terminal async Refinery jobs preserve a clear answer after the worktree node has been removed. */
@@ -43453,10 +44118,23 @@ var DaemonCommandRouter = class {
43453
44118
  const unavailableNodeIds = /* @__PURE__ */ new Set();
43454
44119
  const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
43455
44120
  const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
44121
+ const deadNodeIds = /* @__PURE__ */ new Set();
44122
+ for (const node of mesh.nodes) {
44123
+ if (!isDeadLocalWorktreeNode(node)) continue;
44124
+ const deadId = readInlineMeshNodeId(node);
44125
+ if (deadId) deadNodeIds.add(deadId);
44126
+ }
44127
+ let droppedDeadUnavailable = false;
43456
44128
  for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
43457
44129
  const nodeId = readStringValue(entry);
43458
- if (nodeId) unavailableNodeIds.add(nodeId);
44130
+ if (!nodeId) continue;
44131
+ if (deadNodeIds.has(nodeId)) {
44132
+ droppedDeadUnavailable = true;
44133
+ continue;
44134
+ }
44135
+ unavailableNodeIds.add(nodeId);
43459
44136
  }
44137
+ if (droppedDeadUnavailable) changed = true;
43460
44138
  const nodes = snapshot.nodes.map((statusNode) => {
43461
44139
  const nodeId = normalizeMeshNodeId(statusNode);
43462
44140
  const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
@@ -43571,7 +44249,10 @@ var DaemonCommandRouter = class {
43571
44249
  }
43572
44250
  warmInlineMeshCache(meshId, inlineMesh) {
43573
44251
  if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
43574
- const sanitizedInlineMesh = sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh));
44252
+ const sanitizedInlineMesh = this.applyInlineMeshNodeTombstones(
44253
+ meshId,
44254
+ sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
44255
+ );
43575
44256
  const cached2 = this.inlineMeshCache.get(meshId);
43576
44257
  if (cached2) {
43577
44258
  const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
@@ -43587,7 +44268,10 @@ var DaemonCommandRouter = class {
43587
44268
  const cached3 = this.getCachedInlineMesh(meshId);
43588
44269
  if (cached3) {
43589
44270
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
43590
- const merged = reconcileInlineMeshCache(cached3, inlineMesh);
44271
+ const merged = reconcileInlineMeshCache(
44272
+ cached3,
44273
+ this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
44274
+ );
43591
44275
  this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
43592
44276
  return { mesh: merged, inline: true, source: "inline_cache" };
43593
44277
  }
@@ -43638,12 +44322,49 @@ var DaemonCommandRouter = class {
43638
44322
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
43639
44323
  const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
43640
44324
  if (idx === -1) return false;
44325
+ const canonicalNodeId = readInlineMeshNodeId(mesh.nodes[idx]) || nodeId;
43641
44326
  mesh.nodes.splice(idx, 1);
43642
44327
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
43643
44328
  this.inlineMeshCache.set(meshId, mesh);
44329
+ this.tombstoneRemovedInlineMeshNode(meshId, canonicalNodeId);
44330
+ if (canonicalNodeId !== nodeId) this.tombstoneRemovedInlineMeshNode(meshId, nodeId);
43644
44331
  this.invalidateAggregateMeshStatus(meshId);
43645
44332
  return true;
43646
44333
  }
44334
+ tombstoneRemovedInlineMeshNode(meshId, nodeId) {
44335
+ if (!nodeId) return;
44336
+ let set = this.removedInlineMeshNodeIds.get(meshId);
44337
+ if (!set) {
44338
+ set = /* @__PURE__ */ new Set();
44339
+ this.removedInlineMeshNodeIds.set(meshId, set);
44340
+ }
44341
+ set.add(nodeId);
44342
+ }
44343
+ /** Filter an incoming inline mesh against this mesh's tombstones before it is
44344
+ * reconciled into the cache. A tombstoned node is dropped only while its
44345
+ * workspace is still absent from disk; if the workspace is back (genuine
44346
+ * re-registration), the tombstone is cleared and the node merges normally. */
44347
+ applyInlineMeshNodeTombstones(meshId, incoming) {
44348
+ const tombstones = this.removedInlineMeshNodeIds.get(meshId);
44349
+ if (!tombstones?.size || !incoming || typeof incoming !== "object" || !Array.isArray(incoming.nodes)) {
44350
+ return incoming;
44351
+ }
44352
+ let dropped = false;
44353
+ const nodes = incoming.nodes.filter((node) => {
44354
+ const nodeId = readInlineMeshNodeId(node);
44355
+ if (!nodeId || !tombstones.has(nodeId)) return true;
44356
+ const workspace = readStringValue(node?.workspace);
44357
+ if (workspace && fs25.existsSync(workspace)) {
44358
+ tombstones.delete(nodeId);
44359
+ return true;
44360
+ }
44361
+ dropped = true;
44362
+ return false;
44363
+ });
44364
+ if (tombstones.size === 0) this.removedInlineMeshNodeIds.delete(meshId);
44365
+ if (!dropped) return incoming;
44366
+ return { ...incoming, nodes };
44367
+ }
43647
44368
  normalizeMeshSessionCleanupMode(value) {
43648
44369
  return value === "stop" || value === "delete_stopped" || value === "stop_and_delete" || value === "preserve" ? value : "preserve";
43649
44370
  }
@@ -43666,13 +44387,13 @@ var DaemonCommandRouter = class {
43666
44387
  recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
43667
44388
  };
43668
44389
  }
43669
- const worktreeExists = fs24.existsSync(workspace);
44390
+ const worktreeExists = fs25.existsSync(workspace);
43670
44391
  const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
43671
44392
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
43672
44393
  if (!worktreeExists) {
43673
44394
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
43674
44395
  }
43675
- if (!repoRoot || !fs24.existsSync(repoRoot)) {
44396
+ if (!repoRoot || !fs25.existsSync(repoRoot)) {
43676
44397
  return {
43677
44398
  success: false,
43678
44399
  code: "mesh_worktree_cleanup_missing_source_repo",
@@ -43692,7 +44413,7 @@ var DaemonCommandRouter = class {
43692
44413
  const normalizePath = (value) => {
43693
44414
  const resolved = pathResolve2(value);
43694
44415
  try {
43695
- return fs24.realpathSync(resolved);
44416
+ return fs25.realpathSync(resolved);
43696
44417
  } catch {
43697
44418
  return resolved;
43698
44419
  }
@@ -43778,7 +44499,7 @@ var DaemonCommandRouter = class {
43778
44499
  };
43779
44500
  } catch (deinitError) {
43780
44501
  try {
43781
- fs24.rmSync(workspace, { recursive: true, force: true });
44502
+ fs25.rmSync(workspace, { recursive: true, force: true });
43782
44503
  await execFileAsync4("git", ["worktree", "prune"], {
43783
44504
  cwd: repoRoot,
43784
44505
  encoding: "utf8",
@@ -45557,8 +46278,8 @@ ${hintLines.join("\n")}` : "",
45557
46278
  if (sinceTs > 0) {
45558
46279
  return { success: true, logs: [], totalBuffered: 0 };
45559
46280
  }
45560
- if (fs24.existsSync(LOG_PATH)) {
45561
- const content = fs24.readFileSync(LOG_PATH, "utf-8");
46281
+ if (fs25.existsSync(LOG_PATH)) {
46282
+ const content = fs25.readFileSync(LOG_PATH, "utf-8");
45562
46283
  const allLines = content.split("\n");
45563
46284
  const recent = allLines.slice(-count).join("\n");
45564
46285
  return { success: true, logs: recent, totalLines: allLines.length };
@@ -46103,14 +46824,14 @@ ${hintLines.join("\n")}` : "",
46103
46824
  // Settings page in the dashboard reads/writes via these two
46104
46825
  // commands instead of going through fs from the browser.
46105
46826
  case "list_coordinator_prompts": {
46106
- const fs30 = await import("fs");
46827
+ const fs31 = await import("fs");
46107
46828
  const path41 = await import("path");
46108
46829
  const os30 = await import("os");
46109
46830
  const dir = path41.join(os30.homedir(), ".adhdev", "coordinator-prompts");
46110
46831
  const entries = {};
46111
46832
  try {
46112
- if (fs30.existsSync(dir)) {
46113
- for (const name of fs30.readdirSync(dir)) {
46833
+ if (fs31.existsSync(dir)) {
46834
+ for (const name of fs31.readdirSync(dir)) {
46114
46835
  const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
46115
46836
  const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
46116
46837
  const m = matchAppend || matchOverride;
@@ -46120,7 +46841,7 @@ ${hintLines.join("\n")}` : "",
46120
46841
  const full = path41.join(dir, name);
46121
46842
  let content = "";
46122
46843
  try {
46123
- content = fs30.readFileSync(full, "utf8");
46844
+ content = fs31.readFileSync(full, "utf8");
46124
46845
  } catch {
46125
46846
  }
46126
46847
  if (!entries[key]) entries[key] = { override: "", append: "" };
@@ -46134,7 +46855,7 @@ ${hintLines.join("\n")}` : "",
46134
46855
  return { success: true, dir, entries };
46135
46856
  }
46136
46857
  case "write_coordinator_prompt": {
46137
- const fs30 = await import("fs");
46858
+ const fs31 = await import("fs");
46138
46859
  const path41 = await import("path");
46139
46860
  const os30 = await import("os");
46140
46861
  const key = typeof args?.key === "string" ? args.key.trim() : "";
@@ -46147,11 +46868,11 @@ ${hintLines.join("\n")}` : "",
46147
46868
  const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
46148
46869
  const full = path41.join(dir, filename);
46149
46870
  try {
46150
- fs30.mkdirSync(dir, { recursive: true });
46871
+ fs31.mkdirSync(dir, { recursive: true });
46151
46872
  if (content.trim()) {
46152
- fs30.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
46153
- } else if (fs30.existsSync(full)) {
46154
- fs30.unlinkSync(full);
46873
+ fs31.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
46874
+ } else if (fs31.existsSync(full)) {
46875
+ fs31.unlinkSync(full);
46155
46876
  }
46156
46877
  return { success: true, path: full, kind, key };
46157
46878
  } catch (error) {
@@ -46328,7 +47049,8 @@ ${hintLines.join("\n")}` : "",
46328
47049
  getMeshPeerConnectionStatus: this.deps.getMeshPeerConnectionStatus,
46329
47050
  statusInstanceId: this.deps.statusInstanceId,
46330
47051
  localMachineId: loadConfig().machineId || "",
46331
- probeRemotePeers
47052
+ probeRemotePeers,
47053
+ probeCache: this.meshGitProbeCache
46332
47054
  });
46333
47055
  const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
46334
47056
  const sourceOfTruth = {
@@ -46928,10 +47650,75 @@ ${hintLines.join("\n")}` : "",
46928
47650
  });
46929
47651
  return result;
46930
47652
  }
47653
+ case "get_mesh_node_logs": {
47654
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47655
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47656
+ let nodeDaemonId;
47657
+ if (meshId && nodeId) {
47658
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47659
+ const node = meshRecord?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47660
+ nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47661
+ }
47662
+ const selfDaemonId = this.deps.statusInstanceId;
47663
+ const isRemote = nodeDaemonId && selfDaemonId && nodeDaemonId !== selfDaemonId;
47664
+ if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47665
+ const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "get_mesh_node_logs", {
47666
+ ...typeof args === "object" && args !== null ? args : {},
47667
+ _meshDirectDispatch: true
47668
+ });
47669
+ return forwarded ?? { success: false, error: "no response from remote node" };
47670
+ }
47671
+ const rawTailBytes = Number(args?.tailBytes);
47672
+ const tail = readDaemonLogTail({
47673
+ date: typeof args?.date === "string" ? args.date : void 0,
47674
+ tailBytes: Number.isFinite(rawTailBytes) ? Math.min(rawTailBytes, MAX_TAIL_BYTES) : void 0,
47675
+ grep: typeof args?.grep === "string" ? args.grep : void 0,
47676
+ sinceMs: Number.isFinite(Number(args?.sinceMs)) ? Number(args?.sinceMs) : void 0
47677
+ });
47678
+ if (!tail.success) {
47679
+ return {
47680
+ success: false,
47681
+ error: tail.error || "failed to read daemon log tail",
47682
+ nodeId,
47683
+ logPath: tail.logPath,
47684
+ platform: tail.platform
47685
+ };
47686
+ }
47687
+ const redactedLines = redactLogLines(tail.lines);
47688
+ return {
47689
+ success: true,
47690
+ nodeId,
47691
+ daemonId: selfDaemonId,
47692
+ logPath: tail.logPath,
47693
+ platform: tail.platform,
47694
+ lines: redactedLines,
47695
+ lineCount: redactedLines.length,
47696
+ truncated: tail.truncated,
47697
+ filtered: tail.filtered,
47698
+ bytesReturned: tail.bytesReturned,
47699
+ ...tail.grep ? { grep: tail.grep } : {}
47700
+ };
47701
+ }
46931
47702
  case "refine_mesh_node": {
46932
47703
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46933
47704
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
46934
47705
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
47706
+ {
47707
+ const meshRecordForForward = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47708
+ const forwardNode = meshRecordForForward?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47709
+ const nodeDaemonId = typeof forwardNode?.daemonId === "string" ? forwardNode.daemonId.trim() : void 0;
47710
+ const selfDaemonId = this.deps.statusInstanceId;
47711
+ const isRemote = nodeDaemonId && selfDaemonId && nodeDaemonId !== selfDaemonId;
47712
+ if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47713
+ const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
47714
+ const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "refine_mesh_node", {
47715
+ ...typeof args === "object" && args !== null ? args : {},
47716
+ coordinatorDaemonId: callerCoordinatorDaemonId || selfDaemonId,
47717
+ _meshDirectDispatch: true
47718
+ });
47719
+ return forwarded ?? { success: false, error: "no response from remote node" };
47720
+ }
47721
+ }
46935
47722
  const isDryRun = args?.dryRun !== false && args?.execute !== true;
46936
47723
  if (isDryRun) {
46937
47724
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
@@ -47579,15 +48366,15 @@ ${ptyResult.output.slice(-2e3)}`);
47579
48366
  }
47580
48367
  if (cliType === "codex-cli") {
47581
48368
  const repoMcpConfigPath = pathJoin(workspace, ".mcp.json");
47582
- if (fs24.existsSync(repoMcpConfigPath)) {
48369
+ if (fs25.existsSync(repoMcpConfigPath)) {
47583
48370
  try {
47584
48371
  const repoMcpConfig = parseMeshCoordinatorMcpConfig(
47585
- fs24.readFileSync(repoMcpConfigPath, "utf-8"),
48372
+ fs25.readFileSync(repoMcpConfigPath, "utf-8"),
47586
48373
  "claude_mcp_json"
47587
48374
  );
47588
48375
  const existingServers2 = repoMcpConfig.mcpServers;
47589
48376
  if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
47590
- fs24.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
48377
+ fs25.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
47591
48378
  ...repoMcpConfig,
47592
48379
  mcpServers: {
47593
48380
  ...existingServers2,
@@ -47703,7 +48490,7 @@ ${ptyResult.output.slice(-2e3)}`);
47703
48490
  workspace
47704
48491
  };
47705
48492
  }
47706
- const { existsSync: existsSync43, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
48493
+ const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
47707
48494
  const { dirname: dirname14 } = await import("path");
47708
48495
  const mcpConfigPath = coordinatorSetup.configPath;
47709
48496
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -47746,7 +48533,7 @@ ${ptyResult.output.slice(-2e3)}`);
47746
48533
  if (hermesManualFallback) return returnManualFallback(message);
47747
48534
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
47748
48535
  }
47749
- const hadExistingMcpConfig = existsSync43(mcpConfigPath);
48536
+ const hadExistingMcpConfig = existsSync44(mcpConfigPath);
47750
48537
  let existingMcpConfig = hermesBaseConfig?.config || {};
47751
48538
  if (hermesBaseConfig) {
47752
48539
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname14(mcpConfigPath));
@@ -47904,6 +48691,7 @@ ${ptyResult.output.slice(-2e3)}`);
47904
48691
  const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
47905
48692
  const localMachineId = loadConfig().machineId || "";
47906
48693
  const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
48694
+ const meshGitProbeCache = this.meshGitProbeCache;
47907
48695
  const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
47908
48696
  mesh,
47909
48697
  meshSource: meshRecord.source,
@@ -47914,14 +48702,16 @@ ${ptyResult.output.slice(-2e3)}`);
47914
48702
  // Standing-state model: only an explicit refresh fans
47915
48703
  // out a blocking peer git probe. Default loads return
47916
48704
  // held truth so one slow peer can't block the graph.
47917
- probeRemotePeers: refreshRequested
48705
+ probeRemotePeers: refreshRequested,
48706
+ probeCache: meshGitProbeCache
47918
48707
  }) : {
47919
48708
  directEvidenceCount: 0,
47920
48709
  localConfirmedCount: 0,
47921
48710
  peerAttemptedCount: 0,
47922
48711
  peerConfirmedCount: 0,
47923
48712
  standingEvidenceCount: 0,
47924
- unavailableNodeIds: []
48713
+ unavailableNodeIds: [],
48714
+ deadNodeIds: []
47925
48715
  };
47926
48716
  const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
47927
48717
  const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
@@ -48061,7 +48851,7 @@ ${ptyResult.output.slice(-2e3)}`);
48061
48851
  }
48062
48852
  }
48063
48853
  if (workspace) {
48064
- if (!fs24.existsSync(workspace)) {
48854
+ if (!fs25.existsSync(workspace)) {
48065
48855
  const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
48066
48856
  let remoteProbeApplied = false;
48067
48857
  if (inlineTransitGit) {
@@ -48075,7 +48865,7 @@ ${ptyResult.output.slice(-2e3)}`);
48075
48865
  }
48076
48866
  remoteProbeApplied = true;
48077
48867
  } else if (refreshRequested && !isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
48078
- const remoteGit = await probeRemoteMeshGitStatusWithRetry({
48868
+ const runNodeProbe = () => probeRemoteMeshGitStatusWithRetry({
48079
48869
  dispatchMeshCommand: this.deps.dispatchMeshCommand,
48080
48870
  daemonId,
48081
48871
  workspace,
@@ -48086,6 +48876,7 @@ ${ptyResult.output.slice(-2e3)}`);
48086
48876
  status.connection = connection;
48087
48877
  }
48088
48878
  });
48879
+ const remoteGit = await meshGitProbeCache.probe(daemonId, workspace, runNodeProbe);
48089
48880
  if (remoteGit) {
48090
48881
  status.git = remoteGit;
48091
48882
  status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
@@ -48151,7 +48942,7 @@ ${ptyResult.output.slice(-2e3)}`);
48151
48942
  const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
48152
48943
  const unroutableDeliveries = getRecentUnroutableDeliveries();
48153
48944
  const previewFreshness = (() => {
48154
- const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs24.existsSync(candidate));
48945
+ const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs25.existsSync(candidate));
48155
48946
  return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
48156
48947
  })();
48157
48948
  const asyncRefineJobs = buildMeshAsyncRefineJobs({
@@ -48246,7 +49037,7 @@ ${ptyResult.output.slice(-2e3)}`);
48246
49037
  const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
48247
49038
  const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48248
49039
  const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
48249
- const { existsSync: existsSync43 } = await import("fs");
49040
+ const { existsSync: existsSync44 } = await import("fs");
48250
49041
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
48251
49042
  const mesh = meshRecord?.mesh;
48252
49043
  if (!mesh) return { success: false, error: "Mesh not found" };
@@ -48265,7 +49056,7 @@ ${ptyResult.output.slice(-2e3)}`);
48265
49056
  const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
48266
49057
  for (const item of derivation.items) {
48267
49058
  const workspace = item.workspace;
48268
- if (!workspace || !existsSync43(workspace)) continue;
49059
+ if (!workspace || !existsSync44(workspace)) continue;
48269
49060
  const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
48270
49061
  try {
48271
49062
  const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
@@ -50011,7 +50802,7 @@ var ProviderInstanceManager = class {
50011
50802
  };
50012
50803
 
50013
50804
  // src/providers/version-archive.ts
50014
- import * as fs25 from "fs";
50805
+ import * as fs26 from "fs";
50015
50806
  import * as path36 from "path";
50016
50807
  import * as os28 from "os";
50017
50808
  import { platform as platform8 } from "os";
@@ -50025,8 +50816,8 @@ var VersionArchive = class {
50025
50816
  }
50026
50817
  load() {
50027
50818
  try {
50028
- if (fs25.existsSync(ARCHIVE_PATH)) {
50029
- this.history = JSON.parse(fs25.readFileSync(ARCHIVE_PATH, "utf-8"));
50819
+ if (fs26.existsSync(ARCHIVE_PATH)) {
50820
+ this.history = JSON.parse(fs26.readFileSync(ARCHIVE_PATH, "utf-8"));
50030
50821
  }
50031
50822
  } catch {
50032
50823
  this.history = {};
@@ -50063,8 +50854,8 @@ var VersionArchive = class {
50063
50854
  }
50064
50855
  save() {
50065
50856
  try {
50066
- fs25.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
50067
- fs25.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
50857
+ fs26.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
50858
+ fs26.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
50068
50859
  } catch {
50069
50860
  }
50070
50861
  }
@@ -50089,8 +50880,8 @@ function findBinary2(name) {
50089
50880
  for (const ext of exes) {
50090
50881
  const fullPath = path36.join(p, name + ext);
50091
50882
  try {
50092
- if (fs25.existsSync(fullPath)) {
50093
- const stat2 = fs25.statSync(fullPath);
50883
+ if (fs26.existsSync(fullPath)) {
50884
+ const stat2 = fs26.statSync(fullPath);
50094
50885
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
50095
50886
  return fullPath;
50096
50887
  }
@@ -50137,9 +50928,9 @@ function checkPathExists2(paths) {
50137
50928
  if (p.includes("*")) {
50138
50929
  const home = os28.homedir();
50139
50930
  const resolved = p.replace(/\*/g, home.split(path36.sep).pop() || "");
50140
- if (fs25.existsSync(resolved)) return resolved;
50931
+ if (fs26.existsSync(resolved)) return resolved;
50141
50932
  } else {
50142
- if (fs25.existsSync(p)) return p;
50933
+ if (fs26.existsSync(p)) return p;
50143
50934
  }
50144
50935
  }
50145
50936
  return null;
@@ -50147,7 +50938,7 @@ function checkPathExists2(paths) {
50147
50938
  async function getMacAppVersion(appPath) {
50148
50939
  if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
50149
50940
  const plistPath = path36.join(appPath, "Contents", "Info.plist");
50150
- if (!fs25.existsSync(plistPath)) return null;
50941
+ if (!fs26.existsSync(plistPath)) return null;
50151
50942
  const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
50152
50943
  return raw || null;
50153
50944
  }
@@ -50173,7 +50964,7 @@ async function detectAllVersions(loader, archive) {
50173
50964
  let resolvedBin = cliBin;
50174
50965
  if (!resolvedBin && appPath && currentOs === "darwin") {
50175
50966
  const bundled = path36.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
50176
- if (provider.cli && fs25.existsSync(bundled)) resolvedBin = bundled;
50967
+ if (provider.cli && fs26.existsSync(bundled)) resolvedBin = bundled;
50177
50968
  }
50178
50969
  info.installed = !!(appPath || resolvedBin);
50179
50970
  info.path = appPath || null;
@@ -50212,7 +51003,7 @@ async function detectAllVersions(loader, archive) {
50212
51003
 
50213
51004
  // src/daemon/dev-server.ts
50214
51005
  import * as http2 from "http";
50215
- import * as fs29 from "fs";
51006
+ import * as fs30 from "fs";
50216
51007
  import * as path40 from "path";
50217
51008
  init_config();
50218
51009
 
@@ -50564,7 +51355,7 @@ init_logger();
50564
51355
 
50565
51356
  // src/daemon/dev-cdp-handlers.ts
50566
51357
  init_logger();
50567
- import * as fs26 from "fs";
51358
+ import * as fs27 from "fs";
50568
51359
  import * as path37 from "path";
50569
51360
  async function handleCdpEvaluate(ctx, req, res) {
50570
51361
  const body = await ctx.readBody(req);
@@ -50744,17 +51535,17 @@ async function handleScriptHints(ctx, type, _req, res) {
50744
51535
  }
50745
51536
  let scriptsPath = "";
50746
51537
  const directScripts = path37.join(dir, "scripts.js");
50747
- if (fs26.existsSync(directScripts)) {
51538
+ if (fs27.existsSync(directScripts)) {
50748
51539
  scriptsPath = directScripts;
50749
51540
  } else {
50750
51541
  const scriptsDir = path37.join(dir, "scripts");
50751
- if (fs26.existsSync(scriptsDir)) {
50752
- const versions = fs26.readdirSync(scriptsDir).filter((d) => {
50753
- return fs26.statSync(path37.join(scriptsDir, d)).isDirectory();
51542
+ if (fs27.existsSync(scriptsDir)) {
51543
+ const versions = fs27.readdirSync(scriptsDir).filter((d) => {
51544
+ return fs27.statSync(path37.join(scriptsDir, d)).isDirectory();
50754
51545
  }).sort().reverse();
50755
51546
  for (const ver of versions) {
50756
51547
  const p = path37.join(scriptsDir, ver, "scripts.js");
50757
- if (fs26.existsSync(p)) {
51548
+ if (fs27.existsSync(p)) {
50758
51549
  scriptsPath = p;
50759
51550
  break;
50760
51551
  }
@@ -50766,7 +51557,7 @@ async function handleScriptHints(ctx, type, _req, res) {
50766
51557
  return;
50767
51558
  }
50768
51559
  try {
50769
- const source = fs26.readFileSync(scriptsPath, "utf-8");
51560
+ const source = fs27.readFileSync(scriptsPath, "utf-8");
50770
51561
  const hints = {};
50771
51562
  const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
50772
51563
  let match;
@@ -51581,7 +52372,7 @@ async function handleDomContext(ctx, type, req, res) {
51581
52372
  }
51582
52373
 
51583
52374
  // src/daemon/dev-cli-debug.ts
51584
- import * as fs27 from "fs";
52375
+ import * as fs28 from "fs";
51585
52376
  import * as path38 from "path";
51586
52377
  function slugifyFixtureName(value) {
51587
52378
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
@@ -51597,10 +52388,10 @@ function getCliFixtureDir(ctx, type) {
51597
52388
  function readCliFixture(ctx, type, name) {
51598
52389
  const fixtureDir = getCliFixtureDir(ctx, type);
51599
52390
  const filePath = path38.join(fixtureDir, `${name}.json`);
51600
- if (!fs27.existsSync(filePath)) {
52391
+ if (!fs28.existsSync(filePath)) {
51601
52392
  throw new Error(`Fixture not found: ${filePath}`);
51602
52393
  }
51603
- return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
52394
+ return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
51604
52395
  }
51605
52396
  function getExerciseTranscriptText(result) {
51606
52397
  const parts = [];
@@ -52345,7 +53136,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
52345
53136
  return;
52346
53137
  }
52347
53138
  const fixtureDir = getCliFixtureDir(ctx, type);
52348
- fs27.mkdirSync(fixtureDir, { recursive: true });
53139
+ fs28.mkdirSync(fixtureDir, { recursive: true });
52349
53140
  const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
52350
53141
  const result = await runCliExerciseInternal(ctx, { ...request, type });
52351
53142
  const fixture = {
@@ -52373,7 +53164,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
52373
53164
  notes: typeof body?.notes === "string" ? body.notes : void 0
52374
53165
  };
52375
53166
  const filePath = path38.join(fixtureDir, `${name}.json`);
52376
- fs27.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
53167
+ fs28.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
52377
53168
  ctx.json(res, 200, {
52378
53169
  saved: true,
52379
53170
  name,
@@ -52391,14 +53182,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
52391
53182
  async function handleCliFixtureList(ctx, type, _req, res) {
52392
53183
  try {
52393
53184
  const fixtureDir = getCliFixtureDir(ctx, type);
52394
- if (!fs27.existsSync(fixtureDir)) {
53185
+ if (!fs28.existsSync(fixtureDir)) {
52395
53186
  ctx.json(res, 200, { fixtures: [], count: 0 });
52396
53187
  return;
52397
53188
  }
52398
- const fixtures = fs27.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
53189
+ const fixtures = fs28.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
52399
53190
  const fullPath = path38.join(fixtureDir, file);
52400
53191
  try {
52401
- const raw = JSON.parse(fs27.readFileSync(fullPath, "utf-8"));
53192
+ const raw = JSON.parse(fs28.readFileSync(fullPath, "utf-8"));
52402
53193
  return {
52403
53194
  name: raw.name || file.replace(/\.json$/i, ""),
52404
53195
  path: fullPath,
@@ -52531,7 +53322,7 @@ async function handleCliRaw(ctx, req, res) {
52531
53322
  }
52532
53323
 
52533
53324
  // src/daemon/dev-auto-implement.ts
52534
- import * as fs28 from "fs";
53325
+ import * as fs29 from "fs";
52535
53326
  import * as path39 from "path";
52536
53327
  import * as os29 from "os";
52537
53328
  import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS7, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS7 } from "@adhdev/session-host-core";
@@ -52580,10 +53371,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
52580
53371
  return fallback?.type || null;
52581
53372
  }
52582
53373
  function getLatestScriptVersionDir(scriptsDir) {
52583
- if (!fs28.existsSync(scriptsDir)) return null;
52584
- const versions = fs28.readdirSync(scriptsDir).filter((d) => {
53374
+ if (!fs29.existsSync(scriptsDir)) return null;
53375
+ const versions = fs29.readdirSync(scriptsDir).filter((d) => {
52585
53376
  try {
52586
- return fs28.statSync(path39.join(scriptsDir, d)).isDirectory();
53377
+ return fs29.statSync(path39.join(scriptsDir, d)).isDirectory();
52587
53378
  } catch {
52588
53379
  return false;
52589
53380
  }
@@ -52605,13 +53396,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
52605
53396
  if (!sourceDir) {
52606
53397
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
52607
53398
  }
52608
- if (!fs28.existsSync(desiredDir)) {
52609
- fs28.mkdirSync(path39.dirname(desiredDir), { recursive: true });
52610
- fs28.cpSync(sourceDir, desiredDir, { recursive: true });
53399
+ if (!fs29.existsSync(desiredDir)) {
53400
+ fs29.mkdirSync(path39.dirname(desiredDir), { recursive: true });
53401
+ fs29.cpSync(sourceDir, desiredDir, { recursive: true });
52611
53402
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
52612
53403
  }
52613
53404
  const providerJson = path39.join(desiredDir, "provider.json");
52614
- if (!fs28.existsSync(providerJson)) {
53405
+ if (!fs29.existsSync(providerJson)) {
52615
53406
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
52616
53407
  }
52617
53408
  return { dir: desiredDir };
@@ -52619,15 +53410,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
52619
53410
  function loadAutoImplReferenceScripts(ctx, referenceType) {
52620
53411
  if (!referenceType) return {};
52621
53412
  const refDir = ctx.findProviderDir(referenceType);
52622
- if (!refDir || !fs28.existsSync(refDir)) return {};
53413
+ if (!refDir || !fs29.existsSync(refDir)) return {};
52623
53414
  const referenceScripts = {};
52624
53415
  const scriptsDir = path39.join(refDir, "scripts");
52625
53416
  const latestDir = getLatestScriptVersionDir(scriptsDir);
52626
53417
  if (!latestDir) return referenceScripts;
52627
- for (const file of fs28.readdirSync(latestDir)) {
53418
+ for (const file of fs29.readdirSync(latestDir)) {
52628
53419
  if (!file.endsWith(".js")) continue;
52629
53420
  try {
52630
- referenceScripts[file] = fs28.readFileSync(path39.join(latestDir, file), "utf-8");
53421
+ referenceScripts[file] = fs29.readFileSync(path39.join(latestDir, file), "utf-8");
52631
53422
  } catch {
52632
53423
  }
52633
53424
  }
@@ -52736,15 +53527,15 @@ async function handleAutoImplement(ctx, type, req, res) {
52736
53527
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
52737
53528
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
52738
53529
  const tmpDir = path39.join(os29.tmpdir(), "adhdev-autoimpl");
52739
- if (!fs28.existsSync(tmpDir)) fs28.mkdirSync(tmpDir, { recursive: true });
53530
+ if (!fs29.existsSync(tmpDir)) fs29.mkdirSync(tmpDir, { recursive: true });
52740
53531
  const promptFile = path39.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
52741
- fs28.writeFileSync(promptFile, prompt, "utf-8");
53532
+ fs29.writeFileSync(promptFile, prompt, "utf-8");
52742
53533
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
52743
53534
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
52744
53535
  const spawn4 = agentProvider?.spawn;
52745
53536
  if (!spawn4?.command) {
52746
53537
  try {
52747
- fs28.unlinkSync(promptFile);
53538
+ fs29.unlinkSync(promptFile);
52748
53539
  } catch {
52749
53540
  }
52750
53541
  ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
@@ -52846,7 +53637,7 @@ async function handleAutoImplement(ctx, type, req, res) {
52846
53637
  } catch {
52847
53638
  }
52848
53639
  try {
52849
- fs28.unlinkSync(promptFile);
53640
+ fs29.unlinkSync(promptFile);
52850
53641
  } catch {
52851
53642
  }
52852
53643
  ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
@@ -53072,7 +53863,7 @@ async function handleAutoImplement(ctx, type, req, res) {
53072
53863
  }
53073
53864
  });
53074
53865
  try {
53075
- fs28.unlinkSync(promptFile);
53866
+ fs29.unlinkSync(promptFile);
53076
53867
  } catch {
53077
53868
  }
53078
53869
  ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
@@ -53177,10 +53968,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
53177
53968
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
53178
53969
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
53179
53970
  lines.push("");
53180
- for (const file of fs28.readdirSync(latestScriptsDir)) {
53971
+ for (const file of fs29.readdirSync(latestScriptsDir)) {
53181
53972
  if (file.endsWith(".js") && targetFileNames.has(file)) {
53182
53973
  try {
53183
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53974
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53184
53975
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
53185
53976
  lines.push("```javascript");
53186
53977
  lines.push(content);
@@ -53190,14 +53981,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
53190
53981
  }
53191
53982
  }
53192
53983
  }
53193
- const refFiles = fs28.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
53984
+ const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
53194
53985
  if (refFiles.length > 0) {
53195
53986
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
53196
53987
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
53197
53988
  lines.push("");
53198
53989
  for (const file of refFiles) {
53199
53990
  try {
53200
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53991
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53201
53992
  lines.push(`### \`${file}\` \u{1F512}`);
53202
53993
  lines.push("```javascript");
53203
53994
  lines.push(content);
@@ -53242,7 +54033,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
53242
54033
  const loadGuide = (name) => {
53243
54034
  try {
53244
54035
  const p = path39.join(docsDir, name);
53245
- if (fs28.existsSync(p)) return fs28.readFileSync(p, "utf-8");
54036
+ if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
53246
54037
  } catch {
53247
54038
  }
53248
54039
  return null;
@@ -53486,11 +54277,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
53486
54277
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
53487
54278
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
53488
54279
  lines.push("");
53489
- for (const file of fs28.readdirSync(latestScriptsDir)) {
54280
+ for (const file of fs29.readdirSync(latestScriptsDir)) {
53490
54281
  if (!file.endsWith(".js")) continue;
53491
54282
  if (!targetFileNames.has(file)) continue;
53492
54283
  try {
53493
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54284
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53494
54285
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
53495
54286
  lines.push("```javascript");
53496
54287
  lines.push(content);
@@ -53499,14 +54290,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
53499
54290
  } catch {
53500
54291
  }
53501
54292
  }
53502
- const refFiles = fs28.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
54293
+ const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
53503
54294
  if (refFiles.length > 0) {
53504
54295
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
53505
54296
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
53506
54297
  lines.push("");
53507
54298
  for (const file of refFiles) {
53508
54299
  try {
53509
- const content = fs28.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
54300
+ const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
53510
54301
  lines.push(`### \`${file}\` \u{1F512}`);
53511
54302
  lines.push("```javascript");
53512
54303
  lines.push(content);
@@ -53543,7 +54334,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
53543
54334
  const loadGuide = (name) => {
53544
54335
  try {
53545
54336
  const p = path39.join(docsDir, name);
53546
- if (fs28.existsSync(p)) return fs28.readFileSync(p, "utf-8");
54337
+ if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
53547
54338
  } catch {
53548
54339
  }
53549
54340
  return null;
@@ -54283,7 +55074,7 @@ var DevServer = class _DevServer {
54283
55074
  path40.join(process.cwd(), "packages/web-devconsole/dist")
54284
55075
  ];
54285
55076
  for (const dir of candidates) {
54286
- if (fs29.existsSync(path40.join(dir, "index.html"))) return dir;
55077
+ if (fs30.existsSync(path40.join(dir, "index.html"))) return dir;
54287
55078
  }
54288
55079
  return null;
54289
55080
  }
@@ -54295,7 +55086,7 @@ var DevServer = class _DevServer {
54295
55086
  }
54296
55087
  const htmlPath = path40.join(distDir, "index.html");
54297
55088
  try {
54298
- const html = fs29.readFileSync(htmlPath, "utf-8");
55089
+ const html = fs30.readFileSync(htmlPath, "utf-8");
54299
55090
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
54300
55091
  res.end(html);
54301
55092
  } catch (e) {
@@ -54325,7 +55116,7 @@ var DevServer = class _DevServer {
54325
55116
  return;
54326
55117
  }
54327
55118
  try {
54328
- const content = fs29.readFileSync(filePath);
55119
+ const content = fs30.readFileSync(filePath);
54329
55120
  const ext = path40.extname(filePath);
54330
55121
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
54331
55122
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
@@ -54434,14 +55225,14 @@ var DevServer = class _DevServer {
54434
55225
  const files = [];
54435
55226
  const scan = (d, prefix) => {
54436
55227
  try {
54437
- for (const entry of fs29.readdirSync(d, { withFileTypes: true })) {
55228
+ for (const entry of fs30.readdirSync(d, { withFileTypes: true })) {
54438
55229
  if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
54439
55230
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
54440
55231
  if (entry.isDirectory()) {
54441
55232
  files.push({ path: rel, size: 0, type: "dir" });
54442
55233
  scan(path40.join(d, entry.name), rel);
54443
55234
  } else {
54444
- const stat2 = fs29.statSync(path40.join(d, entry.name));
55235
+ const stat2 = fs30.statSync(path40.join(d, entry.name));
54445
55236
  files.push({ path: rel, size: stat2.size, type: "file" });
54446
55237
  }
54447
55238
  }
@@ -54469,11 +55260,11 @@ var DevServer = class _DevServer {
54469
55260
  this.json(res, 403, { error: "Forbidden" });
54470
55261
  return;
54471
55262
  }
54472
- if (!fs29.existsSync(fullPath) || fs29.statSync(fullPath).isDirectory()) {
55263
+ if (!fs30.existsSync(fullPath) || fs30.statSync(fullPath).isDirectory()) {
54473
55264
  this.json(res, 404, { error: `File not found: ${filePath}` });
54474
55265
  return;
54475
55266
  }
54476
- const content = fs29.readFileSync(fullPath, "utf-8");
55267
+ const content = fs30.readFileSync(fullPath, "utf-8");
54477
55268
  this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
54478
55269
  }
54479
55270
  /** POST /api/providers/:type/file — write a file { path, content } */
@@ -54495,9 +55286,9 @@ var DevServer = class _DevServer {
54495
55286
  return;
54496
55287
  }
54497
55288
  try {
54498
- if (fs29.existsSync(fullPath)) fs29.copyFileSync(fullPath, fullPath + ".bak");
54499
- fs29.mkdirSync(path40.dirname(fullPath), { recursive: true });
54500
- fs29.writeFileSync(fullPath, content, "utf-8");
55289
+ if (fs30.existsSync(fullPath)) fs30.copyFileSync(fullPath, fullPath + ".bak");
55290
+ fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
55291
+ fs30.writeFileSync(fullPath, content, "utf-8");
54501
55292
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
54502
55293
  this.providerLoader.reload();
54503
55294
  this.json(res, 200, { saved: true, path: filePath, chars: content.length });
@@ -54514,8 +55305,8 @@ var DevServer = class _DevServer {
54514
55305
  }
54515
55306
  for (const name of ["scripts.js", "provider.json"]) {
54516
55307
  const p = path40.join(dir, name);
54517
- if (fs29.existsSync(p)) {
54518
- const source = fs29.readFileSync(p, "utf-8");
55308
+ if (fs30.existsSync(p)) {
55309
+ const source = fs30.readFileSync(p, "utf-8");
54519
55310
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
54520
55311
  return;
54521
55312
  }
@@ -54534,11 +55325,11 @@ var DevServer = class _DevServer {
54534
55325
  this.json(res, 404, { error: `Provider not found: ${type}` });
54535
55326
  return;
54536
55327
  }
54537
- const target = fs29.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
55328
+ const target = fs30.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
54538
55329
  const targetPath = path40.join(dir, target);
54539
55330
  try {
54540
- if (fs29.existsSync(targetPath)) fs29.copyFileSync(targetPath, targetPath + ".bak");
54541
- fs29.writeFileSync(targetPath, source, "utf-8");
55331
+ if (fs30.existsSync(targetPath)) fs30.copyFileSync(targetPath, targetPath + ".bak");
55332
+ fs30.writeFileSync(targetPath, source, "utf-8");
54542
55333
  this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
54543
55334
  this.providerLoader.reload();
54544
55335
  this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
@@ -54683,20 +55474,20 @@ var DevServer = class _DevServer {
54683
55474
  let targetDir;
54684
55475
  targetDir = this.providerLoader.getUserProviderDir(category, type);
54685
55476
  const jsonPath = path40.join(targetDir, "provider.json");
54686
- if (fs29.existsSync(jsonPath)) {
55477
+ if (fs30.existsSync(jsonPath)) {
54687
55478
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
54688
55479
  return;
54689
55480
  }
54690
55481
  try {
54691
55482
  const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
54692
- fs29.mkdirSync(targetDir, { recursive: true });
54693
- fs29.writeFileSync(jsonPath, result["provider.json"], "utf-8");
55483
+ fs30.mkdirSync(targetDir, { recursive: true });
55484
+ fs30.writeFileSync(jsonPath, result["provider.json"], "utf-8");
54694
55485
  const createdFiles = ["provider.json"];
54695
55486
  if (result.files) {
54696
55487
  for (const [relPath, content] of Object.entries(result.files)) {
54697
55488
  const fullPath = path40.join(targetDir, relPath);
54698
- fs29.mkdirSync(path40.dirname(fullPath), { recursive: true });
54699
- fs29.writeFileSync(fullPath, content, "utf-8");
55489
+ fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
55490
+ fs30.writeFileSync(fullPath, content, "utf-8");
54700
55491
  createdFiles.push(relPath);
54701
55492
  }
54702
55493
  }
@@ -54745,10 +55536,10 @@ var DevServer = class _DevServer {
54745
55536
  }
54746
55537
  // ─── Phase 2: Auto-Implement Backend ───
54747
55538
  getLatestScriptVersionDir(scriptsDir) {
54748
- if (!fs29.existsSync(scriptsDir)) return null;
54749
- const versions = fs29.readdirSync(scriptsDir).filter((d) => {
55539
+ if (!fs30.existsSync(scriptsDir)) return null;
55540
+ const versions = fs30.readdirSync(scriptsDir).filter((d) => {
54750
55541
  try {
54751
- return fs29.statSync(path40.join(scriptsDir, d)).isDirectory();
55542
+ return fs30.statSync(path40.join(scriptsDir, d)).isDirectory();
54752
55543
  } catch {
54753
55544
  return false;
54754
55545
  }
@@ -54770,13 +55561,13 @@ var DevServer = class _DevServer {
54770
55561
  if (!sourceDir) {
54771
55562
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
54772
55563
  }
54773
- if (!fs29.existsSync(desiredDir)) {
54774
- fs29.mkdirSync(path40.dirname(desiredDir), { recursive: true });
54775
- fs29.cpSync(sourceDir, desiredDir, { recursive: true });
55564
+ if (!fs30.existsSync(desiredDir)) {
55565
+ fs30.mkdirSync(path40.dirname(desiredDir), { recursive: true });
55566
+ fs30.cpSync(sourceDir, desiredDir, { recursive: true });
54776
55567
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
54777
55568
  }
54778
55569
  const providerJson = path40.join(desiredDir, "provider.json");
54779
- if (!fs29.existsSync(providerJson)) {
55570
+ if (!fs30.existsSync(providerJson)) {
54780
55571
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
54781
55572
  }
54782
55573
  return { dir: desiredDir };
@@ -54819,10 +55610,10 @@ var DevServer = class _DevServer {
54819
55610
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
54820
55611
  lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
54821
55612
  lines.push("");
54822
- for (const file of fs29.readdirSync(latestScriptsDir)) {
55613
+ for (const file of fs30.readdirSync(latestScriptsDir)) {
54823
55614
  if (file.endsWith(".js") && targetFileNames.has(file)) {
54824
55615
  try {
54825
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55616
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
54826
55617
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
54827
55618
  lines.push("```javascript");
54828
55619
  lines.push(content);
@@ -54832,14 +55623,14 @@ var DevServer = class _DevServer {
54832
55623
  }
54833
55624
  }
54834
55625
  }
54835
- const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55626
+ const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
54836
55627
  if (refFiles.length > 0) {
54837
55628
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
54838
55629
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
54839
55630
  lines.push("");
54840
55631
  for (const file of refFiles) {
54841
55632
  try {
54842
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55633
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
54843
55634
  lines.push(`### \`${file}\` \u{1F512}`);
54844
55635
  lines.push("```javascript");
54845
55636
  lines.push(content);
@@ -54884,7 +55675,7 @@ var DevServer = class _DevServer {
54884
55675
  const loadGuide = (name) => {
54885
55676
  try {
54886
55677
  const p = path40.join(docsDir, name);
54887
- if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
55678
+ if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
54888
55679
  } catch {
54889
55680
  }
54890
55681
  return null;
@@ -55065,11 +55856,11 @@ var DevServer = class _DevServer {
55065
55856
  lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
55066
55857
  lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
55067
55858
  lines.push("");
55068
- for (const file of fs29.readdirSync(latestScriptsDir)) {
55859
+ for (const file of fs30.readdirSync(latestScriptsDir)) {
55069
55860
  if (!file.endsWith(".js")) continue;
55070
55861
  if (!targetFileNames.has(file)) continue;
55071
55862
  try {
55072
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55863
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55073
55864
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
55074
55865
  lines.push("```javascript");
55075
55866
  lines.push(content);
@@ -55078,14 +55869,14 @@ var DevServer = class _DevServer {
55078
55869
  } catch {
55079
55870
  }
55080
55871
  }
55081
- const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55872
+ const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
55082
55873
  if (refFiles.length > 0) {
55083
55874
  lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
55084
55875
  lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
55085
55876
  lines.push("");
55086
55877
  for (const file of refFiles) {
55087
55878
  try {
55088
- const content = fs29.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55879
+ const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
55089
55880
  lines.push(`### \`${file}\` \u{1F512}`);
55090
55881
  lines.push("```javascript");
55091
55882
  lines.push(content);
@@ -55122,7 +55913,7 @@ var DevServer = class _DevServer {
55122
55913
  const loadGuide = (name) => {
55123
55914
  try {
55124
55915
  const p = path40.join(docsDir, name);
55125
- if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
55916
+ if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
55126
55917
  } catch {
55127
55918
  }
55128
55919
  return null;
@@ -56230,8 +57021,8 @@ async function installExtension(ide, extension) {
56230
57021
  const res = await fetch(extension.vsixUrl);
56231
57022
  if (res.ok) {
56232
57023
  const buffer = Buffer.from(await res.arrayBuffer());
56233
- const fs30 = await import("fs");
56234
- fs30.writeFileSync(vsixPath, buffer);
57024
+ const fs31 = await import("fs");
57025
+ fs31.writeFileSync(vsixPath, buffer);
56235
57026
  return new Promise((resolve24) => {
56236
57027
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
56237
57028
  exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
@@ -56811,7 +57602,7 @@ import { readFileSync as readFileSync33 } from "fs";
56811
57602
  import { dirname as dirname12, resolve as resolve22 } from "path";
56812
57603
 
56813
57604
  // src/providers/sdk/v1/validators/taint.ts
56814
- import { readFileSync as readFileSync34, existsSync as existsSync42 } from "fs";
57605
+ import { readFileSync as readFileSync34, existsSync as existsSync43 } from "fs";
56815
57606
  import { resolve as resolve23, dirname as dirname13, join as join44 } from "path";
56816
57607
 
56817
57608
  // src/providers/sdk/v1/validators/index.ts
@@ -56909,6 +57700,7 @@ export {
56909
57700
  DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
56910
57701
  DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
56911
57702
  DEFAULT_MESH_POLICY,
57703
+ DEFAULT_MESH_SCHEDULING_STRATEGY,
56912
57704
  DEFAULT_SESSION_HOST_APP_NAME,
56913
57705
  DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
56914
57706
  DEFAULT_SESSION_HOST_READY_TIMEOUT_MS,
@@ -56934,9 +57726,12 @@ export {
56934
57726
  InMemoryGitSnapshotStore,
56935
57727
  LOG,
56936
57728
  MAX_LEDGER_SLICE_LIMIT,
57729
+ MESH_CONVERGE_FAST_FORWARD_TAG,
57730
+ MESH_CONVERGE_REFINE_TAG,
56937
57731
  MESH_MISSION_STATUSES,
56938
57732
  MESH_REFINE_CONFIG_LOCATIONS,
56939
57733
  MESH_REFINE_CONFIG_SCHEMA,
57734
+ MESH_SCHEDULING_STRATEGIES,
56940
57735
  MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
56941
57736
  MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
56942
57737
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
@@ -57137,6 +57932,7 @@ export {
57137
57932
  normalizeManagedStatus,
57138
57933
  normalizeMeshCapabilityTags,
57139
57934
  normalizeMeshDaemonRole,
57935
+ normalizeMeshSchedulingStrategy,
57140
57936
  normalizeMeshTaskMode,
57141
57937
  normalizeMeshWorkerResult,
57142
57938
  normalizeMessageParts,
@@ -57174,7 +57970,9 @@ export {
57174
57970
  resetConfig,
57175
57971
  resetDebugRuntimeConfig,
57176
57972
  resetState,
57973
+ resolveAutoConvergeCodeChange,
57177
57974
  resolveChatMessageKind,
57975
+ resolveConvergeRequiredTags,
57178
57976
  resolveCurrentGlobalInstallSurface,
57179
57977
  resolveDebugRuntimeConfig,
57180
57978
  resolveDelegatedWorkerAutoApprove,
@@ -57182,6 +57980,7 @@ export {
57182
57980
  resolveGitRepository,
57183
57981
  resolveMeshHostStatus,
57184
57982
  resolveMeshRefineValidationPlan,
57983
+ resolveNodeSchedulingPriority,
57185
57984
  resolveSessionHostAppName,
57186
57985
  resolveSessionHostAppNameResolution,
57187
57986
  resolveWorktreePath,