@adhdev/daemon-core 0.9.76-rc.3 → 0.9.76-rc.31

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.
Files changed (42) hide show
  1. package/dist/cli-adapters/provider-cli-adapter.d.ts +2 -1
  2. package/dist/cli-adapters/provider-cli-runtime.d.ts +1 -0
  3. package/dist/commands/cli-manager.d.ts +17 -4
  4. package/dist/commands/mesh-coordinator.d.ts +2 -0
  5. package/dist/commands/router.d.ts +4 -0
  6. package/dist/config/mesh-config.d.ts +3 -0
  7. package/dist/git/git-types.d.ts +1 -1
  8. package/dist/git/git-worktree.d.ts +64 -0
  9. package/dist/git/index.d.ts +2 -0
  10. package/dist/index.js +1058 -384
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +1085 -416
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/mesh/coordinator-prompt.d.ts +1 -0
  15. package/dist/providers/cli-provider-instance.d.ts +3 -0
  16. package/dist/providers/provider-instance-manager.d.ts +1 -0
  17. package/dist/providers/provider-instance.d.ts +2 -0
  18. package/dist/repo-mesh-types.d.ts +6 -0
  19. package/dist/shared-types.d.ts +22 -1
  20. package/package.json +3 -4
  21. package/src/cli-adapters/provider-cli-adapter.ts +6 -3
  22. package/src/cli-adapters/provider-cli-runtime.ts +3 -2
  23. package/src/commands/chat-commands.ts +50 -5
  24. package/src/commands/cli-manager.ts +78 -5
  25. package/src/commands/handler.ts +13 -4
  26. package/src/commands/mesh-coordinator.ts +149 -6
  27. package/src/commands/router.ts +319 -32
  28. package/src/config/mesh-config.ts +6 -0
  29. package/src/git/git-commands.ts +5 -1
  30. package/src/git/git-types.ts +1 -0
  31. package/src/git/git-worktree.ts +214 -0
  32. package/src/git/index.ts +14 -0
  33. package/src/mesh/coordinator-prompt.ts +25 -10
  34. package/src/mesh/mesh-events.ts +40 -17
  35. package/src/providers/cli-provider-instance.d.ts +2 -0
  36. package/src/providers/cli-provider-instance.ts +55 -7
  37. package/src/providers/provider-instance-manager.ts +20 -1
  38. package/src/providers/provider-instance.ts +2 -0
  39. package/src/repo-mesh-types.ts +6 -0
  40. package/src/shared-types.ts +24 -1
  41. package/src/status/builders.ts +17 -12
  42. package/src/status/reporter.ts +6 -0
package/dist/index.js CHANGED
@@ -46,6 +46,134 @@ var init_repo_mesh_types = __esm({
46
46
  }
47
47
  });
48
48
 
