@adhdev/daemon-core 0.9.76-rc.2 → 0.9.76-rc.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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,
@@ -5175,20 +5326,23 @@ var TurnSnapshotTracker = class {
5175
5326
  }
5176
5327
  };
5177
5328
 
5329
+ // src/git/index.ts
5330
+ init_git_worktree();
5331
+
5178
5332
  // src/index.ts
5179
5333
  init_config();
5180
5334
 
5181
5335
  // src/config/workspaces.ts
5182
5336
  var fs = __toESM(require("fs"));
5183
5337
  var os = __toESM(require("os"));
5184
- var path4 = __toESM(require("path"));
5338
+ var path5 = __toESM(require("path"));
5185
5339
  var import_crypto2 = require("crypto");
5186
5340
  var MAX_WORKSPACES = 50;
5187
5341
  function expandPath(p) {
5188
5342
  const t = (p || "").trim();
5189
5343
  if (!t) return "";
5190
- if (t.startsWith("~")) return path4.join(os.homedir(), t.slice(1).replace(/^\//, ""));
5191
- return path4.resolve(t);
5344
+ if (t.startsWith("~")) return path5.join(os.homedir(), t.slice(1).replace(/^\//, ""));
5345
+ return path5.resolve(t);
5192
5346
  }
5193
5347
  function validateWorkspacePath(absPath) {
5194
5348
  try {
@@ -5202,7 +5356,7 @@ function validateWorkspacePath(absPath) {
5202
5356
  }
5203
5357
  }
5204
5358
  function defaultWorkspaceLabel(absPath) {
5205
- const base = path4.basename(absPath) || absPath;
5359
+ const base = path5.basename(absPath) || absPath;
5206
5360
  return base;
5207
5361
  }
5208
5362
  function getDefaultWorkspacePath(config) {
@@ -5293,9 +5447,9 @@ function resolveIdeLaunchWorkspace(args, config) {
5293
5447
  return getDefaultWorkspacePath(config) || void 0;
5294
5448
  }
5295
5449
  function findWorkspaceByPath(config, rawPath) {
5296
- const abs = path4.resolve(expandPath(rawPath));
5450
+ const abs = path5.resolve(expandPath(rawPath));
5297
5451
  if (!abs) return void 0;
5298
- return (config.workspaces || []).find((w) => path4.resolve(expandPath(w.path)) === abs);
5452
+ return (config.workspaces || []).find((w) => path5.resolve(expandPath(w.path)) === abs);
5299
5453
  }
5300
5454
  function addWorkspaceEntry(config, rawPath, label, options) {
5301
5455
  const abs = expandPath(rawPath);
@@ -5311,7 +5465,7 @@ function addWorkspaceEntry(config, rawPath, label, options) {
5311
5465
  const v = validateWorkspacePath(abs);
5312
5466
  if (!v.ok) return { error: v.error };
5313
5467
  const list = [...config.workspaces || []];
5314
- if (list.some((w) => path4.resolve(w.path) === abs)) {
5468
+ if (list.some((w) => path5.resolve(w.path) === abs)) {
5315
5469
  return { error: "Workspace already in list" };
5316
5470
  }
5317
5471
  if (list.length >= MAX_WORKSPACES) {
@@ -5345,7 +5499,7 @@ function setDefaultWorkspaceId(config, id) {
5345
5499
  }
5346
5500
 
5347
5501
  // src/config/recent-activity.ts
5348
- var path5 = __toESM(require("path"));
5502
+ var path6 = __toESM(require("path"));
5349
5503
 
5350
5504
  // src/providers/summary-metadata.ts
5351
5505
  function normalizeSummaryItem(item) {
@@ -5414,9 +5568,9 @@ var MAX_ACTIVITY = 30;
5414
5568
  function normalizeWorkspace(workspace) {
5415
5569
  if (!workspace) return "";
5416
5570
  try {
5417
- return path5.resolve(expandPath(workspace));
5571
+ return path6.resolve(expandPath(workspace));
5418
5572
  } catch {
5419
- return path5.resolve(workspace);
5573
+ return path6.resolve(workspace);
5420
5574
  }
5421
5575
  }
5422
5576
  function buildRecentActivityKey(entry) {
@@ -5584,14 +5738,14 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
5584
5738
  }
5585
5739
 
5586
5740
  // src/config/saved-sessions.ts
5587
- var path6 = __toESM(require("path"));
5741
+ var path7 = __toESM(require("path"));
5588
5742
  var MAX_SAVED_SESSIONS = 500;
5589
5743
  function normalizeWorkspace2(workspace) {
5590
5744
  if (!workspace) return "";
5591
5745
  try {
5592
- return path6.resolve(expandPath(workspace));
5746
+ return path7.resolve(expandPath(workspace));
5593
5747
  } catch {
5594
- return path6.resolve(workspace);
5748
+ return path7.resolve(workspace);
5595
5749
  }
5596
5750
  }
5597
5751
  function buildSavedProviderSessionKey(providerSessionId) {
@@ -5770,7 +5924,7 @@ function resetState() {
5770
5924
  var import_child_process = require("child_process");
5771
5925
  var import_fs4 = require("fs");
5772
5926
  var import_os2 = require("os");
5773
- var path7 = __toESM(require("path"));
5927
+ var path8 = __toESM(require("path"));
5774
5928
  var BUILTIN_IDE_DEFINITIONS = [];
5775
5929
  var registeredIDEs = /* @__PURE__ */ new Map();
5776
5930
  function registerIDEDefinition(def) {
@@ -5789,9 +5943,9 @@ function getMergedDefinitions() {
5789
5943
  function findCliCommand(command) {
5790
5944
  const trimmed = String(command || "").trim();
5791
5945
  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);
5946
+ if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
5947
+ const candidate = trimmed.startsWith("~") ? path8.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
5948
+ const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
5795
5949
  return (0, import_fs4.existsSync)(resolved) ? resolved : null;
5796
5950
  }
5797
5951
  try {
@@ -5819,7 +5973,7 @@ function getIdeVersion(cliCommand) {
5819
5973
  function checkPathExists(paths) {
5820
5974
  const home = (0, import_os2.homedir)();
5821
5975
  for (const p of paths) {
5822
- const normalized = p.startsWith("~") ? path7.join(home, p.slice(1)) : p;
5976
+ const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
5823
5977
  if (normalized.includes("*")) {
5824
5978
  const username = home.split(/[\\/]/).pop() || "";
5825
5979
  const resolved = normalized.replace("*", username);
@@ -5831,19 +5985,19 @@ function checkPathExists(paths) {
5831
5985
  return null;
5832
5986
  }
5833
5987
  async function detectIDEs(providerLoader) {
5834
- const os21 = (0, import_os2.platform)();
5988
+ const os22 = (0, import_os2.platform)();
5835
5989
  const results = [];
5836
5990
  for (const def of getMergedDefinitions()) {
5837
5991
  const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
5838
- const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os21] || []) || []);
5992
+ const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os22] || []) || []);
5839
5993
  let resolvedCli = cliPath;
5840
- if (!resolvedCli && appPath && os21 === "darwin") {
5994
+ if (!resolvedCli && appPath && os22 === "darwin") {
5841
5995
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
5842
5996
  if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
5843
5997
  }
5844
- if (!resolvedCli && appPath && os21 === "win32") {
5845
- const { dirname: dirname8 } = await import("path");
5846
- const appDir = dirname8(appPath);
5998
+ if (!resolvedCli && appPath && os22 === "win32") {
5999
+ const { dirname: dirname9 } = await import("path");
6000
+ const appDir = dirname9(appPath);
5847
6001
  const candidates = [
5848
6002
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
5849
6003
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -5858,7 +6012,7 @@ async function detectIDEs(providerLoader) {
5858
6012
  }
5859
6013
  }
5860
6014
  }
5861
- const installed = os21 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
6015
+ const installed = os22 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
5862
6016
  const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
5863
6017
  results.push({
5864
6018
  id: def.id,
@@ -5877,7 +6031,7 @@ async function detectIDEs(providerLoader) {
5877
6031
  // src/detection/cli-detector.ts
5878
6032
  var import_child_process2 = require("child_process");
5879
6033
  var os2 = __toESM(require("os"));
5880
- var path8 = __toESM(require("path"));
6034
+ var path9 = __toESM(require("path"));
5881
6035
  var import_fs5 = require("fs");
5882
6036
  function parseVersion(raw) {
5883
6037
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
@@ -5890,18 +6044,18 @@ function shellQuote(value) {
5890
6044
  function expandHome(value) {
5891
6045
  const trimmed = value.trim();
5892
6046
  if (!trimmed.startsWith("~")) return trimmed;
5893
- return path8.join(os2.homedir(), trimmed.slice(1));
6047
+ return path9.join(os2.homedir(), trimmed.slice(1));
5894
6048
  }
5895
6049
  function isExplicitCommandPath(command) {
5896
6050
  const trimmed = command.trim();
5897
- return path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
6051
+ return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
5898
6052
  }
5899
6053
  function resolveCommandPath(command) {
5900
6054
  const trimmed = command.trim();
5901
6055
  if (!trimmed) return null;
5902
6056
  if (isExplicitCommandPath(trimmed)) {
5903
6057
  const expanded = expandHome(trimmed);
5904
- const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
6058
+ const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
5905
6059
  return (0, import_fs5.existsSync)(candidate) ? candidate : null;
5906
6060
  }
5907
6061
  return null;
@@ -8170,9 +8324,9 @@ ${cleanBody}`;
8170
8324
 
8171
8325
  // src/config/chat-history.ts
8172
8326
  var fs3 = __toESM(require("fs"));
8173
- var path10 = __toESM(require("path"));
8327
+ var path11 = __toESM(require("path"));
8174
8328
  var os5 = __toESM(require("os"));
8175
- var HISTORY_DIR = path10.join(os5.homedir(), ".adhdev", "history");
8329
+ var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
8176
8330
  var RETAIN_DAYS = 30;
8177
8331
  var SAVED_HISTORY_INDEX_VERSION = 1;
8178
8332
  var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -8335,7 +8489,7 @@ function extractSavedHistorySessionIdFromFile(file) {
8335
8489
  function buildSavedHistoryFileSignatureMap(dir, files) {
8336
8490
  return new Map(files.map((file) => {
8337
8491
  try {
8338
- const stat2 = fs3.statSync(path10.join(dir, file));
8492
+ const stat2 = fs3.statSync(path11.join(dir, file));
8339
8493
  return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
8340
8494
  } catch {
8341
8495
  return [file, `${file}:missing`];
@@ -8346,7 +8500,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
8346
8500
  return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
8347
8501
  }
8348
8502
  function getSavedHistoryIndexFilePath(dir) {
8349
- return path10.join(dir, SAVED_HISTORY_INDEX_FILE);
8503
+ return path11.join(dir, SAVED_HISTORY_INDEX_FILE);
8350
8504
  }
8351
8505
  function getSavedHistoryIndexLockPath(dir) {
8352
8506
  return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
@@ -8448,7 +8602,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
8448
8602
  }
8449
8603
  for (const file of Array.from(currentEntries.keys())) {
8450
8604
  if (incomingFiles.has(file)) continue;
8451
- if (!fs3.existsSync(path10.join(dir, file))) {
8605
+ if (!fs3.existsSync(path11.join(dir, file))) {
8452
8606
  currentEntries.delete(file);
8453
8607
  }
8454
8608
  }
@@ -8474,7 +8628,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
8474
8628
  const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
8475
8629
  const files = listHistoryFiles(dir);
8476
8630
  for (const file of files) {
8477
- const stat2 = fs3.statSync(path10.join(dir, file));
8631
+ const stat2 = fs3.statSync(path11.join(dir, file));
8478
8632
  if (stat2.mtimeMs > indexStat.mtimeMs) return true;
8479
8633
  }
8480
8634
  return false;
@@ -8484,14 +8638,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
8484
8638
  }
8485
8639
  function buildSavedHistoryFileSignature(dir, file) {
8486
8640
  try {
8487
- const stat2 = fs3.statSync(path10.join(dir, file));
8641
+ const stat2 = fs3.statSync(path11.join(dir, file));
8488
8642
  return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
8489
8643
  } catch {
8490
8644
  return `${file}:missing`;
8491
8645
  }
8492
8646
  }
8493
8647
  function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
8494
- const filePath = path10.join(dir, file);
8648
+ const filePath = path11.join(dir, file);
8495
8649
  const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
8496
8650
  const currentEntry = entries.get(file) || null;
8497
8651
  const nextSummary = updater(currentEntry?.summary || null);
@@ -8564,7 +8718,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
8564
8718
  function computeSavedHistoryFileSummary(dir, file) {
8565
8719
  const historySessionId = extractSavedHistorySessionIdFromFile(file);
8566
8720
  if (!historySessionId) return null;
8567
- const filePath = path10.join(dir, file);
8721
+ const filePath = path11.join(dir, file);
8568
8722
  const content = fs3.readFileSync(filePath, "utf-8");
8569
8723
  const lines = content.split("\n").filter(Boolean);
8570
8724
  let messageCount = 0;
@@ -8651,7 +8805,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
8651
8805
  const summaryBySessionId = /* @__PURE__ */ new Map();
8652
8806
  const nextPersistedEntries = /* @__PURE__ */ new Map();
8653
8807
  for (const file of files.slice().sort()) {
8654
- const filePath = path10.join(dir, file);
8808
+ const filePath = path11.join(dir, file);
8655
8809
  const signature = fileSignatures.get(file) || `${file}:missing`;
8656
8810
  const cached = savedHistoryFileSummaryCache.get(filePath);
8657
8811
  const persisted = persistedEntries.get(file);
@@ -8771,12 +8925,12 @@ var ChatHistoryWriter = class {
8771
8925
  });
8772
8926
  }
8773
8927
  if (newMessages.length === 0) return;
8774
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
8928
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8775
8929
  fs3.mkdirSync(dir, { recursive: true });
8776
8930
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8777
8931
  const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
8778
8932
  const fileName = `${filePrefix}${date}.jsonl`;
8779
- const filePath = path10.join(dir, fileName);
8933
+ const filePath = path11.join(dir, fileName);
8780
8934
  const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
8781
8935
  fs3.appendFileSync(filePath, lines, "utf-8");
8782
8936
  updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
@@ -8867,11 +9021,11 @@ var ChatHistoryWriter = class {
8867
9021
  const ws = String(workspace || "").trim();
8868
9022
  if (!id || !ws) return;
8869
9023
  try {
8870
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9024
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8871
9025
  fs3.mkdirSync(dir, { recursive: true });
8872
9026
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8873
9027
  const fileName = `${this.sanitize(id)}_${date}.jsonl`;
8874
- const filePath = path10.join(dir, fileName);
9028
+ const filePath = path11.join(dir, fileName);
8875
9029
  const record = {
8876
9030
  ts: (/* @__PURE__ */ new Date()).toISOString(),
8877
9031
  receivedAt: Date.now(),
@@ -8917,14 +9071,14 @@ var ChatHistoryWriter = class {
8917
9071
  this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
8918
9072
  this.lastSeenCounts.delete(fromDedupKey);
8919
9073
  }
8920
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9074
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8921
9075
  if (!fs3.existsSync(dir)) return;
8922
9076
  const fromPrefix = `${this.sanitize(fromId)}_`;
8923
9077
  const toPrefix = `${this.sanitize(toId)}_`;
8924
9078
  const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
8925
9079
  for (const file of files) {
8926
- const sourcePath = path10.join(dir, file);
8927
- const targetPath = path10.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
9080
+ const sourcePath = path11.join(dir, file);
9081
+ const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
8928
9082
  const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
8929
9083
  const rewritten = sourceLines.map((line) => {
8930
9084
  try {
@@ -8958,13 +9112,13 @@ var ChatHistoryWriter = class {
8958
9112
  const sessionId = String(historySessionId || "").trim();
8959
9113
  if (!sessionId) return;
8960
9114
  try {
8961
- const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
9115
+ const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
8962
9116
  if (!fs3.existsSync(dir)) return;
8963
9117
  const prefix = `${this.sanitize(sessionId)}_`;
8964
9118
  const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
8965
9119
  const seen = /* @__PURE__ */ new Set();
8966
9120
  for (const file of files) {
8967
- const filePath = path10.join(dir, file);
9121
+ const filePath = path11.join(dir, file);
8968
9122
  const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8969
9123
  const next = [];
8970
9124
  for (const line of lines) {
@@ -9018,11 +9172,11 @@ var ChatHistoryWriter = class {
9018
9172
  const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
9019
9173
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
9020
9174
  for (const dir of agentDirs) {
9021
- const dirPath = path10.join(HISTORY_DIR, dir.name);
9175
+ const dirPath = path11.join(HISTORY_DIR, dir.name);
9022
9176
  const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
9023
9177
  let removedAny = false;
9024
9178
  for (const file of files) {
9025
- const filePath = path10.join(dirPath, file);
9179
+ const filePath = path11.join(dirPath, file);
9026
9180
  const stat2 = fs3.statSync(filePath);
9027
9181
  if (stat2.mtimeMs < cutoff) {
9028
9182
  fs3.unlinkSync(filePath);
@@ -9072,13 +9226,13 @@ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeR
9072
9226
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
9073
9227
  try {
9074
9228
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
9075
- const dir = path10.join(HISTORY_DIR, sanitized);
9229
+ const dir = path11.join(HISTORY_DIR, sanitized);
9076
9230
  if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
9077
9231
  const files = listHistoryFiles(dir, historySessionId);
9078
9232
  const allMessages = [];
9079
9233
  const seen = /* @__PURE__ */ new Set();
9080
9234
  for (const file of files) {
9081
- const filePath = path10.join(dir, file);
9235
+ const filePath = path11.join(dir, file);
9082
9236
  const content = fs3.readFileSync(filePath, "utf-8");
9083
9237
  const lines = content.trim().split("\n").filter(Boolean);
9084
9238
  for (let i = 0; i < lines.length; i++) {
@@ -9102,7 +9256,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
9102
9256
  function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
9103
9257
  try {
9104
9258
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
9105
- const dir = path10.join(HISTORY_DIR, sanitized);
9259
+ const dir = path11.join(HISTORY_DIR, sanitized);
9106
9260
  if (!fs3.existsSync(dir)) {
9107
9261
  savedHistorySessionCache.delete(sanitized);
9108
9262
  return { sessions: [], hasMore: false };
@@ -9163,11 +9317,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
9163
9317
  }
9164
9318
  function readExistingSessionStartRecord(agentType, historySessionId) {
9165
9319
  try {
9166
- const dir = path10.join(HISTORY_DIR, agentType);
9320
+ const dir = path11.join(HISTORY_DIR, agentType);
9167
9321
  if (!fs3.existsSync(dir)) return null;
9168
9322
  const files = listHistoryFiles(dir, historySessionId).sort();
9169
9323
  for (const file of files) {
9170
- const lines = fs3.readFileSync(path10.join(dir, file), "utf-8").split("\n").filter(Boolean);
9324
+ const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
9171
9325
  for (const line of lines) {
9172
9326
  try {
9173
9327
  const parsed = JSON.parse(line);
@@ -9187,16 +9341,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
9187
9341
  function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
9188
9342
  if (records.length === 0) return false;
9189
9343
  try {
9190
- const dir = path10.join(HISTORY_DIR, agentType);
9344
+ const dir = path11.join(HISTORY_DIR, agentType);
9191
9345
  fs3.mkdirSync(dir, { recursive: true });
9192
9346
  const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
9193
9347
  for (const file of fs3.readdirSync(dir)) {
9194
9348
  if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
9195
- fs3.unlinkSync(path10.join(dir, file));
9349
+ fs3.unlinkSync(path11.join(dir, file));
9196
9350
  }
9197
9351
  }
9198
9352
  const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
9199
- const filePath = path10.join(dir, `${prefix}${targetDate}.jsonl`);
9353
+ const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
9200
9354
  fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
9201
9355
  `, "utf-8");
9202
9356
  invalidatePersistedSavedHistoryIndex(agentType, dir);
@@ -11191,6 +11345,14 @@ function getActiveChatOptions(profile) {
11191
11345
  if (profile === "full") return {};
11192
11346
  return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
11193
11347
  }
11348
+ function resolveSessionStatus(activeChat, providerStatus) {
11349
+ const chatStatus = normalizeManagedStatus(activeChat?.status, { activeModal: activeChat?.activeModal || null });
11350
+ const topLevelStatus = normalizeManagedStatus(providerStatus, { activeModal: activeChat?.activeModal || null });
11351
+ if (chatStatus === "waiting_approval" || topLevelStatus === "waiting_approval") return "waiting_approval";
11352
+ if (chatStatus === "generating" || topLevelStatus === "generating") return "generating";
11353
+ if (topLevelStatus !== "idle") return topLevelStatus;
11354
+ return chatStatus;
11355
+ }
11194
11356
  function shouldIncludeSessionControls(profile) {
11195
11357
  return profile !== "live";
11196
11358
  }
@@ -11269,9 +11431,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
11269
11431
  providerName: state.name,
11270
11432
  kind: "workspace",
11271
11433
  transport: "cdp-page",
11272
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11273
- activeModal: activeChat?.activeModal || null
11274
- }),
11434
+ status: resolveSessionStatus(activeChat, state.status),
11275
11435
  title,
11276
11436
  workspace,
11277
11437
  ...git && { git },
@@ -11306,9 +11466,7 @@ function buildExtensionAgentSession(parent, ext, options) {
11306
11466
  providerSessionId: ext.providerSessionId,
11307
11467
  kind: "agent",
11308
11468
  transport: "cdp-webview",
11309
- status: normalizeManagedStatus(activeChat?.status || ext.status, {
11310
- activeModal: activeChat?.activeModal || null
11311
- }),
11469
+ status: resolveSessionStatus(activeChat, ext.status),
11312
11470
  title: activeChat?.title || ext.name,
11313
11471
  workspace,
11314
11472
  ...git && { git },
@@ -11358,9 +11516,7 @@ function buildCliSession(state, options) {
11358
11516
  providerSessionId: state.providerSessionId,
11359
11517
  kind: "agent",
11360
11518
  transport: "pty",
11361
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11362
- activeModal: activeChat?.activeModal || null
11363
- }),
11519
+ status: resolveSessionStatus(activeChat, state.status),
11364
11520
  title: activeChat?.title || state.name,
11365
11521
  workspace,
11366
11522
  ...git && { git },
@@ -11408,9 +11564,7 @@ function buildAcpSession(state, options) {
11408
11564
  providerName: state.name,
11409
11565
  kind: "agent",
11410
11566
  transport: "acp",
11411
- status: normalizeManagedStatus(activeChat?.status || state.status, {
11412
- activeModal: activeChat?.activeModal || null
11413
- }),
11567
+ status: resolveSessionStatus(activeChat, state.status),
11414
11568
  title: activeChat?.title || state.name,
11415
11569
  workspace,
11416
11570
  ...git && { git },
@@ -11533,7 +11687,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
11533
11687
  // src/commands/chat-commands.ts
11534
11688
  var fs4 = __toESM(require("fs"));
11535
11689
  var os6 = __toESM(require("os"));
11536
- var path11 = __toESM(require("path"));
11690
+ var path12 = __toESM(require("path"));
11537
11691
  var import_node_crypto = require("crypto");
11538
11692
 
11539
11693
  // src/providers/provider-input-support.ts
@@ -11896,6 +12050,34 @@ function normalizeReadChatCommandStatus(status, activeModal) {
11896
12050
  return raw;
11897
12051
  }
11898
12052
  }
12053
+ function isGeneratingLikeStatus(status) {
12054
+ return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
12055
+ }
12056
+ function shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus) {
12057
+ if (!isGeneratingLikeStatus(parsedStatus)) return false;
12058
+ if (hasNonEmptyModalButtons(activeModal)) return false;
12059
+ const adapterRawStatus = typeof adapterStatus?.status === "string" ? adapterStatus.status.trim() : "";
12060
+ if (adapterRawStatus !== "idle") return false;
12061
+ if (typeof adapter.isProcessing === "function" && adapter.isProcessing()) return false;
12062
+ return true;
12063
+ }
12064
+ function normalizeCliReadChatStatus(parsedStatus, activeModal, adapter, adapterStatus) {
12065
+ if (shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus)) return "idle";
12066
+ return typeof parsedStatus === "string" && parsedStatus.trim() ? parsedStatus : "idle";
12067
+ }
12068
+ function finalizeStreamingMessagesWhenIdle(messages, status) {
12069
+ if (status !== "idle") return messages;
12070
+ return messages.map((message) => {
12071
+ const meta = message.meta && typeof message.meta === "object" ? message.meta : void 0;
12072
+ const hasStreamingMeta = meta?.streaming === true;
12073
+ if (message.bubbleState !== "streaming" && !hasStreamingMeta) return message;
12074
+ return {
12075
+ ...message,
12076
+ ...message.bubbleState === "streaming" ? { bubbleState: "final" } : {},
12077
+ ...hasStreamingMeta ? { meta: { ...meta, streaming: false } } : {}
12078
+ };
12079
+ });
12080
+ }
11899
12081
  function buildReadChatCommandResult(payload, args) {
11900
12082
  let validatedPayload;
11901
12083
  const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
@@ -12044,7 +12226,7 @@ function buildDebugBundleText(bundle) {
12044
12226
  }
12045
12227
  function getChatDebugBundleDir() {
12046
12228
  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");
12229
+ return override || path12.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
12048
12230
  }
12049
12231
  function safeBundleIdSegment(value, fallback) {
12050
12232
  const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
@@ -12077,7 +12259,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
12077
12259
  const bundleId = createChatDebugBundleId(targetSessionId);
12078
12260
  const dir = getChatDebugBundleDir();
12079
12261
  fs4.mkdirSync(dir, { recursive: true });
12080
- const savedPath = path11.join(dir, `${bundleId}.json`);
12262
+ const savedPath = path12.join(dir, `${bundleId}.json`);
12081
12263
  const json = `${JSON.stringify(bundle, null, 2)}
12082
12264
  `;
12083
12265
  fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
@@ -12334,10 +12516,13 @@ async function handleReadChat(h, args) {
12334
12516
  const transcriptAuthority = parsedRecord.transcriptAuthority === "provider" || parsedRecord.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
12335
12517
  const coverage = parsedRecord.coverage === "full" || parsedRecord.coverage === "tail" || parsedRecord.coverage === "current-turn" ? parsedRecord.coverage : void 0;
12336
12518
  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}`);
12519
+ const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus);
12520
+ const runtimeMessageMerger = getTargetInstance(h, args);
12521
+ const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus);
12522
+ const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
12523
+ 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
12524
  return buildReadChatCommandResult({
12340
- messages: parsedRecord.messages,
12525
+ messages: returnedMessages,
12341
12526
  status: returnedStatus,
12342
12527
  activeModal,
12343
12528
  debugReadChat: {
@@ -12348,7 +12533,7 @@ async function handleReadChat(h, args) {
12348
12533
  returnedStatus: String(returnedStatus || ""),
12349
12534
  shouldPreferAdapterMessages: false,
12350
12535
  parsedMsgCount: parsedRecord.messages.length,
12351
- returnedMsgCount: parsedRecord.messages.length
12536
+ returnedMsgCount: returnedMessages.length
12352
12537
  },
12353
12538
  ...title ? { title } : {},
12354
12539
  ...providerSessionId ? { providerSessionId } : {},
@@ -13221,7 +13406,7 @@ async function handleResolveAction(h, args) {
13221
13406
 
13222
13407
  // src/commands/cdp-commands.ts
13223
13408
  var fs5 = __toESM(require("fs"));
13224
- var path12 = __toESM(require("path"));
13409
+ var path13 = __toESM(require("path"));
13225
13410
  var os7 = __toESM(require("os"));
13226
13411
  var KEY_TO_VK = {
13227
13412
  Backspace: 8,
@@ -13478,25 +13663,25 @@ function resolveSafePath(requestedPath) {
13478
13663
  const inputPath = rawPath || ".";
13479
13664
  const home = os7.homedir();
13480
13665
  if (inputPath.startsWith("~")) {
13481
- return path12.resolve(path12.join(home, inputPath.slice(1)));
13666
+ return path13.resolve(path13.join(home, inputPath.slice(1)));
13482
13667
  }
13483
13668
  if (process.platform === "win32") {
13484
13669
  const normalized = normalizeWindowsRequestedPath(inputPath);
13485
- if (path12.win32.isAbsolute(normalized)) {
13486
- return path12.win32.normalize(normalized);
13670
+ if (path13.win32.isAbsolute(normalized)) {
13671
+ return path13.win32.normalize(normalized);
13487
13672
  }
13488
- return path12.win32.resolve(normalized);
13673
+ return path13.win32.resolve(normalized);
13489
13674
  }
13490
- if (path12.isAbsolute(inputPath)) {
13491
- return path12.normalize(inputPath);
13675
+ if (path13.isAbsolute(inputPath)) {
13676
+ return path13.normalize(inputPath);
13492
13677
  }
13493
- return path12.resolve(inputPath);
13678
+ return path13.resolve(inputPath);
13494
13679
  }
13495
13680
  function listDirectoryEntriesSafe(dirPath) {
13496
13681
  const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
13497
13682
  const files = [];
13498
13683
  for (const entry of entries) {
13499
- const entryPath = path12.join(dirPath, entry.name);
13684
+ const entryPath = path13.join(dirPath, entry.name);
13500
13685
  try {
13501
13686
  if (entry.isDirectory()) {
13502
13687
  files.push({ name: entry.name, type: "directory" });
@@ -13550,7 +13735,7 @@ async function handleFileRead(h, args) {
13550
13735
  async function handleFileWrite(h, args) {
13551
13736
  try {
13552
13737
  const filePath = resolveSafePath(args?.path);
13553
- fs5.mkdirSync(path12.dirname(filePath), { recursive: true });
13738
+ fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
13554
13739
  fs5.writeFileSync(filePath, args?.content || "", "utf-8");
13555
13740
  return { success: true, path: filePath };
13556
13741
  } catch (e) {
@@ -14669,7 +14854,7 @@ var DaemonCommandHandler = class {
14669
14854
 
14670
14855
  // src/commands/cli-manager.ts
14671
14856
  var os13 = __toESM(require("os"));
14672
- var path16 = __toESM(require("path"));
14857
+ var path17 = __toESM(require("path"));
14673
14858
  var crypto4 = __toESM(require("crypto"));
14674
14859
  var import_fs6 = require("fs");
14675
14860
  var import_child_process6 = require("child_process");
@@ -14679,7 +14864,7 @@ init_config();
14679
14864
 
14680
14865
  // src/providers/cli-provider-instance.ts
14681
14866
  var os12 = __toESM(require("os"));
14682
- var path15 = __toESM(require("path"));
14867
+ var path16 = __toESM(require("path"));
14683
14868
  var crypto3 = __toESM(require("crypto"));
14684
14869
  var fs6 = __toESM(require("fs"));
14685
14870
  var import_node_module = require("module");
@@ -14738,7 +14923,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
14738
14923
  var CachedDatabaseSync = null;
14739
14924
  function getDatabaseSync() {
14740
14925
  if (CachedDatabaseSync) return CachedDatabaseSync;
14741
- const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path15.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
14926
+ const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path16.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
14742
14927
  const sqliteModule = requireFn(`node:${"sqlite"}`);
14743
14928
  CachedDatabaseSync = sqliteModule.DatabaseSync;
14744
14929
  if (!CachedDatabaseSync) {
@@ -14791,7 +14976,7 @@ var CliProviderInstance = class {
14791
14976
  this.providerSessionId = options?.providerSessionId;
14792
14977
  this.launchMode = options?.launchMode || "new";
14793
14978
  this.onProviderSessionResolved = options?.onProviderSessionResolved;
14794
- this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, transportFactory);
14979
+ this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, options?.extraEnv || {}, transportFactory);
14795
14980
  this.monitor = new StatusMonitor();
14796
14981
  this.historyWriter = new ChatHistoryWriter();
14797
14982
  }
@@ -15475,6 +15660,9 @@ ${effect.notification.body || ""}`.trim();
15475
15660
  );
15476
15661
  }
15477
15662
  }
15663
+ mergeRuntimeChatMessages(parsedMessages) {
15664
+ return this.mergeConversationMessages(parsedMessages);
15665
+ }
15478
15666
  mergeConversationMessages(parsedMessages) {
15479
15667
  if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
15480
15668
  return normalizeChatMessages([...parsedMessages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
@@ -16804,11 +16992,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
16804
16992
  // src/commands/cli-manager.ts
16805
16993
  function isExplicitCommand(command) {
16806
16994
  const trimmed = command.trim();
16807
- return path16.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
16995
+ return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
16808
16996
  }
16809
16997
  function expandExecutable(command) {
16810
16998
  const trimmed = command.trim();
16811
- return trimmed.startsWith("~") ? path16.join(os13.homedir(), trimmed.slice(1)) : trimmed;
16999
+ return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
16812
17000
  }
16813
17001
  function commandExists(command) {
16814
17002
  const trimmed = command.trim();
@@ -17002,7 +17190,7 @@ var DaemonCliManager = class {
17002
17190
  attachExisting
17003
17191
  }) || void 0;
17004
17192
  }
17005
- createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false) {
17193
+ createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false, extraEnv) {
17006
17194
  const normalizedType = this.providerLoader.resolveAlias(cliType);
17007
17195
  const provider = this.providerLoader.getMeta(normalizedType);
17008
17196
  if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
@@ -17016,7 +17204,7 @@ var DaemonCliManager = class {
17016
17204
  providerSessionId,
17017
17205
  attachExisting
17018
17206
  );
17019
- return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, transportFactory);
17207
+ return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, extraEnv || {}, transportFactory);
17020
17208
  }
17021
17209
  throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
17022
17210
  }
@@ -17089,7 +17277,7 @@ var DaemonCliManager = class {
17089
17277
  async startSession(cliType, workingDir, cliArgs, initialModel, options) {
17090
17278
  const trimmed = (workingDir || "").trim();
17091
17279
  if (!trimmed) throw new Error("working directory required");
17092
- const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path16.resolve(trimmed);
17280
+ const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
17093
17281
  const normalizedType = this.providerLoader.resolveAlias(cliType);
17094
17282
  const rawProvider = this.providerLoader.getByAlias(cliType);
17095
17283
  const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
@@ -17219,6 +17407,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
17219
17407
  {
17220
17408
  providerSessionId: sessionBinding.providerSessionId,
17221
17409
  launchMode: sessionBinding.launchMode,
17410
+ extraEnv: options?.extraEnv,
17222
17411
  onProviderSessionResolved: ({ providerSessionId, providerName, providerType, workspace }) => {
17223
17412
  this.persistRecentActivity({
17224
17413
  kind: "cli",
@@ -17239,7 +17428,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
17239
17428
  resolvedCliArgs,
17240
17429
  key,
17241
17430
  sessionBinding.providerSessionId,
17242
- false
17431
+ false,
17432
+ options?.extraEnv
17243
17433
  );
17244
17434
  try {
17245
17435
  await adapter.spawn();
@@ -17468,7 +17658,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
17468
17658
  dir,
17469
17659
  args?.cliArgs,
17470
17660
  args?.initialModel,
17471
- { resumeSessionId: args?.resumeSessionId, settingsOverride: args?.settings }
17661
+ { resumeSessionId: args?.resumeSessionId, settingsOverride: args?.settings, extraEnv: args?.env }
17472
17662
  );
17473
17663
  return {
17474
17664
  success: true,
@@ -17590,11 +17780,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
17590
17780
  var import_child_process7 = require("child_process");
17591
17781
  var net = __toESM(require("net"));
17592
17782
  var os15 = __toESM(require("os"));
17593
- var path18 = __toESM(require("path"));
17783
+ var path19 = __toESM(require("path"));
17594
17784
 
17595
17785
  // src/providers/provider-loader.ts
17596
17786
  var fs7 = __toESM(require("fs"));
17597
- var path17 = __toESM(require("path"));
17787
+ var path18 = __toESM(require("path"));
17598
17788
  var os14 = __toESM(require("os"));
17599
17789
  var chokidar = __toESM(require("chokidar"));
17600
17790
  init_logger();
@@ -17918,7 +18108,7 @@ var ProviderLoader = class _ProviderLoader {
17918
18108
  try {
17919
18109
  if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
17920
18110
  return ["ide", "extension", "cli", "acp"].some(
17921
- (category) => fs7.existsSync(path17.join(candidate, category))
18111
+ (category) => fs7.existsSync(path18.join(candidate, category))
17922
18112
  );
17923
18113
  } catch {
17924
18114
  return false;
@@ -17926,20 +18116,20 @@ var ProviderLoader = class _ProviderLoader {
17926
18116
  }
17927
18117
  static hasProviderRootMarker(candidate) {
17928
18118
  try {
17929
- return fs7.existsSync(path17.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
18119
+ return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
17930
18120
  } catch {
17931
18121
  return false;
17932
18122
  }
17933
18123
  }
17934
18124
  detectDefaultUserDir() {
17935
- const fallback = path17.join(os14.homedir(), ".adhdev", "providers");
18125
+ const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
17936
18126
  const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
17937
18127
  const visited = /* @__PURE__ */ new Set();
17938
18128
  for (const start of this.probeStarts) {
17939
- let current = path17.resolve(start);
18129
+ let current = path18.resolve(start);
17940
18130
  while (!visited.has(current)) {
17941
18131
  visited.add(current);
17942
- const siblingCandidate = path17.join(path17.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
18132
+ const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
17943
18133
  if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
17944
18134
  const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
17945
18135
  if (envOptIn || hasMarker) {
@@ -17961,7 +18151,7 @@ var ProviderLoader = class _ProviderLoader {
17961
18151
  return { path: siblingCandidate, source };
17962
18152
  }
17963
18153
  }
17964
- const parent = path17.dirname(current);
18154
+ const parent = path18.dirname(current);
17965
18155
  if (parent === current) break;
17966
18156
  current = parent;
17967
18157
  }
@@ -17971,11 +18161,11 @@ var ProviderLoader = class _ProviderLoader {
17971
18161
  constructor(options) {
17972
18162
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
17973
18163
  this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
17974
- this.defaultProvidersDir = path17.join(os14.homedir(), ".adhdev", "providers");
18164
+ this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
17975
18165
  const detected = this.detectDefaultUserDir();
17976
18166
  this.userDir = detected.path;
17977
18167
  this.userDirSource = detected.source;
17978
- this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
18168
+ this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
17979
18169
  this.disableUpstream = false;
17980
18170
  this.applySourceConfig({
17981
18171
  userDir: options?.userDir,
@@ -18034,7 +18224,7 @@ var ProviderLoader = class _ProviderLoader {
18034
18224
  this.userDir = detected.path;
18035
18225
  this.userDirSource = detected.source;
18036
18226
  }
18037
- this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
18227
+ this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
18038
18228
  this.disableUpstream = this.sourceMode === "no-upstream";
18039
18229
  if (this.explicitProviderDir) {
18040
18230
  this.log(`Config 'providerDir' applied: ${this.userDir}`);
@@ -18048,7 +18238,7 @@ var ProviderLoader = class _ProviderLoader {
18048
18238
  * Canonical provider directory shape for a given root.
18049
18239
  */
18050
18240
  getProviderDir(root, category, type) {
18051
- return path17.join(root, category, type);
18241
+ return path18.join(root, category, type);
18052
18242
  }
18053
18243
  /**
18054
18244
  * Canonical user override directory for a provider.
@@ -18075,7 +18265,7 @@ var ProviderLoader = class _ProviderLoader {
18075
18265
  resolveProviderFile(type, ...segments) {
18076
18266
  const dir = this.findProviderDirInternal(type);
18077
18267
  if (!dir) return null;
18078
- return path17.join(dir, ...segments);
18268
+ return path18.join(dir, ...segments);
18079
18269
  }
18080
18270
  /**
18081
18271
  * Load all providers (3-tier priority)
@@ -18114,7 +18304,7 @@ var ProviderLoader = class _ProviderLoader {
18114
18304
  if (!fs7.existsSync(this.upstreamDir)) return false;
18115
18305
  try {
18116
18306
  return fs7.readdirSync(this.upstreamDir).some(
18117
- (d) => fs7.statSync(path17.join(this.upstreamDir, d)).isDirectory()
18307
+ (d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
18118
18308
  );
18119
18309
  } catch {
18120
18310
  return false;
@@ -18611,8 +18801,8 @@ var ProviderLoader = class _ProviderLoader {
18611
18801
  resolved._resolvedScriptDir = entry.scriptDir;
18612
18802
  resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
18613
18803
  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;
18804
+ const fullDir = path18.join(providerDir, entry.scriptDir);
18805
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18616
18806
  }
18617
18807
  matched = true;
18618
18808
  }
@@ -18627,8 +18817,8 @@ var ProviderLoader = class _ProviderLoader {
18627
18817
  resolved._resolvedScriptDir = base.defaultScriptDir;
18628
18818
  resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
18629
18819
  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;
18820
+ const fullDir = path18.join(providerDir, base.defaultScriptDir);
18821
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18632
18822
  }
18633
18823
  }
18634
18824
  resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
@@ -18645,8 +18835,8 @@ var ProviderLoader = class _ProviderLoader {
18645
18835
  resolved._resolvedScriptDir = dirOverride;
18646
18836
  resolved._resolvedScriptsSource = `versions:${range}`;
18647
18837
  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;
18838
+ const fullDir = path18.join(providerDir, dirOverride);
18839
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18650
18840
  }
18651
18841
  }
18652
18842
  } else if (override.scripts) {
@@ -18662,8 +18852,8 @@ var ProviderLoader = class _ProviderLoader {
18662
18852
  resolved._resolvedScriptDir = base.defaultScriptDir;
18663
18853
  resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
18664
18854
  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;
18855
+ const fullDir = path18.join(providerDir, base.defaultScriptDir);
18856
+ resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
18667
18857
  }
18668
18858
  }
18669
18859
  }
@@ -18695,14 +18885,14 @@ var ProviderLoader = class _ProviderLoader {
18695
18885
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
18696
18886
  return null;
18697
18887
  }
18698
- const dir = path17.join(providerDir, scriptDir);
18888
+ const dir = path18.join(providerDir, scriptDir);
18699
18889
  if (!fs7.existsSync(dir)) {
18700
18890
  this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
18701
18891
  return null;
18702
18892
  }
18703
18893
  const cached = this.scriptsCache.get(dir);
18704
18894
  if (cached) return cached;
18705
- const scriptsJs = path17.join(dir, "scripts.js");
18895
+ const scriptsJs = path18.join(dir, "scripts.js");
18706
18896
  if (fs7.existsSync(scriptsJs)) {
18707
18897
  try {
18708
18898
  delete require.cache[require.resolve(scriptsJs)];
@@ -18744,7 +18934,7 @@ var ProviderLoader = class _ProviderLoader {
18744
18934
  return;
18745
18935
  }
18746
18936
  if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
18747
- this.log(`File changed: ${path17.basename(filePath)}, reloading...`);
18937
+ this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
18748
18938
  this.reload();
18749
18939
  }
18750
18940
  };
@@ -18799,7 +18989,7 @@ var ProviderLoader = class _ProviderLoader {
18799
18989
  }
18800
18990
  const https = require("https");
18801
18991
  const { execSync: execSync7 } = require("child_process");
18802
- const metaPath = path17.join(this.upstreamDir, _ProviderLoader.META_FILE);
18992
+ const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
18803
18993
  let prevEtag = "";
18804
18994
  let prevTimestamp = 0;
18805
18995
  try {
@@ -18859,17 +19049,17 @@ var ProviderLoader = class _ProviderLoader {
18859
19049
  return { updated: false };
18860
19050
  }
18861
19051
  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()}`);
19052
+ const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
19053
+ const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
18864
19054
  await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
18865
19055
  fs7.mkdirSync(tmpExtract, { recursive: true });
18866
19056
  execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
18867
19057
  const extracted = fs7.readdirSync(tmpExtract);
18868
19058
  const rootDir = extracted.find(
18869
- (d) => fs7.statSync(path17.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
19059
+ (d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
18870
19060
  );
18871
19061
  if (!rootDir) throw new Error("Unexpected tarball structure");
18872
- const sourceDir = path17.join(tmpExtract, rootDir);
19062
+ const sourceDir = path18.join(tmpExtract, rootDir);
18873
19063
  const backupDir = this.upstreamDir + ".bak";
18874
19064
  if (fs7.existsSync(this.upstreamDir)) {
18875
19065
  if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
@@ -18944,8 +19134,8 @@ var ProviderLoader = class _ProviderLoader {
18944
19134
  copyDirRecursive(src, dest) {
18945
19135
  fs7.mkdirSync(dest, { recursive: true });
18946
19136
  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);
19137
+ const srcPath = path18.join(src, entry.name);
19138
+ const destPath = path18.join(dest, entry.name);
18949
19139
  if (entry.isDirectory()) {
18950
19140
  this.copyDirRecursive(srcPath, destPath);
18951
19141
  } else {
@@ -18956,7 +19146,7 @@ var ProviderLoader = class _ProviderLoader {
18956
19146
  /** .meta.json save */
18957
19147
  writeMeta(metaPath, etag, timestamp) {
18958
19148
  try {
18959
- fs7.mkdirSync(path17.dirname(metaPath), { recursive: true });
19149
+ fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
18960
19150
  fs7.writeFileSync(metaPath, JSON.stringify({
18961
19151
  etag,
18962
19152
  timestamp,
@@ -18973,7 +19163,7 @@ var ProviderLoader = class _ProviderLoader {
18973
19163
  const scan = (d) => {
18974
19164
  try {
18975
19165
  for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
18976
- if (entry.isDirectory()) scan(path17.join(d, entry.name));
19166
+ if (entry.isDirectory()) scan(path18.join(d, entry.name));
18977
19167
  else if (entry.name === "provider.json") count++;
18978
19168
  }
18979
19169
  } catch {
@@ -19201,17 +19391,17 @@ var ProviderLoader = class _ProviderLoader {
19201
19391
  for (const root of searchRoots) {
19202
19392
  if (!fs7.existsSync(root)) continue;
19203
19393
  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);
19394
+ if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
19395
+ const catDir = path18.join(root, cat);
19206
19396
  if (fs7.existsSync(catDir)) {
19207
19397
  try {
19208
19398
  for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
19209
19399
  if (!entry.isDirectory()) continue;
19210
- const jsonPath = path17.join(catDir, entry.name, "provider.json");
19400
+ const jsonPath = path18.join(catDir, entry.name, "provider.json");
19211
19401
  if (fs7.existsSync(jsonPath)) {
19212
19402
  try {
19213
19403
  const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
19214
- if (data.type === type) return path17.join(catDir, entry.name);
19404
+ if (data.type === type) return path18.join(catDir, entry.name);
19215
19405
  } catch {
19216
19406
  }
19217
19407
  }
@@ -19228,7 +19418,7 @@ var ProviderLoader = class _ProviderLoader {
19228
19418
  * (template substitution is NOT applied here — scripts.js handles that)
19229
19419
  */
19230
19420
  buildScriptWrappersFromDir(dir) {
19231
- const scriptsJs = path17.join(dir, "scripts.js");
19421
+ const scriptsJs = path18.join(dir, "scripts.js");
19232
19422
  if (fs7.existsSync(scriptsJs)) {
19233
19423
  try {
19234
19424
  delete require.cache[require.resolve(scriptsJs)];
@@ -19242,7 +19432,7 @@ var ProviderLoader = class _ProviderLoader {
19242
19432
  for (const file of fs7.readdirSync(dir)) {
19243
19433
  if (!file.endsWith(".js")) continue;
19244
19434
  const scriptName = toCamel(file.replace(".js", ""));
19245
- const filePath = path17.join(dir, file);
19435
+ const filePath = path18.join(dir, file);
19246
19436
  result[scriptName] = (...args) => {
19247
19437
  try {
19248
19438
  let content = fs7.readFileSync(filePath, "utf-8");
@@ -19302,7 +19492,7 @@ var ProviderLoader = class _ProviderLoader {
19302
19492
  }
19303
19493
  const hasJson = entries.some((e) => e.name === "provider.json");
19304
19494
  if (hasJson) {
19305
- const jsonPath = path17.join(d, "provider.json");
19495
+ const jsonPath = path18.join(d, "provider.json");
19306
19496
  try {
19307
19497
  const raw = fs7.readFileSync(jsonPath, "utf-8");
19308
19498
  const mod = JSON.parse(raw);
@@ -19323,7 +19513,7 @@ var ProviderLoader = class _ProviderLoader {
19323
19513
  this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
19324
19514
  } else {
19325
19515
  const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
19326
- const scriptsPath = path17.join(d, "scripts.js");
19516
+ const scriptsPath = path18.join(d, "scripts.js");
19327
19517
  if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
19328
19518
  try {
19329
19519
  delete require.cache[require.resolve(scriptsPath)];
@@ -19349,7 +19539,7 @@ var ProviderLoader = class _ProviderLoader {
19349
19539
  if (!entry.isDirectory()) continue;
19350
19540
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
19351
19541
  if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
19352
- scan(path17.join(d, entry.name));
19542
+ scan(path18.join(d, entry.name));
19353
19543
  }
19354
19544
  }
19355
19545
  };
@@ -19674,8 +19864,8 @@ function detectCurrentWorkspace(ideId) {
19674
19864
  const appNameMap = getMacAppIdentifiers();
19675
19865
  const appName = appNameMap[ideId];
19676
19866
  if (appName) {
19677
- const storagePath = path18.join(
19678
- process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming"),
19867
+ const storagePath = path19.join(
19868
+ process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
19679
19869
  appName,
19680
19870
  "storage.json"
19681
19871
  );
@@ -19864,9 +20054,9 @@ init_logger();
19864
20054
 
19865
20055
  // src/logging/command-log.ts
19866
20056
  var fs8 = __toESM(require("fs"));
19867
- var path19 = __toESM(require("path"));
20057
+ var path20 = __toESM(require("path"));
19868
20058
  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");
20059
+ 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
20060
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
19871
20061
  var MAX_DAYS = 7;
19872
20062
  try {
@@ -19904,13 +20094,13 @@ function getDateStr2() {
19904
20094
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
19905
20095
  }
19906
20096
  var currentDate2 = getDateStr2();
19907
- var currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20097
+ var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
19908
20098
  var writeCount2 = 0;
19909
20099
  function checkRotation() {
19910
20100
  const today = getDateStr2();
19911
20101
  if (today !== currentDate2) {
19912
20102
  currentDate2 = today;
19913
- currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
20103
+ currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
19914
20104
  cleanOldFiles();
19915
20105
  }
19916
20106
  }
@@ -19924,7 +20114,7 @@ function cleanOldFiles() {
19924
20114
  const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
19925
20115
  if (dateMatch && dateMatch[1] < cutoffStr) {
19926
20116
  try {
19927
- fs8.unlinkSync(path19.join(LOG_DIR2, file));
20117
+ fs8.unlinkSync(path20.join(LOG_DIR2, file));
19928
20118
  } catch {
19929
20119
  }
19930
20120
  }
@@ -20007,14 +20197,66 @@ function getRecentCommands(count = 50) {
20007
20197
  cleanOldFiles();
20008
20198
 
20009
20199
  // src/commands/router.ts
20200
+ var yaml = __toESM(require("js-yaml"));
20010
20201
  init_logger();
20011
20202
 
20012
20203
  // src/commands/mesh-coordinator.ts
20013
- var import_node_fs2 = require("fs");
20204
+ var import_node_child_process3 = require("child_process");
20205
+ var import_node_fs3 = require("fs");
20014
20206
  var import_node_module2 = require("module");
20207
+ var os17 = __toESM(require("os"));
20015
20208
  var import_node_path = require("path");
20016
20209
  var DEFAULT_SERVER_NAME = "adhdev-mesh";
20017
20210
  var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
20211
+ var HERMES_CLI_TYPE = "hermes-cli";
20212
+ var HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
20213
+ function isHermesProvider(provider, cliType) {
20214
+ const type = cliType?.trim() || provider?.type?.trim() || "";
20215
+ return type === HERMES_CLI_TYPE;
20216
+ }
20217
+ function resolveHermesMeshCoordinatorSetup(options) {
20218
+ const mcpServer = resolveAdhdevMcpServerLaunch({
20219
+ meshId: options.meshId,
20220
+ nodeExecutable: options.nodeExecutable,
20221
+ adhdevMcpEntryPath: options.adhdevMcpEntryPath
20222
+ });
20223
+ if (!mcpServer) {
20224
+ return {
20225
+ kind: "unsupported",
20226
+ reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
20227
+ };
20228
+ }
20229
+ const configPath = resolveMcpConfigPath(HERMES_MCP_CONFIG_PATH, options.workspace);
20230
+ if (!configPath.trim()) {
20231
+ return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
20232
+ }
20233
+ return {
20234
+ kind: "auto_import",
20235
+ serverName: DEFAULT_SERVER_NAME,
20236
+ configPath,
20237
+ configFormat: "hermes_config_yaml",
20238
+ mcpServer
20239
+ };
20240
+ }
20241
+ function createHermesManualMeshCoordinatorSetup(meshId, workspace) {
20242
+ return {
20243
+ kind: "manual",
20244
+ serverName: DEFAULT_SERVER_NAME,
20245
+ configFormat: "hermes_config_yaml",
20246
+ configPathCommand: HERMES_MCP_CONFIG_PATH,
20247
+ requiresRestart: true,
20248
+ 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.",
20249
+ template: renderMeshCoordinatorTemplate(
20250
+ "mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - --repo-mesh\n - {{meshId}}\n enabled: true\n",
20251
+ {
20252
+ meshId,
20253
+ workspace,
20254
+ serverName: DEFAULT_SERVER_NAME,
20255
+ adhdevMcpCommand: DEFAULT_ADHDEV_MCP_COMMAND
20256
+ }
20257
+ )
20258
+ };
20259
+ }
20018
20260
  function resolveMeshCoordinatorSetup(options) {
20019
20261
  const { provider, meshId, workspace } = options;
20020
20262
  const config = provider?.meshCoordinator;
@@ -20024,6 +20266,9 @@ function resolveMeshCoordinatorSetup(options) {
20024
20266
  reason: config?.reason || "Provider does not declare Repo Mesh coordinator support"
20025
20267
  };
20026
20268
  }
20269
+ if (isHermesProvider(provider, options.cliType)) {
20270
+ return resolveHermesMeshCoordinatorSetup(options);
20271
+ }
20027
20272
  const mcpConfig = config.mcpConfig;
20028
20273
  if (!mcpConfig || mcpConfig.mode === "none") {
20029
20274
  return {
@@ -20033,8 +20278,8 @@ function resolveMeshCoordinatorSetup(options) {
20033
20278
  }
20034
20279
  const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
20035
20280
  if (mcpConfig.mode === "auto_import") {
20036
- const path26 = mcpConfig.path?.trim();
20037
- if (!path26) {
20281
+ const path27 = mcpConfig.path?.trim();
20282
+ if (!path27) {
20038
20283
  return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
20039
20284
  }
20040
20285
  const mcpServer = resolveAdhdevMcpServerLaunch({
@@ -20045,13 +20290,13 @@ function resolveMeshCoordinatorSetup(options) {
20045
20290
  if (!mcpServer) {
20046
20291
  return {
20047
20292
  kind: "unsupported",
20048
- reason: "Could not resolve the ADHDev MCP server entrypoint without relying on a PATH bin shim"
20293
+ reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
20049
20294
  };
20050
20295
  }
20051
20296
  return {
20052
20297
  kind: "auto_import",
20053
20298
  serverName,
20054
- configPath: (0, import_node_path.join)(workspace, path26),
20299
+ configPath: resolveMcpConfigPath(path27, workspace),
20055
20300
  configFormat: mcpConfig.format,
20056
20301
  mcpServer
20057
20302
  };
@@ -20085,14 +20330,85 @@ function resolveMeshCoordinatorSetup(options) {
20085
20330
  function renderMeshCoordinatorTemplate(template, values) {
20086
20331
  return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
20087
20332
  }
20333
+ function resolveMcpConfigPath(configPath, workspace) {
20334
+ const trimmed = configPath.trim();
20335
+ if (trimmed === "~") return os17.homedir();
20336
+ if (trimmed.startsWith("~/")) return (0, import_node_path.join)(os17.homedir(), trimmed.slice(2));
20337
+ if ((0, import_node_path.isAbsolute)(trimmed)) return trimmed;
20338
+ return (0, import_node_path.join)(workspace, trimmed);
20339
+ }
20088
20340
  function resolveAdhdevMcpServerLaunch(options) {
20089
20341
  const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
20090
20342
  if (!entryPath) return null;
20343
+ const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable);
20344
+ if (!nodeExecutable) return null;
20091
20345
  return {
20092
- command: options.nodeExecutable?.trim() || process.execPath,
20093
- args: [entryPath, "--repo-mesh", options.meshId]
20346
+ command: nodeExecutable,
20347
+ args: [entryPath, "--mode", "ipc", "--repo-mesh", options.meshId]
20094
20348
  };
20095
20349
  }
20350
+ function resolveMcpNodeExecutable(explicitExecutable) {
20351
+ const explicit = explicitExecutable?.trim();
20352
+ if (explicit) return explicit;
20353
+ const candidates = [];
20354
+ const addCandidate = (candidate) => {
20355
+ const trimmed = candidate?.trim();
20356
+ if (!trimmed) return;
20357
+ const normalized = normalizeExistingPath(trimmed) || trimmed;
20358
+ if (!candidates.includes(normalized)) candidates.push(normalized);
20359
+ };
20360
+ addCandidate(process.env.ADHDEV_MCP_NODE_EXECUTABLE);
20361
+ addCandidate(process.env.ADHDEV_NODE_EXECUTABLE);
20362
+ addCandidate(process.env.npm_node_execpath);
20363
+ addNodeCandidatesFromPath(process.env.PATH, addCandidate);
20364
+ addNodeCandidatesFromNvm(os17.homedir(), addCandidate);
20365
+ addCandidate("/opt/homebrew/bin/node");
20366
+ addCandidate("/usr/local/bin/node");
20367
+ addCandidate("/usr/bin/node");
20368
+ addCandidate(process.execPath);
20369
+ for (const candidate of candidates) {
20370
+ if (nodeRuntimeSupportsWebSocket(candidate)) return candidate;
20371
+ }
20372
+ return null;
20373
+ }
20374
+ function addNodeCandidatesFromPath(pathValue, addCandidate) {
20375
+ for (const entry of (pathValue || "").split(":")) {
20376
+ const dir = entry.trim();
20377
+ if (!dir) continue;
20378
+ addCandidate((0, import_node_path.join)(dir, "node"));
20379
+ }
20380
+ }
20381
+ function addNodeCandidatesFromNvm(homeDir, addCandidate) {
20382
+ const versionsDir = (0, import_node_path.join)(homeDir, ".nvm", "versions", "node");
20383
+ try {
20384
+ const versionDirs = (0, import_node_fs3.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
20385
+ for (const versionDir of versionDirs) {
20386
+ addCandidate((0, import_node_path.join)(versionsDir, versionDir, "bin", "node"));
20387
+ }
20388
+ } catch {
20389
+ }
20390
+ }
20391
+ function compareNodeVersionNamesDescending(a, b) {
20392
+ const parse = (value) => value.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
20393
+ const left = parse(a);
20394
+ const right = parse(b);
20395
+ for (let i = 0; i < Math.max(left.length, right.length); i++) {
20396
+ const diff = (right[i] || 0) - (left[i] || 0);
20397
+ if (diff !== 0) return diff;
20398
+ }
20399
+ return b.localeCompare(a);
20400
+ }
20401
+ function nodeRuntimeSupportsWebSocket(nodeExecutable) {
20402
+ try {
20403
+ (0, import_node_child_process3.execFileSync)(nodeExecutable, ["-e", "process.exit(typeof WebSocket === 'function' ? 0 : 42)"], {
20404
+ stdio: "ignore",
20405
+ timeout: 3e3
20406
+ });
20407
+ return true;
20408
+ } catch {
20409
+ return false;
20410
+ }
20411
+ }
20096
20412
  function resolveAdhdevMcpEntryPath(explicitPath) {
20097
20413
  const explicit = explicitPath?.trim();
20098
20414
  if (explicit) return normalizeExistingPath(explicit) || explicit;
@@ -20128,15 +20444,15 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
20128
20444
  }
20129
20445
  function normalizeExistingPath(filePath) {
20130
20446
  try {
20131
- if (!(0, import_node_fs2.existsSync)(filePath)) return null;
20132
- return import_node_fs2.realpathSync.native(filePath);
20447
+ if (!(0, import_node_fs3.existsSync)(filePath)) return null;
20448
+ return import_node_fs3.realpathSync.native(filePath);
20133
20449
  } catch {
20134
20450
  return null;
20135
20451
  }
20136
20452
  }
20137
20453
 
20138
20454
  // src/status/snapshot.ts
20139
- var os17 = __toESM(require("os"));
20455
+ var os18 = __toESM(require("os"));
20140
20456
  init_config();
20141
20457
  init_terminal_screen();
20142
20458
  init_logger();
@@ -20192,8 +20508,8 @@ function buildAvailableProviders(providerLoader) {
20192
20508
  }
20193
20509
  function buildMachineInfo(profile = "full") {
20194
20510
  const base = {
20195
- hostname: os17.hostname(),
20196
- platform: os17.platform()
20511
+ hostname: os18.hostname(),
20512
+ platform: os18.platform()
20197
20513
  };
20198
20514
  if (profile === "live") {
20199
20515
  return base;
@@ -20202,23 +20518,23 @@ function buildMachineInfo(profile = "full") {
20202
20518
  const memSnap2 = getHostMemorySnapshot();
20203
20519
  return {
20204
20520
  ...base,
20205
- arch: os17.arch(),
20206
- cpus: os17.cpus().length,
20521
+ arch: os18.arch(),
20522
+ cpus: os18.cpus().length,
20207
20523
  totalMem: memSnap2.totalMem,
20208
- release: os17.release()
20524
+ release: os18.release()
20209
20525
  };
20210
20526
  }
20211
20527
  const memSnap = getHostMemorySnapshot();
20212
20528
  return {
20213
20529
  ...base,
20214
- arch: os17.arch(),
20215
- cpus: os17.cpus().length,
20530
+ arch: os18.arch(),
20531
+ cpus: os18.cpus().length,
20216
20532
  totalMem: memSnap.totalMem,
20217
20533
  freeMem: memSnap.freeMem,
20218
20534
  availableMem: memSnap.availableMem,
20219
- loadavg: os17.loadavg(),
20220
- uptime: os17.uptime(),
20221
- release: os17.release()
20535
+ loadavg: os18.loadavg(),
20536
+ uptime: os18.uptime(),
20537
+ release: os18.release()
20222
20538
  };
20223
20539
  }
20224
20540
  function parseMessageTime(value) {
@@ -20452,14 +20768,14 @@ function buildStatusSnapshot(options) {
20452
20768
  var import_child_process8 = require("child_process");
20453
20769
  var import_child_process9 = require("child_process");
20454
20770
  var fs9 = __toESM(require("fs"));
20455
- var os18 = __toESM(require("os"));
20456
- var path20 = __toESM(require("path"));
20771
+ var os19 = __toESM(require("os"));
20772
+ var path21 = __toESM(require("path"));
20457
20773
  var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
20458
20774
  function getUpgradeLogPath() {
20459
- const home = os18.homedir();
20460
- const dir = path20.join(home, ".adhdev");
20775
+ const home = os19.homedir();
20776
+ const dir = path21.join(home, ".adhdev");
20461
20777
  fs9.mkdirSync(dir, { recursive: true });
20462
- return path20.join(dir, "daemon-upgrade.log");
20778
+ return path21.join(dir, "daemon-upgrade.log");
20463
20779
  }
20464
20780
  function appendUpgradeLog(message) {
20465
20781
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
@@ -20470,14 +20786,14 @@ function appendUpgradeLog(message) {
20470
20786
  }
20471
20787
  }
20472
20788
  function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
20473
- const binDir = path20.dirname(nodeExecutable);
20789
+ const binDir = path21.dirname(nodeExecutable);
20474
20790
  if (platform10 === "win32") {
20475
- const npmCliPath = path20.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
20791
+ const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
20476
20792
  if (fs9.existsSync(npmCliPath)) {
20477
20793
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
20478
20794
  }
20479
20795
  for (const candidate of ["npm.exe", "npm"]) {
20480
- const candidatePath = path20.join(binDir, candidate);
20796
+ const candidatePath = path21.join(binDir, candidate);
20481
20797
  if (fs9.existsSync(candidatePath)) {
20482
20798
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
20483
20799
  }
@@ -20485,7 +20801,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
20485
20801
  return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
20486
20802
  }
20487
20803
  for (const candidate of ["npm"]) {
20488
- const candidatePath = path20.join(binDir, candidate);
20804
+ const candidatePath = path21.join(binDir, candidate);
20489
20805
  if (fs9.existsSync(candidatePath)) {
20490
20806
  return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
20491
20807
  }
@@ -20502,13 +20818,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20502
20818
  let currentDir = resolvedPath;
20503
20819
  try {
20504
20820
  if (fs9.statSync(resolvedPath).isFile()) {
20505
- currentDir = path20.dirname(resolvedPath);
20821
+ currentDir = path21.dirname(resolvedPath);
20506
20822
  }
20507
20823
  } catch {
20508
- currentDir = path20.dirname(resolvedPath);
20824
+ currentDir = path21.dirname(resolvedPath);
20509
20825
  }
20510
20826
  while (true) {
20511
- const packageJsonPath = path20.join(currentDir, "package.json");
20827
+ const packageJsonPath = path21.join(currentDir, "package.json");
20512
20828
  try {
20513
20829
  if (fs9.existsSync(packageJsonPath)) {
20514
20830
  const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
@@ -20519,7 +20835,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20519
20835
  }
20520
20836
  } catch {
20521
20837
  }
20522
- const parentDir = path20.dirname(currentDir);
20838
+ const parentDir = path21.dirname(currentDir);
20523
20839
  if (parentDir === currentDir) {
20524
20840
  return null;
20525
20841
  }
@@ -20527,13 +20843,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
20527
20843
  }
20528
20844
  }
20529
20845
  function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
20530
- const nodeModulesDir = packageName.startsWith("@") ? path20.dirname(path20.dirname(packageRoot)) : path20.dirname(packageRoot);
20531
- if (path20.basename(nodeModulesDir) !== "node_modules") {
20846
+ const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
20847
+ if (path21.basename(nodeModulesDir) !== "node_modules") {
20532
20848
  return null;
20533
20849
  }
20534
- const maybeLibDir = path20.dirname(nodeModulesDir);
20535
- if (path20.basename(maybeLibDir) === "lib") {
20536
- return path20.dirname(maybeLibDir);
20850
+ const maybeLibDir = path21.dirname(nodeModulesDir);
20851
+ if (path21.basename(maybeLibDir) === "lib") {
20852
+ return path21.dirname(maybeLibDir);
20537
20853
  }
20538
20854
  return maybeLibDir;
20539
20855
  }
@@ -20648,7 +20964,7 @@ async function waitForPidExit(pid, timeoutMs) {
20648
20964
  }
20649
20965
  }
20650
20966
  function stopSessionHostProcesses(appName) {
20651
- const pidFile = path20.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
20967
+ const pidFile = path21.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
20652
20968
  try {
20653
20969
  if (fs9.existsSync(pidFile)) {
20654
20970
  const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
@@ -20665,7 +20981,7 @@ function stopSessionHostProcesses(appName) {
20665
20981
  }
20666
20982
  }
20667
20983
  function removeDaemonPidFile() {
20668
- const pidFile = path20.join(os18.homedir(), ".adhdev", "daemon.pid");
20984
+ const pidFile = path21.join(os19.homedir(), ".adhdev", "daemon.pid");
20669
20985
  try {
20670
20986
  fs9.unlinkSync(pidFile);
20671
20987
  } catch {
@@ -20676,7 +20992,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
20676
20992
  const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
20677
20993
  if (!npmRoot) return;
20678
20994
  const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
20679
- const binDir = process.platform === "win32" ? npmPrefix : path20.join(npmPrefix, "bin");
20995
+ const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
20680
20996
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
20681
20997
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
20682
20998
  if (pkgName === "@adhdev/daemon-standalone") {
@@ -20684,25 +21000,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
20684
21000
  }
20685
21001
  if (pkgName.startsWith("@")) {
20686
21002
  const [scope, name] = pkgName.split("/");
20687
- const scopeDir = path20.join(npmRoot, scope);
21003
+ const scopeDir = path21.join(npmRoot, scope);
20688
21004
  if (!fs9.existsSync(scopeDir)) return;
20689
21005
  for (const entry of fs9.readdirSync(scopeDir)) {
20690
21006
  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)}`);
21007
+ fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
21008
+ appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
20693
21009
  }
20694
21010
  } else {
20695
21011
  for (const entry of fs9.readdirSync(npmRoot)) {
20696
21012
  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)}`);
21013
+ fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
21014
+ appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
20699
21015
  }
20700
21016
  }
20701
21017
  if (fs9.existsSync(binDir)) {
20702
21018
  for (const entry of fs9.readdirSync(binDir)) {
20703
21019
  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)}`);
21020
+ fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
21021
+ appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
20706
21022
  }
20707
21023
  }
20708
21024
  }
@@ -20789,6 +21105,10 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
20789
21105
  // src/commands/router.ts
20790
21106
  var fs10 = __toESM(require("fs"));
20791
21107
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
21108
+ var CHANNEL_SERVER_URL = {
21109
+ stable: "https://api.adhf.dev",
21110
+ preview: "https://api-preview.adhf.dev"
21111
+ };
20792
21112
  function normalizeReleaseChannel(value) {
20793
21113
  if (typeof value !== "string") return null;
20794
21114
  const normalized = value.trim().toLowerCase();
@@ -20799,6 +21119,22 @@ function normalizeReleaseChannel(value) {
20799
21119
  function resolveUpgradeChannel(args) {
20800
21120
  return normalizeReleaseChannel(args?.channel) || normalizeReleaseChannel(args?.updatePolicy?.channel) || normalizeReleaseChannel(args?.npmTag) || normalizeReleaseChannel(loadConfig().updateChannel) || "stable";
20801
21121
  }
21122
+ function loadYamlModule() {
21123
+ return yaml;
21124
+ }
21125
+ function getMcpServersKey(format) {
21126
+ return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
21127
+ }
21128
+ function parseMeshCoordinatorMcpConfig(text, format) {
21129
+ if (!text.trim()) return {};
21130
+ if (format === "claude_mcp_json") return JSON.parse(text);
21131
+ const parsed = loadYamlModule().load(text);
21132
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
21133
+ }
21134
+ function serializeMeshCoordinatorMcpConfig(config, format) {
21135
+ if (format === "claude_mcp_json") return JSON.stringify(config, null, 2);
21136
+ return loadYamlModule().dump(config, { noRefs: true, lineWidth: 120 });
21137
+ }
20802
21138
  var CHAT_COMMANDS = [
20803
21139
  "send_chat",
20804
21140
  "new_chat",
@@ -20897,6 +21233,40 @@ var DaemonCommandRouter = class {
20897
21233
  constructor(deps) {
20898
21234
  this.deps = deps;
20899
21235
  }
21236
+ getCachedInlineMesh(meshId, inlineMesh) {
21237
+ if (inlineMesh && typeof inlineMesh === "object") {
21238
+ this.inlineMeshCache.set(meshId, inlineMesh);
21239
+ return inlineMesh;
21240
+ }
21241
+ return this.inlineMeshCache.get(meshId);
21242
+ }
21243
+ async getMeshForCommand(meshId, inlineMesh) {
21244
+ try {
21245
+ const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21246
+ const mesh = getMesh3(meshId);
21247
+ if (mesh) return { mesh, inline: false };
21248
+ } catch {
21249
+ }
21250
+ const cached = this.getCachedInlineMesh(meshId, inlineMesh);
21251
+ return cached ? { mesh: cached, inline: true } : null;
21252
+ }
21253
+ updateInlineMeshNode(meshId, mesh, node) {
21254
+ if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
21255
+ const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
21256
+ if (idx >= 0) mesh.nodes[idx] = node;
21257
+ else mesh.nodes.push(node);
21258
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
21259
+ this.inlineMeshCache.set(meshId, mesh);
21260
+ }
21261
+ removeInlineMeshNode(meshId, mesh, nodeId) {
21262
+ if (!mesh || !Array.isArray(mesh.nodes)) return false;
21263
+ const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
21264
+ if (idx === -1) return false;
21265
+ mesh.nodes.splice(idx, 1);
21266
+ mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
21267
+ this.inlineMeshCache.set(meshId, mesh);
21268
+ return true;
21269
+ }
20900
21270
  async traceSessionHostAction(action, args, run, summarizeResult) {
20901
21271
  const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
20902
21272
  const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
@@ -21485,6 +21855,7 @@ var DaemonCommandRouter = class {
21485
21855
  const npmTag = CHANNEL_NPM_TAG[channel];
21486
21856
  const latest = String(execNpmCommandSync(["view", `${pkgName}@${npmTag}`, "version"], { encoding: "utf-8", timeout: 1e4 }, npmSurface)).trim();
21487
21857
  LOG.info("Upgrade", `Latest ${pkgName}@${npmTag}: v${latest}`);
21858
+ updateConfig({ updateChannel: channel, serverUrl: CHANNEL_SERVER_URL[channel] });
21488
21859
  let currentInstalled = null;
21489
21860
  try {
21490
21861
  const currentJson = String(execNpmCommandSync(["ls", "-g", pkgName, "--depth=0", "--json"], {
@@ -21595,13 +21966,94 @@ var DaemonCommandRouter = class {
21595
21966
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
21596
21967
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
21597
21968
  try {
21598
- const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21599
- const removed = removeNode3(meshId, nodeId);
21969
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
21970
+ const mesh = meshRecord?.mesh;
21971
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
21972
+ if (node?.isLocalWorktree && node.workspace) {
21973
+ try {
21974
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
21975
+ const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
21976
+ if (repoRoot) {
21977
+ const { removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
21978
+ await removeWorktree2(repoRoot, node.workspace);
21979
+ }
21980
+ } catch (e) {
21981
+ LOG.warn("MeshNode", `Worktree cleanup failed for ${nodeId}: ${e.message}`);
21982
+ }
21983
+ }
21984
+ let removed = false;
21985
+ if (meshRecord?.inline) {
21986
+ removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
21987
+ } else {
21988
+ const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
21989
+ removed = removeNode3(meshId, nodeId);
21990
+ }
21600
21991
  return { success: true, removed };
21601
21992
  } catch (e) {
21602
21993
  return { success: false, error: e.message };
21603
21994
  }
21604
21995
  }
21996
+ case "clone_mesh_node": {
21997
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
21998
+ const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
21999
+ const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
22000
+ const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
22001
+ if (!meshId) return { success: false, error: "meshId required" };
22002
+ if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
22003
+ if (!branch) return { success: false, error: "branch required" };
22004
+ try {
22005
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
22006
+ const mesh = meshRecord?.mesh;
22007
+ if (!mesh) return { success: false, error: "Mesh not found" };
22008
+ const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
22009
+ if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
22010
+ const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
22011
+ const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
22012
+ const result = await createWorktree2({
22013
+ repoRoot,
22014
+ branch,
22015
+ baseBranch,
22016
+ meshName: mesh.name
22017
+ });
22018
+ let node;
22019
+ if (meshRecord.inline) {
22020
+ const { randomUUID: randomUUID8 } = await import("crypto");
22021
+ node = {
22022
+ id: `node_${randomUUID8().replace(/-/g, "")}`,
22023
+ workspace: result.worktreePath,
22024
+ repoRoot: result.worktreePath,
22025
+ daemonId: sourceNode.daemonId,
22026
+ userOverrides: { ...sourceNode.userOverrides || {} },
22027
+ policy: { ...sourceNode.policy || {} },
22028
+ isLocalWorktree: true,
22029
+ worktreeBranch: result.branch,
22030
+ clonedFromNodeId: sourceNodeId
22031
+ };
22032
+ this.updateInlineMeshNode(meshId, mesh, node);
22033
+ } else {
22034
+ const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
22035
+ node = addNode3(meshId, {
22036
+ workspace: result.worktreePath,
22037
+ repoRoot: result.worktreePath,
22038
+ daemonId: sourceNode.daemonId,
22039
+ userOverrides: { ...sourceNode.userOverrides || {} },
22040
+ isLocalWorktree: true,
22041
+ worktreeBranch: result.branch,
22042
+ clonedFromNodeId: sourceNodeId,
22043
+ policy: { ...sourceNode.policy || {} }
22044
+ });
22045
+ if (!node) return { success: false, error: "Failed to register worktree node" };
22046
+ }
22047
+ return {
22048
+ success: true,
22049
+ node,
22050
+ worktreePath: result.worktreePath,
22051
+ branch: result.branch
22052
+ };
22053
+ } catch (e) {
22054
+ return { success: false, error: e.message };
22055
+ }
22056
+ }
21605
22057
  // ─── Mesh Coordinator Launch ───
21606
22058
  case "launch_mesh_coordinator": {
21607
22059
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -21636,6 +22088,7 @@ var DaemonCommandRouter = class {
21636
22088
  const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
21637
22089
  const coordinatorSetup = resolveMeshCoordinatorSetup({
21638
22090
  provider: providerMeta,
22091
+ cliType,
21639
22092
  meshId,
21640
22093
  workspace
21641
22094
  });
@@ -21660,7 +22113,8 @@ var DaemonCommandRouter = class {
21660
22113
  meshCoordinatorSetup: coordinatorSetup
21661
22114
  };
21662
22115
  }
21663
- if (coordinatorSetup.configFormat !== "claude_mcp_json") {
22116
+ const configFormat = coordinatorSetup.configFormat;
22117
+ if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
21664
22118
  return {
21665
22119
  success: false,
21666
22120
  code: "mesh_coordinator_unsupported",
@@ -21670,44 +22124,93 @@ var DaemonCommandRouter = class {
21670
22124
  workspace
21671
22125
  };
21672
22126
  }
21673
- const { existsSync: existsSync22, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3 } = await import("fs");
21674
- const mcpConfigPath = coordinatorSetup.configPath;
21675
- const hadExistingMcpConfig = existsSync22(mcpConfigPath);
21676
- let existingMcpConfig = {};
21677
- if (hadExistingMcpConfig) {
21678
- try {
21679
- existingMcpConfig = JSON.parse(readFileSync15(mcpConfigPath, "utf-8"));
21680
- copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
21681
- } catch {
21682
- }
22127
+ let systemPrompt = "";
22128
+ try {
22129
+ systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
22130
+ } catch (error) {
22131
+ const message = error?.message || String(error);
22132
+ LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
22133
+ return {
22134
+ success: false,
22135
+ code: "mesh_coordinator_prompt_failed",
22136
+ error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
22137
+ meshId,
22138
+ cliType,
22139
+ workspace
22140
+ };
21683
22141
  }
22142
+ const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3, mkdirSync: mkdirSync14 } = await import("fs");
22143
+ const { dirname: dirname9 } = await import("path");
22144
+ const mcpConfigPath = coordinatorSetup.configPath;
22145
+ const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
22146
+ const returnManualFallback = (message) => ({
22147
+ success: false,
22148
+ code: "mesh_coordinator_manual_mcp_setup_required",
22149
+ error: message,
22150
+ meshId,
22151
+ cliType,
22152
+ workspace,
22153
+ meshCoordinatorSetup: hermesManualFallback
22154
+ });
21684
22155
  const mcpServerEntry = {
21685
22156
  command: coordinatorSetup.mcpServer.command,
21686
22157
  args: coordinatorSetup.mcpServer.args
21687
22158
  };
21688
22159
  if (args?.inlineMesh) {
21689
22160
  mcpServerEntry.env = {
21690
- ADHDEV_INLINE_MESH: JSON.stringify(mesh)
22161
+ ADHDEV_INLINE_MESH: JSON.stringify(mesh),
22162
+ ADHDEV_MCP_TRANSPORT: "ipc"
21691
22163
  };
21692
22164
  }
22165
+ try {
22166
+ mkdirSync14(dirname9(mcpConfigPath), { recursive: true });
22167
+ } catch (error) {
22168
+ const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
22169
+ LOG.error("MeshCoordinator", message);
22170
+ if (hermesManualFallback) return returnManualFallback(message);
22171
+ return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
22172
+ }
22173
+ const hadExistingMcpConfig = existsSync23(mcpConfigPath);
22174
+ let existingMcpConfig = {};
22175
+ if (hadExistingMcpConfig) {
22176
+ try {
22177
+ existingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
22178
+ copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
22179
+ } catch (error) {
22180
+ LOG.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error?.message || error}`);
22181
+ return {
22182
+ success: false,
22183
+ code: "mesh_coordinator_config_parse_failed",
22184
+ error: `Failed to parse existing MCP config at ${mcpConfigPath}`
22185
+ };
22186
+ }
22187
+ }
22188
+ const mcpServersKey = getMcpServersKey(configFormat);
22189
+ const existingServers = existingMcpConfig[mcpServersKey];
21693
22190
  const mcpConfig = {
21694
22191
  ...existingMcpConfig,
21695
- mcpServers: {
21696
- ...existingMcpConfig.mcpServers || {},
22192
+ [mcpServersKey]: {
22193
+ ...existingServers && typeof existingServers === "object" && !Array.isArray(existingServers) ? existingServers : {},
21697
22194
  [coordinatorSetup.serverName]: mcpServerEntry
21698
22195
  }
21699
22196
  };
21700
- writeFileSync12(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
21701
- LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
21702
- let systemPrompt = "";
21703
22197
  try {
21704
- systemPrompt = buildCoordinatorSystemPrompt2({ mesh });
21705
- } catch {
21706
- 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).`;
22198
+ writeFileSync12(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
22199
+ } catch (error) {
22200
+ const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
22201
+ LOG.error("MeshCoordinator", message);
22202
+ if (hermesManualFallback) return returnManualFallback(message);
22203
+ return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
21707
22204
  }
22205
+ LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
21708
22206
  const cliArgs = [];
22207
+ const launchEnv = {};
21709
22208
  if (systemPrompt) {
21710
- cliArgs.push("--append-system-prompt", systemPrompt);
22209
+ if (configFormat === "hermes_config_yaml") {
22210
+ launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
22211
+ } else {
22212
+ cliArgs.push("--append-system-prompt", systemPrompt);
22213
+ }
21711
22214
  }
21712
22215
  if (cliType === "claude-cli") {
21713
22216
  cliArgs.push("--mcp-config", coordinatorSetup.configPath);
@@ -21716,6 +22219,7 @@ var DaemonCommandRouter = class {
21716
22219
  cliType,
21717
22220
  dir: workspace,
21718
22221
  cliArgs: cliArgs.length > 0 ? cliArgs : void 0,
22222
+ env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
21719
22223
  settings: {
21720
22224
  meshCoordinatorFor: meshId
21721
22225
  }
@@ -23376,11 +23880,11 @@ var ProviderInstanceManager = class {
23376
23880
 
23377
23881
  // src/providers/version-archive.ts
23378
23882
  var fs11 = __toESM(require("fs"));
23379
- var path21 = __toESM(require("path"));
23380
- var os19 = __toESM(require("os"));
23883
+ var path22 = __toESM(require("path"));
23884
+ var os20 = __toESM(require("os"));
23381
23885
  var import_child_process10 = require("child_process");
23382
23886
  var import_os3 = require("os");
23383
- var ARCHIVE_PATH = path21.join(os19.homedir(), ".adhdev", "version-history.json");
23887
+ var ARCHIVE_PATH = path22.join(os20.homedir(), ".adhdev", "version-history.json");
23384
23888
  var MAX_ENTRIES_PER_PROVIDER = 20;
23385
23889
  var VersionArchive = class {
23386
23890
  history = {};
@@ -23427,7 +23931,7 @@ var VersionArchive = class {
23427
23931
  }
23428
23932
  save() {
23429
23933
  try {
23430
- fs11.mkdirSync(path21.dirname(ARCHIVE_PATH), { recursive: true });
23934
+ fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
23431
23935
  fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
23432
23936
  } catch {
23433
23937
  }
@@ -23483,8 +23987,8 @@ function getVersion(binary, versionCommand) {
23483
23987
  function checkPathExists2(paths) {
23484
23988
  for (const p of paths) {
23485
23989
  if (p.includes("*")) {
23486
- const home = os19.homedir();
23487
- const resolved = p.replace(/\*/g, home.split(path21.sep).pop() || "");
23990
+ const home = os20.homedir();
23991
+ const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
23488
23992
  if (fs11.existsSync(resolved)) return resolved;
23489
23993
  } else {
23490
23994
  if (fs11.existsSync(p)) return p;
@@ -23494,7 +23998,7 @@ function checkPathExists2(paths) {
23494
23998
  }
23495
23999
  function getMacAppVersion(appPath) {
23496
24000
  if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
23497
- const plistPath = path21.join(appPath, "Contents", "Info.plist");
24001
+ const plistPath = path22.join(appPath, "Contents", "Info.plist");
23498
24002
  if (!fs11.existsSync(plistPath)) return null;
23499
24003
  const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
23500
24004
  return raw || null;
@@ -23520,7 +24024,7 @@ async function detectAllVersions(loader, archive) {
23520
24024
  const cliBin = provider.cli ? findBinary2(provider.cli) : null;
23521
24025
  let resolvedBin = cliBin;
23522
24026
  if (!resolvedBin && appPath && currentOs === "darwin") {
23523
- const bundled = path21.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
24027
+ const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
23524
24028
  if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
23525
24029
  }
23526
24030
  info.installed = !!(appPath || resolvedBin);
@@ -23561,7 +24065,7 @@ async function detectAllVersions(loader, archive) {
23561
24065
  // src/daemon/dev-server.ts
23562
24066
  var http2 = __toESM(require("http"));
23563
24067
  var fs15 = __toESM(require("fs"));
23564
- var path25 = __toESM(require("path"));
24068
+ var path26 = __toESM(require("path"));
23565
24069
  init_config();
23566
24070
 
23567
24071
  // src/daemon/scaffold-template.ts
@@ -23912,7 +24416,7 @@ init_logger();
23912
24416
 
23913
24417
  // src/daemon/dev-cdp-handlers.ts
23914
24418
  var fs12 = __toESM(require("fs"));
23915
- var path22 = __toESM(require("path"));
24419
+ var path23 = __toESM(require("path"));
23916
24420
  init_logger();
23917
24421
  async function handleCdpEvaluate(ctx, req, res) {
23918
24422
  const body = await ctx.readBody(req);
@@ -24091,17 +24595,17 @@ async function handleScriptHints(ctx, type, _req, res) {
24091
24595
  return;
24092
24596
  }
24093
24597
  let scriptsPath = "";
24094
- const directScripts = path22.join(dir, "scripts.js");
24598
+ const directScripts = path23.join(dir, "scripts.js");
24095
24599
  if (fs12.existsSync(directScripts)) {
24096
24600
  scriptsPath = directScripts;
24097
24601
  } else {
24098
- const scriptsDir = path22.join(dir, "scripts");
24602
+ const scriptsDir = path23.join(dir, "scripts");
24099
24603
  if (fs12.existsSync(scriptsDir)) {
24100
24604
  const versions = fs12.readdirSync(scriptsDir).filter((d) => {
24101
- return fs12.statSync(path22.join(scriptsDir, d)).isDirectory();
24605
+ return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
24102
24606
  }).sort().reverse();
24103
24607
  for (const ver of versions) {
24104
- const p = path22.join(scriptsDir, ver, "scripts.js");
24608
+ const p = path23.join(scriptsDir, ver, "scripts.js");
24105
24609
  if (fs12.existsSync(p)) {
24106
24610
  scriptsPath = p;
24107
24611
  break;
@@ -24930,7 +25434,7 @@ async function handleDomContext(ctx, type, req, res) {
24930
25434
 
24931
25435
  // src/daemon/dev-cli-debug.ts
24932
25436
  var fs13 = __toESM(require("fs"));
24933
- var path23 = __toESM(require("path"));
25437
+ var path24 = __toESM(require("path"));
24934
25438
  function slugifyFixtureName(value) {
24935
25439
  const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
24936
25440
  return normalized || `fixture-${Date.now()}`;
@@ -24940,11 +25444,11 @@ function getCliFixtureDir(ctx, type) {
24940
25444
  if (!providerDir) {
24941
25445
  throw new Error(`Provider directory not found for '${type}'`);
24942
25446
  }
24943
- return path23.join(providerDir, "fixtures");
25447
+ return path24.join(providerDir, "fixtures");
24944
25448
  }
24945
25449
  function readCliFixture(ctx, type, name) {
24946
25450
  const fixtureDir = getCliFixtureDir(ctx, type);
24947
- const filePath = path23.join(fixtureDir, `${name}.json`);
25451
+ const filePath = path24.join(fixtureDir, `${name}.json`);
24948
25452
  if (!fs13.existsSync(filePath)) {
24949
25453
  throw new Error(`Fixture not found: ${filePath}`);
24950
25454
  }
@@ -25711,7 +26215,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
25711
26215
  },
25712
26216
  notes: typeof body?.notes === "string" ? body.notes : void 0
25713
26217
  };
25714
- const filePath = path23.join(fixtureDir, `${name}.json`);
26218
+ const filePath = path24.join(fixtureDir, `${name}.json`);
25715
26219
  fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
25716
26220
  ctx.json(res, 200, {
25717
26221
  saved: true,
@@ -25735,7 +26239,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
25735
26239
  return;
25736
26240
  }
25737
26241
  const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
25738
- const fullPath = path23.join(fixtureDir, file);
26242
+ const fullPath = path24.join(fixtureDir, file);
25739
26243
  try {
25740
26244
  const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
25741
26245
  return {
@@ -25871,8 +26375,8 @@ async function handleCliRaw(ctx, req, res) {
25871
26375
 
25872
26376
  // src/daemon/dev-auto-implement.ts
25873
26377
  var fs14 = __toESM(require("fs"));
25874
- var path24 = __toESM(require("path"));
25875
- var os20 = __toESM(require("os"));
26378
+ var path25 = __toESM(require("path"));
26379
+ var os21 = __toESM(require("os"));
25876
26380
  function getAutoImplPid(ctx) {
25877
26381
  const pid = ctx.autoImplProcess?.pid;
25878
26382
  return typeof pid === "number" && pid > 0 ? pid : null;
@@ -25921,22 +26425,22 @@ function getLatestScriptVersionDir(scriptsDir) {
25921
26425
  if (!fs14.existsSync(scriptsDir)) return null;
25922
26426
  const versions = fs14.readdirSync(scriptsDir).filter((d) => {
25923
26427
  try {
25924
- return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
26428
+ return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
25925
26429
  } catch {
25926
26430
  return false;
25927
26431
  }
25928
26432
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
25929
26433
  if (versions.length === 0) return null;
25930
- return path24.join(scriptsDir, versions[0]);
26434
+ return path25.join(scriptsDir, versions[0]);
25931
26435
  }
25932
26436
  function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
25933
- const canonicalUserDir = path24.resolve(ctx.providerLoader.getUserProviderDir(category, type));
25934
- const desiredDir = requestedDir ? path24.resolve(requestedDir) : canonicalUserDir;
25935
- const upstreamRoot = path24.resolve(ctx.providerLoader.getUpstreamDir());
25936
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path24.sep}`)) {
26437
+ const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
26438
+ const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
26439
+ const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
26440
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
25937
26441
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
25938
26442
  }
25939
- if (path24.basename(desiredDir) !== type) {
26443
+ if (path25.basename(desiredDir) !== type) {
25940
26444
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
25941
26445
  }
25942
26446
  const sourceDir = ctx.findProviderDir(type);
@@ -25944,11 +26448,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
25944
26448
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
25945
26449
  }
25946
26450
  if (!fs14.existsSync(desiredDir)) {
25947
- fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
26451
+ fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
25948
26452
  fs14.cpSync(sourceDir, desiredDir, { recursive: true });
25949
26453
  ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
25950
26454
  }
25951
- const providerJson = path24.join(desiredDir, "provider.json");
26455
+ const providerJson = path25.join(desiredDir, "provider.json");
25952
26456
  if (!fs14.existsSync(providerJson)) {
25953
26457
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
25954
26458
  }
@@ -25959,13 +26463,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
25959
26463
  const refDir = ctx.findProviderDir(referenceType);
25960
26464
  if (!refDir || !fs14.existsSync(refDir)) return {};
25961
26465
  const referenceScripts = {};
25962
- const scriptsDir = path24.join(refDir, "scripts");
26466
+ const scriptsDir = path25.join(refDir, "scripts");
25963
26467
  const latestDir = getLatestScriptVersionDir(scriptsDir);
25964
26468
  if (!latestDir) return referenceScripts;
25965
26469
  for (const file of fs14.readdirSync(latestDir)) {
25966
26470
  if (!file.endsWith(".js")) continue;
25967
26471
  try {
25968
- referenceScripts[file] = fs14.readFileSync(path24.join(latestDir, file), "utf-8");
26472
+ referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
25969
26473
  } catch {
25970
26474
  }
25971
26475
  }
@@ -26073,9 +26577,9 @@ async function handleAutoImplement(ctx, type, req, res) {
26073
26577
  });
26074
26578
  const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
26075
26579
  const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
26076
- const tmpDir = path24.join(os20.tmpdir(), "adhdev-autoimpl");
26580
+ const tmpDir = path25.join(os21.tmpdir(), "adhdev-autoimpl");
26077
26581
  if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
26078
- const promptFile = path24.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
26582
+ const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
26079
26583
  fs14.writeFileSync(promptFile, prompt, "utf-8");
26080
26584
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
26081
26585
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
@@ -26228,7 +26732,7 @@ async function handleAutoImplement(ctx, type, req, res) {
26228
26732
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
26229
26733
  const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
26230
26734
  let shellCmd;
26231
- const isWin = os20.platform() === "win32";
26735
+ const isWin = os21.platform() === "win32";
26232
26736
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
26233
26737
  const promptMode = autoImpl?.promptMode ?? "stdin";
26234
26738
  const extraArgs = autoImpl?.extraArgs ?? [];
@@ -26267,7 +26771,7 @@ async function handleAutoImplement(ctx, type, req, res) {
26267
26771
  try {
26268
26772
  const pty = require("node-pty");
26269
26773
  ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
26270
- const isWin2 = os20.platform() === "win32";
26774
+ const isWin2 = os21.platform() === "win32";
26271
26775
  child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
26272
26776
  name: "xterm-256color",
26273
26777
  cols: 120,
@@ -26507,7 +27011,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26507
27011
  setMode: "set_mode.js"
26508
27012
  };
26509
27013
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
26510
- const scriptsDir = path24.join(providerDir, "scripts");
27014
+ const scriptsDir = path25.join(providerDir, "scripts");
26511
27015
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
26512
27016
  if (latestScriptsDir) {
26513
27017
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -26518,7 +27022,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26518
27022
  for (const file of fs14.readdirSync(latestScriptsDir)) {
26519
27023
  if (file.endsWith(".js") && targetFileNames.has(file)) {
26520
27024
  try {
26521
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27025
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26522
27026
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
26523
27027
  lines.push("```javascript");
26524
27028
  lines.push(content);
@@ -26535,7 +27039,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26535
27039
  lines.push("");
26536
27040
  for (const file of refFiles) {
26537
27041
  try {
26538
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27042
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26539
27043
  lines.push(`### \`${file}\` \u{1F512}`);
26540
27044
  lines.push("```javascript");
26541
27045
  lines.push(content);
@@ -26576,10 +27080,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
26576
27080
  lines.push("");
26577
27081
  }
26578
27082
  }
26579
- const docsDir = path24.join(providerDir, "../../docs");
27083
+ const docsDir = path25.join(providerDir, "../../docs");
26580
27084
  const loadGuide = (name) => {
26581
27085
  try {
26582
- const p = path24.join(docsDir, name);
27086
+ const p = path25.join(docsDir, name);
26583
27087
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
26584
27088
  } catch {
26585
27089
  }
@@ -26816,7 +27320,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26816
27320
  parseApproval: "parse_approval.js"
26817
27321
  };
26818
27322
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
26819
- const scriptsDir = path24.join(providerDir, "scripts");
27323
+ const scriptsDir = path25.join(providerDir, "scripts");
26820
27324
  const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
26821
27325
  if (latestScriptsDir) {
26822
27326
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -26828,7 +27332,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26828
27332
  if (!file.endsWith(".js")) continue;
26829
27333
  if (!targetFileNames.has(file)) continue;
26830
27334
  try {
26831
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27335
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26832
27336
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
26833
27337
  lines.push("```javascript");
26834
27338
  lines.push(content);
@@ -26844,7 +27348,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26844
27348
  lines.push("");
26845
27349
  for (const file of refFiles) {
26846
27350
  try {
26847
- const content = fs14.readFileSync(path24.join(latestScriptsDir, file), "utf-8");
27351
+ const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
26848
27352
  lines.push(`### \`${file}\` \u{1F512}`);
26849
27353
  lines.push("```javascript");
26850
27354
  lines.push(content);
@@ -26877,10 +27381,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
26877
27381
  lines.push("");
26878
27382
  }
26879
27383
  }
26880
- const docsDir = path24.join(providerDir, "../../docs");
27384
+ const docsDir = path25.join(providerDir, "../../docs");
26881
27385
  const loadGuide = (name) => {
26882
27386
  try {
26883
- const p = path24.join(docsDir, name);
27387
+ const p = path25.join(docsDir, name);
26884
27388
  if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
26885
27389
  } catch {
26886
27390
  }
@@ -27327,8 +27831,8 @@ var DevServer = class _DevServer {
27327
27831
  }
27328
27832
  getEndpointList() {
27329
27833
  return this.routes.map((r) => {
27330
- const path26 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
27331
- return `${r.method.padEnd(5)} ${path26}`;
27834
+ const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
27835
+ return `${r.method.padEnd(5)} ${path27}`;
27332
27836
  });
27333
27837
  }
27334
27838
  async start(port = DEV_SERVER_PORT) {
@@ -27616,12 +28120,12 @@ var DevServer = class _DevServer {
27616
28120
  // ─── DevConsole SPA ───
27617
28121
  getConsoleDistDir() {
27618
28122
  const candidates = [
27619
- path25.resolve(__dirname, "../../web-devconsole/dist"),
27620
- path25.resolve(__dirname, "../../../web-devconsole/dist"),
27621
- path25.join(process.cwd(), "packages/web-devconsole/dist")
28123
+ path26.resolve(__dirname, "../../web-devconsole/dist"),
28124
+ path26.resolve(__dirname, "../../../web-devconsole/dist"),
28125
+ path26.join(process.cwd(), "packages/web-devconsole/dist")
27622
28126
  ];
27623
28127
  for (const dir of candidates) {
27624
- if (fs15.existsSync(path25.join(dir, "index.html"))) return dir;
28128
+ if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
27625
28129
  }
27626
28130
  return null;
27627
28131
  }
@@ -27631,7 +28135,7 @@ var DevServer = class _DevServer {
27631
28135
  this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
27632
28136
  return;
27633
28137
  }
27634
- const htmlPath = path25.join(distDir, "index.html");
28138
+ const htmlPath = path26.join(distDir, "index.html");
27635
28139
  try {
27636
28140
  const html = fs15.readFileSync(htmlPath, "utf-8");
27637
28141
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -27656,15 +28160,15 @@ var DevServer = class _DevServer {
27656
28160
  this.json(res, 404, { error: "Not found" });
27657
28161
  return;
27658
28162
  }
27659
- const safePath = path25.normalize(pathname).replace(/^\.\.\//, "");
27660
- const filePath = path25.join(distDir, safePath);
28163
+ const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
28164
+ const filePath = path26.join(distDir, safePath);
27661
28165
  if (!filePath.startsWith(distDir)) {
27662
28166
  this.json(res, 403, { error: "Forbidden" });
27663
28167
  return;
27664
28168
  }
27665
28169
  try {
27666
28170
  const content = fs15.readFileSync(filePath);
27667
- const ext = path25.extname(filePath);
28171
+ const ext = path26.extname(filePath);
27668
28172
  const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
27669
28173
  res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
27670
28174
  res.end(content);
@@ -27777,9 +28281,9 @@ var DevServer = class _DevServer {
27777
28281
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
27778
28282
  if (entry.isDirectory()) {
27779
28283
  files.push({ path: rel, size: 0, type: "dir" });
27780
- scan(path25.join(d, entry.name), rel);
28284
+ scan(path26.join(d, entry.name), rel);
27781
28285
  } else {
27782
- const stat2 = fs15.statSync(path25.join(d, entry.name));
28286
+ const stat2 = fs15.statSync(path26.join(d, entry.name));
27783
28287
  files.push({ path: rel, size: stat2.size, type: "file" });
27784
28288
  }
27785
28289
  }
@@ -27802,7 +28306,7 @@ var DevServer = class _DevServer {
27802
28306
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
27803
28307
  return;
27804
28308
  }
27805
- const fullPath = path25.resolve(dir, path25.normalize(filePath));
28309
+ const fullPath = path26.resolve(dir, path26.normalize(filePath));
27806
28310
  if (!fullPath.startsWith(dir)) {
27807
28311
  this.json(res, 403, { error: "Forbidden" });
27808
28312
  return;
@@ -27827,14 +28331,14 @@ var DevServer = class _DevServer {
27827
28331
  this.json(res, 404, { error: `Provider directory not found: ${type}` });
27828
28332
  return;
27829
28333
  }
27830
- const fullPath = path25.resolve(dir, path25.normalize(filePath));
28334
+ const fullPath = path26.resolve(dir, path26.normalize(filePath));
27831
28335
  if (!fullPath.startsWith(dir)) {
27832
28336
  this.json(res, 403, { error: "Forbidden" });
27833
28337
  return;
27834
28338
  }
27835
28339
  try {
27836
28340
  if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
27837
- fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
28341
+ fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
27838
28342
  fs15.writeFileSync(fullPath, content, "utf-8");
27839
28343
  this.log(`File saved: ${fullPath} (${content.length} chars)`);
27840
28344
  this.providerLoader.reload();
@@ -27851,7 +28355,7 @@ var DevServer = class _DevServer {
27851
28355
  return;
27852
28356
  }
27853
28357
  for (const name of ["scripts.js", "provider.json"]) {
27854
- const p = path25.join(dir, name);
28358
+ const p = path26.join(dir, name);
27855
28359
  if (fs15.existsSync(p)) {
27856
28360
  const source = fs15.readFileSync(p, "utf-8");
27857
28361
  this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
@@ -27872,8 +28376,8 @@ var DevServer = class _DevServer {
27872
28376
  this.json(res, 404, { error: `Provider not found: ${type}` });
27873
28377
  return;
27874
28378
  }
27875
- const target = fs15.existsSync(path25.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
27876
- const targetPath = path25.join(dir, target);
28379
+ const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
28380
+ const targetPath = path26.join(dir, target);
27877
28381
  try {
27878
28382
  if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
27879
28383
  fs15.writeFileSync(targetPath, source, "utf-8");
@@ -28020,7 +28524,7 @@ var DevServer = class _DevServer {
28020
28524
  }
28021
28525
  let targetDir;
28022
28526
  targetDir = this.providerLoader.getUserProviderDir(category, type);
28023
- const jsonPath = path25.join(targetDir, "provider.json");
28527
+ const jsonPath = path26.join(targetDir, "provider.json");
28024
28528
  if (fs15.existsSync(jsonPath)) {
28025
28529
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
28026
28530
  return;
@@ -28032,8 +28536,8 @@ var DevServer = class _DevServer {
28032
28536
  const createdFiles = ["provider.json"];
28033
28537
  if (result.files) {
28034
28538
  for (const [relPath, content] of Object.entries(result.files)) {
28035
- const fullPath = path25.join(targetDir, relPath);
28036
- fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
28539
+ const fullPath = path26.join(targetDir, relPath);
28540
+ fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
28037
28541
  fs15.writeFileSync(fullPath, content, "utf-8");
28038
28542
  createdFiles.push(relPath);
28039
28543
  }
@@ -28086,22 +28590,22 @@ var DevServer = class _DevServer {
28086
28590
  if (!fs15.existsSync(scriptsDir)) return null;
28087
28591
  const versions = fs15.readdirSync(scriptsDir).filter((d) => {
28088
28592
  try {
28089
- return fs15.statSync(path25.join(scriptsDir, d)).isDirectory();
28593
+ return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
28090
28594
  } catch {
28091
28595
  return false;
28092
28596
  }
28093
28597
  }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
28094
28598
  if (versions.length === 0) return null;
28095
- return path25.join(scriptsDir, versions[0]);
28599
+ return path26.join(scriptsDir, versions[0]);
28096
28600
  }
28097
28601
  resolveAutoImplWritableProviderDir(category, type, requestedDir) {
28098
- const canonicalUserDir = path25.resolve(this.providerLoader.getUserProviderDir(category, type));
28099
- const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
28100
- const upstreamRoot = path25.resolve(this.providerLoader.getUpstreamDir());
28101
- if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
28602
+ const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
28603
+ const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
28604
+ const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
28605
+ if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
28102
28606
  return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
28103
28607
  }
28104
- if (path25.basename(desiredDir) !== type) {
28608
+ if (path26.basename(desiredDir) !== type) {
28105
28609
  return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
28106
28610
  }
28107
28611
  const sourceDir = this.findProviderDir(type);
@@ -28109,11 +28613,11 @@ var DevServer = class _DevServer {
28109
28613
  return { dir: null, reason: `Provider source directory not found for '${type}'` };
28110
28614
  }
28111
28615
  if (!fs15.existsSync(desiredDir)) {
28112
- fs15.mkdirSync(path25.dirname(desiredDir), { recursive: true });
28616
+ fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
28113
28617
  fs15.cpSync(sourceDir, desiredDir, { recursive: true });
28114
28618
  this.log(`Auto-implement writable copy created: ${desiredDir}`);
28115
28619
  }
28116
- const providerJson = path25.join(desiredDir, "provider.json");
28620
+ const providerJson = path26.join(desiredDir, "provider.json");
28117
28621
  if (!fs15.existsSync(providerJson)) {
28118
28622
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
28119
28623
  }
@@ -28149,7 +28653,7 @@ var DevServer = class _DevServer {
28149
28653
  setMode: "set_mode.js"
28150
28654
  };
28151
28655
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
28152
- const scriptsDir = path25.join(providerDir, "scripts");
28656
+ const scriptsDir = path26.join(providerDir, "scripts");
28153
28657
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
28154
28658
  if (latestScriptsDir) {
28155
28659
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -28160,7 +28664,7 @@ var DevServer = class _DevServer {
28160
28664
  for (const file of fs15.readdirSync(latestScriptsDir)) {
28161
28665
  if (file.endsWith(".js") && targetFileNames.has(file)) {
28162
28666
  try {
28163
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28667
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28164
28668
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
28165
28669
  lines.push("```javascript");
28166
28670
  lines.push(content);
@@ -28177,7 +28681,7 @@ var DevServer = class _DevServer {
28177
28681
  lines.push("");
28178
28682
  for (const file of refFiles) {
28179
28683
  try {
28180
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28684
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28181
28685
  lines.push(`### \`${file}\` \u{1F512}`);
28182
28686
  lines.push("```javascript");
28183
28687
  lines.push(content);
@@ -28218,10 +28722,10 @@ var DevServer = class _DevServer {
28218
28722
  lines.push("");
28219
28723
  }
28220
28724
  }
28221
- const docsDir = path25.join(providerDir, "../../docs");
28725
+ const docsDir = path26.join(providerDir, "../../docs");
28222
28726
  const loadGuide = (name) => {
28223
28727
  try {
28224
- const p = path25.join(docsDir, name);
28728
+ const p = path26.join(docsDir, name);
28225
28729
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
28226
28730
  } catch {
28227
28731
  }
@@ -28395,7 +28899,7 @@ var DevServer = class _DevServer {
28395
28899
  parseApproval: "parse_approval.js"
28396
28900
  };
28397
28901
  const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
28398
- const scriptsDir = path25.join(providerDir, "scripts");
28902
+ const scriptsDir = path26.join(providerDir, "scripts");
28399
28903
  const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
28400
28904
  if (latestScriptsDir) {
28401
28905
  lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
@@ -28407,7 +28911,7 @@ var DevServer = class _DevServer {
28407
28911
  if (!file.endsWith(".js")) continue;
28408
28912
  if (!targetFileNames.has(file)) continue;
28409
28913
  try {
28410
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28914
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28411
28915
  lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
28412
28916
  lines.push("```javascript");
28413
28917
  lines.push(content);
@@ -28423,7 +28927,7 @@ var DevServer = class _DevServer {
28423
28927
  lines.push("");
28424
28928
  for (const file of refFiles) {
28425
28929
  try {
28426
- const content = fs15.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
28930
+ const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
28427
28931
  lines.push(`### \`${file}\` \u{1F512}`);
28428
28932
  lines.push("```javascript");
28429
28933
  lines.push(content);
@@ -28456,10 +28960,10 @@ var DevServer = class _DevServer {
28456
28960
  lines.push("");
28457
28961
  }
28458
28962
  }
28459
- const docsDir = path25.join(providerDir, "../../docs");
28963
+ const docsDir = path26.join(providerDir, "../../docs");
28460
28964
  const loadGuide = (name) => {
28461
28965
  try {
28462
- const p = path25.join(docsDir, name);
28966
+ const p = path26.join(docsDir, name);
28463
28967
  if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
28464
28968
  } catch {
28465
28969
  }
@@ -29807,6 +30311,7 @@ async function shutdownDaemonComponents(components) {
29807
30311
  createGitWorkspaceMonitor,
29808
30312
  createInteractionId,
29809
30313
  createMesh,
30314
+ createWorktree,
29810
30315
  deleteMesh,
29811
30316
  detectAllVersions,
29812
30317
  detectCLIs,
@@ -29859,6 +30364,7 @@ async function shutdownDaemonComponents(components) {
29859
30364
  launchWithCdp,
29860
30365
  listHostedCliRuntimes,
29861
30366
  listMeshes,
30367
+ listWorktrees,
29862
30368
  loadConfig,
29863
30369
  loadState,
29864
30370
  logCommand,
@@ -29878,6 +30384,7 @@ async function shutdownDaemonComponents(components) {
29878
30384
  normalizeSessionModalFields,
29879
30385
  parsePorcelainV2Status,
29880
30386
  parseProviderSourceConfigUpdate,
30387
+ parseWorktreeListOutput,
29881
30388
  partitionSessionHostDiagnosticsSessions,
29882
30389
  partitionSessionHostRecords,
29883
30390
  prepareSessionChatTailUpdate,
@@ -29887,6 +30394,7 @@ async function shutdownDaemonComponents(components) {
29887
30394
  recordDebugTrace,
29888
30395
  registerExtensionProviders,
29889
30396
  removeNode,
30397
+ removeWorktree,
29890
30398
  resetConfig,
29891
30399
  resetDebugRuntimeConfig,
29892
30400
  resetState,
@@ -29896,6 +30404,7 @@ async function shutdownDaemonComponents(components) {
29896
30404
  resolveGitRepository,
29897
30405
  resolveSessionHostAppName,
29898
30406
  resolveSessionHostAppNameResolution,
30407
+ resolveWorktreePath,
29899
30408
  runAsyncBatch,
29900
30409
  runGit,
29901
30410
  saveConfig,