@adhdev/daemon-core 0.9.76-rc.1 → 0.9.76-rc.11
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/commands/router.d.ts +4 -0
- package/dist/config/mesh-config.d.ts +3 -0
- package/dist/git/git-worktree.d.ts +64 -0
- package/dist/git/index.d.ts +2 -0
- package/dist/index.js +598 -311
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +618 -336
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +1 -0
- package/dist/repo-mesh-types.d.ts +4 -0
- package/dist/shared-types.d.ts +18 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +4 -3
- package/src/commands/mesh-coordinator.ts +1 -1
- package/src/commands/router.ts +157 -10
- package/src/config/mesh-config.ts +6 -0
- package/src/git/git-worktree.ts +214 -0
- package/src/git/index.ts +14 -0
- package/src/mesh/coordinator-prompt.ts +25 -10
- package/src/repo-mesh-types.ts +4 -0
- package/src/shared-types.ts +20 -1
- package/src/status/builders.ts +17 -12
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
|
|
308
|
-
if (!(0, import_fs2.existsSync)(
|
|
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)(
|
|
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
|
|
319
|
-
(0, import_fs2.writeFileSync)(
|
|
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
|
|
327
|
-
return `${url.hostname}/${
|
|
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(
|
|
600
|
+
sections.push(buildRulesSection(coordinatorCliType));
|
|
470
601
|
if (userInstruction) {
|
|
471
602
|
sections.push(`## Additional Context
|
|
472
603
|
${userInstruction}`);
|
|
473
604
|
}
|
|
474
|
-
if (mesh.coordinator
|
|
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
|
-
|
|
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
|
|
542
|
-
c.
|
|
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. **
|
|
547
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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" ?
|
|
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 =
|
|
873
|
+
currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
731
874
|
cleanOldLogs();
|
|
732
875
|
try {
|
|
733
|
-
const oldLog =
|
|
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,
|
|
880
|
+
fs2.renameSync(oldLog, path10.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
738
881
|
}
|
|
739
|
-
const oldLogBackup =
|
|
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 =
|
|
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("~") ?
|
|
1240
|
-
if (
|
|
1241
|
-
return
|
|
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 (!
|
|
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 (!
|
|
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,
|
|
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
|
-
|
|
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;
|
|
@@ -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 || !
|
|
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 || !
|
|
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";
|
|
@@ -1573,12 +1716,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
1573
1716
|
}
|
|
1574
1717
|
return "";
|
|
1575
1718
|
}
|
|
1576
|
-
var os10,
|
|
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
|
-
|
|
1724
|
+
path15 = __toESM(require("path"));
|
|
1582
1725
|
import_session_host_core2 = require("@adhdev/session-host-core");
|
|
1583
1726
|
init_provider_cli_shared();
|
|
1584
1727
|
}
|
|
@@ -1766,8 +1909,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1766
1909
|
const currentSnapshot = normalizeScreenSnapshot(screenText);
|
|
1767
1910
|
const lastSnapshot = this.lastScreenSnapshot;
|
|
1768
1911
|
if (!lastSnapshot || lastSnapshot === currentSnapshot) return screenText;
|
|
1769
|
-
const
|
|
1770
|
-
const
|
|
1912
|
+
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;
|
|
1913
|
+
const staleSnapshotLooksActive = activeScreenPattern.test(lastSnapshot);
|
|
1914
|
+
const currentScreenLooksIdle = /(?:^|\n|\r)\s*[❯›>]\s*(?:Try\s+["“][^\n\r"”]+["”])?\s*(?:\n|\r|$)/.test(screenText) && !activeScreenPattern.test(screenText);
|
|
1771
1915
|
if (staleSnapshotLooksActive && currentScreenLooksIdle) return screenText;
|
|
1772
1916
|
if (currentSnapshot.length >= lastSnapshot.length) return screenText;
|
|
1773
1917
|
return `${screenText}
|
|
@@ -3727,6 +3871,7 @@ __export(index_exports, {
|
|
|
3727
3871
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
|
|
3728
3872
|
createInteractionId: () => createInteractionId,
|
|
3729
3873
|
createMesh: () => createMesh,
|
|
3874
|
+
createWorktree: () => createWorktree,
|
|
3730
3875
|
deleteMesh: () => deleteMesh,
|
|
3731
3876
|
detectAllVersions: () => detectAllVersions,
|
|
3732
3877
|
detectCLIs: () => detectCLIs,
|
|
@@ -3779,6 +3924,7 @@ __export(index_exports, {
|
|
|
3779
3924
|
launchWithCdp: () => launchWithCdp,
|
|
3780
3925
|
listHostedCliRuntimes: () => listHostedCliRuntimes,
|
|
3781
3926
|
listMeshes: () => listMeshes,
|
|
3927
|
+
listWorktrees: () => listWorktrees,
|
|
3782
3928
|
loadConfig: () => loadConfig,
|
|
3783
3929
|
loadState: () => loadState,
|
|
3784
3930
|
logCommand: () => logCommand,
|
|
@@ -3798,6 +3944,7 @@ __export(index_exports, {
|
|
|
3798
3944
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
3799
3945
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
3800
3946
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
3947
|
+
parseWorktreeListOutput: () => parseWorktreeListOutput,
|
|
3801
3948
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
3802
3949
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
3803
3950
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
|
|
@@ -3807,6 +3954,7 @@ __export(index_exports, {
|
|
|
3807
3954
|
recordDebugTrace: () => recordDebugTrace,
|
|
3808
3955
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
3809
3956
|
removeNode: () => removeNode,
|
|
3957
|
+
removeWorktree: () => removeWorktree,
|
|
3810
3958
|
resetConfig: () => resetConfig,
|
|
3811
3959
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
3812
3960
|
resetState: () => resetState,
|
|
@@ -3816,6 +3964,7 @@ __export(index_exports, {
|
|
|
3816
3964
|
resolveGitRepository: () => resolveGitRepository,
|
|
3817
3965
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
3818
3966
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
|
|
3967
|
+
resolveWorktreePath: () => resolveWorktreePath,
|
|
3819
3968
|
runAsyncBatch: () => runAsyncBatch,
|
|
3820
3969
|
runGit: () => runGit,
|
|
3821
3970
|
saveConfig: () => saveConfig,
|
|
@@ -5175,20 +5324,23 @@ var TurnSnapshotTracker = class {
|
|
|
5175
5324
|
}
|
|
5176
5325
|
};
|
|
5177
5326
|
|
|
5327
|
+
// src/git/index.ts
|
|
5328
|
+
init_git_worktree();
|
|
5329
|
+
|
|
5178
5330
|
// src/index.ts
|
|
5179
5331
|
init_config();
|
|
5180
5332
|
|
|
5181
5333
|
// src/config/workspaces.ts
|
|
5182
5334
|
var fs = __toESM(require("fs"));
|
|
5183
5335
|
var os = __toESM(require("os"));
|
|
5184
|
-
var
|
|
5336
|
+
var path5 = __toESM(require("path"));
|
|
5185
5337
|
var import_crypto2 = require("crypto");
|
|
5186
5338
|
var MAX_WORKSPACES = 50;
|
|
5187
5339
|
function expandPath(p) {
|
|
5188
5340
|
const t = (p || "").trim();
|
|
5189
5341
|
if (!t) return "";
|
|
5190
|
-
if (t.startsWith("~")) return
|
|
5191
|
-
return
|
|
5342
|
+
if (t.startsWith("~")) return path5.join(os.homedir(), t.slice(1).replace(/^\//, ""));
|
|
5343
|
+
return path5.resolve(t);
|
|
5192
5344
|
}
|
|
5193
5345
|
function validateWorkspacePath(absPath) {
|
|
5194
5346
|
try {
|
|
@@ -5202,7 +5354,7 @@ function validateWorkspacePath(absPath) {
|
|
|
5202
5354
|
}
|
|
5203
5355
|
}
|
|
5204
5356
|
function defaultWorkspaceLabel(absPath) {
|
|
5205
|
-
const base =
|
|
5357
|
+
const base = path5.basename(absPath) || absPath;
|
|
5206
5358
|
return base;
|
|
5207
5359
|
}
|
|
5208
5360
|
function getDefaultWorkspacePath(config) {
|
|
@@ -5293,9 +5445,9 @@ function resolveIdeLaunchWorkspace(args, config) {
|
|
|
5293
5445
|
return getDefaultWorkspacePath(config) || void 0;
|
|
5294
5446
|
}
|
|
5295
5447
|
function findWorkspaceByPath(config, rawPath) {
|
|
5296
|
-
const abs =
|
|
5448
|
+
const abs = path5.resolve(expandPath(rawPath));
|
|
5297
5449
|
if (!abs) return void 0;
|
|
5298
|
-
return (config.workspaces || []).find((w) =>
|
|
5450
|
+
return (config.workspaces || []).find((w) => path5.resolve(expandPath(w.path)) === abs);
|
|
5299
5451
|
}
|
|
5300
5452
|
function addWorkspaceEntry(config, rawPath, label, options) {
|
|
5301
5453
|
const abs = expandPath(rawPath);
|
|
@@ -5311,7 +5463,7 @@ function addWorkspaceEntry(config, rawPath, label, options) {
|
|
|
5311
5463
|
const v = validateWorkspacePath(abs);
|
|
5312
5464
|
if (!v.ok) return { error: v.error };
|
|
5313
5465
|
const list = [...config.workspaces || []];
|
|
5314
|
-
if (list.some((w) =>
|
|
5466
|
+
if (list.some((w) => path5.resolve(w.path) === abs)) {
|
|
5315
5467
|
return { error: "Workspace already in list" };
|
|
5316
5468
|
}
|
|
5317
5469
|
if (list.length >= MAX_WORKSPACES) {
|
|
@@ -5345,7 +5497,7 @@ function setDefaultWorkspaceId(config, id) {
|
|
|
5345
5497
|
}
|
|
5346
5498
|
|
|
5347
5499
|
// src/config/recent-activity.ts
|
|
5348
|
-
var
|
|
5500
|
+
var path6 = __toESM(require("path"));
|
|
5349
5501
|
|
|
5350
5502
|
// src/providers/summary-metadata.ts
|
|
5351
5503
|
function normalizeSummaryItem(item) {
|
|
@@ -5414,9 +5566,9 @@ var MAX_ACTIVITY = 30;
|
|
|
5414
5566
|
function normalizeWorkspace(workspace) {
|
|
5415
5567
|
if (!workspace) return "";
|
|
5416
5568
|
try {
|
|
5417
|
-
return
|
|
5569
|
+
return path6.resolve(expandPath(workspace));
|
|
5418
5570
|
} catch {
|
|
5419
|
-
return
|
|
5571
|
+
return path6.resolve(workspace);
|
|
5420
5572
|
}
|
|
5421
5573
|
}
|
|
5422
5574
|
function buildRecentActivityKey(entry) {
|
|
@@ -5584,14 +5736,14 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
|
|
|
5584
5736
|
}
|
|
5585
5737
|
|
|
5586
5738
|
// src/config/saved-sessions.ts
|
|
5587
|
-
var
|
|
5739
|
+
var path7 = __toESM(require("path"));
|
|
5588
5740
|
var MAX_SAVED_SESSIONS = 500;
|
|
5589
5741
|
function normalizeWorkspace2(workspace) {
|
|
5590
5742
|
if (!workspace) return "";
|
|
5591
5743
|
try {
|
|
5592
|
-
return
|
|
5744
|
+
return path7.resolve(expandPath(workspace));
|
|
5593
5745
|
} catch {
|
|
5594
|
-
return
|
|
5746
|
+
return path7.resolve(workspace);
|
|
5595
5747
|
}
|
|
5596
5748
|
}
|
|
5597
5749
|
function buildSavedProviderSessionKey(providerSessionId) {
|
|
@@ -5770,7 +5922,7 @@ function resetState() {
|
|
|
5770
5922
|
var import_child_process = require("child_process");
|
|
5771
5923
|
var import_fs4 = require("fs");
|
|
5772
5924
|
var import_os2 = require("os");
|
|
5773
|
-
var
|
|
5925
|
+
var path8 = __toESM(require("path"));
|
|
5774
5926
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
5775
5927
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
5776
5928
|
function registerIDEDefinition(def) {
|
|
@@ -5789,9 +5941,9 @@ function getMergedDefinitions() {
|
|
|
5789
5941
|
function findCliCommand(command) {
|
|
5790
5942
|
const trimmed = String(command || "").trim();
|
|
5791
5943
|
if (!trimmed) return null;
|
|
5792
|
-
if (
|
|
5793
|
-
const candidate = trimmed.startsWith("~") ?
|
|
5794
|
-
const resolved =
|
|
5944
|
+
if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
5945
|
+
const candidate = trimmed.startsWith("~") ? path8.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
5946
|
+
const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
|
|
5795
5947
|
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
5796
5948
|
}
|
|
5797
5949
|
try {
|
|
@@ -5819,7 +5971,7 @@ function getIdeVersion(cliCommand) {
|
|
|
5819
5971
|
function checkPathExists(paths) {
|
|
5820
5972
|
const home = (0, import_os2.homedir)();
|
|
5821
5973
|
for (const p of paths) {
|
|
5822
|
-
const normalized = p.startsWith("~") ?
|
|
5974
|
+
const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
|
|
5823
5975
|
if (normalized.includes("*")) {
|
|
5824
5976
|
const username = home.split(/[\\/]/).pop() || "";
|
|
5825
5977
|
const resolved = normalized.replace("*", username);
|
|
@@ -5842,8 +5994,8 @@ async function detectIDEs(providerLoader) {
|
|
|
5842
5994
|
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
5843
5995
|
}
|
|
5844
5996
|
if (!resolvedCli && appPath && os21 === "win32") {
|
|
5845
|
-
const { dirname:
|
|
5846
|
-
const appDir =
|
|
5997
|
+
const { dirname: dirname9 } = await import("path");
|
|
5998
|
+
const appDir = dirname9(appPath);
|
|
5847
5999
|
const candidates = [
|
|
5848
6000
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
5849
6001
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -5877,7 +6029,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5877
6029
|
// src/detection/cli-detector.ts
|
|
5878
6030
|
var import_child_process2 = require("child_process");
|
|
5879
6031
|
var os2 = __toESM(require("os"));
|
|
5880
|
-
var
|
|
6032
|
+
var path9 = __toESM(require("path"));
|
|
5881
6033
|
var import_fs5 = require("fs");
|
|
5882
6034
|
function parseVersion(raw) {
|
|
5883
6035
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -5890,18 +6042,18 @@ function shellQuote(value) {
|
|
|
5890
6042
|
function expandHome(value) {
|
|
5891
6043
|
const trimmed = value.trim();
|
|
5892
6044
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
5893
|
-
return
|
|
6045
|
+
return path9.join(os2.homedir(), trimmed.slice(1));
|
|
5894
6046
|
}
|
|
5895
6047
|
function isExplicitCommandPath(command) {
|
|
5896
6048
|
const trimmed = command.trim();
|
|
5897
|
-
return
|
|
6049
|
+
return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
5898
6050
|
}
|
|
5899
6051
|
function resolveCommandPath(command) {
|
|
5900
6052
|
const trimmed = command.trim();
|
|
5901
6053
|
if (!trimmed) return null;
|
|
5902
6054
|
if (isExplicitCommandPath(trimmed)) {
|
|
5903
6055
|
const expanded = expandHome(trimmed);
|
|
5904
|
-
const candidate =
|
|
6056
|
+
const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
|
|
5905
6057
|
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
5906
6058
|
}
|
|
5907
6059
|
return null;
|
|
@@ -8170,9 +8322,9 @@ ${cleanBody}`;
|
|
|
8170
8322
|
|
|
8171
8323
|
// src/config/chat-history.ts
|
|
8172
8324
|
var fs3 = __toESM(require("fs"));
|
|
8173
|
-
var
|
|
8325
|
+
var path11 = __toESM(require("path"));
|
|
8174
8326
|
var os5 = __toESM(require("os"));
|
|
8175
|
-
var HISTORY_DIR =
|
|
8327
|
+
var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
|
|
8176
8328
|
var RETAIN_DAYS = 30;
|
|
8177
8329
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
8178
8330
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -8335,7 +8487,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
8335
8487
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
8336
8488
|
return new Map(files.map((file) => {
|
|
8337
8489
|
try {
|
|
8338
|
-
const stat2 = fs3.statSync(
|
|
8490
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8339
8491
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
8340
8492
|
} catch {
|
|
8341
8493
|
return [file, `${file}:missing`];
|
|
@@ -8346,7 +8498,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
8346
8498
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
8347
8499
|
}
|
|
8348
8500
|
function getSavedHistoryIndexFilePath(dir) {
|
|
8349
|
-
return
|
|
8501
|
+
return path11.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
8350
8502
|
}
|
|
8351
8503
|
function getSavedHistoryIndexLockPath(dir) {
|
|
8352
8504
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -8448,7 +8600,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
8448
8600
|
}
|
|
8449
8601
|
for (const file of Array.from(currentEntries.keys())) {
|
|
8450
8602
|
if (incomingFiles.has(file)) continue;
|
|
8451
|
-
if (!fs3.existsSync(
|
|
8603
|
+
if (!fs3.existsSync(path11.join(dir, file))) {
|
|
8452
8604
|
currentEntries.delete(file);
|
|
8453
8605
|
}
|
|
8454
8606
|
}
|
|
@@ -8474,7 +8626,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8474
8626
|
const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
|
|
8475
8627
|
const files = listHistoryFiles(dir);
|
|
8476
8628
|
for (const file of files) {
|
|
8477
|
-
const stat2 = fs3.statSync(
|
|
8629
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8478
8630
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
8479
8631
|
}
|
|
8480
8632
|
return false;
|
|
@@ -8484,14 +8636,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8484
8636
|
}
|
|
8485
8637
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
8486
8638
|
try {
|
|
8487
|
-
const stat2 = fs3.statSync(
|
|
8639
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8488
8640
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
8489
8641
|
} catch {
|
|
8490
8642
|
return `${file}:missing`;
|
|
8491
8643
|
}
|
|
8492
8644
|
}
|
|
8493
8645
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
8494
|
-
const filePath =
|
|
8646
|
+
const filePath = path11.join(dir, file);
|
|
8495
8647
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
8496
8648
|
const currentEntry = entries.get(file) || null;
|
|
8497
8649
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -8564,7 +8716,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
8564
8716
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
8565
8717
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
8566
8718
|
if (!historySessionId) return null;
|
|
8567
|
-
const filePath =
|
|
8719
|
+
const filePath = path11.join(dir, file);
|
|
8568
8720
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
8569
8721
|
const lines = content.split("\n").filter(Boolean);
|
|
8570
8722
|
let messageCount = 0;
|
|
@@ -8651,7 +8803,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
8651
8803
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
8652
8804
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
8653
8805
|
for (const file of files.slice().sort()) {
|
|
8654
|
-
const filePath =
|
|
8806
|
+
const filePath = path11.join(dir, file);
|
|
8655
8807
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
8656
8808
|
const cached = savedHistoryFileSummaryCache.get(filePath);
|
|
8657
8809
|
const persisted = persistedEntries.get(file);
|
|
@@ -8771,12 +8923,12 @@ var ChatHistoryWriter = class {
|
|
|
8771
8923
|
});
|
|
8772
8924
|
}
|
|
8773
8925
|
if (newMessages.length === 0) return;
|
|
8774
|
-
const dir =
|
|
8926
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8775
8927
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8776
8928
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8777
8929
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
8778
8930
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
8779
|
-
const filePath =
|
|
8931
|
+
const filePath = path11.join(dir, fileName);
|
|
8780
8932
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
8781
8933
|
fs3.appendFileSync(filePath, lines, "utf-8");
|
|
8782
8934
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -8867,11 +9019,11 @@ var ChatHistoryWriter = class {
|
|
|
8867
9019
|
const ws = String(workspace || "").trim();
|
|
8868
9020
|
if (!id || !ws) return;
|
|
8869
9021
|
try {
|
|
8870
|
-
const dir =
|
|
9022
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8871
9023
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8872
9024
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8873
9025
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
8874
|
-
const filePath =
|
|
9026
|
+
const filePath = path11.join(dir, fileName);
|
|
8875
9027
|
const record = {
|
|
8876
9028
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8877
9029
|
receivedAt: Date.now(),
|
|
@@ -8917,14 +9069,14 @@ var ChatHistoryWriter = class {
|
|
|
8917
9069
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
8918
9070
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
8919
9071
|
}
|
|
8920
|
-
const dir =
|
|
9072
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8921
9073
|
if (!fs3.existsSync(dir)) return;
|
|
8922
9074
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
8923
9075
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
8924
9076
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
8925
9077
|
for (const file of files) {
|
|
8926
|
-
const sourcePath =
|
|
8927
|
-
const targetPath =
|
|
9078
|
+
const sourcePath = path11.join(dir, file);
|
|
9079
|
+
const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
8928
9080
|
const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
8929
9081
|
const rewritten = sourceLines.map((line) => {
|
|
8930
9082
|
try {
|
|
@@ -8958,13 +9110,13 @@ var ChatHistoryWriter = class {
|
|
|
8958
9110
|
const sessionId = String(historySessionId || "").trim();
|
|
8959
9111
|
if (!sessionId) return;
|
|
8960
9112
|
try {
|
|
8961
|
-
const dir =
|
|
9113
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8962
9114
|
if (!fs3.existsSync(dir)) return;
|
|
8963
9115
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
8964
9116
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
8965
9117
|
const seen = /* @__PURE__ */ new Set();
|
|
8966
9118
|
for (const file of files) {
|
|
8967
|
-
const filePath =
|
|
9119
|
+
const filePath = path11.join(dir, file);
|
|
8968
9120
|
const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
8969
9121
|
const next = [];
|
|
8970
9122
|
for (const line of lines) {
|
|
@@ -9018,11 +9170,11 @@ var ChatHistoryWriter = class {
|
|
|
9018
9170
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
9019
9171
|
const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
9020
9172
|
for (const dir of agentDirs) {
|
|
9021
|
-
const dirPath =
|
|
9173
|
+
const dirPath = path11.join(HISTORY_DIR, dir.name);
|
|
9022
9174
|
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
9023
9175
|
let removedAny = false;
|
|
9024
9176
|
for (const file of files) {
|
|
9025
|
-
const filePath =
|
|
9177
|
+
const filePath = path11.join(dirPath, file);
|
|
9026
9178
|
const stat2 = fs3.statSync(filePath);
|
|
9027
9179
|
if (stat2.mtimeMs < cutoff) {
|
|
9028
9180
|
fs3.unlinkSync(filePath);
|
|
@@ -9072,13 +9224,13 @@ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeR
|
|
|
9072
9224
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
9073
9225
|
try {
|
|
9074
9226
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9075
|
-
const dir =
|
|
9227
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9076
9228
|
if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
|
|
9077
9229
|
const files = listHistoryFiles(dir, historySessionId);
|
|
9078
9230
|
const allMessages = [];
|
|
9079
9231
|
const seen = /* @__PURE__ */ new Set();
|
|
9080
9232
|
for (const file of files) {
|
|
9081
|
-
const filePath =
|
|
9233
|
+
const filePath = path11.join(dir, file);
|
|
9082
9234
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
9083
9235
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
9084
9236
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -9102,7 +9254,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
9102
9254
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
9103
9255
|
try {
|
|
9104
9256
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9105
|
-
const dir =
|
|
9257
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9106
9258
|
if (!fs3.existsSync(dir)) {
|
|
9107
9259
|
savedHistorySessionCache.delete(sanitized);
|
|
9108
9260
|
return { sessions: [], hasMore: false };
|
|
@@ -9163,11 +9315,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
9163
9315
|
}
|
|
9164
9316
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
9165
9317
|
try {
|
|
9166
|
-
const dir =
|
|
9318
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9167
9319
|
if (!fs3.existsSync(dir)) return null;
|
|
9168
9320
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
9169
9321
|
for (const file of files) {
|
|
9170
|
-
const lines = fs3.readFileSync(
|
|
9322
|
+
const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
9171
9323
|
for (const line of lines) {
|
|
9172
9324
|
try {
|
|
9173
9325
|
const parsed = JSON.parse(line);
|
|
@@ -9187,16 +9339,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
9187
9339
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
9188
9340
|
if (records.length === 0) return false;
|
|
9189
9341
|
try {
|
|
9190
|
-
const dir =
|
|
9342
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9191
9343
|
fs3.mkdirSync(dir, { recursive: true });
|
|
9192
9344
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
9193
9345
|
for (const file of fs3.readdirSync(dir)) {
|
|
9194
9346
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
9195
|
-
fs3.unlinkSync(
|
|
9347
|
+
fs3.unlinkSync(path11.join(dir, file));
|
|
9196
9348
|
}
|
|
9197
9349
|
}
|
|
9198
9350
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
9199
|
-
const filePath =
|
|
9351
|
+
const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
9200
9352
|
fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
9201
9353
|
`, "utf-8");
|
|
9202
9354
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -11191,6 +11343,14 @@ function getActiveChatOptions(profile) {
|
|
|
11191
11343
|
if (profile === "full") return {};
|
|
11192
11344
|
return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
|
|
11193
11345
|
}
|
|
11346
|
+
function resolveSessionStatus(activeChat, providerStatus) {
|
|
11347
|
+
const chatStatus = normalizeManagedStatus(activeChat?.status, { activeModal: activeChat?.activeModal || null });
|
|
11348
|
+
const topLevelStatus = normalizeManagedStatus(providerStatus, { activeModal: activeChat?.activeModal || null });
|
|
11349
|
+
if (chatStatus === "waiting_approval" || topLevelStatus === "waiting_approval") return "waiting_approval";
|
|
11350
|
+
if (chatStatus === "generating" || topLevelStatus === "generating") return "generating";
|
|
11351
|
+
if (topLevelStatus !== "idle") return topLevelStatus;
|
|
11352
|
+
return chatStatus;
|
|
11353
|
+
}
|
|
11194
11354
|
function shouldIncludeSessionControls(profile) {
|
|
11195
11355
|
return profile !== "live";
|
|
11196
11356
|
}
|
|
@@ -11269,9 +11429,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
11269
11429
|
providerName: state.name,
|
|
11270
11430
|
kind: "workspace",
|
|
11271
11431
|
transport: "cdp-page",
|
|
11272
|
-
status:
|
|
11273
|
-
activeModal: activeChat?.activeModal || null
|
|
11274
|
-
}),
|
|
11432
|
+
status: resolveSessionStatus(activeChat, state.status),
|
|
11275
11433
|
title,
|
|
11276
11434
|
workspace,
|
|
11277
11435
|
...git && { git },
|
|
@@ -11306,9 +11464,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
11306
11464
|
providerSessionId: ext.providerSessionId,
|
|
11307
11465
|
kind: "agent",
|
|
11308
11466
|
transport: "cdp-webview",
|
|
11309
|
-
status:
|
|
11310
|
-
activeModal: activeChat?.activeModal || null
|
|
11311
|
-
}),
|
|
11467
|
+
status: resolveSessionStatus(activeChat, ext.status),
|
|
11312
11468
|
title: activeChat?.title || ext.name,
|
|
11313
11469
|
workspace,
|
|
11314
11470
|
...git && { git },
|
|
@@ -11358,9 +11514,7 @@ function buildCliSession(state, options) {
|
|
|
11358
11514
|
providerSessionId: state.providerSessionId,
|
|
11359
11515
|
kind: "agent",
|
|
11360
11516
|
transport: "pty",
|
|
11361
|
-
status:
|
|
11362
|
-
activeModal: activeChat?.activeModal || null
|
|
11363
|
-
}),
|
|
11517
|
+
status: resolveSessionStatus(activeChat, state.status),
|
|
11364
11518
|
title: activeChat?.title || state.name,
|
|
11365
11519
|
workspace,
|
|
11366
11520
|
...git && { git },
|
|
@@ -11408,9 +11562,7 @@ function buildAcpSession(state, options) {
|
|
|
11408
11562
|
providerName: state.name,
|
|
11409
11563
|
kind: "agent",
|
|
11410
11564
|
transport: "acp",
|
|
11411
|
-
status:
|
|
11412
|
-
activeModal: activeChat?.activeModal || null
|
|
11413
|
-
}),
|
|
11565
|
+
status: resolveSessionStatus(activeChat, state.status),
|
|
11414
11566
|
title: activeChat?.title || state.name,
|
|
11415
11567
|
workspace,
|
|
11416
11568
|
...git && { git },
|
|
@@ -11533,7 +11685,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
11533
11685
|
// src/commands/chat-commands.ts
|
|
11534
11686
|
var fs4 = __toESM(require("fs"));
|
|
11535
11687
|
var os6 = __toESM(require("os"));
|
|
11536
|
-
var
|
|
11688
|
+
var path12 = __toESM(require("path"));
|
|
11537
11689
|
var import_node_crypto = require("crypto");
|
|
11538
11690
|
|
|
11539
11691
|
// src/providers/provider-input-support.ts
|
|
@@ -12044,7 +12196,7 @@ function buildDebugBundleText(bundle) {
|
|
|
12044
12196
|
}
|
|
12045
12197
|
function getChatDebugBundleDir() {
|
|
12046
12198
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
12047
|
-
return override ||
|
|
12199
|
+
return override || path12.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
12048
12200
|
}
|
|
12049
12201
|
function safeBundleIdSegment(value, fallback) {
|
|
12050
12202
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -12077,7 +12229,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
12077
12229
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
12078
12230
|
const dir = getChatDebugBundleDir();
|
|
12079
12231
|
fs4.mkdirSync(dir, { recursive: true });
|
|
12080
|
-
const savedPath =
|
|
12232
|
+
const savedPath = path12.join(dir, `${bundleId}.json`);
|
|
12081
12233
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
12082
12234
|
`;
|
|
12083
12235
|
fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -13221,7 +13373,7 @@ async function handleResolveAction(h, args) {
|
|
|
13221
13373
|
|
|
13222
13374
|
// src/commands/cdp-commands.ts
|
|
13223
13375
|
var fs5 = __toESM(require("fs"));
|
|
13224
|
-
var
|
|
13376
|
+
var path13 = __toESM(require("path"));
|
|
13225
13377
|
var os7 = __toESM(require("os"));
|
|
13226
13378
|
var KEY_TO_VK = {
|
|
13227
13379
|
Backspace: 8,
|
|
@@ -13478,25 +13630,25 @@ function resolveSafePath(requestedPath) {
|
|
|
13478
13630
|
const inputPath = rawPath || ".";
|
|
13479
13631
|
const home = os7.homedir();
|
|
13480
13632
|
if (inputPath.startsWith("~")) {
|
|
13481
|
-
return
|
|
13633
|
+
return path13.resolve(path13.join(home, inputPath.slice(1)));
|
|
13482
13634
|
}
|
|
13483
13635
|
if (process.platform === "win32") {
|
|
13484
13636
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
13485
|
-
if (
|
|
13486
|
-
return
|
|
13637
|
+
if (path13.win32.isAbsolute(normalized)) {
|
|
13638
|
+
return path13.win32.normalize(normalized);
|
|
13487
13639
|
}
|
|
13488
|
-
return
|
|
13640
|
+
return path13.win32.resolve(normalized);
|
|
13489
13641
|
}
|
|
13490
|
-
if (
|
|
13491
|
-
return
|
|
13642
|
+
if (path13.isAbsolute(inputPath)) {
|
|
13643
|
+
return path13.normalize(inputPath);
|
|
13492
13644
|
}
|
|
13493
|
-
return
|
|
13645
|
+
return path13.resolve(inputPath);
|
|
13494
13646
|
}
|
|
13495
13647
|
function listDirectoryEntriesSafe(dirPath) {
|
|
13496
13648
|
const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
|
|
13497
13649
|
const files = [];
|
|
13498
13650
|
for (const entry of entries) {
|
|
13499
|
-
const entryPath =
|
|
13651
|
+
const entryPath = path13.join(dirPath, entry.name);
|
|
13500
13652
|
try {
|
|
13501
13653
|
if (entry.isDirectory()) {
|
|
13502
13654
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -13550,7 +13702,7 @@ async function handleFileRead(h, args) {
|
|
|
13550
13702
|
async function handleFileWrite(h, args) {
|
|
13551
13703
|
try {
|
|
13552
13704
|
const filePath = resolveSafePath(args?.path);
|
|
13553
|
-
fs5.mkdirSync(
|
|
13705
|
+
fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
|
|
13554
13706
|
fs5.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
13555
13707
|
return { success: true, path: filePath };
|
|
13556
13708
|
} catch (e) {
|
|
@@ -14669,7 +14821,7 @@ var DaemonCommandHandler = class {
|
|
|
14669
14821
|
|
|
14670
14822
|
// src/commands/cli-manager.ts
|
|
14671
14823
|
var os13 = __toESM(require("os"));
|
|
14672
|
-
var
|
|
14824
|
+
var path17 = __toESM(require("path"));
|
|
14673
14825
|
var crypto4 = __toESM(require("crypto"));
|
|
14674
14826
|
var import_fs6 = require("fs");
|
|
14675
14827
|
var import_child_process6 = require("child_process");
|
|
@@ -14679,7 +14831,7 @@ init_config();
|
|
|
14679
14831
|
|
|
14680
14832
|
// src/providers/cli-provider-instance.ts
|
|
14681
14833
|
var os12 = __toESM(require("os"));
|
|
14682
|
-
var
|
|
14834
|
+
var path16 = __toESM(require("path"));
|
|
14683
14835
|
var crypto3 = __toESM(require("crypto"));
|
|
14684
14836
|
var fs6 = __toESM(require("fs"));
|
|
14685
14837
|
var import_node_module = require("module");
|
|
@@ -14738,7 +14890,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
14738
14890
|
var CachedDatabaseSync = null;
|
|
14739
14891
|
function getDatabaseSync() {
|
|
14740
14892
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
14741
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
14893
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path16.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
14742
14894
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
14743
14895
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
14744
14896
|
if (!CachedDatabaseSync) {
|
|
@@ -16804,11 +16956,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
16804
16956
|
// src/commands/cli-manager.ts
|
|
16805
16957
|
function isExplicitCommand(command) {
|
|
16806
16958
|
const trimmed = command.trim();
|
|
16807
|
-
return
|
|
16959
|
+
return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
16808
16960
|
}
|
|
16809
16961
|
function expandExecutable(command) {
|
|
16810
16962
|
const trimmed = command.trim();
|
|
16811
|
-
return trimmed.startsWith("~") ?
|
|
16963
|
+
return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
16812
16964
|
}
|
|
16813
16965
|
function commandExists(command) {
|
|
16814
16966
|
const trimmed = command.trim();
|
|
@@ -17089,7 +17241,7 @@ var DaemonCliManager = class {
|
|
|
17089
17241
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
17090
17242
|
const trimmed = (workingDir || "").trim();
|
|
17091
17243
|
if (!trimmed) throw new Error("working directory required");
|
|
17092
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
17244
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
|
|
17093
17245
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17094
17246
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
17095
17247
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -17590,11 +17742,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17590
17742
|
var import_child_process7 = require("child_process");
|
|
17591
17743
|
var net = __toESM(require("net"));
|
|
17592
17744
|
var os15 = __toESM(require("os"));
|
|
17593
|
-
var
|
|
17745
|
+
var path19 = __toESM(require("path"));
|
|
17594
17746
|
|
|
17595
17747
|
// src/providers/provider-loader.ts
|
|
17596
17748
|
var fs7 = __toESM(require("fs"));
|
|
17597
|
-
var
|
|
17749
|
+
var path18 = __toESM(require("path"));
|
|
17598
17750
|
var os14 = __toESM(require("os"));
|
|
17599
17751
|
var chokidar = __toESM(require("chokidar"));
|
|
17600
17752
|
init_logger();
|
|
@@ -17918,7 +18070,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17918
18070
|
try {
|
|
17919
18071
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
17920
18072
|
return ["ide", "extension", "cli", "acp"].some(
|
|
17921
|
-
(category) => fs7.existsSync(
|
|
18073
|
+
(category) => fs7.existsSync(path18.join(candidate, category))
|
|
17922
18074
|
);
|
|
17923
18075
|
} catch {
|
|
17924
18076
|
return false;
|
|
@@ -17926,20 +18078,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17926
18078
|
}
|
|
17927
18079
|
static hasProviderRootMarker(candidate) {
|
|
17928
18080
|
try {
|
|
17929
|
-
return fs7.existsSync(
|
|
18081
|
+
return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
17930
18082
|
} catch {
|
|
17931
18083
|
return false;
|
|
17932
18084
|
}
|
|
17933
18085
|
}
|
|
17934
18086
|
detectDefaultUserDir() {
|
|
17935
|
-
const fallback =
|
|
18087
|
+
const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17936
18088
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
17937
18089
|
const visited = /* @__PURE__ */ new Set();
|
|
17938
18090
|
for (const start of this.probeStarts) {
|
|
17939
|
-
let current =
|
|
18091
|
+
let current = path18.resolve(start);
|
|
17940
18092
|
while (!visited.has(current)) {
|
|
17941
18093
|
visited.add(current);
|
|
17942
|
-
const siblingCandidate =
|
|
18094
|
+
const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
17943
18095
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
17944
18096
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
17945
18097
|
if (envOptIn || hasMarker) {
|
|
@@ -17961,7 +18113,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17961
18113
|
return { path: siblingCandidate, source };
|
|
17962
18114
|
}
|
|
17963
18115
|
}
|
|
17964
|
-
const parent =
|
|
18116
|
+
const parent = path18.dirname(current);
|
|
17965
18117
|
if (parent === current) break;
|
|
17966
18118
|
current = parent;
|
|
17967
18119
|
}
|
|
@@ -17971,11 +18123,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17971
18123
|
constructor(options) {
|
|
17972
18124
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
17973
18125
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
17974
|
-
this.defaultProvidersDir =
|
|
18126
|
+
this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17975
18127
|
const detected = this.detectDefaultUserDir();
|
|
17976
18128
|
this.userDir = detected.path;
|
|
17977
18129
|
this.userDirSource = detected.source;
|
|
17978
|
-
this.upstreamDir =
|
|
18130
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
17979
18131
|
this.disableUpstream = false;
|
|
17980
18132
|
this.applySourceConfig({
|
|
17981
18133
|
userDir: options?.userDir,
|
|
@@ -18034,7 +18186,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18034
18186
|
this.userDir = detected.path;
|
|
18035
18187
|
this.userDirSource = detected.source;
|
|
18036
18188
|
}
|
|
18037
|
-
this.upstreamDir =
|
|
18189
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
18038
18190
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
18039
18191
|
if (this.explicitProviderDir) {
|
|
18040
18192
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -18048,7 +18200,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18048
18200
|
* Canonical provider directory shape for a given root.
|
|
18049
18201
|
*/
|
|
18050
18202
|
getProviderDir(root, category, type) {
|
|
18051
|
-
return
|
|
18203
|
+
return path18.join(root, category, type);
|
|
18052
18204
|
}
|
|
18053
18205
|
/**
|
|
18054
18206
|
* Canonical user override directory for a provider.
|
|
@@ -18075,7 +18227,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18075
18227
|
resolveProviderFile(type, ...segments) {
|
|
18076
18228
|
const dir = this.findProviderDirInternal(type);
|
|
18077
18229
|
if (!dir) return null;
|
|
18078
|
-
return
|
|
18230
|
+
return path18.join(dir, ...segments);
|
|
18079
18231
|
}
|
|
18080
18232
|
/**
|
|
18081
18233
|
* Load all providers (3-tier priority)
|
|
@@ -18114,7 +18266,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18114
18266
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
18115
18267
|
try {
|
|
18116
18268
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
18117
|
-
(d) => fs7.statSync(
|
|
18269
|
+
(d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
|
|
18118
18270
|
);
|
|
18119
18271
|
} catch {
|
|
18120
18272
|
return false;
|
|
@@ -18611,8 +18763,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18611
18763
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
18612
18764
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
18613
18765
|
if (providerDir) {
|
|
18614
|
-
const fullDir =
|
|
18615
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18766
|
+
const fullDir = path18.join(providerDir, entry.scriptDir);
|
|
18767
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18616
18768
|
}
|
|
18617
18769
|
matched = true;
|
|
18618
18770
|
}
|
|
@@ -18627,8 +18779,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18627
18779
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18628
18780
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
18629
18781
|
if (providerDir) {
|
|
18630
|
-
const fullDir =
|
|
18631
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18782
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18783
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18632
18784
|
}
|
|
18633
18785
|
}
|
|
18634
18786
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -18645,8 +18797,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18645
18797
|
resolved._resolvedScriptDir = dirOverride;
|
|
18646
18798
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
18647
18799
|
if (providerDir) {
|
|
18648
|
-
const fullDir =
|
|
18649
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18800
|
+
const fullDir = path18.join(providerDir, dirOverride);
|
|
18801
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18650
18802
|
}
|
|
18651
18803
|
}
|
|
18652
18804
|
} else if (override.scripts) {
|
|
@@ -18662,8 +18814,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18662
18814
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18663
18815
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
18664
18816
|
if (providerDir) {
|
|
18665
|
-
const fullDir =
|
|
18666
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18817
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18818
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18667
18819
|
}
|
|
18668
18820
|
}
|
|
18669
18821
|
}
|
|
@@ -18695,14 +18847,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18695
18847
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
18696
18848
|
return null;
|
|
18697
18849
|
}
|
|
18698
|
-
const dir =
|
|
18850
|
+
const dir = path18.join(providerDir, scriptDir);
|
|
18699
18851
|
if (!fs7.existsSync(dir)) {
|
|
18700
18852
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
18701
18853
|
return null;
|
|
18702
18854
|
}
|
|
18703
18855
|
const cached = this.scriptsCache.get(dir);
|
|
18704
18856
|
if (cached) return cached;
|
|
18705
|
-
const scriptsJs =
|
|
18857
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
18706
18858
|
if (fs7.existsSync(scriptsJs)) {
|
|
18707
18859
|
try {
|
|
18708
18860
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -18744,7 +18896,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18744
18896
|
return;
|
|
18745
18897
|
}
|
|
18746
18898
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
18747
|
-
this.log(`File changed: ${
|
|
18899
|
+
this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
|
|
18748
18900
|
this.reload();
|
|
18749
18901
|
}
|
|
18750
18902
|
};
|
|
@@ -18799,7 +18951,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18799
18951
|
}
|
|
18800
18952
|
const https = require("https");
|
|
18801
18953
|
const { execSync: execSync7 } = require("child_process");
|
|
18802
|
-
const metaPath =
|
|
18954
|
+
const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
18803
18955
|
let prevEtag = "";
|
|
18804
18956
|
let prevTimestamp = 0;
|
|
18805
18957
|
try {
|
|
@@ -18859,17 +19011,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18859
19011
|
return { updated: false };
|
|
18860
19012
|
}
|
|
18861
19013
|
this.log("Downloading latest providers from GitHub...");
|
|
18862
|
-
const tmpTar =
|
|
18863
|
-
const tmpExtract =
|
|
19014
|
+
const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
19015
|
+
const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
18864
19016
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
18865
19017
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
18866
19018
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
18867
19019
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
18868
19020
|
const rootDir = extracted.find(
|
|
18869
|
-
(d) => fs7.statSync(
|
|
19021
|
+
(d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
18870
19022
|
);
|
|
18871
19023
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
18872
|
-
const sourceDir =
|
|
19024
|
+
const sourceDir = path18.join(tmpExtract, rootDir);
|
|
18873
19025
|
const backupDir = this.upstreamDir + ".bak";
|
|
18874
19026
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
18875
19027
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -18944,8 +19096,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18944
19096
|
copyDirRecursive(src, dest) {
|
|
18945
19097
|
fs7.mkdirSync(dest, { recursive: true });
|
|
18946
19098
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
18947
|
-
const srcPath =
|
|
18948
|
-
const destPath =
|
|
19099
|
+
const srcPath = path18.join(src, entry.name);
|
|
19100
|
+
const destPath = path18.join(dest, entry.name);
|
|
18949
19101
|
if (entry.isDirectory()) {
|
|
18950
19102
|
this.copyDirRecursive(srcPath, destPath);
|
|
18951
19103
|
} else {
|
|
@@ -18956,7 +19108,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18956
19108
|
/** .meta.json save */
|
|
18957
19109
|
writeMeta(metaPath, etag, timestamp) {
|
|
18958
19110
|
try {
|
|
18959
|
-
fs7.mkdirSync(
|
|
19111
|
+
fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
|
|
18960
19112
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
18961
19113
|
etag,
|
|
18962
19114
|
timestamp,
|
|
@@ -18973,7 +19125,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18973
19125
|
const scan = (d) => {
|
|
18974
19126
|
try {
|
|
18975
19127
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
18976
|
-
if (entry.isDirectory()) scan(
|
|
19128
|
+
if (entry.isDirectory()) scan(path18.join(d, entry.name));
|
|
18977
19129
|
else if (entry.name === "provider.json") count++;
|
|
18978
19130
|
}
|
|
18979
19131
|
} catch {
|
|
@@ -19201,17 +19353,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19201
19353
|
for (const root of searchRoots) {
|
|
19202
19354
|
if (!fs7.existsSync(root)) continue;
|
|
19203
19355
|
const candidate = this.getProviderDir(root, cat, type);
|
|
19204
|
-
if (fs7.existsSync(
|
|
19205
|
-
const catDir =
|
|
19356
|
+
if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
|
|
19357
|
+
const catDir = path18.join(root, cat);
|
|
19206
19358
|
if (fs7.existsSync(catDir)) {
|
|
19207
19359
|
try {
|
|
19208
19360
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
19209
19361
|
if (!entry.isDirectory()) continue;
|
|
19210
|
-
const jsonPath =
|
|
19362
|
+
const jsonPath = path18.join(catDir, entry.name, "provider.json");
|
|
19211
19363
|
if (fs7.existsSync(jsonPath)) {
|
|
19212
19364
|
try {
|
|
19213
19365
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
19214
|
-
if (data.type === type) return
|
|
19366
|
+
if (data.type === type) return path18.join(catDir, entry.name);
|
|
19215
19367
|
} catch {
|
|
19216
19368
|
}
|
|
19217
19369
|
}
|
|
@@ -19228,7 +19380,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19228
19380
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
19229
19381
|
*/
|
|
19230
19382
|
buildScriptWrappersFromDir(dir) {
|
|
19231
|
-
const scriptsJs =
|
|
19383
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
19232
19384
|
if (fs7.existsSync(scriptsJs)) {
|
|
19233
19385
|
try {
|
|
19234
19386
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -19242,7 +19394,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19242
19394
|
for (const file of fs7.readdirSync(dir)) {
|
|
19243
19395
|
if (!file.endsWith(".js")) continue;
|
|
19244
19396
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
19245
|
-
const filePath =
|
|
19397
|
+
const filePath = path18.join(dir, file);
|
|
19246
19398
|
result[scriptName] = (...args) => {
|
|
19247
19399
|
try {
|
|
19248
19400
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -19302,7 +19454,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19302
19454
|
}
|
|
19303
19455
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
19304
19456
|
if (hasJson) {
|
|
19305
|
-
const jsonPath =
|
|
19457
|
+
const jsonPath = path18.join(d, "provider.json");
|
|
19306
19458
|
try {
|
|
19307
19459
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
19308
19460
|
const mod = JSON.parse(raw);
|
|
@@ -19323,7 +19475,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19323
19475
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
19324
19476
|
} else {
|
|
19325
19477
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
19326
|
-
const scriptsPath =
|
|
19478
|
+
const scriptsPath = path18.join(d, "scripts.js");
|
|
19327
19479
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
19328
19480
|
try {
|
|
19329
19481
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -19349,7 +19501,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19349
19501
|
if (!entry.isDirectory()) continue;
|
|
19350
19502
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
19351
19503
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
19352
|
-
scan(
|
|
19504
|
+
scan(path18.join(d, entry.name));
|
|
19353
19505
|
}
|
|
19354
19506
|
}
|
|
19355
19507
|
};
|
|
@@ -19674,8 +19826,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
19674
19826
|
const appNameMap = getMacAppIdentifiers();
|
|
19675
19827
|
const appName = appNameMap[ideId];
|
|
19676
19828
|
if (appName) {
|
|
19677
|
-
const storagePath =
|
|
19678
|
-
process.env.APPDATA ||
|
|
19829
|
+
const storagePath = path19.join(
|
|
19830
|
+
process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
|
|
19679
19831
|
appName,
|
|
19680
19832
|
"storage.json"
|
|
19681
19833
|
);
|
|
@@ -19864,9 +20016,9 @@ init_logger();
|
|
|
19864
20016
|
|
|
19865
20017
|
// src/logging/command-log.ts
|
|
19866
20018
|
var fs8 = __toESM(require("fs"));
|
|
19867
|
-
var
|
|
20019
|
+
var path20 = __toESM(require("path"));
|
|
19868
20020
|
var os16 = __toESM(require("os"));
|
|
19869
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
20021
|
+
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
20022
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
19871
20023
|
var MAX_DAYS = 7;
|
|
19872
20024
|
try {
|
|
@@ -19904,13 +20056,13 @@ function getDateStr2() {
|
|
|
19904
20056
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
19905
20057
|
}
|
|
19906
20058
|
var currentDate2 = getDateStr2();
|
|
19907
|
-
var currentFile =
|
|
20059
|
+
var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19908
20060
|
var writeCount2 = 0;
|
|
19909
20061
|
function checkRotation() {
|
|
19910
20062
|
const today = getDateStr2();
|
|
19911
20063
|
if (today !== currentDate2) {
|
|
19912
20064
|
currentDate2 = today;
|
|
19913
|
-
currentFile =
|
|
20065
|
+
currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19914
20066
|
cleanOldFiles();
|
|
19915
20067
|
}
|
|
19916
20068
|
}
|
|
@@ -19924,7 +20076,7 @@ function cleanOldFiles() {
|
|
|
19924
20076
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
19925
20077
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
19926
20078
|
try {
|
|
19927
|
-
fs8.unlinkSync(
|
|
20079
|
+
fs8.unlinkSync(path20.join(LOG_DIR2, file));
|
|
19928
20080
|
} catch {
|
|
19929
20081
|
}
|
|
19930
20082
|
}
|
|
@@ -20010,7 +20162,7 @@ cleanOldFiles();
|
|
|
20010
20162
|
init_logger();
|
|
20011
20163
|
|
|
20012
20164
|
// src/commands/mesh-coordinator.ts
|
|
20013
|
-
var
|
|
20165
|
+
var import_node_fs3 = require("fs");
|
|
20014
20166
|
var import_node_module2 = require("module");
|
|
20015
20167
|
var import_node_path = require("path");
|
|
20016
20168
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
@@ -20033,8 +20185,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20033
20185
|
}
|
|
20034
20186
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
20035
20187
|
if (mcpConfig.mode === "auto_import") {
|
|
20036
|
-
const
|
|
20037
|
-
if (!
|
|
20188
|
+
const path27 = mcpConfig.path?.trim();
|
|
20189
|
+
if (!path27) {
|
|
20038
20190
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
20039
20191
|
}
|
|
20040
20192
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -20051,7 +20203,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20051
20203
|
return {
|
|
20052
20204
|
kind: "auto_import",
|
|
20053
20205
|
serverName,
|
|
20054
|
-
configPath: (0, import_node_path.join)(workspace,
|
|
20206
|
+
configPath: (0, import_node_path.join)(workspace, path27),
|
|
20055
20207
|
configFormat: mcpConfig.format,
|
|
20056
20208
|
mcpServer
|
|
20057
20209
|
};
|
|
@@ -20090,7 +20242,7 @@ function resolveAdhdevMcpServerLaunch(options) {
|
|
|
20090
20242
|
if (!entryPath) return null;
|
|
20091
20243
|
return {
|
|
20092
20244
|
command: options.nodeExecutable?.trim() || process.execPath,
|
|
20093
|
-
args: [entryPath, "--repo-mesh", options.meshId]
|
|
20245
|
+
args: [entryPath, "--mode", "ipc", "--repo-mesh", options.meshId]
|
|
20094
20246
|
};
|
|
20095
20247
|
}
|
|
20096
20248
|
function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
@@ -20128,8 +20280,8 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
20128
20280
|
}
|
|
20129
20281
|
function normalizeExistingPath(filePath) {
|
|
20130
20282
|
try {
|
|
20131
|
-
if (!(0,
|
|
20132
|
-
return
|
|
20283
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) return null;
|
|
20284
|
+
return import_node_fs3.realpathSync.native(filePath);
|
|
20133
20285
|
} catch {
|
|
20134
20286
|
return null;
|
|
20135
20287
|
}
|
|
@@ -20453,13 +20605,13 @@ var import_child_process8 = require("child_process");
|
|
|
20453
20605
|
var import_child_process9 = require("child_process");
|
|
20454
20606
|
var fs9 = __toESM(require("fs"));
|
|
20455
20607
|
var os18 = __toESM(require("os"));
|
|
20456
|
-
var
|
|
20608
|
+
var path21 = __toESM(require("path"));
|
|
20457
20609
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
20458
20610
|
function getUpgradeLogPath() {
|
|
20459
20611
|
const home = os18.homedir();
|
|
20460
|
-
const dir =
|
|
20612
|
+
const dir = path21.join(home, ".adhdev");
|
|
20461
20613
|
fs9.mkdirSync(dir, { recursive: true });
|
|
20462
|
-
return
|
|
20614
|
+
return path21.join(dir, "daemon-upgrade.log");
|
|
20463
20615
|
}
|
|
20464
20616
|
function appendUpgradeLog(message) {
|
|
20465
20617
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -20470,14 +20622,14 @@ function appendUpgradeLog(message) {
|
|
|
20470
20622
|
}
|
|
20471
20623
|
}
|
|
20472
20624
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
20473
|
-
const binDir =
|
|
20625
|
+
const binDir = path21.dirname(nodeExecutable);
|
|
20474
20626
|
if (platform10 === "win32") {
|
|
20475
|
-
const npmCliPath =
|
|
20627
|
+
const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
20476
20628
|
if (fs9.existsSync(npmCliPath)) {
|
|
20477
20629
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20478
20630
|
}
|
|
20479
20631
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
20480
|
-
const candidatePath =
|
|
20632
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20481
20633
|
if (fs9.existsSync(candidatePath)) {
|
|
20482
20634
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20483
20635
|
}
|
|
@@ -20485,7 +20637,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
20485
20637
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20486
20638
|
}
|
|
20487
20639
|
for (const candidate of ["npm"]) {
|
|
20488
|
-
const candidatePath =
|
|
20640
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20489
20641
|
if (fs9.existsSync(candidatePath)) {
|
|
20490
20642
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20491
20643
|
}
|
|
@@ -20502,13 +20654,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20502
20654
|
let currentDir = resolvedPath;
|
|
20503
20655
|
try {
|
|
20504
20656
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
20505
|
-
currentDir =
|
|
20657
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20506
20658
|
}
|
|
20507
20659
|
} catch {
|
|
20508
|
-
currentDir =
|
|
20660
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20509
20661
|
}
|
|
20510
20662
|
while (true) {
|
|
20511
|
-
const packageJsonPath =
|
|
20663
|
+
const packageJsonPath = path21.join(currentDir, "package.json");
|
|
20512
20664
|
try {
|
|
20513
20665
|
if (fs9.existsSync(packageJsonPath)) {
|
|
20514
20666
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -20519,7 +20671,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20519
20671
|
}
|
|
20520
20672
|
} catch {
|
|
20521
20673
|
}
|
|
20522
|
-
const parentDir =
|
|
20674
|
+
const parentDir = path21.dirname(currentDir);
|
|
20523
20675
|
if (parentDir === currentDir) {
|
|
20524
20676
|
return null;
|
|
20525
20677
|
}
|
|
@@ -20527,13 +20679,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20527
20679
|
}
|
|
20528
20680
|
}
|
|
20529
20681
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
20530
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
20531
|
-
if (
|
|
20682
|
+
const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
|
|
20683
|
+
if (path21.basename(nodeModulesDir) !== "node_modules") {
|
|
20532
20684
|
return null;
|
|
20533
20685
|
}
|
|
20534
|
-
const maybeLibDir =
|
|
20535
|
-
if (
|
|
20536
|
-
return
|
|
20686
|
+
const maybeLibDir = path21.dirname(nodeModulesDir);
|
|
20687
|
+
if (path21.basename(maybeLibDir) === "lib") {
|
|
20688
|
+
return path21.dirname(maybeLibDir);
|
|
20537
20689
|
}
|
|
20538
20690
|
return maybeLibDir;
|
|
20539
20691
|
}
|
|
@@ -20648,7 +20800,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
20648
20800
|
}
|
|
20649
20801
|
}
|
|
20650
20802
|
function stopSessionHostProcesses(appName) {
|
|
20651
|
-
const pidFile =
|
|
20803
|
+
const pidFile = path21.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
20652
20804
|
try {
|
|
20653
20805
|
if (fs9.existsSync(pidFile)) {
|
|
20654
20806
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -20665,7 +20817,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
20665
20817
|
}
|
|
20666
20818
|
}
|
|
20667
20819
|
function removeDaemonPidFile() {
|
|
20668
|
-
const pidFile =
|
|
20820
|
+
const pidFile = path21.join(os18.homedir(), ".adhdev", "daemon.pid");
|
|
20669
20821
|
try {
|
|
20670
20822
|
fs9.unlinkSync(pidFile);
|
|
20671
20823
|
} catch {
|
|
@@ -20676,7 +20828,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20676
20828
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20677
20829
|
if (!npmRoot) return;
|
|
20678
20830
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20679
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
20831
|
+
const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
|
|
20680
20832
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
20681
20833
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
20682
20834
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -20684,25 +20836,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20684
20836
|
}
|
|
20685
20837
|
if (pkgName.startsWith("@")) {
|
|
20686
20838
|
const [scope, name] = pkgName.split("/");
|
|
20687
|
-
const scopeDir =
|
|
20839
|
+
const scopeDir = path21.join(npmRoot, scope);
|
|
20688
20840
|
if (!fs9.existsSync(scopeDir)) return;
|
|
20689
20841
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
20690
20842
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
20691
|
-
fs9.rmSync(
|
|
20692
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
20843
|
+
fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
|
|
20844
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
|
|
20693
20845
|
}
|
|
20694
20846
|
} else {
|
|
20695
20847
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
20696
20848
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
20697
|
-
fs9.rmSync(
|
|
20698
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
20849
|
+
fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
|
|
20850
|
+
appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
|
|
20699
20851
|
}
|
|
20700
20852
|
}
|
|
20701
20853
|
if (fs9.existsSync(binDir)) {
|
|
20702
20854
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
20703
20855
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
20704
|
-
fs9.rmSync(
|
|
20705
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
20856
|
+
fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
|
|
20857
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
|
|
20706
20858
|
}
|
|
20707
20859
|
}
|
|
20708
20860
|
}
|
|
@@ -20789,6 +20941,10 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
20789
20941
|
// src/commands/router.ts
|
|
20790
20942
|
var fs10 = __toESM(require("fs"));
|
|
20791
20943
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
20944
|
+
var CHANNEL_SERVER_URL = {
|
|
20945
|
+
stable: "https://api.adhf.dev",
|
|
20946
|
+
preview: "https://api-preview.adhf.dev"
|
|
20947
|
+
};
|
|
20792
20948
|
function normalizeReleaseChannel(value) {
|
|
20793
20949
|
if (typeof value !== "string") return null;
|
|
20794
20950
|
const normalized = value.trim().toLowerCase();
|
|
@@ -20897,6 +21053,40 @@ var DaemonCommandRouter = class {
|
|
|
20897
21053
|
constructor(deps) {
|
|
20898
21054
|
this.deps = deps;
|
|
20899
21055
|
}
|
|
21056
|
+
getCachedInlineMesh(meshId, inlineMesh) {
|
|
21057
|
+
if (inlineMesh && typeof inlineMesh === "object") {
|
|
21058
|
+
this.inlineMeshCache.set(meshId, inlineMesh);
|
|
21059
|
+
return inlineMesh;
|
|
21060
|
+
}
|
|
21061
|
+
return this.inlineMeshCache.get(meshId);
|
|
21062
|
+
}
|
|
21063
|
+
async getMeshForCommand(meshId, inlineMesh) {
|
|
21064
|
+
try {
|
|
21065
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21066
|
+
const mesh = getMesh3(meshId);
|
|
21067
|
+
if (mesh) return { mesh, inline: false };
|
|
21068
|
+
} catch {
|
|
21069
|
+
}
|
|
21070
|
+
const cached = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
21071
|
+
return cached ? { mesh: cached, inline: true } : null;
|
|
21072
|
+
}
|
|
21073
|
+
updateInlineMeshNode(meshId, mesh, node) {
|
|
21074
|
+
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
21075
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
|
|
21076
|
+
if (idx >= 0) mesh.nodes[idx] = node;
|
|
21077
|
+
else mesh.nodes.push(node);
|
|
21078
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21079
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21080
|
+
}
|
|
21081
|
+
removeInlineMeshNode(meshId, mesh, nodeId) {
|
|
21082
|
+
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
21083
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
|
|
21084
|
+
if (idx === -1) return false;
|
|
21085
|
+
mesh.nodes.splice(idx, 1);
|
|
21086
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21087
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21088
|
+
return true;
|
|
21089
|
+
}
|
|
20900
21090
|
async traceSessionHostAction(action, args, run, summarizeResult) {
|
|
20901
21091
|
const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
|
|
20902
21092
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
|
|
@@ -21485,6 +21675,7 @@ var DaemonCommandRouter = class {
|
|
|
21485
21675
|
const npmTag = CHANNEL_NPM_TAG[channel];
|
|
21486
21676
|
const latest = String(execNpmCommandSync(["view", `${pkgName}@${npmTag}`, "version"], { encoding: "utf-8", timeout: 1e4 }, npmSurface)).trim();
|
|
21487
21677
|
LOG.info("Upgrade", `Latest ${pkgName}@${npmTag}: v${latest}`);
|
|
21678
|
+
updateConfig({ updateChannel: channel, serverUrl: CHANNEL_SERVER_URL[channel] });
|
|
21488
21679
|
let currentInstalled = null;
|
|
21489
21680
|
try {
|
|
21490
21681
|
const currentJson = String(execNpmCommandSync(["ls", "-g", pkgName, "--depth=0", "--json"], {
|
|
@@ -21595,13 +21786,94 @@ var DaemonCommandRouter = class {
|
|
|
21595
21786
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
21596
21787
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
21597
21788
|
try {
|
|
21598
|
-
const
|
|
21599
|
-
const
|
|
21789
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21790
|
+
const mesh = meshRecord?.mesh;
|
|
21791
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
21792
|
+
if (node?.isLocalWorktree && node.workspace) {
|
|
21793
|
+
try {
|
|
21794
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
21795
|
+
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
21796
|
+
if (repoRoot) {
|
|
21797
|
+
const { removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21798
|
+
await removeWorktree2(repoRoot, node.workspace);
|
|
21799
|
+
}
|
|
21800
|
+
} catch (e) {
|
|
21801
|
+
LOG.warn("MeshNode", `Worktree cleanup failed for ${nodeId}: ${e.message}`);
|
|
21802
|
+
}
|
|
21803
|
+
}
|
|
21804
|
+
let removed = false;
|
|
21805
|
+
if (meshRecord?.inline) {
|
|
21806
|
+
removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
|
|
21807
|
+
} else {
|
|
21808
|
+
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21809
|
+
removed = removeNode3(meshId, nodeId);
|
|
21810
|
+
}
|
|
21600
21811
|
return { success: true, removed };
|
|
21601
21812
|
} catch (e) {
|
|
21602
21813
|
return { success: false, error: e.message };
|
|
21603
21814
|
}
|
|
21604
21815
|
}
|
|
21816
|
+
case "clone_mesh_node": {
|
|
21817
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
21818
|
+
const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
|
|
21819
|
+
const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
|
|
21820
|
+
const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
|
|
21821
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
21822
|
+
if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
|
|
21823
|
+
if (!branch) return { success: false, error: "branch required" };
|
|
21824
|
+
try {
|
|
21825
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21826
|
+
const mesh = meshRecord?.mesh;
|
|
21827
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
21828
|
+
const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
|
|
21829
|
+
if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
|
|
21830
|
+
const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
|
|
21831
|
+
const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21832
|
+
const result = await createWorktree2({
|
|
21833
|
+
repoRoot,
|
|
21834
|
+
branch,
|
|
21835
|
+
baseBranch,
|
|
21836
|
+
meshName: mesh.name
|
|
21837
|
+
});
|
|
21838
|
+
let node;
|
|
21839
|
+
if (meshRecord.inline) {
|
|
21840
|
+
const { randomUUID: randomUUID8 } = await import("crypto");
|
|
21841
|
+
node = {
|
|
21842
|
+
id: `node_${randomUUID8().replace(/-/g, "")}`,
|
|
21843
|
+
workspace: result.worktreePath,
|
|
21844
|
+
repoRoot: result.worktreePath,
|
|
21845
|
+
daemonId: sourceNode.daemonId,
|
|
21846
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21847
|
+
policy: { ...sourceNode.policy || {} },
|
|
21848
|
+
isLocalWorktree: true,
|
|
21849
|
+
worktreeBranch: result.branch,
|
|
21850
|
+
clonedFromNodeId: sourceNodeId
|
|
21851
|
+
};
|
|
21852
|
+
this.updateInlineMeshNode(meshId, mesh, node);
|
|
21853
|
+
} else {
|
|
21854
|
+
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21855
|
+
node = addNode3(meshId, {
|
|
21856
|
+
workspace: result.worktreePath,
|
|
21857
|
+
repoRoot: result.worktreePath,
|
|
21858
|
+
daemonId: sourceNode.daemonId,
|
|
21859
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21860
|
+
isLocalWorktree: true,
|
|
21861
|
+
worktreeBranch: result.branch,
|
|
21862
|
+
clonedFromNodeId: sourceNodeId,
|
|
21863
|
+
policy: { ...sourceNode.policy || {} }
|
|
21864
|
+
});
|
|
21865
|
+
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
21866
|
+
}
|
|
21867
|
+
return {
|
|
21868
|
+
success: true,
|
|
21869
|
+
node,
|
|
21870
|
+
worktreePath: result.worktreePath,
|
|
21871
|
+
branch: result.branch
|
|
21872
|
+
};
|
|
21873
|
+
} catch (e) {
|
|
21874
|
+
return { success: false, error: e.message };
|
|
21875
|
+
}
|
|
21876
|
+
}
|
|
21605
21877
|
// ─── Mesh Coordinator Launch ───
|
|
21606
21878
|
case "launch_mesh_coordinator": {
|
|
21607
21879
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
@@ -21670,9 +21942,24 @@ var DaemonCommandRouter = class {
|
|
|
21670
21942
|
workspace
|
|
21671
21943
|
};
|
|
21672
21944
|
}
|
|
21673
|
-
|
|
21945
|
+
let systemPrompt = "";
|
|
21946
|
+
try {
|
|
21947
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
21948
|
+
} catch (error) {
|
|
21949
|
+
const message = error?.message || String(error);
|
|
21950
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
21951
|
+
return {
|
|
21952
|
+
success: false,
|
|
21953
|
+
code: "mesh_coordinator_prompt_failed",
|
|
21954
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
21955
|
+
meshId,
|
|
21956
|
+
cliType,
|
|
21957
|
+
workspace
|
|
21958
|
+
};
|
|
21959
|
+
}
|
|
21960
|
+
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3 } = await import("fs");
|
|
21674
21961
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
21675
|
-
const hadExistingMcpConfig =
|
|
21962
|
+
const hadExistingMcpConfig = existsSync23(mcpConfigPath);
|
|
21676
21963
|
let existingMcpConfig = {};
|
|
21677
21964
|
if (hadExistingMcpConfig) {
|
|
21678
21965
|
try {
|
|
@@ -21687,7 +21974,8 @@ var DaemonCommandRouter = class {
|
|
|
21687
21974
|
};
|
|
21688
21975
|
if (args?.inlineMesh) {
|
|
21689
21976
|
mcpServerEntry.env = {
|
|
21690
|
-
ADHDEV_INLINE_MESH: JSON.stringify(mesh)
|
|
21977
|
+
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
21978
|
+
ADHDEV_MCP_TRANSPORT: "ipc"
|
|
21691
21979
|
};
|
|
21692
21980
|
}
|
|
21693
21981
|
const mcpConfig = {
|
|
@@ -21699,12 +21987,6 @@ var DaemonCommandRouter = class {
|
|
|
21699
21987
|
};
|
|
21700
21988
|
writeFileSync12(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
|
|
21701
21989
|
LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
21702
|
-
let systemPrompt = "";
|
|
21703
|
-
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).`;
|
|
21707
|
-
}
|
|
21708
21990
|
const cliArgs = [];
|
|
21709
21991
|
if (systemPrompt) {
|
|
21710
21992
|
cliArgs.push("--append-system-prompt", systemPrompt);
|
|
@@ -23376,11 +23658,11 @@ var ProviderInstanceManager = class {
|
|
|
23376
23658
|
|
|
23377
23659
|
// src/providers/version-archive.ts
|
|
23378
23660
|
var fs11 = __toESM(require("fs"));
|
|
23379
|
-
var
|
|
23661
|
+
var path22 = __toESM(require("path"));
|
|
23380
23662
|
var os19 = __toESM(require("os"));
|
|
23381
23663
|
var import_child_process10 = require("child_process");
|
|
23382
23664
|
var import_os3 = require("os");
|
|
23383
|
-
var ARCHIVE_PATH =
|
|
23665
|
+
var ARCHIVE_PATH = path22.join(os19.homedir(), ".adhdev", "version-history.json");
|
|
23384
23666
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
23385
23667
|
var VersionArchive = class {
|
|
23386
23668
|
history = {};
|
|
@@ -23427,7 +23709,7 @@ var VersionArchive = class {
|
|
|
23427
23709
|
}
|
|
23428
23710
|
save() {
|
|
23429
23711
|
try {
|
|
23430
|
-
fs11.mkdirSync(
|
|
23712
|
+
fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
|
|
23431
23713
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
23432
23714
|
} catch {
|
|
23433
23715
|
}
|
|
@@ -23484,7 +23766,7 @@ function checkPathExists2(paths) {
|
|
|
23484
23766
|
for (const p of paths) {
|
|
23485
23767
|
if (p.includes("*")) {
|
|
23486
23768
|
const home = os19.homedir();
|
|
23487
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
23769
|
+
const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
|
|
23488
23770
|
if (fs11.existsSync(resolved)) return resolved;
|
|
23489
23771
|
} else {
|
|
23490
23772
|
if (fs11.existsSync(p)) return p;
|
|
@@ -23494,7 +23776,7 @@ function checkPathExists2(paths) {
|
|
|
23494
23776
|
}
|
|
23495
23777
|
function getMacAppVersion(appPath) {
|
|
23496
23778
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
23497
|
-
const plistPath =
|
|
23779
|
+
const plistPath = path22.join(appPath, "Contents", "Info.plist");
|
|
23498
23780
|
if (!fs11.existsSync(plistPath)) return null;
|
|
23499
23781
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
23500
23782
|
return raw || null;
|
|
@@ -23520,7 +23802,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23520
23802
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
23521
23803
|
let resolvedBin = cliBin;
|
|
23522
23804
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
23523
|
-
const bundled =
|
|
23805
|
+
const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
23524
23806
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
23525
23807
|
}
|
|
23526
23808
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -23561,7 +23843,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23561
23843
|
// src/daemon/dev-server.ts
|
|
23562
23844
|
var http2 = __toESM(require("http"));
|
|
23563
23845
|
var fs15 = __toESM(require("fs"));
|
|
23564
|
-
var
|
|
23846
|
+
var path26 = __toESM(require("path"));
|
|
23565
23847
|
init_config();
|
|
23566
23848
|
|
|
23567
23849
|
// src/daemon/scaffold-template.ts
|
|
@@ -23912,7 +24194,7 @@ init_logger();
|
|
|
23912
24194
|
|
|
23913
24195
|
// src/daemon/dev-cdp-handlers.ts
|
|
23914
24196
|
var fs12 = __toESM(require("fs"));
|
|
23915
|
-
var
|
|
24197
|
+
var path23 = __toESM(require("path"));
|
|
23916
24198
|
init_logger();
|
|
23917
24199
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
23918
24200
|
const body = await ctx.readBody(req);
|
|
@@ -24091,17 +24373,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
24091
24373
|
return;
|
|
24092
24374
|
}
|
|
24093
24375
|
let scriptsPath = "";
|
|
24094
|
-
const directScripts =
|
|
24376
|
+
const directScripts = path23.join(dir, "scripts.js");
|
|
24095
24377
|
if (fs12.existsSync(directScripts)) {
|
|
24096
24378
|
scriptsPath = directScripts;
|
|
24097
24379
|
} else {
|
|
24098
|
-
const scriptsDir =
|
|
24380
|
+
const scriptsDir = path23.join(dir, "scripts");
|
|
24099
24381
|
if (fs12.existsSync(scriptsDir)) {
|
|
24100
24382
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
24101
|
-
return fs12.statSync(
|
|
24383
|
+
return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
|
|
24102
24384
|
}).sort().reverse();
|
|
24103
24385
|
for (const ver of versions) {
|
|
24104
|
-
const p =
|
|
24386
|
+
const p = path23.join(scriptsDir, ver, "scripts.js");
|
|
24105
24387
|
if (fs12.existsSync(p)) {
|
|
24106
24388
|
scriptsPath = p;
|
|
24107
24389
|
break;
|
|
@@ -24930,7 +25212,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
24930
25212
|
|
|
24931
25213
|
// src/daemon/dev-cli-debug.ts
|
|
24932
25214
|
var fs13 = __toESM(require("fs"));
|
|
24933
|
-
var
|
|
25215
|
+
var path24 = __toESM(require("path"));
|
|
24934
25216
|
function slugifyFixtureName(value) {
|
|
24935
25217
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24936
25218
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -24940,11 +25222,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
24940
25222
|
if (!providerDir) {
|
|
24941
25223
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
24942
25224
|
}
|
|
24943
|
-
return
|
|
25225
|
+
return path24.join(providerDir, "fixtures");
|
|
24944
25226
|
}
|
|
24945
25227
|
function readCliFixture(ctx, type, name) {
|
|
24946
25228
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
24947
|
-
const filePath =
|
|
25229
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
24948
25230
|
if (!fs13.existsSync(filePath)) {
|
|
24949
25231
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
24950
25232
|
}
|
|
@@ -25711,7 +25993,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
25711
25993
|
},
|
|
25712
25994
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
25713
25995
|
};
|
|
25714
|
-
const filePath =
|
|
25996
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
25715
25997
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
25716
25998
|
ctx.json(res, 200, {
|
|
25717
25999
|
saved: true,
|
|
@@ -25735,7 +26017,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
25735
26017
|
return;
|
|
25736
26018
|
}
|
|
25737
26019
|
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 =
|
|
26020
|
+
const fullPath = path24.join(fixtureDir, file);
|
|
25739
26021
|
try {
|
|
25740
26022
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
25741
26023
|
return {
|
|
@@ -25871,7 +26153,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
25871
26153
|
|
|
25872
26154
|
// src/daemon/dev-auto-implement.ts
|
|
25873
26155
|
var fs14 = __toESM(require("fs"));
|
|
25874
|
-
var
|
|
26156
|
+
var path25 = __toESM(require("path"));
|
|
25875
26157
|
var os20 = __toESM(require("os"));
|
|
25876
26158
|
function getAutoImplPid(ctx) {
|
|
25877
26159
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -25921,22 +26203,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
25921
26203
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
25922
26204
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
25923
26205
|
try {
|
|
25924
|
-
return fs14.statSync(
|
|
26206
|
+
return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
25925
26207
|
} catch {
|
|
25926
26208
|
return false;
|
|
25927
26209
|
}
|
|
25928
26210
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
25929
26211
|
if (versions.length === 0) return null;
|
|
25930
|
-
return
|
|
26212
|
+
return path25.join(scriptsDir, versions[0]);
|
|
25931
26213
|
}
|
|
25932
26214
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
25933
|
-
const canonicalUserDir =
|
|
25934
|
-
const desiredDir = requestedDir ?
|
|
25935
|
-
const upstreamRoot =
|
|
25936
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
26215
|
+
const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
26216
|
+
const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
|
|
26217
|
+
const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
|
|
26218
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
|
|
25937
26219
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
25938
26220
|
}
|
|
25939
|
-
if (
|
|
26221
|
+
if (path25.basename(desiredDir) !== type) {
|
|
25940
26222
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
25941
26223
|
}
|
|
25942
26224
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -25944,11 +26226,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
25944
26226
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
25945
26227
|
}
|
|
25946
26228
|
if (!fs14.existsSync(desiredDir)) {
|
|
25947
|
-
fs14.mkdirSync(
|
|
26229
|
+
fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
25948
26230
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
25949
26231
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
25950
26232
|
}
|
|
25951
|
-
const providerJson =
|
|
26233
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
25952
26234
|
if (!fs14.existsSync(providerJson)) {
|
|
25953
26235
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
25954
26236
|
}
|
|
@@ -25959,13 +26241,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
25959
26241
|
const refDir = ctx.findProviderDir(referenceType);
|
|
25960
26242
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
25961
26243
|
const referenceScripts = {};
|
|
25962
|
-
const scriptsDir =
|
|
26244
|
+
const scriptsDir = path25.join(refDir, "scripts");
|
|
25963
26245
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
25964
26246
|
if (!latestDir) return referenceScripts;
|
|
25965
26247
|
for (const file of fs14.readdirSync(latestDir)) {
|
|
25966
26248
|
if (!file.endsWith(".js")) continue;
|
|
25967
26249
|
try {
|
|
25968
|
-
referenceScripts[file] = fs14.readFileSync(
|
|
26250
|
+
referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
|
|
25969
26251
|
} catch {
|
|
25970
26252
|
}
|
|
25971
26253
|
}
|
|
@@ -26073,9 +26355,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
26073
26355
|
});
|
|
26074
26356
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
26075
26357
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
26076
|
-
const tmpDir =
|
|
26358
|
+
const tmpDir = path25.join(os20.tmpdir(), "adhdev-autoimpl");
|
|
26077
26359
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
26078
|
-
const promptFile =
|
|
26360
|
+
const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
26079
26361
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
26080
26362
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
26081
26363
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -26507,7 +26789,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26507
26789
|
setMode: "set_mode.js"
|
|
26508
26790
|
};
|
|
26509
26791
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26510
|
-
const scriptsDir =
|
|
26792
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26511
26793
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26512
26794
|
if (latestScriptsDir) {
|
|
26513
26795
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26518,7 +26800,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26518
26800
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
26519
26801
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
26520
26802
|
try {
|
|
26521
|
-
const content = fs14.readFileSync(
|
|
26803
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26522
26804
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26523
26805
|
lines.push("```javascript");
|
|
26524
26806
|
lines.push(content);
|
|
@@ -26535,7 +26817,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26535
26817
|
lines.push("");
|
|
26536
26818
|
for (const file of refFiles) {
|
|
26537
26819
|
try {
|
|
26538
|
-
const content = fs14.readFileSync(
|
|
26820
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26539
26821
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26540
26822
|
lines.push("```javascript");
|
|
26541
26823
|
lines.push(content);
|
|
@@ -26576,10 +26858,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26576
26858
|
lines.push("");
|
|
26577
26859
|
}
|
|
26578
26860
|
}
|
|
26579
|
-
const docsDir =
|
|
26861
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26580
26862
|
const loadGuide = (name) => {
|
|
26581
26863
|
try {
|
|
26582
|
-
const p =
|
|
26864
|
+
const p = path25.join(docsDir, name);
|
|
26583
26865
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26584
26866
|
} catch {
|
|
26585
26867
|
}
|
|
@@ -26816,7 +27098,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26816
27098
|
parseApproval: "parse_approval.js"
|
|
26817
27099
|
};
|
|
26818
27100
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26819
|
-
const scriptsDir =
|
|
27101
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26820
27102
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26821
27103
|
if (latestScriptsDir) {
|
|
26822
27104
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26828,7 +27110,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26828
27110
|
if (!file.endsWith(".js")) continue;
|
|
26829
27111
|
if (!targetFileNames.has(file)) continue;
|
|
26830
27112
|
try {
|
|
26831
|
-
const content = fs14.readFileSync(
|
|
27113
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26832
27114
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26833
27115
|
lines.push("```javascript");
|
|
26834
27116
|
lines.push(content);
|
|
@@ -26844,7 +27126,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26844
27126
|
lines.push("");
|
|
26845
27127
|
for (const file of refFiles) {
|
|
26846
27128
|
try {
|
|
26847
|
-
const content = fs14.readFileSync(
|
|
27129
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26848
27130
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26849
27131
|
lines.push("```javascript");
|
|
26850
27132
|
lines.push(content);
|
|
@@ -26877,10 +27159,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26877
27159
|
lines.push("");
|
|
26878
27160
|
}
|
|
26879
27161
|
}
|
|
26880
|
-
const docsDir =
|
|
27162
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26881
27163
|
const loadGuide = (name) => {
|
|
26882
27164
|
try {
|
|
26883
|
-
const p =
|
|
27165
|
+
const p = path25.join(docsDir, name);
|
|
26884
27166
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26885
27167
|
} catch {
|
|
26886
27168
|
}
|
|
@@ -27327,8 +27609,8 @@ var DevServer = class _DevServer {
|
|
|
27327
27609
|
}
|
|
27328
27610
|
getEndpointList() {
|
|
27329
27611
|
return this.routes.map((r) => {
|
|
27330
|
-
const
|
|
27331
|
-
return `${r.method.padEnd(5)} ${
|
|
27612
|
+
const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
27613
|
+
return `${r.method.padEnd(5)} ${path27}`;
|
|
27332
27614
|
});
|
|
27333
27615
|
}
|
|
27334
27616
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -27616,12 +27898,12 @@ var DevServer = class _DevServer {
|
|
|
27616
27898
|
// ─── DevConsole SPA ───
|
|
27617
27899
|
getConsoleDistDir() {
|
|
27618
27900
|
const candidates = [
|
|
27619
|
-
|
|
27620
|
-
|
|
27621
|
-
|
|
27901
|
+
path26.resolve(__dirname, "../../web-devconsole/dist"),
|
|
27902
|
+
path26.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
27903
|
+
path26.join(process.cwd(), "packages/web-devconsole/dist")
|
|
27622
27904
|
];
|
|
27623
27905
|
for (const dir of candidates) {
|
|
27624
|
-
if (fs15.existsSync(
|
|
27906
|
+
if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
|
|
27625
27907
|
}
|
|
27626
27908
|
return null;
|
|
27627
27909
|
}
|
|
@@ -27631,7 +27913,7 @@ var DevServer = class _DevServer {
|
|
|
27631
27913
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
27632
27914
|
return;
|
|
27633
27915
|
}
|
|
27634
|
-
const htmlPath =
|
|
27916
|
+
const htmlPath = path26.join(distDir, "index.html");
|
|
27635
27917
|
try {
|
|
27636
27918
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
27637
27919
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -27656,15 +27938,15 @@ var DevServer = class _DevServer {
|
|
|
27656
27938
|
this.json(res, 404, { error: "Not found" });
|
|
27657
27939
|
return;
|
|
27658
27940
|
}
|
|
27659
|
-
const safePath =
|
|
27660
|
-
const filePath =
|
|
27941
|
+
const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
|
|
27942
|
+
const filePath = path26.join(distDir, safePath);
|
|
27661
27943
|
if (!filePath.startsWith(distDir)) {
|
|
27662
27944
|
this.json(res, 403, { error: "Forbidden" });
|
|
27663
27945
|
return;
|
|
27664
27946
|
}
|
|
27665
27947
|
try {
|
|
27666
27948
|
const content = fs15.readFileSync(filePath);
|
|
27667
|
-
const ext =
|
|
27949
|
+
const ext = path26.extname(filePath);
|
|
27668
27950
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
27669
27951
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
27670
27952
|
res.end(content);
|
|
@@ -27777,9 +28059,9 @@ var DevServer = class _DevServer {
|
|
|
27777
28059
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
27778
28060
|
if (entry.isDirectory()) {
|
|
27779
28061
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
27780
|
-
scan(
|
|
28062
|
+
scan(path26.join(d, entry.name), rel);
|
|
27781
28063
|
} else {
|
|
27782
|
-
const stat2 = fs15.statSync(
|
|
28064
|
+
const stat2 = fs15.statSync(path26.join(d, entry.name));
|
|
27783
28065
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
27784
28066
|
}
|
|
27785
28067
|
}
|
|
@@ -27802,7 +28084,7 @@ var DevServer = class _DevServer {
|
|
|
27802
28084
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27803
28085
|
return;
|
|
27804
28086
|
}
|
|
27805
|
-
const fullPath =
|
|
28087
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27806
28088
|
if (!fullPath.startsWith(dir)) {
|
|
27807
28089
|
this.json(res, 403, { error: "Forbidden" });
|
|
27808
28090
|
return;
|
|
@@ -27827,14 +28109,14 @@ var DevServer = class _DevServer {
|
|
|
27827
28109
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27828
28110
|
return;
|
|
27829
28111
|
}
|
|
27830
|
-
const fullPath =
|
|
28112
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27831
28113
|
if (!fullPath.startsWith(dir)) {
|
|
27832
28114
|
this.json(res, 403, { error: "Forbidden" });
|
|
27833
28115
|
return;
|
|
27834
28116
|
}
|
|
27835
28117
|
try {
|
|
27836
28118
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
27837
|
-
fs15.mkdirSync(
|
|
28119
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
27838
28120
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
27839
28121
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
27840
28122
|
this.providerLoader.reload();
|
|
@@ -27851,7 +28133,7 @@ var DevServer = class _DevServer {
|
|
|
27851
28133
|
return;
|
|
27852
28134
|
}
|
|
27853
28135
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
27854
|
-
const p =
|
|
28136
|
+
const p = path26.join(dir, name);
|
|
27855
28137
|
if (fs15.existsSync(p)) {
|
|
27856
28138
|
const source = fs15.readFileSync(p, "utf-8");
|
|
27857
28139
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -27872,8 +28154,8 @@ var DevServer = class _DevServer {
|
|
|
27872
28154
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
27873
28155
|
return;
|
|
27874
28156
|
}
|
|
27875
|
-
const target = fs15.existsSync(
|
|
27876
|
-
const targetPath =
|
|
28157
|
+
const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
28158
|
+
const targetPath = path26.join(dir, target);
|
|
27877
28159
|
try {
|
|
27878
28160
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
27879
28161
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -28020,7 +28302,7 @@ var DevServer = class _DevServer {
|
|
|
28020
28302
|
}
|
|
28021
28303
|
let targetDir;
|
|
28022
28304
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
28023
|
-
const jsonPath =
|
|
28305
|
+
const jsonPath = path26.join(targetDir, "provider.json");
|
|
28024
28306
|
if (fs15.existsSync(jsonPath)) {
|
|
28025
28307
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
28026
28308
|
return;
|
|
@@ -28032,8 +28314,8 @@ var DevServer = class _DevServer {
|
|
|
28032
28314
|
const createdFiles = ["provider.json"];
|
|
28033
28315
|
if (result.files) {
|
|
28034
28316
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
28035
|
-
const fullPath =
|
|
28036
|
-
fs15.mkdirSync(
|
|
28317
|
+
const fullPath = path26.join(targetDir, relPath);
|
|
28318
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
28037
28319
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
28038
28320
|
createdFiles.push(relPath);
|
|
28039
28321
|
}
|
|
@@ -28086,22 +28368,22 @@ var DevServer = class _DevServer {
|
|
|
28086
28368
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
28087
28369
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
28088
28370
|
try {
|
|
28089
|
-
return fs15.statSync(
|
|
28371
|
+
return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
28090
28372
|
} catch {
|
|
28091
28373
|
return false;
|
|
28092
28374
|
}
|
|
28093
28375
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
28094
28376
|
if (versions.length === 0) return null;
|
|
28095
|
-
return
|
|
28377
|
+
return path26.join(scriptsDir, versions[0]);
|
|
28096
28378
|
}
|
|
28097
28379
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
28098
|
-
const canonicalUserDir =
|
|
28099
|
-
const desiredDir = requestedDir ?
|
|
28100
|
-
const upstreamRoot =
|
|
28101
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
28380
|
+
const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
28381
|
+
const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
|
|
28382
|
+
const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
|
|
28383
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
|
|
28102
28384
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
28103
28385
|
}
|
|
28104
|
-
if (
|
|
28386
|
+
if (path26.basename(desiredDir) !== type) {
|
|
28105
28387
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
28106
28388
|
}
|
|
28107
28389
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -28109,11 +28391,11 @@ var DevServer = class _DevServer {
|
|
|
28109
28391
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
28110
28392
|
}
|
|
28111
28393
|
if (!fs15.existsSync(desiredDir)) {
|
|
28112
|
-
fs15.mkdirSync(
|
|
28394
|
+
fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
28113
28395
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
28114
28396
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
28115
28397
|
}
|
|
28116
|
-
const providerJson =
|
|
28398
|
+
const providerJson = path26.join(desiredDir, "provider.json");
|
|
28117
28399
|
if (!fs15.existsSync(providerJson)) {
|
|
28118
28400
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
28119
28401
|
}
|
|
@@ -28149,7 +28431,7 @@ var DevServer = class _DevServer {
|
|
|
28149
28431
|
setMode: "set_mode.js"
|
|
28150
28432
|
};
|
|
28151
28433
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28152
|
-
const scriptsDir =
|
|
28434
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28153
28435
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28154
28436
|
if (latestScriptsDir) {
|
|
28155
28437
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28160,7 +28442,7 @@ var DevServer = class _DevServer {
|
|
|
28160
28442
|
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
28161
28443
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
28162
28444
|
try {
|
|
28163
|
-
const content = fs15.readFileSync(
|
|
28445
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28164
28446
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28165
28447
|
lines.push("```javascript");
|
|
28166
28448
|
lines.push(content);
|
|
@@ -28177,7 +28459,7 @@ var DevServer = class _DevServer {
|
|
|
28177
28459
|
lines.push("");
|
|
28178
28460
|
for (const file of refFiles) {
|
|
28179
28461
|
try {
|
|
28180
|
-
const content = fs15.readFileSync(
|
|
28462
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28181
28463
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28182
28464
|
lines.push("```javascript");
|
|
28183
28465
|
lines.push(content);
|
|
@@ -28218,10 +28500,10 @@ var DevServer = class _DevServer {
|
|
|
28218
28500
|
lines.push("");
|
|
28219
28501
|
}
|
|
28220
28502
|
}
|
|
28221
|
-
const docsDir =
|
|
28503
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28222
28504
|
const loadGuide = (name) => {
|
|
28223
28505
|
try {
|
|
28224
|
-
const p =
|
|
28506
|
+
const p = path26.join(docsDir, name);
|
|
28225
28507
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28226
28508
|
} catch {
|
|
28227
28509
|
}
|
|
@@ -28395,7 +28677,7 @@ var DevServer = class _DevServer {
|
|
|
28395
28677
|
parseApproval: "parse_approval.js"
|
|
28396
28678
|
};
|
|
28397
28679
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28398
|
-
const scriptsDir =
|
|
28680
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28399
28681
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28400
28682
|
if (latestScriptsDir) {
|
|
28401
28683
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28407,7 +28689,7 @@ var DevServer = class _DevServer {
|
|
|
28407
28689
|
if (!file.endsWith(".js")) continue;
|
|
28408
28690
|
if (!targetFileNames.has(file)) continue;
|
|
28409
28691
|
try {
|
|
28410
|
-
const content = fs15.readFileSync(
|
|
28692
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28411
28693
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28412
28694
|
lines.push("```javascript");
|
|
28413
28695
|
lines.push(content);
|
|
@@ -28423,7 +28705,7 @@ var DevServer = class _DevServer {
|
|
|
28423
28705
|
lines.push("");
|
|
28424
28706
|
for (const file of refFiles) {
|
|
28425
28707
|
try {
|
|
28426
|
-
const content = fs15.readFileSync(
|
|
28708
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28427
28709
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28428
28710
|
lines.push("```javascript");
|
|
28429
28711
|
lines.push(content);
|
|
@@ -28456,10 +28738,10 @@ var DevServer = class _DevServer {
|
|
|
28456
28738
|
lines.push("");
|
|
28457
28739
|
}
|
|
28458
28740
|
}
|
|
28459
|
-
const docsDir =
|
|
28741
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28460
28742
|
const loadGuide = (name) => {
|
|
28461
28743
|
try {
|
|
28462
|
-
const p =
|
|
28744
|
+
const p = path26.join(docsDir, name);
|
|
28463
28745
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28464
28746
|
} catch {
|
|
28465
28747
|
}
|
|
@@ -29807,6 +30089,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29807
30089
|
createGitWorkspaceMonitor,
|
|
29808
30090
|
createInteractionId,
|
|
29809
30091
|
createMesh,
|
|
30092
|
+
createWorktree,
|
|
29810
30093
|
deleteMesh,
|
|
29811
30094
|
detectAllVersions,
|
|
29812
30095
|
detectCLIs,
|
|
@@ -29859,6 +30142,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29859
30142
|
launchWithCdp,
|
|
29860
30143
|
listHostedCliRuntimes,
|
|
29861
30144
|
listMeshes,
|
|
30145
|
+
listWorktrees,
|
|
29862
30146
|
loadConfig,
|
|
29863
30147
|
loadState,
|
|
29864
30148
|
logCommand,
|
|
@@ -29878,6 +30162,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29878
30162
|
normalizeSessionModalFields,
|
|
29879
30163
|
parsePorcelainV2Status,
|
|
29880
30164
|
parseProviderSourceConfigUpdate,
|
|
30165
|
+
parseWorktreeListOutput,
|
|
29881
30166
|
partitionSessionHostDiagnosticsSessions,
|
|
29882
30167
|
partitionSessionHostRecords,
|
|
29883
30168
|
prepareSessionChatTailUpdate,
|
|
@@ -29887,6 +30172,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29887
30172
|
recordDebugTrace,
|
|
29888
30173
|
registerExtensionProviders,
|
|
29889
30174
|
removeNode,
|
|
30175
|
+
removeWorktree,
|
|
29890
30176
|
resetConfig,
|
|
29891
30177
|
resetDebugRuntimeConfig,
|
|
29892
30178
|
resetState,
|
|
@@ -29896,6 +30182,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29896
30182
|
resolveGitRepository,
|
|
29897
30183
|
resolveSessionHostAppName,
|
|
29898
30184
|
resolveSessionHostAppNameResolution,
|
|
30185
|
+
resolveWorktreePath,
|
|
29899
30186
|
runAsyncBatch,
|
|
29900
30187
|
runGit,
|
|
29901
30188
|
saveConfig,
|