49
+ // src/git/git-worktree.ts
50
+ var git_worktree_exports = {};
51
+ __export(git_worktree_exports, {
52
+ createWorktree: () => createWorktree,
53
+ listWorktrees: () => listWorktrees,
54
+ parseWorktreeListOutput: () => parseWorktreeListOutput,
55
+ removeWorktree: () => removeWorktree,
56
+ resolveWorktreePath: () => resolveWorktreePath
57
+ });
58
+ function resolveWorktreePath(repoRoot, meshName, branch) {
59
+ const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
60
+ const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
61
+ const parentDir = path4.dirname(repoRoot);
62
+ return path4.join(parentDir, WORKTREE_DIR_NAME, safeMeshName, safeBranch);
63
+ }
64
+ async function createWorktree(opts) {
65
+ const { repoRoot, branch, baseBranch, meshName } = opts;
66
+ const targetDir = opts.targetDir || resolveWorktreePath(repoRoot, meshName, branch);
67
+ if ((0, import_node_fs2.existsSync)(targetDir)) {
68
+ throw new Error(`Worktree target directory already exists: ${targetDir}`);
69
+ }
70
+ await (0, import_promises3.mkdir)(path4.dirname(targetDir), { recursive: true });
71
+ const args = ["worktree", "add", targetDir, "-b", branch];
72
+ if (baseBranch) {
73
+ args.push(baseBranch);
74
+ }
75
+ try {
76
+ await execFileAsync2("git", args, {
77
+ cwd: repoRoot,
78
+ encoding: "utf8",
79
+ timeout: GIT_TIMEOUT_MS,
80
+ maxBuffer: GIT_MAX_BUFFER,
81
+ windowsHide: true
82
+ });
83
+ } catch (error) {
84
+ const stderr = typeof error.stderr === "string" ? error.stderr : "";
85
+ if (/already exists/i.test(stderr)) {
86
+ throw new Error(`Branch '${branch}' already exists or is checked out in another worktree`);
87
+ }
88
+ throw new Error(`git worktree add failed: ${stderr.trim() || error.message}`);
89
+ }
90
+ return {
91
+ success: true,
92
+ worktreePath: targetDir,
93
+ branch
94
+ };
95
+ }
96
+ async function removeWorktree(repoRoot, worktreePath) {
97
+ if (!(0, import_node_fs2.existsSync)(worktreePath)) {
98
+ await pruneWorktrees(repoRoot);
99
+ return { success: true, removedPath: worktreePath };
100
+ }
101
+ try {
102
+ await execFileAsync2("git", ["worktree", "remove", worktreePath, "--force"], {
103
+ cwd: repoRoot,
104
+ encoding: "utf8",
105
+ timeout: GIT_TIMEOUT_MS,
106
+ maxBuffer: GIT_MAX_BUFFER,
107
+ windowsHide: true
108
+ });
109
+ } catch (error) {
110
+ const stderr = typeof error.stderr === "string" ? error.stderr : "";
111
+ throw new Error(`git worktree remove failed: ${stderr.trim() || error.message}`);
112
+ }
113
+ return { success: true, removedPath: worktreePath };
114
+ }
115
+ async function listWorktrees(repoRoot) {
116
+ const { stdout } = await execFileAsync2("git", ["worktree", "list", "--porcelain"], {
117
+ cwd: repoRoot,
118
+ encoding: "utf8",
119
+ timeout: GIT_TIMEOUT_MS,
120
+ maxBuffer: GIT_MAX_BUFFER,
121
+ windowsHide: true
122
+ });
123
+ return parseWorktreeListOutput(stdout);
124
+ }
125
+ function parseWorktreeListOutput(output) {
126
+ const entries = [];
127
+ const blocks = output.trim().split(/\n\n+/);
128
+ for (const block of blocks) {
129
+ if (!block.trim()) continue;
130
+ const lines = block.trim().split("\n");
131
+ const entry = { path: "", head: "", branch: null, bare: false };
132
+ for (const line of lines) {
133
+ if (line.startsWith("worktree ")) {
134
+ entry.path = line.slice("worktree ".length).trim();
135
+ } else if (line.startsWith("HEAD ")) {
136
+ entry.head = line.slice("HEAD ".length).trim();
137
+ } else if (line.startsWith("branch ")) {
138
+ const ref = line.slice("branch ".length).trim();
139
+ entry.branch = ref.replace(/^refs\/heads\//, "");
140
+ } else if (line === "bare") {
141
+ entry.bare = true;
142
+ }
143
+ }
144
+ if (entry.path) {
145
+ entries.push(entry);
146
+ }
147
+ }
148
+ return entries;
149
+ }
150
+ async function pruneWorktrees(repoRoot) {
151
+ try {
152
+ await execFileAsync2("git", ["worktree", "prune"], {
153
+ cwd: repoRoot,
154
+ encoding: "utf8",
155
+ timeout: GIT_TIMEOUT_MS,
156
+ windowsHide: true
157
+ });
158
+ } catch {
159
+ }
160
+ }
161
+ var path4, import_promises3, import_node_fs2, import_node_child_process2, import_node_util2, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER;
162
+ var init_git_worktree = __esm({
163
+ "src/git/git-worktree.ts"() {
164
+ "use strict";
165
+ path4 = __toESM(require("path"));
166
+ import_promises3 = require("fs/promises");
167
+ import_node_fs2 = require("fs");
168
+ import_node_child_process2 = require("child_process");
169
+ import_node_util2 = require("util");
170
+ execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
171
+ WORKTREE_DIR_NAME = ".adhdev-worktrees";
172
+ GIT_TIMEOUT_MS = 3e4;
173
+ GIT_MAX_BUFFER = 4 * 1024 * 1024;
174
+ }
175
+ });
176
+
49
177
  // src/config/config.ts
50
178
  var config_exports = {};
51
179
  __export(config_exports, {
@@ -304,10 +432,10 @@ function getMeshConfigPath() {
304
432
  return (0, import_path2.join)(getConfigDir(), "meshes.json");
305
433
  }
306
434
  function loadMeshConfig() {
307
- const path26 = getMeshConfigPath();
308
- if (!(0, import_fs2.existsSync)(path26)) return { meshes: [] };
435
+ const path27 = getMeshConfigPath();
436
+ if (!(0, import_fs2.existsSync)(path27)) return { meshes: [] };
309
437
  try {
310
- const raw = JSON.parse((0, import_fs2.readFileSync)(path26, "utf-8"));
438
+ const raw = JSON.parse((0, import_fs2.readFileSync)(path27, "utf-8"));
311
439
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
312
440
  return raw;
313
441
  } catch {
@@ -315,16 +443,16 @@ function loadMeshConfig() {
315
443
  }
316
444
  }
317
445
  function saveMeshConfig(config) {
318
- const path26 = getMeshConfigPath();
319
- (0, import_fs2.writeFileSync)(path26, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
446
+ const path27 = getMeshConfigPath();
447
+ (0, import_fs2.writeFileSync)(path27, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
320
448
  }
321
449
  function normalizeRepoIdentity(remoteUrl) {
322
450
  let identity = remoteUrl.trim();
323
451
  if (identity.startsWith("http://") || identity.startsWith("https://")) {
324
452
  try {
325
453
  const url = new URL(identity);
326
- const path26 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
327
- return `${url.hostname}/${path26}`;
454
+ const path27 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
455
+ return `${url.hostname}/${path27}`;
328
456
  } catch {
329
457
  }
330
458
  }
@@ -399,9 +527,12 @@ function addNode(meshId, opts) {
399
527
  id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
400
528
  workspace: opts.workspace.trim(),
401
529
  repoRoot: opts.repoRoot,
530
+ daemonId: opts.daemonId,
402
531
  userOverrides: opts.userOverrides || {},
403
532
  policy: opts.policy || {},
404
- isLocalWorktree: opts.isLocalWorktree
533
+ isLocalWorktree: opts.isLocalWorktree,
534
+ worktreeBranch: opts.worktreeBranch,
535
+ clonedFromNodeId: opts.clonedFromNodeId
405
536
  };
406
537
  mesh.nodes.push(node);
407
538
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -449,7 +580,7 @@ __export(coordinator_prompt_exports, {
449
580
  buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt
450
581
  });
451
582
  function buildCoordinatorSystemPrompt(ctx) {
452
- const { mesh, status, userInstruction } = ctx;
583
+ const { mesh, status, userInstruction, coordinatorCliType } = ctx;
453
584
  const sections = [];
454
585
  sections.push(`You are a **Repo Mesh Coordinator** \u2014 a technical team lead who orchestrates work across multiple agent sessions on a shared Git repository.
455
586
 
@@ -463,15 +594,15 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
463
594
  } else {
464
595
  sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
465
596
  }
466
- sections.push(buildPolicySection(mesh.policy));
597
+ sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
467
598
  sections.push(TOOLS_SECTION);
468
599
  sections.push(WORKFLOW_SECTION);
469
- sections.push(RULES_SECTION);
600
+ sections.push(buildRulesSection(coordinatorCliType));
470
601
  if (userInstruction) {
471
602
  sections.push(`## Additional Context
472
603
  ${userInstruction}`);
473
604
  }
474
- if (mesh.coordinator.systemPromptSuffix) {
605
+ if (mesh.coordinator?.systemPromptSuffix) {
475
606
  sections.push(mesh.coordinator.systemPromptSuffix);
476
607
  }
477
608
  return sections.join("\n\n");
@@ -516,10 +647,29 @@ function buildPolicySection(policy) {
516
647
  return `## Policy
517
648
  ${rules.join("\n")}`;
518
649
  }
519
- var TOOLS_SECTION, WORKFLOW_SECTION, RULES_SECTION;
650
+ function buildRulesSection(coordinatorCliType) {
651
+ const coordinatorNote = coordinatorCliType ? `
652
+ - **Coordinator runtime is not a delegation default.** This coordinator is running as \`${coordinatorCliType}\`, but delegated node sessions must follow the user's requested provider, not the coordinator's own runtime.` : "";
653
+ return `## Rules
654
+
655
+ - **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
656
+ - **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
657
+ - **Respect explicit provider requests.** If the user names an agent/provider, pass the matching provider type to \`mesh_launch_session\`: Hermes \u2192 \`hermes-cli\`, Claude Code/Claude \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`. Never substitute \`claude-cli\` just because the coordinator itself is Claude Code.
658
+ - **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
659
+ - **Don't inspect code.** Trust the agent's output. Verify via \`mesh_git_status\`, not by reading source files.
660
+ - **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
661
+ - **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
662
+ - **Keep the user informed.** Report progress after each delegation round \u2014 one or two sentences, not a narration.
663
+ - **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
664
+ - **Never fabricate tool results.** Always call the actual tool; never pretend you did.
665
+ - **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
666
+ - **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
667
+ }
668
+ var TOOLS_SECTION, WORKFLOW_SECTION;
520
669
  var init_coordinator_prompt = __esm({
521
670
  "src/mesh/coordinator-prompt.ts"() {
522
671
  "use strict";
672
+ init_repo_mesh_types();
523
673
  TOOLS_SECTION = `## Available Tools
524
674
 
525
675
  | Tool | Purpose |
@@ -531,30 +681,23 @@ var init_coordinator_prompt = __esm({
531
681
  | \`mesh_read_chat\` | Read an agent's recent messages to check progress |
532
682
  | \`mesh_git_status\` | Check git status on a specific node |
533
683
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
534
- | \`mesh_approve\` | Approve/reject a pending agent action |`;
684
+ | \`mesh_approve\` | Approve/reject a pending agent action |
685
+ | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
686
+ | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
535
687
  WORKFLOW_SECTION = `## Orchestration Workflow
536
688
 
537
689
  1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
538
690
  2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
539
691
  3. **Delegate** \u2014 For each task:
540
692
  a. Pick the best node (consider: health, dirty state, current workload).
541
- b. If no session exists, call \`mesh_launch_session\` to start one.
542
- c. Call \`mesh_send_task\` with a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
693
+ b. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
694
+ c. If no session exists, call \`mesh_launch_session\` to start one.
695
+ d. Call \`mesh_send_task\` with a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
543
696
  4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
544
697
  5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
545
698
  6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
546
- 7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
547
- RULES_SECTION = `## Rules
548
-
549
- - **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
550
- - **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
551
- - **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
552
- - **Don't inspect code.** Trust the agent's output. Verify via \`mesh_git_status\`, not by reading source files.
553
- - **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
554
- - **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
555
- - **Keep the user informed.** Report progress after each delegation round \u2014 one or two sentences, not a narration.
556
- - **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
557
- - **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
699
+ 7. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
700
+ 8. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
558
701
  }
559
702
  });
560
703
 
@@ -573,13 +716,13 @@ function getDaemonLogDir() {
573
716
  return LOG_DIR;
574
717
  }
575
718
  function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
576
- return path9.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
719
+ return path10.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
577
720
  }
578
721
  function checkDateRotation() {
579
722
  const today = getDateStr();
580
723
  if (today !== currentDate) {
581
724
  currentDate = today;
582
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
725
+ currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
583
726
  cleanOldLogs();
584
727
  }
585
728
  }
@@ -593,7 +736,7 @@ function cleanOldLogs() {
593
736
  const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
594
737
  if (dateMatch && dateMatch[1] < cutoffStr) {
595
738
  try {
596
- fs2.unlinkSync(path9.join(LOG_DIR, file));
739
+ fs2.unlinkSync(path10.join(LOG_DIR, file));
597
740
  } catch {
598
741
  }
599
742
  }
@@ -709,17 +852,17 @@ function installGlobalInterceptor() {
709
852
  writeToFile(`Log file: ${currentLogFile}`);
710
853
  writeToFile(`Log level: ${currentLevel}`);
711
854
  }
712
- var fs2, path9, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
855
+ var fs2, path10, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
713
856
  var init_logger = __esm({
714
857
  "src/logging/logger.ts"() {
715
858
  "use strict";
716
859
  fs2 = __toESM(require("fs"));
717
- path9 = __toESM(require("path"));
860
+ path10 = __toESM(require("path"));
718
861
  os4 = __toESM(require("os"));
719
862
  LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
720
863
  LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
721
864
  currentLevel = "info";
722
- LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os4.homedir(), "Library", "Logs", "adhdev") : path9.join(os4.homedir(), ".local", "share", "adhdev", "logs");
865
+ LOG_DIR = process.platform === "win32" ? path10.join(process.env.LOCALAPPDATA || process.env.APPDATA || path10.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path10.join(os4.homedir(), "Library", "Logs", "adhdev") : path10.join(os4.homedir(), ".local", "share", "adhdev", "logs");
723
866
  MAX_LOG_SIZE = 5 * 1024 * 1024;
724
867
  MAX_LOG_DAYS = 7;
725
868
  try {
@@ -727,16 +870,16 @@ var init_logger = __esm({
727
870
  } catch {
728
871
  }
729
872
  currentDate = getDateStr();
730
- currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
873
+ currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
731
874
  cleanOldLogs();
732
875
  try {
733
- const oldLog = path9.join(LOG_DIR, "daemon.log");
876
+ const oldLog = path10.join(LOG_DIR, "daemon.log");
734
877
  if (fs2.existsSync(oldLog)) {
735
878
  const stat2 = fs2.statSync(oldLog);
736
879
  const oldDate = stat2.mtime.toISOString().slice(0, 10);
737
- fs2.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
880
+ fs2.renameSync(oldLog, path10.join(LOG_DIR, `daemon-${oldDate}.log`));
738
881
  }
739
- const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
882
+ const oldLogBackup = path10.join(LOG_DIR, "daemon.log.old");
740
883
  if (fs2.existsSync(oldLogBackup)) {
741
884
  fs2.unlinkSync(oldLogBackup);
742
885
  }
@@ -768,7 +911,7 @@ var init_logger = __esm({
768
911
  }
769
912
  };
770
913
  interceptorInstalled = false;
771
- LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
914
+ LOG_PATH = path10.join(LOG_DIR, `daemon-${getDateStr()}.log`);
772
915
  }
773
916
  });
774
917
 
@@ -1236,9 +1379,9 @@ function buildCliScreenSnapshot(text) {
1236
1379
  function findBinary(name) {
1237
1380
  const trimmed = String(name || "").trim();
1238
1381
  if (!trimmed) return trimmed;
1239
- const expanded = trimmed.startsWith("~") ? path13.join(os9.homedir(), trimmed.slice(1)) : trimmed;
1240
- if (path13.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
1241
- return path13.isAbsolute(expanded) ? expanded : path13.resolve(expanded);
1382
+ const expanded = trimmed.startsWith("~") ? path14.join(os9.homedir(), trimmed.slice(1)) : trimmed;
1383
+ if (path14.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
1384
+ return path14.isAbsolute(expanded) ? expanded : path14.resolve(expanded);
1242
1385
  }
1243
1386
  const isWin = os9.platform() === "win32";
1244
1387
  try {
@@ -1254,7 +1397,7 @@ function findBinary(name) {
1254
1397
  }
1255
1398
  }
1256
1399
  function isScriptBinary(binaryPath) {
1257
- if (!path13.isAbsolute(binaryPath)) return false;
1400
+ if (!path14.isAbsolute(binaryPath)) return false;
1258
1401
  try {
1259
1402
  const fs16 = require("fs");
1260
1403
  const resolved = fs16.realpathSync(binaryPath);
@@ -1270,7 +1413,7 @@ function isScriptBinary(binaryPath) {
1270
1413
  }
1271
1414
  }
1272
1415
  function looksLikeMachOOrElf(filePath) {
1273
- if (!path13.isAbsolute(filePath)) return false;
1416
+ if (!path14.isAbsolute(filePath)) return false;
1274
1417
  try {
1275
1418
  const fs16 = require("fs");
1276
1419
  const resolved = fs16.realpathSync(filePath);
@@ -1359,12 +1502,12 @@ function normalizeCliProviderForRuntime(raw) {
1359
1502
  }
1360
1503
  };
1361
1504
  }
1362
- var os9, path13, import_child_process4, buildCliSpawnEnv;
1505
+ var os9, path14, import_child_process4, buildCliSpawnEnv;
1363
1506
  var init_provider_cli_shared = __esm({
1364
1507
  "src/cli-adapters/provider-cli-shared.ts"() {
1365
1508
  "use strict";
1366
1509
  os9 = __toESM(require("os"));
1367
- path13 = __toESM(require("path"));
1510
+ path14 = __toESM(require("path"));
1368
1511
  import_child_process4 = require("child_process");
1369
1512
  init_spawn_env();
1370
1513
  buildCliSpawnEnv = import_session_host_core.sanitizeSpawnEnv;
@@ -1487,7 +1630,7 @@ var init_provider_cli_config = __esm({
1487
1630
 
1488
1631
  // src/cli-adapters/provider-cli-runtime.ts
1489
1632
  function resolveCliSpawnPlan(options) {
1490
- const { provider, runtimeSettings, workingDir, extraArgs } = options;
1633
+ const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
1491
1634
  const { spawn: spawnConfig } = provider;
1492
1635
  const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
1493
1636
  const binaryPath = findBinary(configuredCommand);
@@ -1495,9 +1638,9 @@ function resolveCliSpawnPlan(options) {
1495
1638
  const allArgs = [...spawnConfig.args, ...extraArgs];
1496
1639
  let shellCmd;
1497
1640
  let shellArgs;
1498
- const useShellUnix = !isWin && (!!spawnConfig.shell || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1641
+ const useShellUnix = !isWin && (!!spawnConfig.shell || !path15.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
1499
1642
  const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
1500
- const useShellWin = !!spawnConfig.shell || isCmdShim || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
1643
+ const useShellWin = !!spawnConfig.shell || isCmdShim || !path15.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
1501
1644
  const useShell = isWin ? useShellWin : useShellUnix;
1502
1645
  if (useShell) {
1503
1646
  shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
@@ -1511,7 +1654,7 @@ function resolveCliSpawnPlan(options) {
1511
1654
  shellCmd = binaryPath;
1512
1655
  shellArgs = allArgs;
1513
1656
  }
1514
- const env = buildCliSpawnEnv(process.env, spawnConfig.env);
1657
+ const env = buildCliSpawnEnv(process.env, { ...spawnConfig.env || {}, ...extraEnv || {} });
1515
1658
  env.TERMINAL_CWD = workingDir;
1516
1659
  return {
1517
1660
  binaryPath,
@@ -1573,12 +1716,12 @@ function respondToCliTerminalQueries(options) {
1573
1716
  }
1574
1717
  return "";
1575
1718
  }
1576
- var os10, path14, import_session_host_core2;
1719
+ var os10, path15, import_session_host_core2;
1577
1720
  var init_provider_cli_runtime = __esm({
1578
1721
  "src/cli-adapters/provider-cli-runtime.ts"() {
1579
1722
  "use strict";
1580
1723
  os10 = __toESM(require("os"));
1581
- path14 = __toESM(require("path"));
1724
+ path15 = __toESM(require("path"));
1582
1725
  import_session_host_core2 = require("@adhdev/session-host-core");
1583
1726
  init_provider_cli_shared();
1584
1727
  }
@@ -1614,8 +1757,9 @@ var init_provider_cli_adapter = __esm({
1614
1757
  init_provider_cli_runtime();
1615
1758
  init_provider_cli_shared();
1616
1759
  ProviderCliAdapter = class _ProviderCliAdapter {
1617
- constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
1760
+ constructor(provider, workingDir, extraArgs = [], extraEnv = {}, transportFactory = new NodePtyTransportFactory()) {
1618
1761
  this.extraArgs = extraArgs;
1762
+ this.extraEnv = extraEnv;
1619
1763
  this.provider = provider;
1620
1764
  this.transportFactory = transportFactory;
1621
1765
  this.cliType = provider.type;
@@ -1766,8 +1910,9 @@ var init_provider_cli_adapter = __esm({
1766
1910
  const currentSnapshot = normalizeScreenSnapshot(screenText);
1767
1911
  const lastSnapshot = this.lastScreenSnapshot;
1768
1912
  if (!lastSnapshot || lastSnapshot === currentSnapshot) return screenText;
1769
- const staleSnapshotLooksActive = /\besc to (?:interrupt|stop)\b|Enter to interrupt, Ctrl\+C to cancel/i.test(lastSnapshot);
1770
- const currentScreenLooksIdle = /(?:^|\n|\r)\s*[❯›>]\s*(?:\n|\r|$)/.test(screenText) && !/\besc to (?:interrupt|stop)\b|Enter to interrupt, Ctrl\+C to cancel/i.test(screenText);
1913
+ const activeScreenPattern = /\besc to (?:interrupt|stop)\b|Enter to interrupt, Ctrl\+C to cancel|Enter to confirm\s*[·•-]\s*Esc to cancel|\b(?:MCP servers?|tool calls?)\b[^\n\r]{0,160}\brequire approval\b/i;
1914
+ const staleSnapshotLooksActive = activeScreenPattern.test(lastSnapshot);
1915
+ const currentScreenLooksIdle = /(?:^|\n|\r)\s*[❯›>]\s*(?:Try\s+["“][^\n\r"”]+["”])?\s*(?:\n|\r|$)/.test(screenText) && !activeScreenPattern.test(screenText);
1771
1916
  if (staleSnapshotLooksActive && currentScreenLooksIdle) return screenText;
1772
1917
  if (currentSnapshot.length >= lastSnapshot.length) return screenText;
1773
1918
  return `${screenText}
@@ -1930,7 +2075,8 @@ ${lastSnapshot}`;
1930
2075
  provider: this.provider,
1931
2076
  runtimeSettings: this.runtimeSettings,
1932
2077
  workingDir: this.workingDir,
1933
- extraArgs: this.extraArgs
2078
+ extraArgs: this.extraArgs,
2079
+ extraEnv: this.extraEnv
1934
2080
  });
1935
2081
  LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
1936
2082
  this.resetTraceSession();
@@ -3727,6 +3873,7 @@ __export(index_exports, {
3727
3873
  createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
3728
3874
  createInteractionId: () => createInteractionId,
3729
3875
  createMesh: () => createMesh,
3876
+ createWorktree: () => createWorktree,
3730
3877
  deleteMesh: () => deleteMesh,
3731
3878
  detectAllVersions: () => detectAllVersions,
3732
3879
  detectCLIs: () => detectCLIs,
@@ -3779,6 +3926,7 @@ __export(index_exports, {
3779
3926
  launchWithCdp: () => launchWithCdp,
3780
3927
  listHostedCliRuntimes: () => listHostedCliRuntimes,
3781
3928
  listMeshes: () => listMeshes,
3929
+ listWorktrees: () => listWorktrees,
3782
3930
  loadConfig: () => loadConfig,
3783
3931
  loadState: () => loadState,
3784
3932
  logCommand: () => logCommand,
@@ -3798,6 +3946,7 @@ __export(index_exports, {
3798
3946
  normalizeSessionModalFields: () => normalizeSessionModalFields,
3799
3947
  parsePorcelainV2Status: () => parsePorcelainV2Status,
3800
3948
  parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
3949
+ parseWorktreeListOutput: () => parseWorktreeListOutput,
3801
3950
  partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
3802
3951
  partitionSessionHostRecords: () => partitionSessionHostRecords,
3803
3952
  prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
@@ -3807,6 +3956,7 @@ __export(index_exports, {
3807
3956
  recordDebugTrace: () => recordDebugTrace,
3808
3957
  registerExtensionProviders: () => registerExtensionProviders,
3809
3958
  removeNode: () => removeNode,
3959
+ removeWorktree: () => removeWorktree,
3810
3960
  resetConfig: () => resetConfig,
3811
3961
  resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
3812
3962
  resetState: () => resetState,
@@ -3816,6 +3966,7 @@ __export(index_exports, {
3816
3966
  resolveGitRepository: () => resolveGitRepository,
3817
3967
  resolveSessionHostAppName: () => resolveSessionHostAppName,
3818
3968
  resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
3969
+ resolveWorktreePath: () => resolveWorktreePath,
3819
3970
  runAsyncBatch: () => runAsyncBatch,
3820
3971
  runGit: () => runGit,
3821
3972
  saveConfig: () => saveConfig,
@@ -4739,6 +4890,7 @@ var FAILURE_REASONS = /* @__PURE__ */ new Set([
4739
4890
  "dirty_index_required",
4740
4891
  "conflict",
4741
4892
  "invalid_args",
4893
+ "nothing_to_commit",
4742
4894
  "git_command_failed"
4743
4895
  ]);
4744
4896
  function failure(reason, error) {
@@ -4983,7 +5135,10 @@ async function gitCheckpoint(workspace, message, includeUntracked) {
4983
5135
  } catch (err) {
4984
5136
  const output = (err?.stdout || "") + (err?.stderr || "");
4985
5137
  if (/nothing to commit/i.test(output)) {
4986
- throw new GitCommandError("git_command_failed", "Nothing to commit");
5138
+ throw new GitCommandError("nothing_to_commit", "Nothing to commit \u2014 working tree is clean.", {
5139
+ stdout: err?.stdout,
5140
+ stderr: err?.stderr
5141
+ });
4987
5142
  }
4988
5143
  throw err;
4989
5144
  }
@@ -5175,20 +5330,23 @@ var TurnSnapshotTracker = class {
5175
5330
  }
5176
5331
  };
5177
5332
 
5333
+ // src/git/index.ts
5334
+ init_git_worktree();
5335
+
5178
5336
  // src/index.ts
5179
5337
  init_config();
5180
5338
 
5181
5339
  // src/config/workspaces.ts
5182
5340
  var fs = __toESM(require("fs"));
5183
5341
  var os = __toESM(require("os"));
5184
- var path4 = __toESM(require("path"));
5342
+ var path5 = __toESM(require("path"));
5185
5343
  var import_crypto2 = require("crypto");
5186
5344
  var MAX_WORKSPACES = 50;
5187
5345
  function expandPath(p) {
5188
5346
  const t = (p || "").trim();
5189
5347
  if (!t) return "";
5190
- if (t.startsWith("~")) return path4.join(os.homedir(), t.slice(1).replace(/^\//, ""));
5191
- return path4.resolve(t);
5348
+ if (t.startsWith("~")) return path5.join(os.homedir(), t.slice(1).replace(/^\//, ""));
5349
+ return path5.resolve(t);
5192
5350
  }
5193
5351
  function validateWorkspacePath(absPath) {
5194
5352
  try {
@@ -5202,7 +5360,7 @@ function validateWorkspacePath(absPath) {
5202
5360
  }
5203
5361
  }
5204
5362
  function defaultWorkspaceLabel(absPath) {
5205
- const base = path4.basename(absPath) || absPath;
5363
+ const base = path5.basename(absPath) || absPath;
5206
5364
  return base;
5207
5365
  }
5208
5366
  function getDefaultWorkspacePath(config) {
@@ -5293,9 +5451,9 @@ function resolveIdeLaunchWorkspace(args, config) {
5293
5451
  return getDefaultWorkspacePath(config) || void 0;
5294
5452
  }
5295
5453
  function findWorkspaceByPath(config, rawPath) {
5296
- const abs = path4.resolve(expandPath(rawPath));
5454
+ const abs = path5.resolve(expandPath(rawPath));
5297
5455
  if (!abs) return void 0;
5298
- return (config.workspaces || []).find((w) => path4.resolve(expandPath(w.path)) === abs);
5456
+ return (config.workspaces || []).find((w) => path5.resolve(expandPath(w.path)) === abs);
5299
5457
  }
5300
5458
  function addWorkspaceEntry(config, rawPath, label, options) {
5301
5459
  const abs = expandPath(rawPath);
@@ -5311,7 +5469,7 @@ function addWorkspaceEntry(config, rawPath, label, options) {
5311
5469
  const v = validateWorkspacePath(abs);
5312
5470
  if (!v.ok) return { error: v.error };
5313
5471
  const list = [...config.workspaces || []];
5314
- if (list.some((w) => path4.resolve(w.path) === abs)) {
5472
+ if (list.some((w) => path5.resolve(w.path) === abs)) {
5315
5473
  return { error: "Workspace already in list" };
5316
5474
  }
5317
5475
  if (list.length >= MAX_WORKSPACES) {
@@ -5345,7 +5503,7 @@ function setDefaultWorkspaceId(config, id) {
5345
5503
  }
5346
5504
 
5347
5505
  // src/config/recent-activity.ts
5348
- var path5 = __toESM(require("path"));
5506
+ var path6 = __toESM(require("path"));
5349
5507
 
5350
5508
  // src/providers/summary-metadata.ts
5351
5509
  function normalizeSummaryItem(item) {
@@ -5414,9 +5572,9 @@ var MAX_ACTIVITY = 30;
5414
5572
  function normalizeWorkspace(workspace) {
5415
5573
  if (!workspace) return "";
5416
5574
  try {
5417
- return path5.resolve(expandPath(workspace));
5575
+ return path6.resolve(expandPath(workspace));
5418
5576
  } catch {
5419
- return path5.resolve(workspace);
5577
+ return path6.resolve(workspace);
5420
5578
  }
5421
5579
  }
5422
5580
  function buildRecentActivityKey(entry) {
@@ -5584,14 +5742,14 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
5584
5742
  }
5585
5743
 
5586
5744
  // src/config/saved-sessions.ts
5587
- var path6 = __toESM(require("path"));
5745
+ var path7 = __toESM(require("path"));
5588
5746
  var MAX_SAVED_SESSIONS = 500;
5589
5747
  function normalizeWorkspace2(workspace) {
5590
5748
  if (!workspace) return "";
5591
5749
  try {
5592
- return path6.resolve(expandPath(workspace));
5750
+ return path7.resolve(expandPath(workspace));
5593
5751
  } catch {
5594
- return path6.resolve(workspace);
5752
+ return path7.resolve(workspace);
5595
5753
  }
5596
5754
  }
5597
5755
  function buildSavedProviderSessionKey(providerSessionId) {
@@ -5770,7 +5928,7 @@ function resetState() {
5770
5928
  var import_child_process = require("child_process");
5771
5929
  var import_fs4 = require("fs");
5772
5930
  var import_os2 = require("os");
5773
- var path7 = __toESM(require("path"));
5931
+ var path8 = __toESM(require("path"));
5774
5932
  var BUILTIN_IDE_DEFINITIONS = [];
5775
5933
  var registeredIDEs = /* @__PURE__ */ new Map();
5776
5934
  function registerIDEDefinition(def) {
@@ -5789,9 +5947,9 @@ function getMergedDefinitions() {
5789
5947
  function findCliCommand(command) {
5790
5948
  const trimmed = String(command || "").trim();
5791
5949
  if (!trimmed) return null;
5792
- if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
5793
- const candidate = trimmed.startsWith("~") ? path7.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
5794
- const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
5950
+ if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
5951
+ const candidate = trimmed.startsWith("~") ? path8.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
5952
+ const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
5795
5953
  return (0, import_fs4.existsSync)(resolved) ? resolved : null;
5796
5954
  }
5797
5955
  try {
@@ -5819,7 +5977,7 @@ function getIdeVersion(cliCommand) {
5819
5977
  function checkPathExists(paths) {
5820
5978
  const home = (0, import_os2.homedir)();
5821
5979
  for (const p of paths) {
5822
- const normalized = p.startsWith("~") ? path7.join(home, p.slice(1)) : p;
5980
+ const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
5823
5981
  if (normalized.includes("*")) {
5824
5982
  const username = home.split(/[\\/]/).pop() || "";
5825
5983
  const resolved = normalized.replace("*", username);
@@ -5831,19 +5989,19 @@ function checkPathExists(paths) {
5831
5989
  return null;
5832
5990
  }
5833
5991
  async function detectIDEs(providerLoader) {
5834
- const os21 = (0, import_os2.platform)();
5992
+ const os22 = (0, import_os2.platform)();
5835
5993
  const results = [];
5836
5994
  for (const def of getMergedDefinitions()) {
5837
5995
  const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
5838
- const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os21] || []) || []);
5996
+ const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os22] || []) || []);
5839
5997
  let resolvedCli = cliPath;
5840
- if (!resolvedCli && appPath && os21 === "darwin") {
5998
+ if (!resolvedCli && appPath && os22 === "darwin") {
5841
5999
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
5842
6000
  if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
5843
6001
  }
5844
- if (!resolvedCli && appPath && os21 === "win32") {
5845
- const { dirname: dirname8 } = await import("path");
5846
- const appDir = dirname8(appPath);
6002
+ if (!resolvedCli && appPath && os22 === "win32") {
6003
+ const { dirname: dirname9 } = await import("path");
6004
+ const appDir = dirname9(appPath);
5847
6005
  const candidates = [
5848
6006
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
5849
6007
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -5858,7 +6016,7 @@ async function detectIDEs(providerLoader) {
5858
6016
  }
5859
6017
  }
5860
6018
  }
5861
- const installed = os21 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
6019
+ const installed = os22 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
5862
6020
  const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
5863
6021
  results.push({
5864
6022
  id: def.id,
@@ -5877,7 +6035,7 @@ async function detectIDEs(providerLoader) {
5877
6035
  // src/detection/cli-detector.ts
5878
6036
  var import_child_process2 = require("child_process");
5879
6037
  var os2 = __toESM(require("os"));
5880
- var path8 = __toESM(require("path"));
6038
+ var path9 = __toESM(require("path"));
5881
6039
  var import_fs5 = require("fs");
5882
6040
  function parseVersion(raw) {
5883
6041
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
@@ -5890,18 +6048,18 @@ function shellQuote(value) {
5890
6048
  function expandHome(value) {
5891
6049
  const trimmed = value.trim();
5892
6050
  if (!trimmed.startsWith("~")) return trimmed;
5893
- return path8.join(os2.homedir(), trimmed.slice(1));
6051
+ return path9.join(os2.homedir(), trimmed.slice(1));
5894
6052
  }
5895
6053
  function isExplicitCommandPath(command) {
5896
6054
  const trimmed = command.trim();
5897
- return path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
6055
+ return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
5898
6056
  }
5899
6057
  function resolveCommandPath(command) {
5900
6058
  const trimmed = command.trim();
5901
6059
  if (!trimmed) return null;
5902
6060
  if (isExplicitCommandPath(trimmed)) {
5903
6061
  const expanded = expandHome(trimmed);
5904
- const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
6062
+ const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
5905
6063
  return (0, import_fs5.existsSync)(candidate) ? candidate : null;
5906
6064
  }
5907
6065
  return null;
@@ -8170,9 +8328,9 @@ ${cleanBody}`;
8170
8328
 
8171
8329
  // src/config/chat-history.ts
8172
8330
  var fs3 = __toESM(require("fs"));
8173
- var path10 = __toESM(require("path"));
8331
+ var path11 = __toESM(require("path"));
8174
8332
  var os5 = __toESM(require("os"));
8175
- var HISTORY_DIR = path10.join(os5.homedir(), ".adhdev", "history");
8333
+ var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
8176
8334
  var RETAIN_DAYS = 30;
8177
8335
  var SAVED_HISTORY_INDEX_VERSION = 1;
8178
8336
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -8335,7 +8493,7 @@ function extractSavedHistorySessionIdFromFile(file) {
8335
8493
  function buildSavedHistoryFileSignatureMap(dir, files) {
8336
8494
  return new Map(files.map((file) => {
8337
8495
  try {
8338
- const stat2 = fs3.statSync(path10.join(dir, file));
8496
+ const stat2 = fs3.statSync(path11.join(dir, file));
8339
8497
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
8340
8498
  } catch {
8341
8499
  return [file, `${file}:missing`];
@@ -8346,7 +8504,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
8346
8504
  return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
8347
8505
  }
8348
8506
  function getSavedHistoryIndexFilePath(dir) {
8349
- return path10.join(dir, SAVED_HISTORY_INDEX_FILE);
8507
+ return path11.join(dir, SAVED_HISTORY_INDEX_FILE);
8350
8508
  }
8351
8509
  function getSavedHistoryIndexLockPath(dir) {
8352
8510
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -8448,7 +8606,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
8448
8606
  }
8449
8607
  for (const file of Array.from(currentEntries.keys())) {
8450
8608
  if (incomingFiles.has(file)) continue;
8451
- if (!fs3.existsSync(path10.join(dir, file))) {
8609
+ if (!fs3.existsSync(path11.join(dir, file))) {
8452
8610
  currentEntries.delete(file);
8453
8611
  }
8454
8612
  }
@@ -8474,7 +8632,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
8474
8632
  const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
8475
8633
  const files = listHistoryFiles(dir);
8476
8634
  for (const file of files) {
8477
- const stat2 = fs3.statSync(path10.join(dir, file));
8635
+ const stat2 = fs3.statSync(path11.join(dir, file));
8478
8636
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
8479
8637
  }
8480
8638
  return false;
@@ -8484,14 +8642,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
8484
8642
  }
8485
8643
  function buildSavedHistoryFileSignature(dir, file) {
8486
8644
  try {
8487
- const stat2 = fs3.statSync(path10.join(dir, file));
8645
+ const stat2 = fs3.statSync(path11.join(dir, file));
8488
8646
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
8489
8647
  } catch {
8490
8648
  return `${file}:missing`;
8491
8649
  }
8492
8650
  }
8493
8651
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
8494
- const filePath = path10.join(dir, file);
8652
+ const filePath = path11.join(dir, file);
8495
8653
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
8496
8654
  const currentEntry = entries.get(file) || null;
8497
8655
  const nextSummary = updater(currentEntry?.summary || null);
@@ -8564,7 +8722,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
8564
8722
  function computeSavedHistoryFileSummary(dir, file) {
8565
8723
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
8566
8724
  if (!historySessionId) return null;
8567
- const filePath = path10.join(dir, file);
8725
+ const filePath = path11.join(dir, file);
8568
8726
  const content = fs3.readFileSync(filePath, "utf-8");
8569
8727
  const lines = content.split("\n").filter(Boolean);
8570
8728
  let messageCount = 0;
@@ -8651,7 +8809,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
8651
8809
  const summaryBySessionId = /* @__PURE__ */ new Map();
8652
8810
  const nextPersistedEntries = /* @__PURE__ */ new Map();
8653
8811
  for (const file of files.slice().sort()) {
8654
- const filePath = path10.join(dir, file);
8812
+ const filePath = path11.join(dir, file);
8655
8813
  const signature = fileSignatures.get(file) || `${file}:missing`;
8656
8814
  const cached = savedHistoryFileSummaryCache.get(filePath);
8657
8815
  const persisted = persistedEntries.get(file);
@@ -8771,12 +8929,12 @@ var ChatHistoryWriter = class {
8771
8929
  });
8772
8930
  }
8773
8931
  if (newMessages.length === 0) return;
8774
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
8932
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8775
8933
  fs3.mkdirSync(dir, { recursive: true });
8776
8934
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8777
8935
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
8778
8936
  const fileName = `${filePrefix}${date}.jsonl`;
8779
- const filePath = path10.join(dir, fileName);
8937
+ const filePath = path11.join(dir, fileName);
8780
8938
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
8781
8939
  fs3.appendFileSync(filePath, lines, "utf-8");
8782
8940
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -8867,11 +9025,11 @@ var ChatHistoryWriter = class {
8867
9025
  const ws = String(workspace || "").trim();
8868
9026
  if (!id || !ws) return;
8869
9027
  try {
8870
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9028
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8871
9029
  fs3.mkdirSync(dir, { recursive: true });
8872
9030
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8873
9031
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
8874
- const filePath = path10.join(dir, fileName);
9032
+ const filePath = path11.join(dir, fileName);
8875
9033
  const record = {
8876
9034
  ts: (/* @__PURE__ */ new Date()).toISOString(),
8877
9035
  receivedAt: Date.now(),
@@ -8917,14 +9075,14 @@ var ChatHistoryWriter = class {
8917
9075
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
8918
9076
  this.lastSeenCounts.delete(fromDedupKey);
8919
9077
  }
8920
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9078
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8921
9079
  if (!fs3.existsSync(dir)) return;
8922
9080
  const fromPrefix = `${this.sanitize(fromId)}_`;
8923
9081
  const toPrefix = `${this.sanitize(toId)}_`;
8924
9082
  const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
8925
9083
  for (const file of files) {
8926
- const sourcePath = path10.join(dir, file);
8927
- const targetPath = path10.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
9084
+ const sourcePath = path11.join(dir, file);
9085
+ const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
8928
9086
  const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
8929
9087
  const rewritten = sourceLines.map((line) => {
8930
9088
  try {
@@ -8958,13 +9116,13 @@ var ChatHistoryWriter = class {
8958
9116
  const sessionId = String(historySessionId || "").trim();
8959
9117
  if (!sessionId) return;
8960
9118
  try {
8961
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9119
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8962
9120
  if (!fs3.existsSync(dir)) return;
8963
9121
  const prefix = `${this.sanitize(sessionId)}_`;
8964
9122
  const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
8965
9123
  const seen = /* @__PURE__ */ new Set();
8966
9124
  for (const file of files) {
8967
- const filePath = path10.join(dir, file);
9125
+ const filePath = path11.join(dir, file);
8968
9126
  const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8969
9127
  const next = [];
8970
9128
  for (const line of lines) {
@@ -9018,11 +9176,11 @@ var ChatHistoryWriter = class {
9018
9176
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
9019
9177
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
9020
9178
  for (const dir of agentDirs) {
9021
- const dirPath = path10.join(HISTORY_DIR, dir.name);
9179
+ const dirPath = path11.join(HISTORY_DIR, dir.name);
9022
9180
  const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
9023
9181
  let removedAny = false;
9024
9182
  for (const file of files) {
9025
- const filePath = path10.join(dirPath, file);
9183
+ const filePath = path11.join(dirPath, file);
9026
9184
  const stat2 = fs3.statSync(filePath);
9027
9185
  if (stat2.mtimeMs < cutoff) {
9028
9186
  fs3.unlinkSync(filePath);
@@ -9072,13 +9230,13 @@ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeR
9072
9230
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
9073
9231
  try {
9074
9232
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
9075
- const dir = path10.join(HISTORY_DIR, sanitized);
9233
+ const dir = path11.join(HISTORY_DIR, sanitized);
9076
9234
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
9077
9235
  const files = listHistoryFiles(dir, historySessionId);
9078
9236
  const allMessages = [];
9079
9237
  const seen = /* @__PURE__ */ new Set();
9080
9238
  for (const file of files) {
9081
- const filePath = path10.join(dir, file);
9239
+ const filePath = path11.join(dir, file);
9082
9240
  const content = fs3.readFileSync(filePath, "utf-8");
9083
9241
  const lines = content.trim().split("\n").filter(Boolean);
9084
9242
  for (let i = 0; i < lines.length; i++) {
@@ -9102,7 +9260,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
9102
9260
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
9103
9261
  try {
9104
9262
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
9105
- const dir = path10.join(HISTORY_DIR, sanitized);
9263
+ const dir = path11.join(HISTORY_DIR, sanitized);
9106
9264
  if (!fs3.existsSync(dir)) {
9107
9265
  savedHistorySessionCache.delete(sanitized);
9108
9266
  return { sessions: [], hasMore: false };
@@ -9163,11 +9321,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
9163
9321
  }
9164
9322
  function readExistingSessionStartRecord(agentType, historySessionId) {
9165
9323
  try {
9166
- const dir = path10.join(HISTORY_DIR, agentType);
9324
+ const dir = path11.join(HISTORY_DIR, agentType);
9167
9325
  if (!fs3.existsSync(dir)) return null;
9168
9326
  const files = listHistoryFiles(dir, historySessionId).sort();
9169
9327
  for (const file of files) {
9170
- const lines = fs3.readFileSync(path10.join(dir, file), "utf-8").split("\n").filter(Boolean);
9328
+ const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
9171
9329
  for (const line of lines) {
9172
9330
  try {
9173
9331
  const parsed = JSON.parse(line);
@@ -9187,16 +9345,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
9187
9345
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
9188
9346
  if (records.length === 0) return false;
9189
9347
  try {
9190
- const dir = path10.join(HISTORY_DIR, agentType);
9348
+ const dir = path11.join(HISTORY_DIR, agentType);
9191
9349
  fs3.mkdirSync(dir, { recursive: true });
9192
9350
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
9193
9351
  for (const file of fs3.readdirSync(dir)) {
9194
9352
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
9195
- fs3.unlinkSync(path10.join(dir, file));
9353
+ fs3.unlinkSync(path11.join(dir, file));
9196
9354
  }
9197
9355
  }
9198
9356
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
9199
- const filePath = path10.join(dir, `${prefix}${targetDate}.jsonl`);
9357
+ const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
9200
9358
  fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
9201
9359
  `, "utf-8");
9202
9360
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -11191,6 +11349,14 @@ function getActiveChatOptions(profile) {
11191
11349
  if (profile === "full") return {};
11192
11350
  return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
11193
11351
  }
11352
+ function resolveSessionStatus(activeChat, providerStatus) {
11353
+ const chatStatus = normalizeManagedStatus(activeChat?.status, { activeModal: activeChat?.activeModal || null });
11354
+ const topLevelStatus = normalizeManagedStatus(providerStatus, { activeModal: activeChat?.activeModal || null });
11355
+ if (chatStatus === "waiting_approval" || topLevelStatus === "waiting_approval") return "waiting_approval";
11356
+ if (chatStatus === "generating" || topLevelStatus === "generating") return "generating";
11357
+ if (topLevelStatus !== "idle") return topLevelStatus;
11358
+ return chatStatus;
11359
+ }
11194
11360
  function shouldIncludeSessionControls(profile) {
11195
11361
  return profile !== "live";
11196
11362
  }
@@ -11269,9 +11435,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
11269
11435
  providerName: state.name,
11270
11436
  kind: "workspace",
11271
11437
  transport: "cdp-page",
11272
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11273
- activeModal: activeChat?.activeModal || null
11274
- }),
11438
+ status: resolveSessionStatus(activeChat, state.status),
11275
11439
  title,
11276
11440
  workspace,
11277
11441
  ...git && { git },
@@ -11306,9 +11470,7 @@ function buildExtensionAgentSession(parent, ext, options) {
11306
11470
  providerSessionId: ext.providerSessionId,
11307
11471
  kind: "agent",
11308
11472
  transport: "cdp-webview",
11309
- status: normalizeManagedStatus(activeChat?.status || ext.status, {
11310
- activeModal: activeChat?.activeModal || null
11311
- }),
11473
+ status: resolveSessionStatus(activeChat, ext.status),
11312
11474
  title: activeChat?.title || ext.name,
11313
11475
  workspace,
11314
11476
  ...git && { git },
@@ -11358,9 +11520,7 @@ function buildCliSession(state, options) {
11358
11520
  providerSessionId: state.providerSessionId,
11359
11521
  kind: "agent",
11360
11522
  transport: "pty",
11361
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11362
- activeModal: activeChat?.activeModal || null
11363
- }),
11523
+ status: resolveSessionStatus(activeChat, state.status),
11364
11524
  title: activeChat?.title || state.name,
11365
11525
  workspace,
11366
11526
  ...git && { git },
@@ -11408,9 +11568,7 @@ function buildAcpSession(state, options) {
11408
11568
  providerName: state.name,
11409
11569
  kind: "agent",
11410
11570
  transport: "acp",
11411
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11412
- activeModal: activeChat?.activeModal || null
11413
- }),
11571
+ status: resolveSessionStatus(activeChat, state.status),
11414
11572
  title: activeChat?.title || state.name,
11415
11573
  workspace,
11416
11574
  ...git && { git },
@@ -11533,7 +11691,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
11533
11691
  // src/commands/chat-commands.ts
11534
11692
  var fs4 = __toESM(require("fs"));
11535
11693
  var os6 = __toESM(require("os"));
11536
- var path11 = __toESM(require("path"));
11694
+ var path12 = __toESM(require("path"));
11537
11695
  var import_node_crypto = require("crypto");
11538
11696
 
11539
11697
  // src/providers/provider-input-support.ts
@@ -11896,6 +12054,34 @@ function normalizeReadChatCommandStatus(status, activeModal) {
11896
12054
  return raw;
11897
12055
  }
11898
12056
  }
12057
+ function isGeneratingLikeStatus(status) {
12058
+ return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
12059
+ }
12060
+ function shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus) {
12061
+ if (!isGeneratingLikeStatus(parsedStatus)) return false;
12062
+ if (hasNonEmptyModalButtons(activeModal)) return false;
12063
+ const adapterRawStatus = typeof adapterStatus?.status === "string" ? adapterStatus.status.trim() : "";
12064
+ if (adapterRawStatus !== "idle") return false;
12065
+ if (typeof adapter.isProcessing === "function" && adapter.isProcessing()) return false;
12066
+ return true;
12067
+ }
12068
+ function normalizeCliReadChatStatus(parsedStatus, activeModal, adapter, adapterStatus) {
12069
+ if (shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus)) return "idle";
12070
+ return typeof parsedStatus === "string" && parsedStatus.trim() ? parsedStatus : "idle";
12071
+ }
12072
+ function finalizeStreamingMessagesWhenIdle(messages, status) {
12073
+ if (status !== "idle") return messages;
12074
+ return messages.map((message) => {
12075
+ const meta = message.meta && typeof message.meta === "object" ? message.meta : void 0;
12076
+ const hasStreamingMeta = meta?.streaming === true;
12077
+ if (message.bubbleState !== "streaming" && !hasStreamingMeta) return message;
12078
+ return {
12079
+ ...message,
12080
+ ...message.bubbleState === "streaming" ? { bubbleState: "final" } : {},
12081
+ ...hasStreamingMeta ? { meta: { ...meta, streaming: false } } : {}
12082
+ };
12083
+ });
12084
+ }
11899
12085
  function buildReadChatCommandResult(payload, args) {
11900
12086
  let validatedPayload;
11901
12087
  const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
@@ -12044,7 +12230,7 @@ function buildDebugBundleText(bundle) {
12044
12230
  }
12045
12231
  function getChatDebugBundleDir() {
12046
12232
  const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
12047
- return override || path11.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
12233
+ return override || path12.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
12048
12234
  }
12049
12235
  function safeBundleIdSegment(value, fallback) {
12050
12236
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -12077,7 +12263,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
12077
12263
  const bundleId = createChatDebugBundleId(targetSessionId);
12078
12264
  const dir = getChatDebugBundleDir();
12079
12265
  fs4.mkdirSync(dir, { recursive: true });
12080
- const savedPath = path11.join(dir, `${bundleId}.json`);
12266
+ const savedPath = path12.join(dir, `${bundleId}.json`);
12081
12267
  const json = `${JSON.stringify(bundle, null, 2)}
12082
12268
  `;
12083
12269
  fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
@@ -12307,7 +12493,7 @@ async function handleChatHistory(h, args) {
12307
12493
  }
12308
12494
  }
12309
12495
  async function handleReadChat(h, args) {
12310
- const provider = h.getProvider(args?.agentType);
12496
+ const provider = h.getProvider(args?.agentType || args?.providerType);
12311
12497
  const transport = getTargetTransport(h, provider);
12312
12498
  const historySessionId = getHistorySessionId(h, args);
12313
12499
  const _log = (msg) => LOG.debug("Command", `[read_chat] ${msg}`);
@@ -12334,10 +12520,13 @@ async function handleReadChat(h, args) {
12334
12520
  const transcriptAuthority = parsedRecord.transcriptAuthority === "provider" || parsedRecord.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
12335
12521
  const coverage = parsedRecord.coverage === "full" || parsedRecord.coverage === "tail" || parsedRecord.coverage === "current-turn" ? parsedRecord.coverage : void 0;
12336
12522
  const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
12337
- const returnedStatus = parsedRecord.status || "idle";
12338
- LOG.debug("Command", `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord.status || "")} parsedMsgCount=${parsedRecord.messages.length}`);
12523
+ const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus);
12524
+ const runtimeMessageMerger = getTargetInstance(h, args);
12525
+ const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus);
12526
+ const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
12527
+ LOG.debug("Command", `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord.status || "")} parsedMsgCount=${parsedRecord.messages.length} returnedMsgCount=${returnedMessages.length}`);
12339
12528
  return buildReadChatCommandResult({
12340
- messages: parsedRecord.messages,
12529
+ messages: returnedMessages,
12341
12530
  status: returnedStatus,
12342
12531
  activeModal,
12343
12532
  debugReadChat: {
@@ -12348,7 +12537,7 @@ async function handleReadChat(h, args) {
12348
12537
  returnedStatus: String(returnedStatus || ""),
12349
12538
  shouldPreferAdapterMessages: false,
12350
12539
  parsedMsgCount: parsedRecord.messages.length,
12351
- returnedMsgCount: parsedRecord.messages.length
12540
+ returnedMsgCount: returnedMessages.length
12352
12541
  },
12353
12542
  ...title ? { title } : {},
12354
12543
  ...providerSessionId ? { providerSessionId } : {},
@@ -13221,7 +13410,7 @@ async function handleResolveAction(h, args) {
13221
13410
 
13222
13411
  // src/commands/cdp-commands.ts
13223
13412
  var fs5 = __toESM(require("fs"));
13224
- var path12 = __toESM(require("path"));
13413
+ var path13 = __toESM(require("path"));
13225
13414
  var os7 = __toESM(require("os"));
13226
13415
  var KEY_TO_VK = {
13227
13416
  Backspace: 8,
@@ -13478,25 +13667,25 @@ function resolveSafePath(requestedPath) {
13478
13667
  const inputPath = rawPath || ".";
13479
13668
  const home = os7.homedir();
13480
13669
  if (inputPath.startsWith("~")) {
13481
- return path12.resolve(path12.join(home, inputPath.slice(1)));
13670
+ return path13.resolve(path13.join(home, inputPath.slice(1)));
13482
13671
  }
13483
13672
  if (process.platform === "win32") {
13484
13673
  const normalized = normalizeWindowsRequestedPath(inputPath);
13485
- if (path12.win32.isAbsolute(normalized)) {
13486
- return path12.win32.normalize(normalized);
13674
+ if (path13.win32.isAbsolute(normalized)) {
13675
+ return path13.win32.normalize(normalized);
13487
13676
  }
13488
- return path12.win32.resolve(normalized);
13677
+ return path13.win32.resolve(normalized);
13489
13678
  }
13490
- if (path12.isAbsolute(inputPath)) {
13491
- return path12.normalize(inputPath);
13679
+ if (path13.isAbsolute(inputPath)) {
13680
+ return path13.normalize(inputPath);
13492
13681
  }
13493
- return path12.resolve(inputPath);
13682
+ return path13.resolve(inputPath);
13494
13683
  }
13495
13684
  function listDirectoryEntriesSafe(dirPath) {
13496
13685
  const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
13497
13686
  const files = [];
13498
13687
  for (const entry of entries) {
13499
- const entryPath = path12.join(dirPath, entry.name);
13688
+ const entryPath = path13.join(dirPath, entry.name);
13500
13689
  try {
13501
13690
  if (entry.isDirectory()) {
13502
13691
  files.push({ name: entry.name, type: "directory" });
@@ -13550,7 +13739,7 @@ async function handleFileRead(h, args) {
13550
13739
  async function handleFileWrite(h, args) {
13551
13740
  try {
13552
13741
  const filePath = resolveSafePath(args?.path);
13553
- fs5.mkdirSync(path12.dirname(filePath), { recursive: true });
13742
+ fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
13554
13743
  fs5.writeFileSync(filePath, args?.content || "", "utf-8");
13555
13744
  return { success: true, path: filePath };
13556
13745
  } catch (e) {
@@ -14334,9 +14523,11 @@ var DaemonCommandHandler = class {
14334
14523
  }
14335
14524
  const sessionLookupFailed = !!targetSessionId && !session;
14336
14525
  const managerKey = this.extractIdeType(args, sessionLookupFailed);
14337
- let providerType;
14526
+ let providerType = args?.agentType || args?.providerType;
14338
14527
  if (!sessionLookupFailed) {
14339
- providerType = session?.providerType || args?.agentType || args?.providerType || this.inferProviderType(managerKey);
14528
+ providerType = session?.providerType || providerType || this.inferProviderType(managerKey);
14529
+ } else if (!providerType) {
14530
+ providerType = this.inferProviderType(managerKey);
14340
14531
  }
14341
14532
  return { session, managerKey, providerType, sessionLookupFailed };
14342
14533
  }
@@ -14416,7 +14607,8 @@ var DaemonCommandHandler = class {
14416
14607
  "pty_resize",
14417
14608
  "invoke_provider_script"
14418
14609
  ]);
14419
- if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd)) {
14610
+ const allowsInactiveReadChatFallback = cmd === "read_chat" && !!this._currentRoute.providerType && (typeof args?.providerSessionId === "string" && args.providerSessionId.trim().length > 0 || typeof args?.historySessionId === "string" && args.historySessionId.trim().length > 0);
14611
+ if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd) && !allowsInactiveReadChatFallback) {
14420
14612
  const result2 = {
14421
14613
  success: false,
14422
14614
  error: `Live session not found for targetSessionId: ${String(args?.targetSessionId || "").trim() || "unknown"}`
@@ -14669,7 +14861,7 @@ var DaemonCommandHandler = class {
14669
14861
 
14670
14862
  // src/commands/cli-manager.ts
14671
14863
  var os13 = __toESM(require("os"));
14672
- var path16 = __toESM(require("path"));
14864
+ var path17 = __toESM(require("path"));
14673
14865
  var crypto4 = __toESM(require("crypto"));
14674
14866
  var import_fs6 = require("fs");
14675
14867
  var import_child_process6 = require("child_process");
@@ -14679,7 +14871,7 @@ init_config();
14679
14871
 
14680
14872
  // src/providers/cli-provider-instance.ts
14681
14873
  var os12 = __toESM(require("os"));
14682
- var path15 = __toESM(require("path"));
14874
+ var path16 = __toESM(require("path"));
14683
14875
  var crypto3 = __toESM(require("crypto"));
14684
14876
  var fs6 = __toESM(require("fs"));
14685
14877
  var import_node_module = require("module");
@@ -14738,7 +14930,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
14738
14930
  var CachedDatabaseSync = null;
14739
14931
  function getDatabaseSync() {
14740
14932
  if (CachedDatabaseSync) return CachedDatabaseSync;
14741
- const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path15.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
14933
+ const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path16.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
14742
14934
  const sqliteModule = requireFn(`node:${"sqlite"}`);
14743
14935
  CachedDatabaseSync = sqliteModule.DatabaseSync;
14744
14936
  if (!CachedDatabaseSync) {
@@ -14791,7 +14983,7 @@ var CliProviderInstance = class {
14791
14983
  this.providerSessionId = options?.providerSessionId;
14792
14984
  this.launchMode = options?.launchMode || "new";
14793
14985
  this.onProviderSessionResolved = options?.onProviderSessionResolved;
14794
- this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, transportFactory);
14986
+ this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, options?.extraEnv || {}, transportFactory);
14795
14987
  this.monitor = new StatusMonitor();
14796
14988
  this.historyWriter = new ChatHistoryWriter();
14797
14989
  }
@@ -15268,7 +15460,19 @@ var CliProviderInstance = class {
15268
15460
  }
15269
15461
  }
15270
15462
  pushEvent(event) {
15271
- this.events.push(event);
15463
+ const enrichedEvent = {
15464
+ ...event,
15465
+ instanceId: typeof event.instanceId === "string" && event.instanceId.trim() ? event.instanceId : this.instanceId,
15466
+ targetSessionId: typeof event.targetSessionId === "string" && event.targetSessionId.trim() ? event.targetSessionId : this.instanceId,
15467
+ providerType: typeof event.providerType === "string" && event.providerType.trim() ? event.providerType : this.type,
15468
+ workspaceName: typeof event.workspaceName === "string" && event.workspaceName.trim() ? event.workspaceName : this.workingDir,
15469
+ providerSessionId: typeof event.providerSessionId === "string" && event.providerSessionId.trim() ? event.providerSessionId : this.providerSessionId
15470
+ };
15471
+ if (this.context?.emitProviderEvent) {
15472
+ this.context.emitProviderEvent(enrichedEvent);
15473
+ return;
15474
+ }
15475
+ this.events.push(enrichedEvent);
15272
15476
  }
15273
15477
  flushEvents() {
15274
15478
  const events = [...this.events];
@@ -15475,12 +15679,31 @@ ${effect.notification.body || ""}`.trim();
15475
15679
  );
15476
15680
  }
15477
15681
  }
15682
+ mergeRuntimeChatMessages(parsedMessages) {
15683
+ return this.mergeConversationMessages(parsedMessages);
15684
+ }
15478
15685
  mergeConversationMessages(parsedMessages) {
15479
15686
  if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
15480
- return normalizeChatMessages([...parsedMessages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
15481
- const aTime = a.message.receivedAt || a.message.timestamp || 0;
15482
- const bTime = b.message.receivedAt || b.message.timestamp || 0;
15483
- if (aTime !== bTime) return aTime - bTime;
15687
+ const parsedEntries = parsedMessages.map((message, index) => ({
15688
+ message,
15689
+ index,
15690
+ source: "parsed"
15691
+ }));
15692
+ const runtimeEntries = this.runtimeMessages.map((entry, index) => ({
15693
+ message: entry.message,
15694
+ index: parsedMessages.length + index,
15695
+ source: "runtime"
15696
+ }));
15697
+ const getTime = (message) => {
15698
+ const value = typeof message.receivedAt === "number" ? message.receivedAt : typeof message.timestamp === "number" ? message.timestamp : 0;
15699
+ return Number.isFinite(value) && value > 0 ? value : 0;
15700
+ };
15701
+ return normalizeChatMessages([...parsedEntries, ...runtimeEntries].sort((a, b) => {
15702
+ const aTime = getTime(a.message);
15703
+ const bTime = getTime(b.message);
15704
+ if (aTime && bTime && aTime !== bTime) return aTime - bTime;
15705
+ if (aTime && !bTime && a.source === "runtime" && b.source === "parsed") return -1;
15706
+ if (!aTime && bTime && a.source === "parsed" && b.source === "runtime") return 1;
15484
15707
  return a.index - b.index;
15485
15708
  }).map((entry) => entry.message));
15486
15709
  }
@@ -16804,11 +17027,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
16804
17027
  // src/commands/cli-manager.ts
16805
17028
  function isExplicitCommand(command) {
16806
17029
  const trimmed = command.trim();
16807
- return path16.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
17030
+ return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
16808
17031
  }
16809
17032
  function expandExecutable(command) {
16810
17033
  const trimmed = command.trim();
16811
- return trimmed.startsWith("~") ? path16.join(os13.homedir(), trimmed.slice(1)) : trimmed;
17034
+ return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
16812
17035
  }
16813
17036
  function commandExists(command) {
16814
17037
  const trimmed = command.trim();
@@ -16832,6 +17055,35 @@ function colorize(color, text) {
16832
17055
  const fn = chalkApi?.[color];
16833
17056
  return typeof fn === "function" ? fn(text) : text;
16834
17057
  }
17058
+ var COORDINATOR_DELEGATED_ENV_UNSETS = {
17059
+ ADHDEV_INLINE_MESH: "",
17060
+ ADHDEV_MCP_TRANSPORT: "",
17061
+ ADHDEV_MESH_ID: "",
17062
+ HERMES_EPHEMERAL_SYSTEM_PROMPT: ""
17063
+ };
17064
+ function hasCliArg(args, flag) {
17065
+ return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
17066
+ }
17067
+ function ensureEmptyDelegatedMcpConfig(workspace) {
17068
+ const baseDir = path17.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
17069
+ (0, import_fs6.mkdirSync)(baseDir, { recursive: true });
17070
+ const workspaceHash = crypto4.createHash("sha256").update(path17.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
17071
+ const filePath = path17.join(baseDir, `${workspaceHash}.json`);
17072
+ (0, import_fs6.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
17073
+ return filePath;
17074
+ }
17075
+ function buildCoordinatorDelegatedCliLaunchOptions(input) {
17076
+ const cliType = String(input.cliType || "").trim();
17077
+ const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
17078
+ const env = { ...input.env || {}, ...COORDINATOR_DELEGATED_ENV_UNSETS };
17079
+ if (cliType === "hermes-cli" && !hasCliArg(cliArgs, "--ignore-user-config")) {
17080
+ cliArgs.unshift("--ignore-user-config");
17081
+ }
17082
+ if (cliType === "claude-cli" && !hasCliArg(cliArgs, "--mcp-config")) {
17083
+ cliArgs.unshift("--mcp-config", ensureEmptyDelegatedMcpConfig(input.workspace));
17084
+ }
17085
+ return { cliArgs, env };
17086
+ }
16835
17087
  function isUuid(value) {
16836
17088
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
16837
17089
  }
@@ -17002,7 +17254,7 @@ var DaemonCliManager = class {
17002
17254
  attachExisting
17003
17255
  }) || void 0;
17004
17256
  }
17005
- createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false) {
17257
+ createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false, extraEnv) {
17006
17258
  const normalizedType = this.providerLoader.resolveAlias(cliType);
17007
17259
  const provider = this.providerLoader.getMeta(normalizedType);
17008
17260
  if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
@@ -17016,7 +17268,7 @@ var DaemonCliManager = class {
17016
17268
  providerSessionId,
17017
17269
  attachExisting
17018
17270
  );
17019
- return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, transportFactory);
17271
+ return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, extraEnv || {}, transportFactory);
17020
17272
  }
17021
17273
  throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
17022
17274
  }
@@ -17089,7 +17341,7 @@ var DaemonCliManager = class {
17089
17341
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
17090
17342
  const trimmed = (workingDir || "").trim();
17091
17343
  if (!trimmed) throw new Error("working directory required");
17092
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path16.resolve(trimmed);
17344
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
17093
17345
  const normalizedType = this.providerLoader.resolveAlias(cliType);
17094
17346
  const rawProvider = this.providerLoader.getByAlias(cliType);
17095
17347
  const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
@@ -17219,6 +17471,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
17219
17471
  {
17220
17472
  providerSessionId: sessionBinding.providerSessionId,
17221
17473
  launchMode: sessionBinding.launchMode,
17474
+ extraEnv: options?.extraEnv,
17222
17475
  onProviderSessionResolved: ({ providerSessionId, providerName, providerType, workspace }) => {
17223
17476
  this.persistRecentActivity({
17224
17477
  kind: "cli",
@@ -17239,7 +17492,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
17239
17492
  resolvedCliArgs,
17240
17493
  key,
17241
17494
  sessionBinding.providerSessionId,
17242
- false
17495
+ false,
17496
+ options?.extraEnv
17243
17497
  );
17244
17498
  try {
17245
17499
  await adapter.spawn();
@@ -17463,12 +17717,23 @@ Run 'adhdev doctor' for detailed diagnostics.`
17463
17717
  const dir = resolved.path;
17464
17718
  const launchSource = resolved.source;
17465
17719
  if (!cliType) throw new Error("cliType required");
17720
+ const settingsOverride = args?.settings && typeof args.settings === "object" ? args.settings : void 0;
17721
+ const delegatedLaunch = settingsOverride?.launchedByCoordinator === true ? buildCoordinatorDelegatedCliLaunchOptions({
17722
+ cliType,
17723
+ workspace: dir,
17724
+ cliArgs: args?.cliArgs,
17725
+ env: args?.env
17726
+ }) : null;
17466
17727
  const started = await this.startSession(
17467
17728
  cliType,
17468
17729
  dir,
17469
- args?.cliArgs,
17730
+ delegatedLaunch ? delegatedLaunch.cliArgs : args?.cliArgs,
17470
17731
  args?.initialModel,
17471
- { resumeSessionId: args?.resumeSessionId, settingsOverride: args?.settings }
17732
+ {
17733
+ resumeSessionId: args?.resumeSessionId,
17734
+ settingsOverride,
17735
+ extraEnv: delegatedLaunch ? delegatedLaunch.env : args?.env
17736
+ }
17472
17737
  );
17473
17738
  return {
17474
17739
  success: true,
@@ -17590,11 +17855,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
17590
17855
  var import_child_process7 = require("child_process");
17591
17856
  var net = __toESM(require("net"));
17592
17857
  var os15 = __toESM(require("os"));
17593
- var path18 = __toESM(require("path"));
17858
+ var path19 = __toESM(require("path"));
17594
17859
 
17595
17860
  // src/providers/provider-loader.ts
17596
17861
  var fs7 = __toESM(require("fs"));
17597
- var path17 = __toESM(require("path"));
17862
+ var path18 = __toESM(require("path"));
17598
17863
  var os14 = __toESM(require("os"));
17599
17864
  var chokidar = __toESM(require("chokidar"));
17600
17865
  init_logger();
@@ -17918,7 +18183,7 @@ var ProviderLoader = class _ProviderLoader {
17918
18183
  try {
17919
18184
  if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
17920
18185
  return ["ide", "extension", "cli", "acp"].some(
17921
- (category) => fs7.existsSync(path17.join(candidate, category))
18186
+ (category) => fs7.existsSync(path18.join(candidate, category))
17922
18187
  );
17923
18188
  } catch {
17924
18189
  return false;
@@ -17926,20 +18191,20 @@ var ProviderLoader = class _ProviderLoader {
17926
18191
  }
17927
18192
  static hasProviderRootMarker(candidate) {
17928
18193
  try {
17929
- return fs7.existsSync(path17.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
18194
+ return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
17930
18195
  } catch {
17931
18196
  return false;
17932
18197
  }
17933
18198
  }
17934
18199
  detectDefaultUserDir() {
17935
- const fallback = path17.join(os14.homedir(), ".adhdev", "providers");
18200
+ const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
17936
18201
  const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
17937
18202
  const visited = /* @__PURE__ */ new Set();
17938
18203
  for (const start of this.probeStarts) {
17939
- let current = path17.resolve(start);
18204
+ let current = path18.resolve(start);
17940
18205
  while (!visited.has(current)) {
17941
18206
  visited.add(current);
17942
- const siblingCandidate = path17.join(path17.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
18207
+ const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
17943
18208
  if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
17944
18209
  const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
17945
18210
  if (envOptIn || hasMarker) {
@@ -17961,7 +18226,7 @@ var ProviderLoader = class _ProviderLoader {
17961
18226
  return { path: siblingCandidate, source };
17962
18227
  }
17963
18228
  }
17964
- const parent = path17.dirname(current);
18229
+ const parent = path18.dirname(current);
17965
18230
  if (parent === current) break;
17966
18231
  current = parent;
17967
18232
  }
@@ -17971,11 +18236,11 @@ var ProviderLoader = class _ProviderLoader {
17971
18236
  constructor(options) {
17972
18237
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
17973
18238
  this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
17974
- this.defaultProvidersDir = path17.join(os14.homedir(), ".adhdev", "providers");
18239
+ this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
17975
18240
  const detected = this.detectDefaultUserDir();
17976
18241
  this.userDir = detected.path;
17977
18242
  this.userDirSource = detected.source;
17978
- this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
18243
+ this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
17979
18244
  this.disableUpstream = false;
17980
18245
  this.applySourceConfig({
17981
18246
  userDir: options?.userDir,
@@ -18034,7 +18299,7 @@ var ProviderLoader = class _ProviderLoader {
18034
18299
  this.userDir = detected.path;
18035
18300
  this.userDirSource = detected.source;
18036
18301
  }
18037
- this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
18302
+ this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
18038
18303
  this.disableUpstream = this.sourceMode === "no-upstream";
18039
18304
  if (this.explicitProviderDir) {
18040
18305
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
@@ -18048,7 +18313,7 @@ var ProviderLoader = class _ProviderLoader {
18048
18313
  * Canonical provider directory shape for a given root.
18049
18314
  */
18050
18315
  getProviderDir(root, category, type) {
18051
- return path17.join(root, category, type);
18316
+ return path18.join(root, category, type);
18052
18317
  }
18053
18318
  /**
18054
18319
  * Canonical user override directory for a provider.
@@ -18075,7 +18340,7 @@ var ProviderLoader = class _ProviderLoader {
18075
18340
  resolveProviderFile(type, ...segments) {
18076
18341
  const dir = this.findProviderDirInternal(type);
18077
18342
  if (!dir) return null;
18078
- return path17.join(dir, ...segments);
18343
+ return path18.join(dir, ...segments);
18079
18344
  }
18080
18345
  /**
18081
18346
  * Load all providers (3-tier priority)
@@ -18114,7 +18379,7 @@ var ProviderLoader = class _ProviderLoader {
18114
18379
  if (!fs7.existsSync(this.upstreamDir)) return false;
18115
18380
  try {
18116
18381
  return fs7.readdirSync(this.upstreamDir).some(
18117
- (d) => fs7.statSync(path17.join(this.upstreamDir, d)).isDirectory()
18382
+ (d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
18118
18383
  );
18119
18384
  } catch {
18120
18385
  return false;
@@ -18611,8 +18876,8 @@ var ProviderLoader = class _ProviderLoader {
18611
18876
  resolved._resolvedScriptDir = entry.scriptDir;
18612
18877
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
18613
18878
  if (providerDir) {
18614
- const fullDir = path17.join(providerDir, entry.scriptDir);
18615
- resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
18879
+ const fullDir = path18.join(providerDir, entry.scriptDir);
18880
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18616
18881
  }
18617
18882
  matched = true;
18618
18883
  }
@@ -18627,8 +18892,8 @@ var ProviderLoader = class _ProviderLoader {
18627
18892
  resolved._resolvedScriptDir = base.defaultScriptDir;
18628
18893
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
18629
18894
  if (providerDir) {
18630
- const fullDir = path17.join(providerDir, base.defaultScriptDir);
18631
- resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
18895
+ const fullDir = path18.join(providerDir, base.defaultScriptDir);
18896
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18632
18897
  }
18633
18898
  }
18634
18899
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -18645,8 +18910,8 @@ var ProviderLoader = class _ProviderLoader {
18645
18910
  resolved._resolvedScriptDir = dirOverride;
18646
18911
  resolved._resolvedScriptsSource = `versions:${range}`;
18647
18912
  if (providerDir) {
18648
- const fullDir = path17.join(providerDir, dirOverride);
18649
- resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
18913
+ const fullDir = path18.join(providerDir, dirOverride);
18914
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18650
18915
  }
18651
18916
  }
18652
18917
  } else if (override.scripts) {
@@ -18662,8 +18927,8 @@ var ProviderLoader = class _ProviderLoader {
18662
18927
  resolved._resolvedScriptDir = base.defaultScriptDir;
18663
18928
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
18664
18929
  if (providerDir) {
18665
- const fullDir = path17.join(providerDir, base.defaultScriptDir);
18666
- resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
18930
+ const fullDir = path18.join(providerDir, base.defaultScriptDir);
18931
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18667
18932
  }
18668
18933
  }
18669
18934
  }
@@ -18695,14 +18960,14 @@ var ProviderLoader = class _ProviderLoader {
18695
18960
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
18696
18961
  return null;
18697
18962
  }
18698
- const dir = path17.join(providerDir, scriptDir);
18963
+ const dir = path18.join(providerDir, scriptDir);
18699
18964
  if (!fs7.existsSync(dir)) {
18700
18965
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
18701
18966
  return null;
18702
18967
  }
18703
18968
  const cached = this.scriptsCache.get(dir);
18704
18969
  if (cached) return cached;
18705
- const scriptsJs = path17.join(dir, "scripts.js");
18970
+ const scriptsJs = path18.join(dir, "scripts.js");
18706
18971
  if (fs7.existsSync(scriptsJs)) {
18707
18972
  try {
18708
18973
  delete require.cache[require.resolve(scriptsJs)];
@@ -18744,7 +19009,7 @@ var ProviderLoader = class _ProviderLoader {
18744
19009
  return;
18745
19010
  }
18746
19011
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
18747
- this.log(`File changed: ${path17.basename(filePath)}, reloading...`);
19012
+ this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
18748
19013
  this.reload();
18749
19014
  }
18750
19015
  };
@@ -18799,7 +19064,7 @@ var ProviderLoader = class _ProviderLoader {
18799
19064
  }
18800
19065
  const https = require("https");
18801
19066
  const { execSync: execSync7 } = require("child_process");
18802
- const metaPath = path17.join(this.upstreamDir, _ProviderLoader.META_FILE);
19067
+ const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
18803
19068
  let prevEtag = "";
18804
19069
  let prevTimestamp = 0;
18805
19070
  try {
@@ -18859,17 +19124,17 @@ var ProviderLoader = class _ProviderLoader {
18859
19124
  return { updated: false };
18860
19125
  }
18861
19126
  this.log("Downloading latest providers from GitHub...");
18862
- const tmpTar = path17.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
18863
- const tmpExtract = path17.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
19127
+ const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
19128
+ const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
18864
19129
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
18865
19130
  fs7.mkdirSync(tmpExtract, { recursive: true });
18866
19131
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
18867
19132
  const extracted = fs7.readdirSync(tmpExtract);
18868
19133
  const rootDir = extracted.find(
18869
- (d) => fs7.statSync(path17.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
19134
+ (d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
18870
19135
  );
18871
19136
  if (!rootDir) throw new Error("Unexpected tarball structure");
18872
- const sourceDir = path17.join(tmpExtract, rootDir);
19137
+ const sourceDir = path18.join(tmpExtract, rootDir);
18873
19138
  const backupDir = this.upstreamDir + ".bak";
18874
19139
  if (fs7.existsSync(this.upstreamDir)) {
18875
19140
  if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
@@ -18944,8 +19209,8 @@ var ProviderLoader = class _ProviderLoader {
18944
19209
  copyDirRecursive(src, dest) {
18945
19210
  fs7.mkdirSync(dest, { recursive: true });
18946
19211
  for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
18947
- const srcPath = path17.join(src, entry.name);
18948
- const destPath = path17.join(dest, entry.name);
19212
+ const srcPath = path18.join(src, entry.name);
19213
+ const destPath = path18.join(dest, entry.name);
18949
19214
  if (entry.isDirectory()) {
18950
19215
  this.copyDirRecursive(srcPath, destPath);
18951
19216
  } else {
@@ -18956,7 +19221,7 @@ var ProviderLoader = class _ProviderLoader {
18956
19221
  /** .meta.json save */
18957
19222
  writeMeta(metaPath, etag, timestamp) {
18958
19223
  try {
18959
- fs7.mkdirSync(path17.dirname(metaPath), { recursive: true });
19224
+ fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
18960
19225
  fs7.writeFileSync(metaPath, JSON.stringify({
18961
19226
  etag,
18962
19227
  timestamp,
@@ -18973,7 +19238,7 @@ var ProviderLoader = class _ProviderLoader {
18973
19238
  const scan = (d) => {
18974
19239
  try {
18975
19240
  for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
18976
- if (entry.isDirectory()) scan(path17.join(d, entry.name));
19241
+ if (entry.isDirectory()) scan(path18.join(d, entry.name));
18977
19242
  else if (entry.name === "provider.json") count++;
18978
19243
  }
18979
19244
  } catch {
@@ -19201,17 +19466,17 @@ var ProviderLoader = class _ProviderLoader {
19201
19466
  for (const root of searchRoots) {
19202
19467
  if (!fs7.existsSync(root)) continue;
19203
19468
  const candidate = this.getProviderDir(root, cat, type);
19204
- if (fs7.existsSync(path17.join(candidate, "provider.json"))) return candidate;
19205
- const catDir = path17.join(root, cat);
19469
+ if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
19470
+ const catDir = path18.join(root, cat);
19206
19471
  if (fs7.existsSync(catDir)) {
19207
19472
  try {
19208
19473
  for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
19209
19474
  if (!entry.isDirectory()) continue;
19210
- const jsonPath = path17.join(catDir, entry.name, "provider.json");
19475
+ const jsonPath = path18.join(catDir, entry.name, "provider.json");
19211
19476
  if (fs7.existsSync(jsonPath)) {
19212
19477
  try {
19213
19478
  const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
19214
- if (data.type === type) return path17.join(catDir, entry.name);
19479
+ if (data.type === type) return path18.join(catDir, entry.name);
19215
19480
  } catch {
19216
19481
  }
19217
19482
  }
@@ -19228,7 +19493,7 @@ var ProviderLoader = class _ProviderLoader {
19228
19493
  * (template substitution is NOT applied here — scripts.js handles that)
19229
19494
  */
19230
19495
  buildScriptWrappersFromDir(dir) {
19231
- const scriptsJs = path17.join(dir, "scripts.js");
19496
+ const scriptsJs = path18.join(dir, "scripts.js");
19232
19497
  if (fs7.existsSync(scriptsJs)) {
19233
19498
  try {
19234
19499
  delete require.cache[require.resolve(scriptsJs)];
@@ -19242,7 +19507,7 @@ var ProviderLoader = class _ProviderLoader {
19242
19507
  for (const file of fs7.readdirSync(dir)) {
19243
19508
  if (!file.endsWith(".js")) continue;
19244
19509
  const scriptName = toCamel(file.replace(".js", ""));
19245
- const filePath = path17.join(dir, file);
19510
+ const filePath = path18.join(dir, file);
19246
19511
  result[scriptName] = (...args) => {
19247
19512
  try {
19248
19513
  let content = fs7.readFileSync(filePath, "utf-8");
@@ -19302,7 +19567,7 @@ var ProviderLoader = class _ProviderLoader {
19302
19567
  }
19303
19568
  const hasJson = entries.some((e) => e.name === "provider.json");
19304
19569
  if (hasJson) {
19305
- const jsonPath = path17.join(d, "provider.json");
19570
+ const jsonPath = path18.join(d, "provider.json");
19306
19571
  try {
19307
19572
  const raw = fs7.readFileSync(jsonPath, "utf-8");
19308
19573
  const mod = JSON.parse(raw);
@@ -19323,7 +19588,7 @@ var ProviderLoader = class _ProviderLoader {
19323
19588
  this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
19324
19589
  } else {
19325
19590
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
19326
- const scriptsPath = path17.join(d, "scripts.js");
19591
+ const scriptsPath = path18.join(d, "scripts.js");
19327
19592
  if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
19328
19593
  try {
19329
19594
  delete require.cache[require.resolve(scriptsPath)];
@@ -19349,7 +19614,7 @@ var ProviderLoader = class _ProviderLoader {
19349
19614
  if (!entry.isDirectory()) continue;
19350
19615
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
19351
19616
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
19352
- scan(path17.join(d, entry.name));
19617
+ scan(path18.join(d, entry.name));
19353
19618
  }
19354
19619
  }
19355
19620
  };
@@ -19674,8 +19939,8 @@ function detectCurrentWorkspace(ideId) {
19674
19939
  const appNameMap = getMacAppIdentifiers();
19675
19940
  const appName = appNameMap[ideId];
19676
19941
  if (appName) {
19677
- const storagePath = path18.join(
19678
- process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming"),
19942
+ const storagePath = path19.join(
19943
+ process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
19679
19944
  appName,
19680
19945
  "storage.json"
19681
19946
  );
@@ -19864,9 +20129,9 @@ init_logger();
19864
20129
 
19865
20130
  // src/logging/command-log.ts
19866
20131
  var fs8 = __toESM(require("fs"));
19867
- var path19 = __toESM(require("path"));
20132
+ var path20 = __toESM(require("path"));
19868
20133
  var os16 = __toESM(require("os"));
19869
- var LOG_DIR2 = process.platform === "win32" ? path19.join(process.env.LOCALAPPDATA || process.env.APPDATA || path19.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path19.join(os16.homedir(), "Library", "Logs", "adhdev") : path19.join(os16.homedir(), ".local", "share", "adhdev", "logs");
20134
+ var LOG_DIR2 = process.platform === "win32" ? path20.join(process.env.LOCALAPPDATA || process.env.APPDATA || path20.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path20.join(os16.homedir(), "Library", "Logs", "adhdev") : path20.join(os16.homedir(), ".local", "share", "adhdev", "logs");
19870
20135
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
19871
20136
  var MAX_DAYS = 7;
19872
20137
  try {
@@ -19904,13 +20169,13 @@ function getDateStr2() {
19904
20169
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
19905
20170
  }
19906
20171
  var currentDate2 = getDateStr2();
19907
- var currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20172
+ var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
19908
20173
  var writeCount2 = 0;
19909
20174
  function checkRotation() {
19910
20175
  const today = getDateStr2();
19911
20176
  if (today !== currentDate2) {
19912
20177
  currentDate2 = today;
19913
- currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20178
+ currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
19914
20179
  cleanOldFiles();
19915
20180
  }
19916
20181
  }
@@ -19924,7 +20189,7 @@ function cleanOldFiles() {
19924
20189
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
19925
20190
  if (dateMatch && dateMatch[1] < cutoffStr) {
19926
20191
  try {
19927
- fs8.unlinkSync(path19.join(LOG_DIR2, file));
20192
+ fs8.unlinkSync(path20.join(LOG_DIR2, file));
19928
20193
  } catch {
19929
20194
  }
19930
20195
  }
@@ -20007,14 +20272,66 @@ function getRecentCommands(count = 50) {
20007
20272
  cleanOldFiles();
20008
20273
 
20009
20274
  // src/commands/router.ts
20275
+ var yaml = __toESM(require("js-yaml"));
20010
20276
  init_logger();
20011
20277
 
20012
20278
  // src/commands/mesh-coordinator.ts
20013
- var import_node_fs2 = require("fs");
20279
+ var import_node_child_process3 = require("child_process");
20280
+ var import_node_fs3 = require("fs");
20014
20281
  var import_node_module2 = require("module");
20282
+ var os17 = __toESM(require("os"));
20015
20283
  var import_node_path = require("path");
20016
20284
  var DEFAULT_SERVER_NAME = "adhdev-mesh";
20017
20285
  var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
20286
+ var HERMES_CLI_TYPE = "hermes-cli";
20287
+ var HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
20288
+ function isHermesProvider(provider, cliType) {
20289
+ const type = cliType?.trim() || provider?.type?.trim() || "";
20290
+ return type === HERMES_CLI_TYPE;
20291
+ }
20292
+ function resolveHermesMeshCoordinatorSetup(options) {
20293
+ const mcpServer = resolveAdhdevMcpServerLaunch({
20294
+ meshId: options.meshId,
20295
+ nodeExecutable: options.nodeExecutable,
20296
+ adhdevMcpEntryPath: options.adhdevMcpEntryPath
20297
+ });
20298
+ if (!mcpServer) {
20299
+ return {
20300
+ kind: "unsupported",
20301
+ reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
20302
+ };
20303
+ }
20304
+ const configPath = resolveMcpConfigPath(HERMES_MCP_CONFIG_PATH, options.workspace);
20305
+ if (!configPath.trim()) {
20306
+ return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
20307
+ }
20308
+ return {
20309
+ kind: "auto_import",
20310
+ serverName: DEFAULT_SERVER_NAME,
20311
+ configPath,
20312
+ configFormat: "hermes_config_yaml",
20313
+ mcpServer
20314
+ };
20315
+ }
20316
+ function createHermesManualMeshCoordinatorSetup(meshId, workspace) {
20317
+ return {
20318
+ kind: "manual",
20319
+ serverName: DEFAULT_SERVER_NAME,
20320
+ configFormat: "hermes_config_yaml",
20321
+ configPathCommand: HERMES_MCP_CONFIG_PATH,
20322
+ requiresRestart: true,
20323
+ instructions: "Hermes CLI does not auto-import repo-local .mcp.json. Add this MCP server to Hermes config under mcp_servers, then start a fresh Hermes session.",
20324
+ template: renderMeshCoordinatorTemplate(
20325
+ "mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
20326
+ {
20327
+ meshId,
20328
+ workspace,
20329
+ serverName: DEFAULT_SERVER_NAME,
20330
+ adhdevMcpCommand: DEFAULT_ADHDEV_MCP_COMMAND
20331
+ }
20332
+ )
20333
+ };
20334
+ }
20018
20335
  function resolveMeshCoordinatorSetup(options) {
20019
20336
  const { provider, meshId, workspace } = options;
20020
20337
  const config = provider?.meshCoordinator;
@@ -20024,6 +20341,9 @@ function resolveMeshCoordinatorSetup(options) {
20024
20341
  reason: config?.reason || "Provider does not declare Repo Mesh coordinator support"
20025
20342
  };
20026
20343
  }
20344
+ if (isHermesProvider(provider, options.cliType)) {
20345
+ return resolveHermesMeshCoordinatorSetup(options);
20346
+ }
20027
20347
  const mcpConfig = config.mcpConfig;
20028
20348
  if (!mcpConfig || mcpConfig.mode === "none") {
20029
20349
  return {
@@ -20033,8 +20353,8 @@ function resolveMeshCoordinatorSetup(options) {
20033
20353
  }
20034
20354
  const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
20035
20355
  if (mcpConfig.mode === "auto_import") {
20036
- const path26 = mcpConfig.path?.trim();
20037
- if (!path26) {
20356
+ const path27 = mcpConfig.path?.trim();
20357
+ if (!path27) {
20038
20358
  return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
20039
20359
  }
20040
20360
  const mcpServer = resolveAdhdevMcpServerLaunch({
@@ -20045,13 +20365,13 @@ function resolveMeshCoordinatorSetup(options) {
20045
20365
  if (!mcpServer) {
20046
20366
  return {
20047
20367
  kind: "unsupported",
20048
- reason: "Could not resolve the ADHDev MCP server entrypoint without relying on a PATH bin shim"
20368
+ reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
20049
20369
  };
20050
20370
  }
20051
20371
  return {
20052
20372
  kind: "auto_import",
20053
20373
  serverName,
20054
- configPath: (0, import_node_path.join)(workspace, path26),
20374
+ configPath: resolveMcpConfigPath(path27, workspace),
20055
20375
  configFormat: mcpConfig.format,
20056
20376
  mcpServer
20057
20377
  };
@@ -20085,14 +20405,85 @@ function resolveMeshCoordinatorSetup(options) {
20085
20405
  function renderMeshCoordinatorTemplate(template, values) {
20086
20406
  return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
20087
20407
  }
20408
+ function resolveMcpConfigPath(configPath, workspace) {
20409
+ const trimmed = configPath.trim();
20410
+ if (trimmed === "~") return os17.homedir();
20411
+ if (trimmed.startsWith("~/")) return (0, import_node_path.join)(os17.homedir(), trimmed.slice(2));
20412
+ if ((0, import_node_path.isAbsolute)(trimmed)) return trimmed;
20413
+ return (0, import_node_path.join)(workspace, trimmed);
20414
+ }
20088
20415
  function resolveAdhdevMcpServerLaunch(options) {
20089
20416
  const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
20090
20417
  if (!entryPath) return null;
20418
+ const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
20419
+ if (!nodeExecutable) return null;
20091
20420
  return {
20092
- command: options.nodeExecutable?.trim() || process.execPath,
20093
- args: [entryPath, "--repo-mesh", options.meshId]
20421
+ command: nodeExecutable,
20422
+ args: [entryPath, "--mode", "ipc", "--repo-mesh", options.meshId]
20094
20423
  };
20095
20424
  }
20425
+ function resolveMcpNodeExecutable(explicitExecutable) {
20426
+ const explicit = explicitExecutable?.trim();
20427
+ if (explicit) return explicit;
20428
+ const candidates = [];
20429
+ const addCandidate = (candidate) => {
20430
+ const trimmed = candidate?.trim();
20431
+ if (!trimmed) return;
20432
+ const normalized = normalizeExistingPath(trimmed) || trimmed;
20433
+ if (!candidates.includes(normalized)) candidates.push(normalized);
20434
+ };
20435
+ addCandidate(process.env.ADHDEV_MCP_NODE_EXECUTABLE);
20436
+ addCandidate(process.env.ADHDEV_NODE_EXECUTABLE);
20437
+ addCandidate(process.env.npm_node_execpath);
20438
+ addNodeCandidatesFromPath(process.env.PATH, addCandidate);
20439
+ addNodeCandidatesFromNvm(os17.homedir(), addCandidate);
20440
+ addCandidate("/opt/homebrew/bin/node");
20441
+ addCandidate("/usr/local/bin/node");
20442
+ addCandidate("/usr/bin/node");
20443
+ addCandidate(process.execPath);
20444
+ for (const candidate of candidates) {
20445
+ if (nodeRuntimeSupportsWebSocket(candidate)) return candidate;
20446
+ }
20447
+ return null;
20448
+ }
20449
+ function addNodeCandidatesFromPath(pathValue, addCandidate) {
20450
+ for (const entry of (pathValue || "").split(":")) {
20451
+ const dir = entry.trim();
20452
+ if (!dir) continue;
20453
+ addCandidate((0, import_node_path.join)(dir, "node"));
20454
+ }
20455
+ }
20456
+ function addNodeCandidatesFromNvm(homeDir, addCandidate) {
20457
+ const versionsDir = (0, import_node_path.join)(homeDir, ".nvm", "versions", "node");
20458
+ try {
20459
+ const versionDirs = (0, import_node_fs3.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
20460
+ for (const versionDir of versionDirs) {
20461
+ addCandidate((0, import_node_path.join)(versionsDir, versionDir, "bin", "node"));
20462
+ }
20463
+ } catch {
20464
+ }
20465
+ }
20466
+ function compareNodeVersionNamesDescending(a, b) {
20467
+ const parse = (value) => value.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
20468
+ const left = parse(a);
20469
+ const right = parse(b);
20470
+ for (let i = 0; i < Math.max(left.length, right.length); i++) {
20471
+ const diff = (right[i] || 0) - (left[i] || 0);
20472
+ if (diff !== 0) return diff;
20473
+ }
20474
+ return b.localeCompare(a);
20475
+ }
20476
+ function nodeRuntimeSupportsWebSocket(nodeExecutable) {
20477
+ try {
20478
+ (0, import_node_child_process3.execFileSync)(nodeExecutable, ["-e", "process.exit(typeof WebSocket === 'function' ? 0 : 42)"], {
20479
+ stdio: "ignore",
20480
+ timeout: 3e3
20481
+ });
20482
+ return true;
20483
+ } catch {
20484
+ return false;
20485
+ }
20486
+ }
20096
20487
  function resolveAdhdevMcpEntryPath(explicitPath) {
20097
20488
  const explicit = explicitPath?.trim();
20098
20489
  if (explicit) return normalizeExistingPath(explicit) || explicit;
@@ -20128,15 +20519,15 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
20128
20519
  }
20129
20520
  function normalizeExistingPath(filePath) {
20130
20521
  try {
20131
- if (!(0, import_node_fs2.existsSync)(filePath)) return null;
20132
- return import_node_fs2.realpathSync.native(filePath);
20522
+ if (!(0, import_node_fs3.existsSync)(filePath)) return null;
20523
+ return import_node_fs3.realpathSync.native(filePath);
20133
20524
  } catch {
20134
20525
  return null;
20135
20526
  }
20136
20527
  }
20137
20528
 
20138
20529
  // src/status/snapshot.ts
20139
- var os17 = __toESM(require("os"));
20530
+ var os18 = __toESM(require("os"));
20140
20531
  init_config();
20141
20532
  init_terminal_screen();
20142
20533
  init_logger();
@@ -20192,8 +20583,8 @@ function buildAvailableProviders(providerLoader) {
20192
20583
  }
20193
20584
  function buildMachineInfo(profile = "full") {
20194
20585
  const base = {
20195
- hostname: os17.hostname(),
20196
- platform: os17.platform()
20586
+ hostname: os18.hostname(),
20587
+ platform: os18.platform()
20197
20588
  };
20198
20589
  if (profile === "live") {
20199
20590
  return base;
@@ -20202,23 +20593,23 @@ function buildMachineInfo(profile = "full") {
20202
20593
  const memSnap2 = getHostMemorySnapshot();
20203
20594
  return {
20204
20595
  ...base,
20205
- arch: os17.arch(),
20206
- cpus: os17.cpus().length,
20596
+ arch: os18.arch(),
20597
+ cpus: os18.cpus().length,
20207
20598
  totalMem: memSnap2.totalMem,
20208
- release: os17.release()
20599
+ release: os18.release()
20209
20600
  };
20210
20601
  }
20211
20602
  const memSnap = getHostMemorySnapshot();
20212
20603
  return {
20213
20604
  ...base,
20214
- arch: os17.arch(),
20215
- cpus: os17.cpus().length,
20605
+ arch: os18.arch(),
20606
+ cpus: os18.cpus().length,
20216
20607
  totalMem: memSnap.totalMem,
20217
20608
  freeMem: memSnap.freeMem,
20218
20609
  availableMem: memSnap.availableMem,
20219
- loadavg: os17.loadavg(),
20220
- uptime: os17.uptime(),
20221
- release: os17.release()
20610
+ loadavg: os18.loadavg(),
20611
+ uptime: os18.uptime(),
20612
+ release: os18.release()
20222
20613
  };
20223
20614
  }
20224
20615
  function parseMessageTime(value) {
@@ -20452,14 +20843,14 @@ function buildStatusSnapshot(options) {
20452
20843
  var import_child_process8 = require("child_process");
20453
20844
  var import_child_process9 = require("child_process");
20454
20845
  var fs9 = __toESM(require("fs"));
20455
- var os18 = __toESM(require("os"));
20456
- var path20 = __toESM(require("path"));
20846
+ var os19 = __toESM(require("os"));
20847
+ var path21 = __toESM(require("path"));
20457
20848
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
20458
20849
  function getUpgradeLogPath() {
20459
- const home = os18.homedir();
20460
- const dir = path20.join(home, ".adhdev");
20850
+ const home = os19.homedir();
20851
+ const dir = path21.join(home, ".adhdev");
20461
20852
  fs9.mkdirSync(dir, { recursive: true });
20462
- return path20.join(dir, "daemon-upgrade.log");
20853
+ return path21.join(dir, "daemon-upgrade.log");
20463
20854
  }
20464
20855
  function appendUpgradeLog(message) {
20465
20856
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -20470,14 +20861,14 @@ function appendUpgradeLog(message) {
20470
20861
  }
20471
20862
  }
20472
20863
  function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
20473
- const binDir = path20.dirname(nodeExecutable);
20864
+ const binDir = path21.dirname(nodeExecutable);
20474
20865
  if (platform10 === "win32") {
20475
- const npmCliPath = path20.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
20866
+ const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
20476
20867
  if (fs9.existsSync(npmCliPath)) {
20477
20868
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
20478
20869
  }
20479
20870
  for (const candidate of ["npm.exe", "npm"]) {
20480
- const candidatePath = path20.join(binDir, candidate);
20871
+ const candidatePath = path21.join(binDir, candidate);
20481
20872
  if (fs9.existsSync(candidatePath)) {
20482
20873
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
20483
20874
  }
@@ -20485,7 +20876,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
20485
20876
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
20486
20877
  }
20487
20878
  for (const candidate of ["npm"]) {
20488
- const candidatePath = path20.join(binDir, candidate);
20879
+ const candidatePath = path21.join(binDir, candidate);
20489
20880
  if (fs9.existsSync(candidatePath)) {
20490
20881
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
20491
20882
  }
@@ -20502,13 +20893,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20502
20893
  let currentDir = resolvedPath;
20503
20894
  try {
20504
20895
  if (fs9.statSync(resolvedPath).isFile()) {
20505
- currentDir = path20.dirname(resolvedPath);
20896
+ currentDir = path21.dirname(resolvedPath);
20506
20897
  }
20507
20898
  } catch {
20508
- currentDir = path20.dirname(resolvedPath);
20899
+ currentDir = path21.dirname(resolvedPath);
20509
20900
  }
20510
20901
  while (true) {
20511
- const packageJsonPath = path20.join(currentDir, "package.json");
20902
+ const packageJsonPath = path21.join(currentDir, "package.json");
20512
20903
  try {
20513
20904
  if (fs9.existsSync(packageJsonPath)) {
20514
20905
  const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
@@ -20519,7 +20910,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20519
20910
  }
20520
20911
  } catch {
20521
20912
  }
20522
- const parentDir = path20.dirname(currentDir);
20913
+ const parentDir = path21.dirname(currentDir);
20523
20914
  if (parentDir === currentDir) {
20524
20915
  return null;
20525
20916
  }
@@ -20527,13 +20918,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20527
20918
  }
20528
20919
  }
20529
20920
  function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
20530
- const nodeModulesDir = packageName.startsWith("@") ? path20.dirname(path20.dirname(packageRoot)) : path20.dirname(packageRoot);
20531
- if (path20.basename(nodeModulesDir) !== "node_modules") {
20921
+ const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
20922
+ if (path21.basename(nodeModulesDir) !== "node_modules") {
20532
20923
  return null;
20533
20924
  }
20534
- const maybeLibDir = path20.dirname(nodeModulesDir);
20535
- if (path20.basename(maybeLibDir) === "lib") {
20536
- return path20.dirname(maybeLibDir);
20925
+ const maybeLibDir = path21.dirname(nodeModulesDir);
20926
+ if (path21.basename(maybeLibDir) === "lib") {
20927
+ return path21.dirname(maybeLibDir);
20537
20928
  }
20538
20929
  return maybeLibDir;
20539
20930
  }
@@ -20648,7 +21039,7 @@ async function waitForPidExit(pid, timeoutMs) {
20648
21039
  }
20649
21040
  }
20650
21041
  function stopSessionHostProcesses(appName) {
20651
- const pidFile = path20.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
21042
+ const pidFile = path21.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
20652
21043
  try {
20653
21044
  if (fs9.existsSync(pidFile)) {
20654
21045
  const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
@@ -20665,7 +21056,7 @@ function stopSessionHostProcesses(appName) {
20665
21056
  }
20666
21057
  }
20667
21058
  function removeDaemonPidFile() {
20668
- const pidFile = path20.join(os18.homedir(), ".adhdev", "daemon.pid");
21059
+ const pidFile = path21.join(os19.homedir(), ".adhdev", "daemon.pid");
20669
21060
  try {
20670
21061
  fs9.unlinkSync(pidFile);
20671
21062
  } catch {
@@ -20676,7 +21067,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
20676
21067
  const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
20677
21068
  if (!npmRoot) return;
20678
21069
  const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
20679
- const binDir = process.platform === "win32" ? npmPrefix : path20.join(npmPrefix, "bin");
21070
+ const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
20680
21071
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
20681
21072
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
20682
21073
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -20684,25 +21075,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
20684
21075
  }
20685
21076
  if (pkgName.startsWith("@")) {
20686
21077
  const [scope, name] = pkgName.split("/");
20687
- const scopeDir = path20.join(npmRoot, scope);
21078
+ const scopeDir = path21.join(npmRoot, scope);
20688
21079
  if (!fs9.existsSync(scopeDir)) return;
20689
21080
  for (const entry of fs9.readdirSync(scopeDir)) {
20690
21081
  if (!entry.startsWith(`.${name}-`)) continue;
20691
- fs9.rmSync(path20.join(scopeDir, entry), { recursive: true, force: true });
20692
- appendUpgradeLog(`Removed stale scoped staging dir: ${path20.join(scopeDir, entry)}`);
21082
+ fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
21083
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
20693
21084
  }
20694
21085
  } else {
20695
21086
  for (const entry of fs9.readdirSync(npmRoot)) {
20696
21087
  if (!entry.startsWith(`.${pkgName}-`)) continue;
20697
- fs9.rmSync(path20.join(npmRoot, entry), { recursive: true, force: true });
20698
- appendUpgradeLog(`Removed stale staging dir: ${path20.join(npmRoot, entry)}`);
21088
+ fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
21089
+ appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
20699
21090
  }
20700
21091
  }
20701
21092
  if (fs9.existsSync(binDir)) {
20702
21093
  for (const entry of fs9.readdirSync(binDir)) {
20703
21094
  if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
20704
- fs9.rmSync(path20.join(binDir, entry), { recursive: true, force: true });
20705
- appendUpgradeLog(`Removed stale bin staging entry: ${path20.join(binDir, entry)}`);
21095
+ fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
21096
+ appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
20706
21097
  }
20707
21098
  }
20708
21099
  }
@@ -20803,6 +21194,56 @@ function normalizeReleaseChannel(value) {
20803
21194
  function resolveUpgradeChannel(args) {
20804
21195
  return normalizeReleaseChannel(args?.channel) || normalizeReleaseChannel(args?.updatePolicy?.channel) || normalizeReleaseChannel(args?.npmTag) || normalizeReleaseChannel(loadConfig().updateChannel) || "stable";
20805
21196
  }
21197
+ function readProviderPriorityFromPolicy(policy) {
21198
+ const record = policy && typeof policy === "object" && !Array.isArray(policy) ? policy : {};
21199
+ const raw = record.providerPriority;
21200
+ if (!Array.isArray(raw)) return [];
21201
+ const seen = /* @__PURE__ */ new Set();
21202
+ return raw.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean).filter((type) => {
21203
+ if (seen.has(type)) return false;
21204
+ seen.add(type);
21205
+ return true;
21206
+ });
21207
+ }
21208
+ async function resolveProviderTypeFromPriority(args) {
21209
+ if (!args.providerPriority.length) {
21210
+ return { error: `Node '${args.nodeId}' has no providerPriority policy; pass cliType explicitly or configure node.policy.providerPriority` };
21211
+ }
21212
+ const failed = [];
21213
+ for (const requestedType of args.providerPriority) {
21214
+ const normalizedType = args.providerLoader.resolveAlias(requestedType);
21215
+ if (!args.providerLoader.isMachineProviderEnabled(normalizedType)) {
21216
+ failed.push(`${requestedType}: disabled`);
21217
+ continue;
21218
+ }
21219
+ const detected = await detectCLI(normalizedType, args.providerLoader, { includeVersion: false });
21220
+ args.providerLoader.setCliDetectionResults([{
21221
+ id: normalizedType,
21222
+ installed: !!detected,
21223
+ path: detected?.path
21224
+ }], false);
21225
+ args.onStatusChange?.();
21226
+ if (detected) return { providerType: normalizedType };
21227
+ failed.push(`${requestedType}: not detected`);
21228
+ }
21229
+ return { error: `No usable provider detected for node '${args.nodeId}' from providerPriority: ${failed.join("; ")}` };
21230
+ }
21231
+ function loadYamlModule() {
21232
+ return yaml;
21233
+ }
21234
+ function getMcpServersKey(format) {
21235
+ return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
21236
+ }
21237
+ function parseMeshCoordinatorMcpConfig(text, format) {
21238
+ if (!text.trim()) return {};
21239
+ if (format === "claude_mcp_json") return JSON.parse(text);
21240
+ const parsed = loadYamlModule().load(text);
21241
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
21242
+ }
21243
+ function serializeMeshCoordinatorMcpConfig(config, format) {
21244
+ if (format === "claude_mcp_json") return JSON.stringify(config, null, 2);
21245
+ return loadYamlModule().dump(config, { noRefs: true, lineWidth: 120 });
21246
+ }
20806
21247
  var CHAT_COMMANDS = [
20807
21248
  "send_chat",
20808
21249
  "new_chat",
@@ -20901,6 +21342,40 @@ var DaemonCommandRouter = class {
20901
21342
  constructor(deps) {
20902
21343
  this.deps = deps;
20903
21344
  }
21345
+ getCachedInlineMesh(meshId, inlineMesh) {
21346
+ if (inlineMesh && typeof inlineMesh === "object") {
21347
+ this.inlineMeshCache.set(meshId, inlineMesh);
21348
+ return inlineMesh;
21349
+ }
21350
+ return this.inlineMeshCache.get(meshId);
21351
+ }
21352
+ async getMeshForCommand(meshId, inlineMesh) {
21353
+ try {
21354
+ const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21355
+ const mesh = getMesh3(meshId);
21356
+ if (mesh) return { mesh, inline: false };
21357
+ } catch {
21358
+ }
21359
+ const cached = this.getCachedInlineMesh(meshId, inlineMesh);
21360
+ return cached ? { mesh: cached, inline: true } : null;
21361
+ }
21362
+ updateInlineMeshNode(meshId, mesh, node) {
21363
+ if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
21364
+ const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
21365
+ if (idx >= 0) mesh.nodes[idx] = node;
21366
+ else mesh.nodes.push(node);
21367
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
21368
+ this.inlineMeshCache.set(meshId, mesh);
21369
+ }
21370
+ removeInlineMeshNode(meshId, mesh, nodeId) {
21371
+ if (!mesh || !Array.isArray(mesh.nodes)) return false;
21372
+ const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
21373
+ if (idx === -1) return false;
21374
+ mesh.nodes.splice(idx, 1);
21375
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
21376
+ this.inlineMeshCache.set(meshId, mesh);
21377
+ return true;
21378
+ }
20904
21379
  async traceSessionHostAction(action, args, run, summarizeResult) {
20905
21380
  const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
20906
21381
  const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
@@ -21588,7 +22063,13 @@ var DaemonCommandRouter = class {
21588
22063
  if (!workspace) return { success: false, error: "workspace required" };
21589
22064
  try {
21590
22065
  const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21591
- const node = addNode3(meshId, { workspace });
22066
+ const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
22067
+ const readOnly = args?.readOnly === true;
22068
+ const policy = {
22069
+ ...readOnly ? { readOnly: true } : {},
22070
+ ...providerPriority.length ? { providerPriority } : {}
22071
+ };
22072
+ const node = addNode3(meshId, { workspace, ...policy ? { policy } : {} });
21592
22073
  if (!node) return { success: false, error: "Mesh not found" };
21593
22074
  return { success: true, node };
21594
22075
  } catch (e) {
@@ -21600,17 +22081,98 @@ var DaemonCommandRouter = class {
21600
22081
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
21601
22082
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
21602
22083
  try {
21603
- const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21604
- const removed = removeNode3(meshId, nodeId);
22084
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
22085
+ const mesh = meshRecord?.mesh;
22086
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
22087
+ if (node?.isLocalWorktree && node.workspace) {
22088
+ try {
22089
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
22090
+ const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
22091
+ if (repoRoot) {
22092
+ const { removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
22093
+ await removeWorktree2(repoRoot, node.workspace);
22094
+ }
22095
+ } catch (e) {
22096
+ LOG.warn("MeshNode", `Worktree cleanup failed for ${nodeId}: ${e.message}`);
22097
+ }
22098
+ }
22099
+ let removed = false;
22100
+ if (meshRecord?.inline) {
22101
+ removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
22102
+ } else {
22103
+ const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
22104
+ removed = removeNode3(meshId, nodeId);
22105
+ }
21605
22106
  return { success: true, removed };
21606
22107
  } catch (e) {
21607
22108
  return { success: false, error: e.message };
21608
22109
  }
21609
22110
  }
22111
+ case "clone_mesh_node": {
22112
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
22113
+ const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
22114
+ const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
22115
+ const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
22116
+ if (!meshId) return { success: false, error: "meshId required" };
22117
+ if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
22118
+ if (!branch) return { success: false, error: "branch required" };
22119
+ try {
22120
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
22121
+ const mesh = meshRecord?.mesh;
22122
+ if (!mesh) return { success: false, error: "Mesh not found" };
22123
+ const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
22124
+ if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
22125
+ const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
22126
+ const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
22127
+ const result = await createWorktree2({
22128
+ repoRoot,
22129
+ branch,
22130
+ baseBranch,
22131
+ meshName: mesh.name
22132
+ });
22133
+ let node;
22134
+ if (meshRecord.inline) {
22135
+ const { randomUUID: randomUUID8 } = await import("crypto");
22136
+ node = {
22137
+ id: `node_${randomUUID8().replace(/-/g, "")}`,
22138
+ workspace: result.worktreePath,
22139
+ repoRoot: result.worktreePath,
22140
+ daemonId: sourceNode.daemonId,
22141
+ userOverrides: { ...sourceNode.userOverrides || {} },
22142
+ policy: { ...sourceNode.policy || {} },
22143
+ isLocalWorktree: true,
22144
+ worktreeBranch: result.branch,
22145
+ clonedFromNodeId: sourceNodeId
22146
+ };
22147
+ this.updateInlineMeshNode(meshId, mesh, node);
22148
+ } else {
22149
+ const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
22150
+ node = addNode3(meshId, {
22151
+ workspace: result.worktreePath,
22152
+ repoRoot: result.worktreePath,
22153
+ daemonId: sourceNode.daemonId,
22154
+ userOverrides: { ...sourceNode.userOverrides || {} },
22155
+ isLocalWorktree: true,
22156
+ worktreeBranch: result.branch,
22157
+ clonedFromNodeId: sourceNodeId,
22158
+ policy: { ...sourceNode.policy || {} }
22159
+ });
22160
+ if (!node) return { success: false, error: "Failed to register worktree node" };
22161
+ }
22162
+ return {
22163
+ success: true,
22164
+ node,
22165
+ worktreePath: result.worktreePath,
22166
+ branch: result.branch
22167
+ };
22168
+ } catch (e) {
22169
+ return { success: false, error: e.message };
22170
+ }
22171
+ }
21610
22172
  // ─── Mesh Coordinator Launch ───
21611
22173
  case "launch_mesh_coordinator": {
21612
22174
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
21613
- const cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "claude-cli";
22175
+ let cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "";
21614
22176
  if (!meshId) return { success: false, error: "meshId required" };
21615
22177
  try {
21616
22178
  const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
@@ -21638,9 +22200,29 @@ var DaemonCommandRouter = class {
21638
22200
  }
21639
22201
  const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
21640
22202
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
22203
+ if (!cliType) {
22204
+ const resolved = await resolveProviderTypeFromPriority({
22205
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || "coordinator"),
22206
+ providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
22207
+ providerLoader: this.deps.providerLoader,
22208
+ onStatusChange: this.deps.onStatusChange
22209
+ });
22210
+ if (!resolved.providerType) {
22211
+ return {
22212
+ success: false,
22213
+ code: "mesh_coordinator_provider_priority_unusable",
22214
+ error: resolved.error || "No usable provider found from node providerPriority",
22215
+ meshId,
22216
+ cliType,
22217
+ workspace
22218
+ };
22219
+ }
22220
+ cliType = resolved.providerType;
22221
+ }
21641
22222
  const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
21642
22223
  const coordinatorSetup = resolveMeshCoordinatorSetup({
21643
22224
  provider: providerMeta,
22225
+ cliType,
21644
22226
  meshId,
21645
22227
  workspace
21646
22228
  });
@@ -21665,7 +22247,8 @@ var DaemonCommandRouter = class {
21665
22247
  meshCoordinatorSetup: coordinatorSetup
21666
22248
  };
21667
22249
  }
21668
- if (coordinatorSetup.configFormat !== "claude_mcp_json") {
22250
+ const configFormat = coordinatorSetup.configFormat;
22251
+ if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
21669
22252
  return {
21670
22253
  success: false,
21671
22254
  code: "mesh_coordinator_unsupported",
@@ -21675,44 +22258,93 @@ var DaemonCommandRouter = class {
21675
22258
  workspace
21676
22259
  };
21677
22260
  }
21678
- const { existsSync: existsSync22, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3 } = await import("fs");
21679
- const mcpConfigPath = coordinatorSetup.configPath;
21680
- const hadExistingMcpConfig = existsSync22(mcpConfigPath);
21681
- let existingMcpConfig = {};
21682
- if (hadExistingMcpConfig) {
21683
- try {
21684
- existingMcpConfig = JSON.parse(readFileSync15(mcpConfigPath, "utf-8"));
21685
- copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
21686
- } catch {
21687
- }
22261
+ let systemPrompt = "";
22262
+ try {
22263
+ systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
22264
+ } catch (error) {
22265
+ const message = error?.message || String(error);
22266
+ LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
22267
+ return {
22268
+ success: false,
22269
+ code: "mesh_coordinator_prompt_failed",
22270
+ error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
22271
+ meshId,
22272
+ cliType,
22273
+ workspace
22274
+ };
21688
22275
  }
22276
+ const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync13, copyFileSync: copyFileSync3, mkdirSync: mkdirSync15 } = await import("fs");
22277
+ const { dirname: dirname9 } = await import("path");
22278
+ const mcpConfigPath = coordinatorSetup.configPath;
22279
+ const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
22280
+ const returnManualFallback = (message) => ({
22281
+ success: false,
22282
+ code: "mesh_coordinator_manual_mcp_setup_required",
22283
+ error: message,
22284
+ meshId,
22285
+ cliType,
22286
+ workspace,
22287
+ meshCoordinatorSetup: hermesManualFallback
22288
+ });
21689
22289
  const mcpServerEntry = {
21690
22290
  command: coordinatorSetup.mcpServer.command,
21691
22291
  args: coordinatorSetup.mcpServer.args
21692
22292
  };
21693
22293
  if (args?.inlineMesh) {
21694
22294
  mcpServerEntry.env = {
21695
- ADHDEV_INLINE_MESH: JSON.stringify(mesh)
22295
+ ADHDEV_INLINE_MESH: JSON.stringify(mesh),
22296
+ ADHDEV_MCP_TRANSPORT: "ipc"
21696
22297
  };
21697
22298
  }
22299
+ try {
22300
+ mkdirSync15(dirname9(mcpConfigPath), { recursive: true });
22301
+ } catch (error) {
22302
+ const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
22303
+ LOG.error("MeshCoordinator", message);
22304
+ if (hermesManualFallback) return returnManualFallback(message);
22305
+ return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
22306
+ }
22307
+ const hadExistingMcpConfig = existsSync23(mcpConfigPath);
22308
+ let existingMcpConfig = {};
22309
+ if (hadExistingMcpConfig) {
22310
+ try {
22311
+ existingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
22312
+ copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
22313
+ } catch (error) {
22314
+ LOG.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error?.message || error}`);
22315
+ return {
22316
+ success: false,
22317
+ code: "mesh_coordinator_config_parse_failed",
22318
+ error: `Failed to parse existing MCP config at ${mcpConfigPath}`
22319
+ };
22320
+ }
22321
+ }
22322
+ const mcpServersKey = getMcpServersKey(configFormat);
22323
+ const existingServers = existingMcpConfig[mcpServersKey];
21698
22324
  const mcpConfig = {
21699
22325
  ...existingMcpConfig,
21700
- mcpServers: {
21701
- ...existingMcpConfig.mcpServers || {},
22326
+ [mcpServersKey]: {
22327
+ ...existingServers && typeof existingServers === "object" && !Array.isArray(existingServers) ? existingServers : {},
21702
22328
  [coordinatorSetup.serverName]: mcpServerEntry
21703
22329
  }
21704
22330
  };
21705
- writeFileSync12(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
21706
- LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
21707
- let systemPrompt = "";
21708
22331
  try {
21709
- systemPrompt = buildCoordinatorSystemPrompt2({ mesh });
21710
- } catch {
21711
- systemPrompt = `You are a Repo Mesh Coordinator for "${mesh.name}". Use the adhdev-mesh MCP tools (mesh_status, mesh_list_nodes, mesh_send_task, mesh_read_chat, mesh_launch_session, etc.) to orchestrate work across ${mesh.nodes.length} node(s).`;
22332
+ writeFileSync13(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
22333
+ } catch (error) {
22334
+ const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
22335
+ LOG.error("MeshCoordinator", message);
22336
+ if (hermesManualFallback) return returnManualFallback(message);
22337
+ return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
21712
22338
  }
22339
+ LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
21713
22340
  const cliArgs = [];
22341
+ const launchEnv = {};
21714
22342
  if (systemPrompt) {
21715
- cliArgs.push("--append-system-prompt", systemPrompt);
22343
+ if (configFormat === "hermes_config_yaml") {
22344
+ launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
22345
+ } else {
22346
+ cliArgs.push("--append-system-prompt", systemPrompt);
22347
+ }
21716
22348
  }
21717
22349
  if (cliType === "claude-cli") {
21718
22350
  cliArgs.push("--mcp-config", coordinatorSetup.configPath);
@@ -21721,6 +22353,7 @@ var DaemonCommandRouter = class {
21721
22353
  cliType,
21722
22354
  dir: workspace,
21723
22355
  cliArgs: cliArgs.length > 0 ? cliArgs : void 0,
22356
+ env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
21724
22357
  settings: {
21725
22358
  meshCoordinatorFor: meshId
21726
22359
  }
@@ -21900,6 +22533,12 @@ var DaemonStatusReporter = class {
21900
22533
  if (providerType) {
21901
22534
  payload.providerType = providerType;
21902
22535
  }
22536
+ if (typeof event.providerSessionId === "string" && event.providerSessionId.trim()) {
22537
+ payload.providerSessionId = event.providerSessionId.trim();
22538
+ }
22539
+ if (typeof event.workspaceName === "string" && event.workspaceName.trim()) {
22540
+ payload.workspaceName = event.workspaceName.trim();
22541
+ }
21903
22542
  if (typeof event.duration === "number" && Number.isFinite(event.duration)) {
21904
22543
  payload.duration = event.duration;
21905
22544
  }
@@ -23147,7 +23786,10 @@ var ProviderInstanceManager = class {
23147
23786
  this.instances.get(id).dispose();
23148
23787
  }
23149
23788
  this.instances.set(id, instance);
23150
- await instance.init(context);
23789
+ await instance.init({
23790
+ ...context,
23791
+ emitProviderEvent: (event) => this.emitProviderEvent(instance.type, id, event)
23792
+ });
23151
23793
  }
23152
23794
  /**
23153
23795
  * Instance remove
@@ -23309,6 +23951,17 @@ var ProviderInstanceManager = class {
23309
23951
  onEvent(listener) {
23310
23952
  this.eventListeners.push(listener);
23311
23953
  }
23954
+ emitProviderEvent(providerType, instanceId, event) {
23955
+ const payload = {
23956
+ ...event,
23957
+ providerType,
23958
+ instanceId: typeof event.instanceId === "string" && event.instanceId.trim() ? event.instanceId : instanceId,
23959
+ targetSessionId: typeof event.targetSessionId === "string" && event.targetSessionId.trim() ? event.targetSessionId : instanceId
23960
+ };
23961
+ for (const listener of this.eventListeners) {
23962
+ listener(payload);
23963
+ }
23964
+ }
23312
23965
  emitPendingEvents(providerType, state, extra = {}) {
23313
23966
  for (const event of state.pendingEvents) {
23314
23967
  for (const listener of this.eventListeners) {
@@ -23381,11 +24034,11 @@ var ProviderInstanceManager = class {
23381
24034
 
23382
24035
  // src/providers/version-archive.ts
23383
24036
  var fs11 = __toESM(require("fs"));
23384
- var path21 = __toESM(require("path"));
23385
- var os19 = __toESM(require("os"));
24037
+ var path22 = __toESM(require("path"));
24038
+ var os20 = __toESM(require("os"));
23386
24039
  var import_child_process10 = require("child_process");
23387
24040
  var import_os3 = require("os");
23388
- var ARCHIVE_PATH = path21.join(os19.homedir(), ".adhdev", "version-history.json");
24041
+ var ARCHIVE_PATH = path22.join(os20.homedir(), ".adhdev", "version-history.json");
23389
24042
  var MAX_ENTRIES_PER_PROVIDER = 20;
23390
24043
  var VersionArchive = class {
23391
24044
  history = {};
@@ -23432,7 +24085,7 @@ var VersionArchive = class {
23432
24085
  }
23433
24086
  save() {
23434
24087
  try {
23435
- fs11.mkdirSync(path21.dirname(ARCHIVE_PATH), { recursive: true });
24088
+ fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
23436
24089
  fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
23437
24090
  } catch {
23438
24091
  }
@@ -23488,8 +24141,8 @@ function getVersion(binary, versionCommand) {
23488
24141
  function checkPathExists2(paths) {
23489
24142
  for (const p of paths) {
23490
24143
  if (p.includes("*")) {
23491
- const home = os19.homedir();
23492
- const resolved = p.replace(/\*/g, home.split(path21.sep).pop() || "");
24144
+ const home = os20.homedir();
24145
+ const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
23493
24146
  if (fs11.existsSync(resolved)) return resolved;
23494
24147
  } else {
23495
24148
  if (fs11.existsSync(p)) return p;
@@ -23499,7 +24152,7 @@ function checkPathExists2(paths) {
23499
24152
  }
23500
24153
  function getMacAppVersion(appPath) {
23501
24154
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
23502
- const plistPath = path21.join(appPath, "Contents", "Info.plist");
24155
+ const plistPath = path22.join(appPath, "Contents", "Info.plist");
23503
24156
  if (!fs11.existsSync(plistPath)) return null;
23504
24157
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
23505
24158
  return raw || null;
@@ -23525,7 +24178,7 @@ async function detectAllVersions(loader, archive) {
23525
24178
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
23526
24179
  let resolvedBin = cliBin;
23527
24180
  if (!resolvedBin && appPath && currentOs === "darwin") {
23528
- const bundled = path21.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
24181
+ const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
23529
24182
  if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
23530
24183
  }
23531
24184
  info.installed = !!(appPath || resolvedBin);
@@ -23566,7 +24219,7 @@ async function detectAllVersions(loader, archive) {
23566
24219
  // src/daemon/dev-server.ts
23567
24220
  var http2 = __toESM(require("http"));
23568
24221
  var fs15 = __toESM(require("fs"));
23569
- var path25 = __toESM(require("path"));
24222
+ var path26 = __toESM(require("path"));
23570
24223
  init_config();
23571
24224
 
23572
24225
  // src/daemon/scaffold-template.ts
@@ -23917,7 +24570,7 @@ init_logger();
23917
24570
 
23918
24571
  // src/daemon/dev-cdp-handlers.ts
23919
24572
  var fs12 = __toESM(require("fs"));
23920
- var path22 = __toESM(require("path"));
24573
+ var path23 = __toESM(require("path"));
23921
24574
  init_logger();
23922
24575
  async function handleCdpEvaluate(ctx, req, res) {
23923
24576
  const body = await ctx.readBody(req);
@@ -24096,17 +24749,17 @@ async function handleScriptHints(ctx, type, _req, res) {
24096
24749
  return;
24097
24750
  }
24098
24751
  let scriptsPath = "";
24099
- const directScripts = path22.join(dir, "scripts.js");
24752
+ const directScripts = path23.join(dir, "scripts.js");
24100
24753
  if (fs12.existsSync(directScripts)) {
24101
24754
  scriptsPath = directScripts;
24102
24755
  } else {
24103
- const scriptsDir = path22.join(dir, "scripts");
24756
+ const scriptsDir = path23.join(dir, "scripts");
24104
24757
  if (fs12.existsSync(scriptsDir)) {
24105
24758
  const versions = fs12.readdirSync(scriptsDir).filter((d) => {
24106
- return fs12.statSync(path22.join(scriptsDir, d)).isDirectory();
24759
+ return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
24107
24760
  }).sort().reverse();
24108
24761
  for (const ver of versions) {
24109
- const p = path22.join(scriptsDir, ver, "scripts.js");
24762
+ const p = path23.join(scriptsDir, ver, "scripts.js");
24110
24763
  if (fs12.existsSync(p)) {
24111
24764
  scriptsPath = p;
24112
24765
  break;
@@ -24935,7 +25588,7 @@ async function handleDomContext(ctx, type, req, res) {
24935
25588
 
24936
25589
  // src/daemon/dev-cli-debug.ts
24937
25590
  var fs13 = __toESM(require("fs"));
24938
- var path23 = __toESM(require("path"));
25591
+ var path24 = __toESM(require("path"));
24939
25592
  function slugifyFixtureName(value) {
24940
25593
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
24941
25594
  return normalized || `fixture-${Date.now()}`;
@@ -24945,11 +25598,11 @@ function getCliFixtureDir(ctx, type) {
24945
25598
  if (!providerDir) {
24946
25599
  throw new Error(`Provider directory not found for '${type}'`);
24947
25600
  }
24948
- return path23.join(providerDir, "fixtures");
25601
+ return path24.join(providerDir, "fixtures");
24949
25602
  }
24950
25603
  function readCliFixture(ctx, type, name) {
24951
25604
  const fixtureDir = getCliFixtureDir(ctx, type);
24952
- const filePath = path23.join(fixtureDir, `${name}.json`);
25605
+ const filePath = path24.join(fixtureDir, `${name}.json`);
24953
25606
  if (!fs13.existsSync(filePath)) {
24954
25607
  throw new Error(`Fixture not found: ${filePath}`);
24955
25608
  }
@@ -25716,7 +26369,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
25716
26369
  },
25717
26370
  notes: typeof body?.notes === "string" ? body.notes : void 0
25718
26371
  };
25719
- const filePath = path23.join(fixtureDir, `${name}.json`);
26372
+ const filePath = path24.join(fixtureDir, `${name}.json`);
25720
26373
  fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
25721
26374
  ctx.json(res, 200, {
25722
26375
  saved: true,
@@ -25740,7 +26393,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
25740
26393
  return;
25741
26394
  }
25742
26395
  const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
25743
- const fullPath = path23.join(fixtureDir, file);
26396
+ const fullPath = path24.join(fixtureDir, file);
25744
26397
  try {
25745
26398
  const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
25746
26399
  return {
@@ -25876,8 +26529,8 @@ async function handleCliRaw(ctx, req, res) {
25876
26529
 
25877
26530
  // src/daemon/dev-auto-implement.ts
25878
26531
  var fs14 = __toESM(require("fs"));
25879
- var path24 = __toESM(require("path"));
25880
- var os20 = __toESM(require("os"));
26532
+ var path25 = __toESM(require("path"));
26533
+ var os21 = __toESM(require("os"));
25881
26534
  function getAutoImplPid(ctx) {
25882
26535
  const pid = ctx.autoImplProcess?.pid;
25883
26536
  return typeof pid === "number" && pid > 0 ? pid : null;
@@ -25926,22 +26579,22 @@ function getLatestScriptVersionDir(scriptsDir) {
25926
26579
  if (!fs14.existsSync(scriptsDir)) return null;
25927
26580
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
25928
26581
  try {
25929
- return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
26582
+ return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
25930
26583
  } catch {
25931
26584
  return false;
25932
26585
  }
25933
26586
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
25934
26587
  if (versions.length === 0) return null;
25935
- return path24.join(scriptsDir, versions[0]);
26588
+ return path25.join(scriptsDir, versions[0]);
25936
26589
  }
25937
26590
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
25938
- const canonicalUserDir = path24.resolve(ctx.providerLoader.getUserProviderDir(category, type));
25939
- const desiredDir = requestedDir ? path24.resolve(requestedDir) : canonicalUserDir;
25940
- const upstreamRoot = path24.resolve(ctx.providerLoader.getUpstreamDir());
25941
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path24.sep}`)) {
26591
+ const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
26592
+ const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
26593
+ const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
26594
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
25942
26595
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
25943
26596
  }
25944
- if (path24.basename(desiredDir) !== type) {
26597
+ if (path25.basename(desiredDir) !== type) {
25945
26598
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
25946
26599
  }
25947
26600
  const sourceDir = ctx.findProviderDir(type);
@@ -25949,11 +26602,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
25949
26602
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
25950
26603
  }
25951
26604
  if (!fs14.existsSync(desiredDir)) {
25952
- fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
26605
+ fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
25953
26606
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
25954
26607
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
25955
26608
  }
25956
- const providerJson = path24.join(desiredDir, "provider.json");
26609
+ const providerJson = path25.join(desiredDir, "provider.json");
25957
26610
  if (!fs14.existsSync(providerJson)) {
25958
26611
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
25959
26612
  }
@@ -25964,13 +26617,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
25964
26617
  const refDir = ctx.findProviderDir(referenceType);
25965
26618
  if (!refDir || !fs14.existsSync(refDir)) return {};
25966
26619
  const referenceScripts = {};
25967
- const scriptsDir = path24.join(refDir, "scripts");
26620
+ const scriptsDir = path25.join(refDir, "scripts");
25968
26621
  const latestDir = getLatestScriptVersionDir(scriptsDir);
25969
26622
  if (!latestDir) return referenceScripts;
25970
26623
  for (const file of fs14.readdirSync(latestDir)) {
25971
26624
  if (!file.endsWith(".js")) continue;
25972
26625
  try {
25973
- referenceScripts[file] = fs14.readFileSync(path24.join(latestDir, file), "utf-8");
26626
+ referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
25974
26627
  } catch {
25975
26628
  }
25976
26629
  }
@@ -26078,9 +26731,9 @@ async function handleAutoImplement(ctx, type, req, res) {
26078
26731
  });
26079
26732
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
26080
26733
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
26081
- const tmpDir = path24.join(os20.tmpdir(), "adhdev-autoimpl");
26734
+ const tmpDir = path25.join(os21.tmpdir(), "adhdev-autoimpl");
26082
26735
  if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
26083
- const promptFile = path24.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
26736
+ const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
26084
26737
  fs14.writeFileSync(promptFile, prompt, "utf-8");
26085
26738
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
26086
26739
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -26233,7 +26886,7 @@ async function handleAutoImplement(ctx, type, req, res) {
26233
26886
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
26234
26887
  const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
26235
26888
  let shellCmd;
26236
- const isWin = os20.platform() === "win32";
26889
+ const isWin = os21.platform() === "win32";
26237
26890
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
26238
26891
  const promptMode = autoImpl?.promptMode ?? "stdin";
26239
26892
  const extraArgs = autoImpl?.extraArgs ?? [];
@@ -26272,7 +26925,7 @@ async function handleAutoImplement(ctx, type, req, res) {
26272
26925
  try {
26273
26926
  const pty = require("node-pty");
26274
26927
  ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
26275
- const isWin2 = os20.platform() === "win32";
26928
+ const isWin2 = os21.platform() === "win32";
26276
26929
  child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
26277
26930
  name: "xterm-256color",
26278
26931
  cols: 120,
@@ -26512,7 +27165,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26512
27165
  setMode: "set_mode.js"
26513
27166
  };
26514
27167
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
26515
- const scriptsDir = path24.join(providerDir, "scripts");
27168
+ const scriptsDir = path25.join(providerDir, "scripts");
26516
27169
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
26517
27170
  if (latestScriptsDir) {
26518
27171
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -26523,7 +27176,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26523
27176
  for (const file of fs14.readdirSync(latestScriptsDir)) {
26524
27177
  if (file.endsWith(".js") && targetFileNames.has(file)) {
26525
27178
  try {
26526
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27179
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26527
27180
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
26528
27181
  lines.push("```javascript");
26529
27182
  lines.push(content);
@@ -26540,7 +27193,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26540
27193
  lines.push("");
26541
27194
  for (const file of refFiles) {
26542
27195
  try {
26543
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27196
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26544
27197
  lines.push(`### \`${file}\` \u{1F512}`);
26545
27198
  lines.push("```javascript");
26546
27199
  lines.push(content);
@@ -26581,10 +27234,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26581
27234
  lines.push("");
26582
27235
  }
26583
27236
  }
26584
- const docsDir = path24.join(providerDir, "../../docs");
27237
+ const docsDir = path25.join(providerDir, "../../docs");
26585
27238
  const loadGuide = (name) => {
26586
27239
  try {
26587
- const p = path24.join(docsDir, name);
27240
+ const p = path25.join(docsDir, name);
26588
27241
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
26589
27242
  } catch {
26590
27243
  }
@@ -26821,7 +27474,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26821
27474
  parseApproval: "parse_approval.js"
26822
27475
  };
26823
27476
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
26824
- const scriptsDir = path24.join(providerDir, "scripts");
27477
+ const scriptsDir = path25.join(providerDir, "scripts");
26825
27478
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
26826
27479
  if (latestScriptsDir) {
26827
27480
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -26833,7 +27486,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26833
27486
  if (!file.endsWith(".js")) continue;
26834
27487
  if (!targetFileNames.has(file)) continue;
26835
27488
  try {
26836
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27489
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26837
27490
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
26838
27491
  lines.push("```javascript");
26839
27492
  lines.push(content);
@@ -26849,7 +27502,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26849
27502
  lines.push("");
26850
27503
  for (const file of refFiles) {
26851
27504
  try {
26852
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27505
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26853
27506
  lines.push(`### \`${file}\` \u{1F512}`);
26854
27507
  lines.push("```javascript");
26855
27508
  lines.push(content);
@@ -26882,10 +27535,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26882
27535
  lines.push("");
26883
27536
  }
26884
27537
  }
26885
- const docsDir = path24.join(providerDir, "../../docs");
27538
+ const docsDir = path25.join(providerDir, "../../docs");
26886
27539
  const loadGuide = (name) => {
26887
27540
  try {
26888
- const p = path24.join(docsDir, name);
27541
+ const p = path25.join(docsDir, name);
26889
27542
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
26890
27543
  } catch {
26891
27544
  }
@@ -27332,8 +27985,8 @@ var DevServer = class _DevServer {
27332
27985
  }
27333
27986
  getEndpointList() {
27334
27987
  return this.routes.map((r) => {
27335
- const path26 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
27336
- return `${r.method.padEnd(5)} ${path26}`;
27988
+ const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
27989
+ return `${r.method.padEnd(5)} ${path27}`;
27337
27990
  });
27338
27991
  }
27339
27992
  async start(port = DEV_SERVER_PORT) {
@@ -27621,12 +28274,12 @@ var DevServer = class _DevServer {
27621
28274
  // ─── DevConsole SPA ───
27622
28275
  getConsoleDistDir() {
27623
28276
  const candidates = [
27624
- path25.resolve(__dirname, "../../web-devconsole/dist"),
27625
- path25.resolve(__dirname, "../../../web-devconsole/dist"),
27626
- path25.join(process.cwd(), "packages/web-devconsole/dist")
28277
+ path26.resolve(__dirname, "../../web-devconsole/dist"),
28278
+ path26.resolve(__dirname, "../../../web-devconsole/dist"),
28279
+ path26.join(process.cwd(), "packages/web-devconsole/dist")
27627
28280
  ];
27628
28281
  for (const dir of candidates) {
27629
- if (fs15.existsSync(path25.join(dir, "index.html"))) return dir;
28282
+ if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
27630
28283
  }
27631
28284
  return null;
27632
28285
  }
@@ -27636,7 +28289,7 @@ var DevServer = class _DevServer {
27636
28289
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
27637
28290
  return;
27638
28291
  }
27639
- const htmlPath = path25.join(distDir, "index.html");
28292
+ const htmlPath = path26.join(distDir, "index.html");
27640
28293
  try {
27641
28294
  const html = fs15.readFileSync(htmlPath, "utf-8");
27642
28295
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -27661,15 +28314,15 @@ var DevServer = class _DevServer {
27661
28314
  this.json(res, 404, { error: "Not found" });
27662
28315
  return;
27663
28316
  }
27664
- const safePath = path25.normalize(pathname).replace(/^\.\.\//, "");
27665
- const filePath = path25.join(distDir, safePath);
28317
+ const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
28318
+ const filePath = path26.join(distDir, safePath);
27666
28319
  if (!filePath.startsWith(distDir)) {
27667
28320
  this.json(res, 403, { error: "Forbidden" });
27668
28321
  return;
27669
28322
  }
27670
28323
  try {
27671
28324
  const content = fs15.readFileSync(filePath);
27672
- const ext = path25.extname(filePath);
28325
+ const ext = path26.extname(filePath);
27673
28326
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
27674
28327
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
27675
28328
  res.end(content);
@@ -27782,9 +28435,9 @@ var DevServer = class _DevServer {
27782
28435
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
27783
28436
  if (entry.isDirectory()) {
27784
28437
  files.push({ path: rel, size: 0, type: "dir" });
27785
- scan(path25.join(d, entry.name), rel);
28438
+ scan(path26.join(d, entry.name), rel);
27786
28439
  } else {
27787
- const stat2 = fs15.statSync(path25.join(d, entry.name));
28440
+ const stat2 = fs15.statSync(path26.join(d, entry.name));
27788
28441
  files.push({ path: rel, size: stat2.size, type: "file" });
27789
28442
  }
27790
28443
  }
@@ -27807,7 +28460,7 @@ var DevServer = class _DevServer {
27807
28460
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
27808
28461
  return;
27809
28462
  }
27810
- const fullPath = path25.resolve(dir, path25.normalize(filePath));
28463
+ const fullPath = path26.resolve(dir, path26.normalize(filePath));
27811
28464
  if (!fullPath.startsWith(dir)) {
27812
28465
  this.json(res, 403, { error: "Forbidden" });
27813
28466
  return;
@@ -27832,14 +28485,14 @@ var DevServer = class _DevServer {
27832
28485
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
27833
28486
  return;
27834
28487
  }
27835
- const fullPath = path25.resolve(dir, path25.normalize(filePath));
28488
+ const fullPath = path26.resolve(dir, path26.normalize(filePath));
27836
28489
  if (!fullPath.startsWith(dir)) {
27837
28490
  this.json(res, 403, { error: "Forbidden" });
27838
28491
  return;
27839
28492
  }
27840
28493
  try {
27841
28494
  if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
27842
- fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
28495
+ fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
27843
28496
  fs15.writeFileSync(fullPath, content, "utf-8");
27844
28497
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
27845
28498
  this.providerLoader.reload();
@@ -27856,7 +28509,7 @@ var DevServer = class _DevServer {
27856
28509
  return;
27857
28510
  }
27858
28511
  for (const name of ["scripts.js", "provider.json"]) {
27859
- const p = path25.join(dir, name);
28512
+ const p = path26.join(dir, name);
27860
28513
  if (fs15.existsSync(p)) {
27861
28514
  const source = fs15.readFileSync(p, "utf-8");
27862
28515
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -27877,8 +28530,8 @@ var DevServer = class _DevServer {
27877
28530
  this.json(res, 404, { error: `Provider not found: ${type}` });
27878
28531
  return;
27879
28532
  }
27880
- const target = fs15.existsSync(path25.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
27881
- const targetPath = path25.join(dir, target);
28533
+ const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
28534
+ const targetPath = path26.join(dir, target);
27882
28535
  try {
27883
28536
  if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
27884
28537
  fs15.writeFileSync(targetPath, source, "utf-8");
@@ -28025,7 +28678,7 @@ var DevServer = class _DevServer {
28025
28678
  }
28026
28679
  let targetDir;
28027
28680
  targetDir = this.providerLoader.getUserProviderDir(category, type);
28028
- const jsonPath = path25.join(targetDir, "provider.json");
28681
+ const jsonPath = path26.join(targetDir, "provider.json");
28029
28682
  if (fs15.existsSync(jsonPath)) {
28030
28683
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
28031
28684
  return;
@@ -28037,8 +28690,8 @@ var DevServer = class _DevServer {
28037
28690
  const createdFiles = ["provider.json"];
28038
28691
  if (result.files) {
28039
28692
  for (const [relPath, content] of Object.entries(result.files)) {
28040
- const fullPath = path25.join(targetDir, relPath);
28041
- fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
28693
+ const fullPath = path26.join(targetDir, relPath);
28694
+ fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
28042
28695
  fs15.writeFileSync(fullPath, content, "utf-8");
28043
28696
  createdFiles.push(relPath);
28044
28697
  }
@@ -28091,22 +28744,22 @@ var DevServer = class _DevServer {
28091
28744
  if (!fs15.existsSync(scriptsDir)) return null;
28092
28745
  const versions = fs15.readdirSync(scriptsDir).filter((d) => {
28093
28746
  try {
28094
- return fs15.statSync(path25.join(scriptsDir, d)).isDirectory();
28747
+ return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
28095
28748
  } catch {
28096
28749
  return false;
28097
28750
  }
28098
28751
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
28099
28752
  if (versions.length === 0) return null;
28100
- return path25.join(scriptsDir, versions[0]);
28753
+ return path26.join(scriptsDir, versions[0]);
28101
28754
  }
28102
28755
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
28103
- const canonicalUserDir = path25.resolve(this.providerLoader.getUserProviderDir(category, type));
28104
- const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
28105
- const upstreamRoot = path25.resolve(this.providerLoader.getUpstreamDir());
28106
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
28756
+ const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
28757
+ const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
28758
+ const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
28759
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
28107
28760
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
28108
28761
  }
28109
- if (path25.basename(desiredDir) !== type) {
28762
+ if (path26.basename(desiredDir) !== type) {
28110
28763
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
28111
28764
  }
28112
28765
  const sourceDir = this.findProviderDir(type);
@@ -28114,11 +28767,11 @@ var DevServer = class _DevServer {
28114
28767
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
28115
28768
  }
28116
28769
  if (!fs15.existsSync(desiredDir)) {
28117
- fs15.mkdirSync(path25.dirname(desiredDir), { recursive: true });
28770
+ fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
28118
28771
  fs15.cpSync(sourceDir, desiredDir, { recursive: true });
28119
28772
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
28120
28773
  }
28121
- const providerJson = path25.join(desiredDir, "provider.json");
28774
+ const providerJson = path26.join(desiredDir, "provider.json");
28122
28775
  if (!fs15.existsSync(providerJson)) {
28123
28776
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
28124
28777
  }
@@ -28154,7 +28807,7 @@ var DevServer = class _DevServer {
28154
28807
  setMode: "set_mode.js"
28155
28808
  };
28156
28809
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
28157
- const scriptsDir = path25.join(providerDir, "scripts");
28810
+ const scriptsDir = path26.join(providerDir, "scripts");
28158
28811
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
28159
28812
  if (latestScriptsDir) {
28160
28813
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -28165,7 +28818,7 @@ var DevServer = class _DevServer {
28165
28818
  for (const file of fs15.readdirSync(latestScriptsDir)) {
28166
28819
  if (file.endsWith(".js") && targetFileNames.has(file)) {
28167
28820
  try {
28168
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28821
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28169
28822
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
28170
28823
  lines.push("```javascript");
28171
28824
  lines.push(content);
@@ -28182,7 +28835,7 @@ var DevServer = class _DevServer {
28182
28835
  lines.push("");
28183
28836
  for (const file of refFiles) {
28184
28837
  try {
28185
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28838
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28186
28839
  lines.push(`### \`${file}\` \u{1F512}`);
28187
28840
  lines.push("```javascript");
28188
28841
  lines.push(content);
@@ -28223,10 +28876,10 @@ var DevServer = class _DevServer {
28223
28876
  lines.push("");
28224
28877
  }
28225
28878
  }
28226
- const docsDir = path25.join(providerDir, "../../docs");
28879
+ const docsDir = path26.join(providerDir, "../../docs");
28227
28880
  const loadGuide = (name) => {
28228
28881
  try {
28229
- const p = path25.join(docsDir, name);
28882
+ const p = path26.join(docsDir, name);
28230
28883
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
28231
28884
  } catch {
28232
28885
  }
@@ -28400,7 +29053,7 @@ var DevServer = class _DevServer {
28400
29053
  parseApproval: "parse_approval.js"
28401
29054
  };
28402
29055
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
28403
- const scriptsDir = path25.join(providerDir, "scripts");
29056
+ const scriptsDir = path26.join(providerDir, "scripts");
28404
29057
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
28405
29058
  if (latestScriptsDir) {
28406
29059
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -28412,7 +29065,7 @@ var DevServer = class _DevServer {
28412
29065
  if (!file.endsWith(".js")) continue;
28413
29066
  if (!targetFileNames.has(file)) continue;
28414
29067
  try {
28415
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
29068
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28416
29069
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
28417
29070
  lines.push("```javascript");
28418
29071
  lines.push(content);
@@ -28428,7 +29081,7 @@ var DevServer = class _DevServer {
28428
29081
  lines.push("");
28429
29082
  for (const file of refFiles) {
28430
29083
  try {
28431
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
29084
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28432
29085
  lines.push(`### \`${file}\` \u{1F512}`);
28433
29086
  lines.push("```javascript");
28434
29087
  lines.push(content);
@@ -28461,10 +29114,10 @@ var DevServer = class _DevServer {
28461
29114
  lines.push("");
28462
29115
  }
28463
29116
  }
28464
- const docsDir = path25.join(providerDir, "../../docs");
29117
+ const docsDir = path26.join(providerDir, "../../docs");
28465
29118
  const loadGuide = (name) => {
28466
29119
  try {
28467
- const p = path25.join(docsDir, name);
29120
+ const p = path26.join(docsDir, name);
28468
29121
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
28469
29122
  } catch {
28470
29123
  }
@@ -29468,33 +30121,49 @@ init_config();
29468
30121
  // src/mesh/mesh-events.ts
29469
30122
  init_mesh_config();
29470
30123
  init_logger();
30124
+ function readNonEmptyString(value) {
30125
+ return typeof value === "string" && value.trim() ? value.trim() : "";
30126
+ }
30127
+ function formatCompletionMetadata(event) {
30128
+ const parts = [
30129
+ readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : "",
30130
+ readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : "",
30131
+ readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : ""
30132
+ ].filter(Boolean);
30133
+ return parts.length > 0 ? ` (${parts.join("; ")})` : "";
30134
+ }
29471
30135
  function setupMeshEventForwarding(components) {
29472
30136
  components.instanceManager.onEvent((event) => {
29473
30137
  if (event.event !== "agent:generating_completed" && event.event !== "agent:waiting_approval") return;
29474
- const instanceId = event.instanceId;
30138
+ const instanceId = readNonEmptyString(event.instanceId);
29475
30139
  if (!instanceId) return;
29476
30140
  const sourceInstance = components.instanceManager.getInstance(instanceId);
29477
30141
  if (!sourceInstance || sourceInstance.category !== "cli") return;
29478
30142
  const state = sourceInstance.getState();
29479
- const workspace = state.workspace;
30143
+ const workspace = readNonEmptyString(state.workspace);
29480
30144
  if (!workspace) return;
29481
- const mesh = getMeshByRepo(workspace);
29482
- if (!mesh) return;
30145
+ const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
30146
+ const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
30147
+ const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
30148
+ const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
30149
+ if (!meshId) return;
29483
30150
  const allInstances = components.instanceManager.getByCategory("cli");
29484
30151
  const coordinatorInstances = allInstances.filter((inst) => {
29485
30152
  const instState = inst.getState();
29486
- if (instState.settings?.meshCoordinatorFor !== mesh.id) return false;
30153
+ if (instState.settings?.meshCoordinatorFor !== meshId) return false;
29487
30154
  if (instState.instanceId === instanceId) return false;
29488
30155
  return true;
29489
30156
  });
29490
30157
  if (coordinatorInstances.length === 0) return;
29491
- const targetNode = mesh.nodes.find((n) => n.workspace === workspace);
29492
- const nodeLabel = targetNode ? `Node '${targetNode.id}'` : `Agent at ${workspace}`;
30158
+ const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
30159
+ const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
30160
+ const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
30161
+ const metadata = formatCompletionMetadata(event);
29493
30162
  let messageText = "";
29494
30163
  if (event.event === "agent:generating_completed") {
29495
- messageText = `[System] ${nodeLabel} has completed its task and is now idle. You may use mesh_read_chat to review its progress.`;
30164
+ messageText = `[System] ${nodeLabel} has completed its task and is now idle${metadata}. You may use mesh_read_chat to review its progress.`;
29496
30165
  } else if (event.event === "agent:waiting_approval") {
29497
- messageText = `[System] ${nodeLabel} is waiting for approval to proceed. You may use mesh_read_chat and mesh_approve to handle it.`;
30166
+ messageText = `[System] ${nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
29498
30167
  }
29499
30168
  if (!messageText) return;
29500
30169
  for (const coord of coordinatorInstances) {
@@ -29812,6 +30481,7 @@ async function shutdownDaemonComponents(components) {
29812
30481
  createGitWorkspaceMonitor,
29813
30482
  createInteractionId,
29814
30483
  createMesh,
30484
+ createWorktree,
29815
30485
  deleteMesh,
29816
30486
  detectAllVersions,
29817
30487
  detectCLIs,
@@ -29864,6 +30534,7 @@ async function shutdownDaemonComponents(components) {
29864
30534
  launchWithCdp,
29865
30535
  listHostedCliRuntimes,
29866
30536
  listMeshes,
30537
+ listWorktrees,
29867
30538
  loadConfig,
29868
30539
  loadState,
29869
30540
  logCommand,
@@ -29883,6 +30554,7 @@ async function shutdownDaemonComponents(components) {
29883
30554
  normalizeSessionModalFields,
29884
30555
  parsePorcelainV2Status,
29885
30556
  parseProviderSourceConfigUpdate,
30557
+ parseWorktreeListOutput,
29886
30558
  partitionSessionHostDiagnosticsSessions,
29887
30559
  partitionSessionHostRecords,
29888
30560
  prepareSessionChatTailUpdate,
@@ -29892,6 +30564,7 @@ async function shutdownDaemonComponents(components) {
29892
30564
  recordDebugTrace,
29893
30565
  registerExtensionProviders,
29894
30566
  removeNode,
30567
+ removeWorktree,
29895
30568
  resetConfig,
29896
30569
  resetDebugRuntimeConfig,
29897
30570
  resetState,
@@ -29901,6 +30574,7 @@ async function shutdownDaemonComponents(components) {
29901
30574
  resolveGitRepository,
29902
30575
  resolveSessionHostAppName,
29903
30576
  resolveSessionHostAppNameResolution,
30577
+ resolveWorktreePath,
29904
30578
  runAsyncBatch,
29905
30579
  runGit,
29906
30580
  saveConfig,