@adhdev/daemon-core 0.9.76-rc.10 → 0.9.76-rc.12
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/cli-adapters/provider-cli-adapter.d.ts +2 -1
- package/dist/cli-adapters/provider-cli-runtime.d.ts +1 -0
- package/dist/commands/cli-manager.d.ts +6 -4
- 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 +660 -334
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +680 -359
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +1 -0
- package/dist/providers/cli-provider-instance.d.ts +1 -0
- package/dist/repo-mesh-types.d.ts +4 -0
- package/package.json +3 -1
- package/src/cli-adapters/provider-cli-adapter.ts +2 -0
- package/src/cli-adapters/provider-cli-runtime.ts +3 -2
- package/src/commands/cli-manager.ts +13 -3
- package/src/commands/mesh-coordinator.ts +11 -2
- package/src/commands/router.ts +205 -23
- 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/providers/cli-provider-instance.ts +2 -1
- package/src/repo-mesh-types.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -46,6 +46,134 @@ var init_repo_mesh_types = __esm({
|
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
// src/git/git-worktree.ts
|
|
50
|
+
var git_worktree_exports = {};
|
|
51
|
+
__export(git_worktree_exports, {
|
|
52
|
+
createWorktree: () => createWorktree,
|
|
53
|
+
listWorktrees: () => listWorktrees,
|
|
54
|
+
parseWorktreeListOutput: () => parseWorktreeListOutput,
|
|
55
|
+
removeWorktree: () => removeWorktree,
|
|
56
|
+
resolveWorktreePath: () => resolveWorktreePath
|
|
57
|
+
});
|
|
58
|
+
function resolveWorktreePath(repoRoot, meshName, branch) {
|
|
59
|
+
const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
60
|
+
const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
61
|
+
const parentDir = path4.dirname(repoRoot);
|
|
62
|
+
return path4.join(parentDir, WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
63
|
+
}
|
|
64
|
+
async function createWorktree(opts) {
|
|
65
|
+
const { repoRoot, branch, baseBranch, meshName } = opts;
|
|
66
|
+
const targetDir = opts.targetDir || resolveWorktreePath(repoRoot, meshName, branch);
|
|
67
|
+
if ((0, import_node_fs2.existsSync)(targetDir)) {
|
|
68
|
+
throw new Error(`Worktree target directory already exists: ${targetDir}`);
|
|
69
|
+
}
|
|
70
|
+
await (0, import_promises3.mkdir)(path4.dirname(targetDir), { recursive: true });
|
|
71
|
+
const args = ["worktree", "add", targetDir, "-b", branch];
|
|
72
|
+
if (baseBranch) {
|
|
73
|
+
args.push(baseBranch);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await execFileAsync2("git", args, {
|
|
77
|
+
cwd: repoRoot,
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
timeout: GIT_TIMEOUT_MS,
|
|
80
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
81
|
+
windowsHide: true
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const stderr = typeof error.stderr === "string" ? error.stderr : "";
|
|
85
|
+
if (/already exists/i.test(stderr)) {
|
|
86
|
+
throw new Error(`Branch '${branch}' already exists or is checked out in another worktree`);
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`git worktree add failed: ${stderr.trim() || error.message}`);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
worktreePath: targetDir,
|
|
93
|
+
branch
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function removeWorktree(repoRoot, worktreePath) {
|
|
97
|
+
if (!(0, import_node_fs2.existsSync)(worktreePath)) {
|
|
98
|
+
await pruneWorktrees(repoRoot);
|
|
99
|
+
return { success: true, removedPath: worktreePath };
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
await execFileAsync2("git", ["worktree", "remove", worktreePath, "--force"], {
|
|
103
|
+
cwd: repoRoot,
|
|
104
|
+
encoding: "utf8",
|
|
105
|
+
timeout: GIT_TIMEOUT_MS,
|
|
106
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
107
|
+
windowsHide: true
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const stderr = typeof error.stderr === "string" ? error.stderr : "";
|
|
111
|
+
throw new Error(`git worktree remove failed: ${stderr.trim() || error.message}`);
|
|
112
|
+
}
|
|
113
|
+
return { success: true, removedPath: worktreePath };
|
|
114
|
+
}
|
|
115
|
+
async function listWorktrees(repoRoot) {
|
|
116
|
+
const { stdout } = await execFileAsync2("git", ["worktree", "list", "--porcelain"], {
|
|
117
|
+
cwd: repoRoot,
|
|
118
|
+
encoding: "utf8",
|
|
119
|
+
timeout: GIT_TIMEOUT_MS,
|
|
120
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
121
|
+
windowsHide: true
|
|
122
|
+
});
|
|
123
|
+
return parseWorktreeListOutput(stdout);
|
|
124
|
+
}
|
|
125
|
+
function parseWorktreeListOutput(output) {
|
|
126
|
+
const entries = [];
|
|
127
|
+
const blocks = output.trim().split(/\n\n+/);
|
|
128
|
+
for (const block of blocks) {
|
|
129
|
+
if (!block.trim()) continue;
|
|
130
|
+
const lines = block.trim().split("\n");
|
|
131
|
+
const entry = { path: "", head: "", branch: null, bare: false };
|
|
132
|
+
for (const line of lines) {
|
|
133
|
+
if (line.startsWith("worktree ")) {
|
|
134
|
+
entry.path = line.slice("worktree ".length).trim();
|
|
135
|
+
} else if (line.startsWith("HEAD ")) {
|
|
136
|
+
entry.head = line.slice("HEAD ".length).trim();
|
|
137
|
+
} else if (line.startsWith("branch ")) {
|
|
138
|
+
const ref = line.slice("branch ".length).trim();
|
|
139
|
+
entry.branch = ref.replace(/^refs\/heads\//, "");
|
|
140
|
+
} else if (line === "bare") {
|
|
141
|
+
entry.bare = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (entry.path) {
|
|
145
|
+
entries.push(entry);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return entries;
|
|
149
|
+
}
|
|
150
|
+
async function pruneWorktrees(repoRoot) {
|
|
151
|
+
try {
|
|
152
|
+
await execFileAsync2("git", ["worktree", "prune"], {
|
|
153
|
+
cwd: repoRoot,
|
|
154
|
+
encoding: "utf8",
|
|
155
|
+
timeout: GIT_TIMEOUT_MS,
|
|
156
|
+
windowsHide: true
|
|
157
|
+
});
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
var path4, import_promises3, import_node_fs2, import_node_child_process2, import_node_util2, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER;
|
|
162
|
+
var init_git_worktree = __esm({
|
|
163
|
+
"src/git/git-worktree.ts"() {
|
|
164
|
+
"use strict";
|
|
165
|
+
path4 = __toESM(require("path"));
|
|
166
|
+
import_promises3 = require("fs/promises");
|
|
167
|
+
import_node_fs2 = require("fs");
|
|
168
|
+
import_node_child_process2 = require("child_process");
|
|
169
|
+
import_node_util2 = require("util");
|
|
170
|
+
execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
171
|
+
WORKTREE_DIR_NAME = ".adhdev-worktrees";
|
|
172
|
+
GIT_TIMEOUT_MS = 3e4;
|
|
173
|
+
GIT_MAX_BUFFER = 4 * 1024 * 1024;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
49
177
|
// src/config/config.ts
|
|
50
178
|
var config_exports = {};
|
|
51
179
|
__export(config_exports, {
|
|
@@ -304,10 +432,10 @@ function getMeshConfigPath() {
|
|
|
304
432
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
305
433
|
}
|
|
306
434
|
function loadMeshConfig() {
|
|
307
|
-
const
|
|
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;
|
|
@@ -1487,7 +1630,7 @@ var init_provider_cli_config = __esm({
|
|
|
1487
1630
|
|
|
1488
1631
|
// src/cli-adapters/provider-cli-runtime.ts
|
|
1489
1632
|
function resolveCliSpawnPlan(options) {
|
|
1490
|
-
const { provider, runtimeSettings, workingDir, extraArgs } = options;
|
|
1633
|
+
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
1491
1634
|
const { spawn: spawnConfig } = provider;
|
|
1492
1635
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
1493
1636
|
const binaryPath = findBinary(configuredCommand);
|
|
@@ -1495,9 +1638,9 @@ function resolveCliSpawnPlan(options) {
|
|
|
1495
1638
|
const allArgs = [...spawnConfig.args, ...extraArgs];
|
|
1496
1639
|
let shellCmd;
|
|
1497
1640
|
let shellArgs;
|
|
1498
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
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";
|
|
@@ -1511,7 +1654,7 @@ function resolveCliSpawnPlan(options) {
|
|
|
1511
1654
|
shellCmd = binaryPath;
|
|
1512
1655
|
shellArgs = allArgs;
|
|
1513
1656
|
}
|
|
1514
|
-
const env = buildCliSpawnEnv(process.env, spawnConfig.env);
|
|
1657
|
+
const env = buildCliSpawnEnv(process.env, { ...spawnConfig.env || {}, ...extraEnv || {} });
|
|
1515
1658
|
env.TERMINAL_CWD = workingDir;
|
|
1516
1659
|
return {
|
|
1517
1660
|
binaryPath,
|
|
@@ -1573,12 +1716,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
1573
1716
|
}
|
|
1574
1717
|
return "";
|
|
1575
1718
|
}
|
|
1576
|
-
var os10,
|
|
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
|
}
|
|
@@ -1614,8 +1757,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1614
1757
|
init_provider_cli_runtime();
|
|
1615
1758
|
init_provider_cli_shared();
|
|
1616
1759
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
1617
|
-
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
1760
|
+
constructor(provider, workingDir, extraArgs = [], extraEnv = {}, transportFactory = new NodePtyTransportFactory()) {
|
|
1618
1761
|
this.extraArgs = extraArgs;
|
|
1762
|
+
this.extraEnv = extraEnv;
|
|
1619
1763
|
this.provider = provider;
|
|
1620
1764
|
this.transportFactory = transportFactory;
|
|
1621
1765
|
this.cliType = provider.type;
|
|
@@ -1931,7 +2075,8 @@ ${lastSnapshot}`;
|
|
|
1931
2075
|
provider: this.provider,
|
|
1932
2076
|
runtimeSettings: this.runtimeSettings,
|
|
1933
2077
|
workingDir: this.workingDir,
|
|
1934
|
-
extraArgs: this.extraArgs
|
|
2078
|
+
extraArgs: this.extraArgs,
|
|
2079
|
+
extraEnv: this.extraEnv
|
|
1935
2080
|
});
|
|
1936
2081
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1937
2082
|
this.resetTraceSession();
|
|
@@ -3728,6 +3873,7 @@ __export(index_exports, {
|
|
|
3728
3873
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
|
|
3729
3874
|
createInteractionId: () => createInteractionId,
|
|
3730
3875
|
createMesh: () => createMesh,
|
|
3876
|
+
createWorktree: () => createWorktree,
|
|
3731
3877
|
deleteMesh: () => deleteMesh,
|
|
3732
3878
|
detectAllVersions: () => detectAllVersions,
|
|
3733
3879
|
detectCLIs: () => detectCLIs,
|
|
@@ -3780,6 +3926,7 @@ __export(index_exports, {
|
|
|
3780
3926
|
launchWithCdp: () => launchWithCdp,
|
|
3781
3927
|
listHostedCliRuntimes: () => listHostedCliRuntimes,
|
|
3782
3928
|
listMeshes: () => listMeshes,
|
|
3929
|
+
listWorktrees: () => listWorktrees,
|
|
3783
3930
|
loadConfig: () => loadConfig,
|
|
3784
3931
|
loadState: () => loadState,
|
|
3785
3932
|
logCommand: () => logCommand,
|
|
@@ -3799,6 +3946,7 @@ __export(index_exports, {
|
|
|
3799
3946
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
3800
3947
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
3801
3948
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
3949
|
+
parseWorktreeListOutput: () => parseWorktreeListOutput,
|
|
3802
3950
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
3803
3951
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
3804
3952
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
|
|
@@ -3808,6 +3956,7 @@ __export(index_exports, {
|
|
|
3808
3956
|
recordDebugTrace: () => recordDebugTrace,
|
|
3809
3957
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
3810
3958
|
removeNode: () => removeNode,
|
|
3959
|
+
removeWorktree: () => removeWorktree,
|
|
3811
3960
|
resetConfig: () => resetConfig,
|
|
3812
3961
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
3813
3962
|
resetState: () => resetState,
|
|
@@ -3817,6 +3966,7 @@ __export(index_exports, {
|
|
|
3817
3966
|
resolveGitRepository: () => resolveGitRepository,
|
|
3818
3967
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
3819
3968
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
|
|
3969
|
+
resolveWorktreePath: () => resolveWorktreePath,
|
|
3820
3970
|
runAsyncBatch: () => runAsyncBatch,
|
|
3821
3971
|
runGit: () => runGit,
|
|
3822
3972
|
saveConfig: () => saveConfig,
|
|
@@ -5176,20 +5326,23 @@ var TurnSnapshotTracker = class {
|
|
|
5176
5326
|
}
|
|
5177
5327
|
};
|
|
5178
5328
|
|
|
5329
|
+
// src/git/index.ts
|
|
5330
|
+
init_git_worktree();
|
|
5331
|
+
|
|
5179
5332
|
// src/index.ts
|
|
5180
5333
|
init_config();
|
|
5181
5334
|
|
|
5182
5335
|
// src/config/workspaces.ts
|
|
5183
5336
|
var fs = __toESM(require("fs"));
|
|
5184
5337
|
var os = __toESM(require("os"));
|
|
5185
|
-
var
|
|
5338
|
+
var path5 = __toESM(require("path"));
|
|
5186
5339
|
var import_crypto2 = require("crypto");
|
|
5187
5340
|
var MAX_WORKSPACES = 50;
|
|
5188
5341
|
function expandPath(p) {
|
|
5189
5342
|
const t = (p || "").trim();
|
|
5190
5343
|
if (!t) return "";
|
|
5191
|
-
if (t.startsWith("~")) return
|
|
5192
|
-
return
|
|
5344
|
+
if (t.startsWith("~")) return path5.join(os.homedir(), t.slice(1).replace(/^\//, ""));
|
|
5345
|
+
return path5.resolve(t);
|
|
5193
5346
|
}
|
|
5194
5347
|
function validateWorkspacePath(absPath) {
|
|
5195
5348
|
try {
|
|
@@ -5203,7 +5356,7 @@ function validateWorkspacePath(absPath) {
|
|
|
5203
5356
|
}
|
|
5204
5357
|
}
|
|
5205
5358
|
function defaultWorkspaceLabel(absPath) {
|
|
5206
|
-
const base =
|
|
5359
|
+
const base = path5.basename(absPath) || absPath;
|
|
5207
5360
|
return base;
|
|
5208
5361
|
}
|
|
5209
5362
|
function getDefaultWorkspacePath(config) {
|
|
@@ -5294,9 +5447,9 @@ function resolveIdeLaunchWorkspace(args, config) {
|
|
|
5294
5447
|
return getDefaultWorkspacePath(config) || void 0;
|
|
5295
5448
|
}
|
|
5296
5449
|
function findWorkspaceByPath(config, rawPath) {
|
|
5297
|
-
const abs =
|
|
5450
|
+
const abs = path5.resolve(expandPath(rawPath));
|
|
5298
5451
|
if (!abs) return void 0;
|
|
5299
|
-
return (config.workspaces || []).find((w) =>
|
|
5452
|
+
return (config.workspaces || []).find((w) => path5.resolve(expandPath(w.path)) === abs);
|
|
5300
5453
|
}
|
|
5301
5454
|
function addWorkspaceEntry(config, rawPath, label, options) {
|
|
5302
5455
|
const abs = expandPath(rawPath);
|
|
@@ -5312,7 +5465,7 @@ function addWorkspaceEntry(config, rawPath, label, options) {
|
|
|
5312
5465
|
const v = validateWorkspacePath(abs);
|
|
5313
5466
|
if (!v.ok) return { error: v.error };
|
|
5314
5467
|
const list = [...config.workspaces || []];
|
|
5315
|
-
if (list.some((w) =>
|
|
5468
|
+
if (list.some((w) => path5.resolve(w.path) === abs)) {
|
|
5316
5469
|
return { error: "Workspace already in list" };
|
|
5317
5470
|
}
|
|
5318
5471
|
if (list.length >= MAX_WORKSPACES) {
|
|
@@ -5346,7 +5499,7 @@ function setDefaultWorkspaceId(config, id) {
|
|
|
5346
5499
|
}
|
|
5347
5500
|
|
|
5348
5501
|
// src/config/recent-activity.ts
|
|
5349
|
-
var
|
|
5502
|
+
var path6 = __toESM(require("path"));
|
|
5350
5503
|
|
|
5351
5504
|
// src/providers/summary-metadata.ts
|
|
5352
5505
|
function normalizeSummaryItem(item) {
|
|
@@ -5415,9 +5568,9 @@ var MAX_ACTIVITY = 30;
|
|
|
5415
5568
|
function normalizeWorkspace(workspace) {
|
|
5416
5569
|
if (!workspace) return "";
|
|
5417
5570
|
try {
|
|
5418
|
-
return
|
|
5571
|
+
return path6.resolve(expandPath(workspace));
|
|
5419
5572
|
} catch {
|
|
5420
|
-
return
|
|
5573
|
+
return path6.resolve(workspace);
|
|
5421
5574
|
}
|
|
5422
5575
|
}
|
|
5423
5576
|
function buildRecentActivityKey(entry) {
|
|
@@ -5585,14 +5738,14 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
|
|
|
5585
5738
|
}
|
|
5586
5739
|
|
|
5587
5740
|
// src/config/saved-sessions.ts
|
|
5588
|
-
var
|
|
5741
|
+
var path7 = __toESM(require("path"));
|
|
5589
5742
|
var MAX_SAVED_SESSIONS = 500;
|
|
5590
5743
|
function normalizeWorkspace2(workspace) {
|
|
5591
5744
|
if (!workspace) return "";
|
|
5592
5745
|
try {
|
|
5593
|
-
return
|
|
5746
|
+
return path7.resolve(expandPath(workspace));
|
|
5594
5747
|
} catch {
|
|
5595
|
-
return
|
|
5748
|
+
return path7.resolve(workspace);
|
|
5596
5749
|
}
|
|
5597
5750
|
}
|
|
5598
5751
|
function buildSavedProviderSessionKey(providerSessionId) {
|
|
@@ -5771,7 +5924,7 @@ function resetState() {
|
|
|
5771
5924
|
var import_child_process = require("child_process");
|
|
5772
5925
|
var import_fs4 = require("fs");
|
|
5773
5926
|
var import_os2 = require("os");
|
|
5774
|
-
var
|
|
5927
|
+
var path8 = __toESM(require("path"));
|
|
5775
5928
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
5776
5929
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
5777
5930
|
function registerIDEDefinition(def) {
|
|
@@ -5790,9 +5943,9 @@ function getMergedDefinitions() {
|
|
|
5790
5943
|
function findCliCommand(command) {
|
|
5791
5944
|
const trimmed = String(command || "").trim();
|
|
5792
5945
|
if (!trimmed) return null;
|
|
5793
|
-
if (
|
|
5794
|
-
const candidate = trimmed.startsWith("~") ?
|
|
5795
|
-
const resolved =
|
|
5946
|
+
if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
5947
|
+
const candidate = trimmed.startsWith("~") ? path8.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
5948
|
+
const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
|
|
5796
5949
|
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
5797
5950
|
}
|
|
5798
5951
|
try {
|
|
@@ -5820,7 +5973,7 @@ function getIdeVersion(cliCommand) {
|
|
|
5820
5973
|
function checkPathExists(paths) {
|
|
5821
5974
|
const home = (0, import_os2.homedir)();
|
|
5822
5975
|
for (const p of paths) {
|
|
5823
|
-
const normalized = p.startsWith("~") ?
|
|
5976
|
+
const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
|
|
5824
5977
|
if (normalized.includes("*")) {
|
|
5825
5978
|
const username = home.split(/[\\/]/).pop() || "";
|
|
5826
5979
|
const resolved = normalized.replace("*", username);
|
|
@@ -5832,19 +5985,19 @@ function checkPathExists(paths) {
|
|
|
5832
5985
|
return null;
|
|
5833
5986
|
}
|
|
5834
5987
|
async function detectIDEs(providerLoader) {
|
|
5835
|
-
const
|
|
5988
|
+
const os22 = (0, import_os2.platform)();
|
|
5836
5989
|
const results = [];
|
|
5837
5990
|
for (const def of getMergedDefinitions()) {
|
|
5838
5991
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
5839
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
5992
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os22] || []) || []);
|
|
5840
5993
|
let resolvedCli = cliPath;
|
|
5841
|
-
if (!resolvedCli && appPath &&
|
|
5994
|
+
if (!resolvedCli && appPath && os22 === "darwin") {
|
|
5842
5995
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
5843
5996
|
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
5844
5997
|
}
|
|
5845
|
-
if (!resolvedCli && appPath &&
|
|
5846
|
-
const { dirname:
|
|
5847
|
-
const appDir =
|
|
5998
|
+
if (!resolvedCli && appPath && os22 === "win32") {
|
|
5999
|
+
const { dirname: dirname9 } = await import("path");
|
|
6000
|
+
const appDir = dirname9(appPath);
|
|
5848
6001
|
const candidates = [
|
|
5849
6002
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
5850
6003
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -5859,7 +6012,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5859
6012
|
}
|
|
5860
6013
|
}
|
|
5861
6014
|
}
|
|
5862
|
-
const installed =
|
|
6015
|
+
const installed = os22 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
5863
6016
|
const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
|
|
5864
6017
|
results.push({
|
|
5865
6018
|
id: def.id,
|
|
@@ -5878,7 +6031,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5878
6031
|
// src/detection/cli-detector.ts
|
|
5879
6032
|
var import_child_process2 = require("child_process");
|
|
5880
6033
|
var os2 = __toESM(require("os"));
|
|
5881
|
-
var
|
|
6034
|
+
var path9 = __toESM(require("path"));
|
|
5882
6035
|
var import_fs5 = require("fs");
|
|
5883
6036
|
function parseVersion(raw) {
|
|
5884
6037
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -5891,18 +6044,18 @@ function shellQuote(value) {
|
|
|
5891
6044
|
function expandHome(value) {
|
|
5892
6045
|
const trimmed = value.trim();
|
|
5893
6046
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
5894
|
-
return
|
|
6047
|
+
return path9.join(os2.homedir(), trimmed.slice(1));
|
|
5895
6048
|
}
|
|
5896
6049
|
function isExplicitCommandPath(command) {
|
|
5897
6050
|
const trimmed = command.trim();
|
|
5898
|
-
return
|
|
6051
|
+
return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
5899
6052
|
}
|
|
5900
6053
|
function resolveCommandPath(command) {
|
|
5901
6054
|
const trimmed = command.trim();
|
|
5902
6055
|
if (!trimmed) return null;
|
|
5903
6056
|
if (isExplicitCommandPath(trimmed)) {
|
|
5904
6057
|
const expanded = expandHome(trimmed);
|
|
5905
|
-
const candidate =
|
|
6058
|
+
const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
|
|
5906
6059
|
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
5907
6060
|
}
|
|
5908
6061
|
return null;
|
|
@@ -8171,9 +8324,9 @@ ${cleanBody}`;
|
|
|
8171
8324
|
|
|
8172
8325
|
// src/config/chat-history.ts
|
|
8173
8326
|
var fs3 = __toESM(require("fs"));
|
|
8174
|
-
var
|
|
8327
|
+
var path11 = __toESM(require("path"));
|
|
8175
8328
|
var os5 = __toESM(require("os"));
|
|
8176
|
-
var HISTORY_DIR =
|
|
8329
|
+
var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
|
|
8177
8330
|
var RETAIN_DAYS = 30;
|
|
8178
8331
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
8179
8332
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -8336,7 +8489,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
8336
8489
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
8337
8490
|
return new Map(files.map((file) => {
|
|
8338
8491
|
try {
|
|
8339
|
-
const stat2 = fs3.statSync(
|
|
8492
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8340
8493
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
8341
8494
|
} catch {
|
|
8342
8495
|
return [file, `${file}:missing`];
|
|
@@ -8347,7 +8500,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
8347
8500
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
8348
8501
|
}
|
|
8349
8502
|
function getSavedHistoryIndexFilePath(dir) {
|
|
8350
|
-
return
|
|
8503
|
+
return path11.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
8351
8504
|
}
|
|
8352
8505
|
function getSavedHistoryIndexLockPath(dir) {
|
|
8353
8506
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -8449,7 +8602,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
8449
8602
|
}
|
|
8450
8603
|
for (const file of Array.from(currentEntries.keys())) {
|
|
8451
8604
|
if (incomingFiles.has(file)) continue;
|
|
8452
|
-
if (!fs3.existsSync(
|
|
8605
|
+
if (!fs3.existsSync(path11.join(dir, file))) {
|
|
8453
8606
|
currentEntries.delete(file);
|
|
8454
8607
|
}
|
|
8455
8608
|
}
|
|
@@ -8475,7 +8628,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8475
8628
|
const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
|
|
8476
8629
|
const files = listHistoryFiles(dir);
|
|
8477
8630
|
for (const file of files) {
|
|
8478
|
-
const stat2 = fs3.statSync(
|
|
8631
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8479
8632
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
8480
8633
|
}
|
|
8481
8634
|
return false;
|
|
@@ -8485,14 +8638,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8485
8638
|
}
|
|
8486
8639
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
8487
8640
|
try {
|
|
8488
|
-
const stat2 = fs3.statSync(
|
|
8641
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8489
8642
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
8490
8643
|
} catch {
|
|
8491
8644
|
return `${file}:missing`;
|
|
8492
8645
|
}
|
|
8493
8646
|
}
|
|
8494
8647
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
8495
|
-
const filePath =
|
|
8648
|
+
const filePath = path11.join(dir, file);
|
|
8496
8649
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
8497
8650
|
const currentEntry = entries.get(file) || null;
|
|
8498
8651
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -8565,7 +8718,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
8565
8718
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
8566
8719
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
8567
8720
|
if (!historySessionId) return null;
|
|
8568
|
-
const filePath =
|
|
8721
|
+
const filePath = path11.join(dir, file);
|
|
8569
8722
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
8570
8723
|
const lines = content.split("\n").filter(Boolean);
|
|
8571
8724
|
let messageCount = 0;
|
|
@@ -8652,7 +8805,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
8652
8805
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
8653
8806
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
8654
8807
|
for (const file of files.slice().sort()) {
|
|
8655
|
-
const filePath =
|
|
8808
|
+
const filePath = path11.join(dir, file);
|
|
8656
8809
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
8657
8810
|
const cached = savedHistoryFileSummaryCache.get(filePath);
|
|
8658
8811
|
const persisted = persistedEntries.get(file);
|
|
@@ -8772,12 +8925,12 @@ var ChatHistoryWriter = class {
|
|
|
8772
8925
|
});
|
|
8773
8926
|
}
|
|
8774
8927
|
if (newMessages.length === 0) return;
|
|
8775
|
-
const dir =
|
|
8928
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8776
8929
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8777
8930
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8778
8931
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
8779
8932
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
8780
|
-
const filePath =
|
|
8933
|
+
const filePath = path11.join(dir, fileName);
|
|
8781
8934
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
8782
8935
|
fs3.appendFileSync(filePath, lines, "utf-8");
|
|
8783
8936
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -8868,11 +9021,11 @@ var ChatHistoryWriter = class {
|
|
|
8868
9021
|
const ws = String(workspace || "").trim();
|
|
8869
9022
|
if (!id || !ws) return;
|
|
8870
9023
|
try {
|
|
8871
|
-
const dir =
|
|
9024
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8872
9025
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8873
9026
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8874
9027
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
8875
|
-
const filePath =
|
|
9028
|
+
const filePath = path11.join(dir, fileName);
|
|
8876
9029
|
const record = {
|
|
8877
9030
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8878
9031
|
receivedAt: Date.now(),
|
|
@@ -8918,14 +9071,14 @@ var ChatHistoryWriter = class {
|
|
|
8918
9071
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
8919
9072
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
8920
9073
|
}
|
|
8921
|
-
const dir =
|
|
9074
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8922
9075
|
if (!fs3.existsSync(dir)) return;
|
|
8923
9076
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
8924
9077
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
8925
9078
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
8926
9079
|
for (const file of files) {
|
|
8927
|
-
const sourcePath =
|
|
8928
|
-
const targetPath =
|
|
9080
|
+
const sourcePath = path11.join(dir, file);
|
|
9081
|
+
const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
8929
9082
|
const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
8930
9083
|
const rewritten = sourceLines.map((line) => {
|
|
8931
9084
|
try {
|
|
@@ -8959,13 +9112,13 @@ var ChatHistoryWriter = class {
|
|
|
8959
9112
|
const sessionId = String(historySessionId || "").trim();
|
|
8960
9113
|
if (!sessionId) return;
|
|
8961
9114
|
try {
|
|
8962
|
-
const dir =
|
|
9115
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8963
9116
|
if (!fs3.existsSync(dir)) return;
|
|
8964
9117
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
8965
9118
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
8966
9119
|
const seen = /* @__PURE__ */ new Set();
|
|
8967
9120
|
for (const file of files) {
|
|
8968
|
-
const filePath =
|
|
9121
|
+
const filePath = path11.join(dir, file);
|
|
8969
9122
|
const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
8970
9123
|
const next = [];
|
|
8971
9124
|
for (const line of lines) {
|
|
@@ -9019,11 +9172,11 @@ var ChatHistoryWriter = class {
|
|
|
9019
9172
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
9020
9173
|
const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
9021
9174
|
for (const dir of agentDirs) {
|
|
9022
|
-
const dirPath =
|
|
9175
|
+
const dirPath = path11.join(HISTORY_DIR, dir.name);
|
|
9023
9176
|
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
9024
9177
|
let removedAny = false;
|
|
9025
9178
|
for (const file of files) {
|
|
9026
|
-
const filePath =
|
|
9179
|
+
const filePath = path11.join(dirPath, file);
|
|
9027
9180
|
const stat2 = fs3.statSync(filePath);
|
|
9028
9181
|
if (stat2.mtimeMs < cutoff) {
|
|
9029
9182
|
fs3.unlinkSync(filePath);
|
|
@@ -9073,13 +9226,13 @@ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeR
|
|
|
9073
9226
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
9074
9227
|
try {
|
|
9075
9228
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9076
|
-
const dir =
|
|
9229
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9077
9230
|
if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
|
|
9078
9231
|
const files = listHistoryFiles(dir, historySessionId);
|
|
9079
9232
|
const allMessages = [];
|
|
9080
9233
|
const seen = /* @__PURE__ */ new Set();
|
|
9081
9234
|
for (const file of files) {
|
|
9082
|
-
const filePath =
|
|
9235
|
+
const filePath = path11.join(dir, file);
|
|
9083
9236
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
9084
9237
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
9085
9238
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -9103,7 +9256,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
9103
9256
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
9104
9257
|
try {
|
|
9105
9258
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9106
|
-
const dir =
|
|
9259
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9107
9260
|
if (!fs3.existsSync(dir)) {
|
|
9108
9261
|
savedHistorySessionCache.delete(sanitized);
|
|
9109
9262
|
return { sessions: [], hasMore: false };
|
|
@@ -9164,11 +9317,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
9164
9317
|
}
|
|
9165
9318
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
9166
9319
|
try {
|
|
9167
|
-
const dir =
|
|
9320
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9168
9321
|
if (!fs3.existsSync(dir)) return null;
|
|
9169
9322
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
9170
9323
|
for (const file of files) {
|
|
9171
|
-
const lines = fs3.readFileSync(
|
|
9324
|
+
const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
9172
9325
|
for (const line of lines) {
|
|
9173
9326
|
try {
|
|
9174
9327
|
const parsed = JSON.parse(line);
|
|
@@ -9188,16 +9341,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
9188
9341
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
9189
9342
|
if (records.length === 0) return false;
|
|
9190
9343
|
try {
|
|
9191
|
-
const dir =
|
|
9344
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9192
9345
|
fs3.mkdirSync(dir, { recursive: true });
|
|
9193
9346
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
9194
9347
|
for (const file of fs3.readdirSync(dir)) {
|
|
9195
9348
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
9196
|
-
fs3.unlinkSync(
|
|
9349
|
+
fs3.unlinkSync(path11.join(dir, file));
|
|
9197
9350
|
}
|
|
9198
9351
|
}
|
|
9199
9352
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
9200
|
-
const filePath =
|
|
9353
|
+
const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
9201
9354
|
fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
9202
9355
|
`, "utf-8");
|
|
9203
9356
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -11534,7 +11687,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
11534
11687
|
// src/commands/chat-commands.ts
|
|
11535
11688
|
var fs4 = __toESM(require("fs"));
|
|
11536
11689
|
var os6 = __toESM(require("os"));
|
|
11537
|
-
var
|
|
11690
|
+
var path12 = __toESM(require("path"));
|
|
11538
11691
|
var import_node_crypto = require("crypto");
|
|
11539
11692
|
|
|
11540
11693
|
// src/providers/provider-input-support.ts
|
|
@@ -12045,7 +12198,7 @@ function buildDebugBundleText(bundle) {
|
|
|
12045
12198
|
}
|
|
12046
12199
|
function getChatDebugBundleDir() {
|
|
12047
12200
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
12048
|
-
return override ||
|
|
12201
|
+
return override || path12.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
12049
12202
|
}
|
|
12050
12203
|
function safeBundleIdSegment(value, fallback) {
|
|
12051
12204
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -12078,7 +12231,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
12078
12231
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
12079
12232
|
const dir = getChatDebugBundleDir();
|
|
12080
12233
|
fs4.mkdirSync(dir, { recursive: true });
|
|
12081
|
-
const savedPath =
|
|
12234
|
+
const savedPath = path12.join(dir, `${bundleId}.json`);
|
|
12082
12235
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
12083
12236
|
`;
|
|
12084
12237
|
fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -13222,7 +13375,7 @@ async function handleResolveAction(h, args) {
|
|
|
13222
13375
|
|
|
13223
13376
|
// src/commands/cdp-commands.ts
|
|
13224
13377
|
var fs5 = __toESM(require("fs"));
|
|
13225
|
-
var
|
|
13378
|
+
var path13 = __toESM(require("path"));
|
|
13226
13379
|
var os7 = __toESM(require("os"));
|
|
13227
13380
|
var KEY_TO_VK = {
|
|
13228
13381
|
Backspace: 8,
|
|
@@ -13479,25 +13632,25 @@ function resolveSafePath(requestedPath) {
|
|
|
13479
13632
|
const inputPath = rawPath || ".";
|
|
13480
13633
|
const home = os7.homedir();
|
|
13481
13634
|
if (inputPath.startsWith("~")) {
|
|
13482
|
-
return
|
|
13635
|
+
return path13.resolve(path13.join(home, inputPath.slice(1)));
|
|
13483
13636
|
}
|
|
13484
13637
|
if (process.platform === "win32") {
|
|
13485
13638
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
13486
|
-
if (
|
|
13487
|
-
return
|
|
13639
|
+
if (path13.win32.isAbsolute(normalized)) {
|
|
13640
|
+
return path13.win32.normalize(normalized);
|
|
13488
13641
|
}
|
|
13489
|
-
return
|
|
13642
|
+
return path13.win32.resolve(normalized);
|
|
13490
13643
|
}
|
|
13491
|
-
if (
|
|
13492
|
-
return
|
|
13644
|
+
if (path13.isAbsolute(inputPath)) {
|
|
13645
|
+
return path13.normalize(inputPath);
|
|
13493
13646
|
}
|
|
13494
|
-
return
|
|
13647
|
+
return path13.resolve(inputPath);
|
|
13495
13648
|
}
|
|
13496
13649
|
function listDirectoryEntriesSafe(dirPath) {
|
|
13497
13650
|
const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
|
|
13498
13651
|
const files = [];
|
|
13499
13652
|
for (const entry of entries) {
|
|
13500
|
-
const entryPath =
|
|
13653
|
+
const entryPath = path13.join(dirPath, entry.name);
|
|
13501
13654
|
try {
|
|
13502
13655
|
if (entry.isDirectory()) {
|
|
13503
13656
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -13551,7 +13704,7 @@ async function handleFileRead(h, args) {
|
|
|
13551
13704
|
async function handleFileWrite(h, args) {
|
|
13552
13705
|
try {
|
|
13553
13706
|
const filePath = resolveSafePath(args?.path);
|
|
13554
|
-
fs5.mkdirSync(
|
|
13707
|
+
fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
|
|
13555
13708
|
fs5.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
13556
13709
|
return { success: true, path: filePath };
|
|
13557
13710
|
} catch (e) {
|
|
@@ -14670,7 +14823,7 @@ var DaemonCommandHandler = class {
|
|
|
14670
14823
|
|
|
14671
14824
|
// src/commands/cli-manager.ts
|
|
14672
14825
|
var os13 = __toESM(require("os"));
|
|
14673
|
-
var
|
|
14826
|
+
var path17 = __toESM(require("path"));
|
|
14674
14827
|
var crypto4 = __toESM(require("crypto"));
|
|
14675
14828
|
var import_fs6 = require("fs");
|
|
14676
14829
|
var import_child_process6 = require("child_process");
|
|
@@ -14680,7 +14833,7 @@ init_config();
|
|
|
14680
14833
|
|
|
14681
14834
|
// src/providers/cli-provider-instance.ts
|
|
14682
14835
|
var os12 = __toESM(require("os"));
|
|
14683
|
-
var
|
|
14836
|
+
var path16 = __toESM(require("path"));
|
|
14684
14837
|
var crypto3 = __toESM(require("crypto"));
|
|
14685
14838
|
var fs6 = __toESM(require("fs"));
|
|
14686
14839
|
var import_node_module = require("module");
|
|
@@ -14739,7 +14892,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
14739
14892
|
var CachedDatabaseSync = null;
|
|
14740
14893
|
function getDatabaseSync() {
|
|
14741
14894
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
14742
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
14895
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path16.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
14743
14896
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
14744
14897
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
14745
14898
|
if (!CachedDatabaseSync) {
|
|
@@ -14792,7 +14945,7 @@ var CliProviderInstance = class {
|
|
|
14792
14945
|
this.providerSessionId = options?.providerSessionId;
|
|
14793
14946
|
this.launchMode = options?.launchMode || "new";
|
|
14794
14947
|
this.onProviderSessionResolved = options?.onProviderSessionResolved;
|
|
14795
|
-
this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, transportFactory);
|
|
14948
|
+
this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, options?.extraEnv || {}, transportFactory);
|
|
14796
14949
|
this.monitor = new StatusMonitor();
|
|
14797
14950
|
this.historyWriter = new ChatHistoryWriter();
|
|
14798
14951
|
}
|
|
@@ -16805,11 +16958,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
16805
16958
|
// src/commands/cli-manager.ts
|
|
16806
16959
|
function isExplicitCommand(command) {
|
|
16807
16960
|
const trimmed = command.trim();
|
|
16808
|
-
return
|
|
16961
|
+
return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
16809
16962
|
}
|
|
16810
16963
|
function expandExecutable(command) {
|
|
16811
16964
|
const trimmed = command.trim();
|
|
16812
|
-
return trimmed.startsWith("~") ?
|
|
16965
|
+
return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
16813
16966
|
}
|
|
16814
16967
|
function commandExists(command) {
|
|
16815
16968
|
const trimmed = command.trim();
|
|
@@ -17003,7 +17156,7 @@ var DaemonCliManager = class {
|
|
|
17003
17156
|
attachExisting
|
|
17004
17157
|
}) || void 0;
|
|
17005
17158
|
}
|
|
17006
|
-
createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false) {
|
|
17159
|
+
createAdapter(cliType, workingDir, cliArgs, runtimeId, providerSessionId, attachExisting = false, extraEnv) {
|
|
17007
17160
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17008
17161
|
const provider = this.providerLoader.getMeta(normalizedType);
|
|
17009
17162
|
if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
|
|
@@ -17017,7 +17170,7 @@ var DaemonCliManager = class {
|
|
|
17017
17170
|
providerSessionId,
|
|
17018
17171
|
attachExisting
|
|
17019
17172
|
);
|
|
17020
|
-
return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, transportFactory);
|
|
17173
|
+
return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs, extraEnv || {}, transportFactory);
|
|
17021
17174
|
}
|
|
17022
17175
|
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
17023
17176
|
}
|
|
@@ -17090,7 +17243,7 @@ var DaemonCliManager = class {
|
|
|
17090
17243
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
17091
17244
|
const trimmed = (workingDir || "").trim();
|
|
17092
17245
|
if (!trimmed) throw new Error("working directory required");
|
|
17093
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
17246
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
|
|
17094
17247
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17095
17248
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
17096
17249
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -17220,6 +17373,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17220
17373
|
{
|
|
17221
17374
|
providerSessionId: sessionBinding.providerSessionId,
|
|
17222
17375
|
launchMode: sessionBinding.launchMode,
|
|
17376
|
+
extraEnv: options?.extraEnv,
|
|
17223
17377
|
onProviderSessionResolved: ({ providerSessionId, providerName, providerType, workspace }) => {
|
|
17224
17378
|
this.persistRecentActivity({
|
|
17225
17379
|
kind: "cli",
|
|
@@ -17240,7 +17394,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17240
17394
|
resolvedCliArgs,
|
|
17241
17395
|
key,
|
|
17242
17396
|
sessionBinding.providerSessionId,
|
|
17243
|
-
false
|
|
17397
|
+
false,
|
|
17398
|
+
options?.extraEnv
|
|
17244
17399
|
);
|
|
17245
17400
|
try {
|
|
17246
17401
|
await adapter.spawn();
|
|
@@ -17469,7 +17624,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17469
17624
|
dir,
|
|
17470
17625
|
args?.cliArgs,
|
|
17471
17626
|
args?.initialModel,
|
|
17472
|
-
{ resumeSessionId: args?.resumeSessionId, settingsOverride: args?.settings }
|
|
17627
|
+
{ resumeSessionId: args?.resumeSessionId, settingsOverride: args?.settings, extraEnv: args?.env }
|
|
17473
17628
|
);
|
|
17474
17629
|
return {
|
|
17475
17630
|
success: true,
|
|
@@ -17591,11 +17746,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17591
17746
|
var import_child_process7 = require("child_process");
|
|
17592
17747
|
var net = __toESM(require("net"));
|
|
17593
17748
|
var os15 = __toESM(require("os"));
|
|
17594
|
-
var
|
|
17749
|
+
var path19 = __toESM(require("path"));
|
|
17595
17750
|
|
|
17596
17751
|
// src/providers/provider-loader.ts
|
|
17597
17752
|
var fs7 = __toESM(require("fs"));
|
|
17598
|
-
var
|
|
17753
|
+
var path18 = __toESM(require("path"));
|
|
17599
17754
|
var os14 = __toESM(require("os"));
|
|
17600
17755
|
var chokidar = __toESM(require("chokidar"));
|
|
17601
17756
|
init_logger();
|
|
@@ -17919,7 +18074,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17919
18074
|
try {
|
|
17920
18075
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
17921
18076
|
return ["ide", "extension", "cli", "acp"].some(
|
|
17922
|
-
(category) => fs7.existsSync(
|
|
18077
|
+
(category) => fs7.existsSync(path18.join(candidate, category))
|
|
17923
18078
|
);
|
|
17924
18079
|
} catch {
|
|
17925
18080
|
return false;
|
|
@@ -17927,20 +18082,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17927
18082
|
}
|
|
17928
18083
|
static hasProviderRootMarker(candidate) {
|
|
17929
18084
|
try {
|
|
17930
|
-
return fs7.existsSync(
|
|
18085
|
+
return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
17931
18086
|
} catch {
|
|
17932
18087
|
return false;
|
|
17933
18088
|
}
|
|
17934
18089
|
}
|
|
17935
18090
|
detectDefaultUserDir() {
|
|
17936
|
-
const fallback =
|
|
18091
|
+
const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17937
18092
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
17938
18093
|
const visited = /* @__PURE__ */ new Set();
|
|
17939
18094
|
for (const start of this.probeStarts) {
|
|
17940
|
-
let current =
|
|
18095
|
+
let current = path18.resolve(start);
|
|
17941
18096
|
while (!visited.has(current)) {
|
|
17942
18097
|
visited.add(current);
|
|
17943
|
-
const siblingCandidate =
|
|
18098
|
+
const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
17944
18099
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
17945
18100
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
17946
18101
|
if (envOptIn || hasMarker) {
|
|
@@ -17962,7 +18117,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17962
18117
|
return { path: siblingCandidate, source };
|
|
17963
18118
|
}
|
|
17964
18119
|
}
|
|
17965
|
-
const parent =
|
|
18120
|
+
const parent = path18.dirname(current);
|
|
17966
18121
|
if (parent === current) break;
|
|
17967
18122
|
current = parent;
|
|
17968
18123
|
}
|
|
@@ -17972,11 +18127,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17972
18127
|
constructor(options) {
|
|
17973
18128
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
17974
18129
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
17975
|
-
this.defaultProvidersDir =
|
|
18130
|
+
this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17976
18131
|
const detected = this.detectDefaultUserDir();
|
|
17977
18132
|
this.userDir = detected.path;
|
|
17978
18133
|
this.userDirSource = detected.source;
|
|
17979
|
-
this.upstreamDir =
|
|
18134
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
17980
18135
|
this.disableUpstream = false;
|
|
17981
18136
|
this.applySourceConfig({
|
|
17982
18137
|
userDir: options?.userDir,
|
|
@@ -18035,7 +18190,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18035
18190
|
this.userDir = detected.path;
|
|
18036
18191
|
this.userDirSource = detected.source;
|
|
18037
18192
|
}
|
|
18038
|
-
this.upstreamDir =
|
|
18193
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
18039
18194
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
18040
18195
|
if (this.explicitProviderDir) {
|
|
18041
18196
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -18049,7 +18204,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18049
18204
|
* Canonical provider directory shape for a given root.
|
|
18050
18205
|
*/
|
|
18051
18206
|
getProviderDir(root, category, type) {
|
|
18052
|
-
return
|
|
18207
|
+
return path18.join(root, category, type);
|
|
18053
18208
|
}
|
|
18054
18209
|
/**
|
|
18055
18210
|
* Canonical user override directory for a provider.
|
|
@@ -18076,7 +18231,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18076
18231
|
resolveProviderFile(type, ...segments) {
|
|
18077
18232
|
const dir = this.findProviderDirInternal(type);
|
|
18078
18233
|
if (!dir) return null;
|
|
18079
|
-
return
|
|
18234
|
+
return path18.join(dir, ...segments);
|
|
18080
18235
|
}
|
|
18081
18236
|
/**
|
|
18082
18237
|
* Load all providers (3-tier priority)
|
|
@@ -18115,7 +18270,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18115
18270
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
18116
18271
|
try {
|
|
18117
18272
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
18118
|
-
(d) => fs7.statSync(
|
|
18273
|
+
(d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
|
|
18119
18274
|
);
|
|
18120
18275
|
} catch {
|
|
18121
18276
|
return false;
|
|
@@ -18612,8 +18767,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18612
18767
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
18613
18768
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
18614
18769
|
if (providerDir) {
|
|
18615
|
-
const fullDir =
|
|
18616
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18770
|
+
const fullDir = path18.join(providerDir, entry.scriptDir);
|
|
18771
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18617
18772
|
}
|
|
18618
18773
|
matched = true;
|
|
18619
18774
|
}
|
|
@@ -18628,8 +18783,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18628
18783
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18629
18784
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
18630
18785
|
if (providerDir) {
|
|
18631
|
-
const fullDir =
|
|
18632
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18786
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18787
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18633
18788
|
}
|
|
18634
18789
|
}
|
|
18635
18790
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -18646,8 +18801,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18646
18801
|
resolved._resolvedScriptDir = dirOverride;
|
|
18647
18802
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
18648
18803
|
if (providerDir) {
|
|
18649
|
-
const fullDir =
|
|
18650
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18804
|
+
const fullDir = path18.join(providerDir, dirOverride);
|
|
18805
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18651
18806
|
}
|
|
18652
18807
|
}
|
|
18653
18808
|
} else if (override.scripts) {
|
|
@@ -18663,8 +18818,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18663
18818
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18664
18819
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
18665
18820
|
if (providerDir) {
|
|
18666
|
-
const fullDir =
|
|
18667
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18821
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18822
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18668
18823
|
}
|
|
18669
18824
|
}
|
|
18670
18825
|
}
|
|
@@ -18696,14 +18851,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18696
18851
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
18697
18852
|
return null;
|
|
18698
18853
|
}
|
|
18699
|
-
const dir =
|
|
18854
|
+
const dir = path18.join(providerDir, scriptDir);
|
|
18700
18855
|
if (!fs7.existsSync(dir)) {
|
|
18701
18856
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
18702
18857
|
return null;
|
|
18703
18858
|
}
|
|
18704
18859
|
const cached = this.scriptsCache.get(dir);
|
|
18705
18860
|
if (cached) return cached;
|
|
18706
|
-
const scriptsJs =
|
|
18861
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
18707
18862
|
if (fs7.existsSync(scriptsJs)) {
|
|
18708
18863
|
try {
|
|
18709
18864
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -18745,7 +18900,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18745
18900
|
return;
|
|
18746
18901
|
}
|
|
18747
18902
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
18748
|
-
this.log(`File changed: ${
|
|
18903
|
+
this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
|
|
18749
18904
|
this.reload();
|
|
18750
18905
|
}
|
|
18751
18906
|
};
|
|
@@ -18800,7 +18955,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18800
18955
|
}
|
|
18801
18956
|
const https = require("https");
|
|
18802
18957
|
const { execSync: execSync7 } = require("child_process");
|
|
18803
|
-
const metaPath =
|
|
18958
|
+
const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
18804
18959
|
let prevEtag = "";
|
|
18805
18960
|
let prevTimestamp = 0;
|
|
18806
18961
|
try {
|
|
@@ -18860,17 +19015,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18860
19015
|
return { updated: false };
|
|
18861
19016
|
}
|
|
18862
19017
|
this.log("Downloading latest providers from GitHub...");
|
|
18863
|
-
const tmpTar =
|
|
18864
|
-
const tmpExtract =
|
|
19018
|
+
const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
19019
|
+
const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
18865
19020
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
18866
19021
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
18867
19022
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
18868
19023
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
18869
19024
|
const rootDir = extracted.find(
|
|
18870
|
-
(d) => fs7.statSync(
|
|
19025
|
+
(d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
18871
19026
|
);
|
|
18872
19027
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
18873
|
-
const sourceDir =
|
|
19028
|
+
const sourceDir = path18.join(tmpExtract, rootDir);
|
|
18874
19029
|
const backupDir = this.upstreamDir + ".bak";
|
|
18875
19030
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
18876
19031
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -18945,8 +19100,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18945
19100
|
copyDirRecursive(src, dest) {
|
|
18946
19101
|
fs7.mkdirSync(dest, { recursive: true });
|
|
18947
19102
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
18948
|
-
const srcPath =
|
|
18949
|
-
const destPath =
|
|
19103
|
+
const srcPath = path18.join(src, entry.name);
|
|
19104
|
+
const destPath = path18.join(dest, entry.name);
|
|
18950
19105
|
if (entry.isDirectory()) {
|
|
18951
19106
|
this.copyDirRecursive(srcPath, destPath);
|
|
18952
19107
|
} else {
|
|
@@ -18957,7 +19112,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18957
19112
|
/** .meta.json save */
|
|
18958
19113
|
writeMeta(metaPath, etag, timestamp) {
|
|
18959
19114
|
try {
|
|
18960
|
-
fs7.mkdirSync(
|
|
19115
|
+
fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
|
|
18961
19116
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
18962
19117
|
etag,
|
|
18963
19118
|
timestamp,
|
|
@@ -18974,7 +19129,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18974
19129
|
const scan = (d) => {
|
|
18975
19130
|
try {
|
|
18976
19131
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
18977
|
-
if (entry.isDirectory()) scan(
|
|
19132
|
+
if (entry.isDirectory()) scan(path18.join(d, entry.name));
|
|
18978
19133
|
else if (entry.name === "provider.json") count++;
|
|
18979
19134
|
}
|
|
18980
19135
|
} catch {
|
|
@@ -19202,17 +19357,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19202
19357
|
for (const root of searchRoots) {
|
|
19203
19358
|
if (!fs7.existsSync(root)) continue;
|
|
19204
19359
|
const candidate = this.getProviderDir(root, cat, type);
|
|
19205
|
-
if (fs7.existsSync(
|
|
19206
|
-
const catDir =
|
|
19360
|
+
if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
|
|
19361
|
+
const catDir = path18.join(root, cat);
|
|
19207
19362
|
if (fs7.existsSync(catDir)) {
|
|
19208
19363
|
try {
|
|
19209
19364
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
19210
19365
|
if (!entry.isDirectory()) continue;
|
|
19211
|
-
const jsonPath =
|
|
19366
|
+
const jsonPath = path18.join(catDir, entry.name, "provider.json");
|
|
19212
19367
|
if (fs7.existsSync(jsonPath)) {
|
|
19213
19368
|
try {
|
|
19214
19369
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
19215
|
-
if (data.type === type) return
|
|
19370
|
+
if (data.type === type) return path18.join(catDir, entry.name);
|
|
19216
19371
|
} catch {
|
|
19217
19372
|
}
|
|
19218
19373
|
}
|
|
@@ -19229,7 +19384,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19229
19384
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
19230
19385
|
*/
|
|
19231
19386
|
buildScriptWrappersFromDir(dir) {
|
|
19232
|
-
const scriptsJs =
|
|
19387
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
19233
19388
|
if (fs7.existsSync(scriptsJs)) {
|
|
19234
19389
|
try {
|
|
19235
19390
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -19243,7 +19398,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19243
19398
|
for (const file of fs7.readdirSync(dir)) {
|
|
19244
19399
|
if (!file.endsWith(".js")) continue;
|
|
19245
19400
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
19246
|
-
const filePath =
|
|
19401
|
+
const filePath = path18.join(dir, file);
|
|
19247
19402
|
result[scriptName] = (...args) => {
|
|
19248
19403
|
try {
|
|
19249
19404
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -19303,7 +19458,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19303
19458
|
}
|
|
19304
19459
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
19305
19460
|
if (hasJson) {
|
|
19306
|
-
const jsonPath =
|
|
19461
|
+
const jsonPath = path18.join(d, "provider.json");
|
|
19307
19462
|
try {
|
|
19308
19463
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
19309
19464
|
const mod = JSON.parse(raw);
|
|
@@ -19324,7 +19479,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19324
19479
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
19325
19480
|
} else {
|
|
19326
19481
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
19327
|
-
const scriptsPath =
|
|
19482
|
+
const scriptsPath = path18.join(d, "scripts.js");
|
|
19328
19483
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
19329
19484
|
try {
|
|
19330
19485
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -19350,7 +19505,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19350
19505
|
if (!entry.isDirectory()) continue;
|
|
19351
19506
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
19352
19507
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
19353
|
-
scan(
|
|
19508
|
+
scan(path18.join(d, entry.name));
|
|
19354
19509
|
}
|
|
19355
19510
|
}
|
|
19356
19511
|
};
|
|
@@ -19675,8 +19830,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
19675
19830
|
const appNameMap = getMacAppIdentifiers();
|
|
19676
19831
|
const appName = appNameMap[ideId];
|
|
19677
19832
|
if (appName) {
|
|
19678
|
-
const storagePath =
|
|
19679
|
-
process.env.APPDATA ||
|
|
19833
|
+
const storagePath = path19.join(
|
|
19834
|
+
process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
|
|
19680
19835
|
appName,
|
|
19681
19836
|
"storage.json"
|
|
19682
19837
|
);
|
|
@@ -19865,9 +20020,9 @@ init_logger();
|
|
|
19865
20020
|
|
|
19866
20021
|
// src/logging/command-log.ts
|
|
19867
20022
|
var fs8 = __toESM(require("fs"));
|
|
19868
|
-
var
|
|
20023
|
+
var path20 = __toESM(require("path"));
|
|
19869
20024
|
var os16 = __toESM(require("os"));
|
|
19870
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
20025
|
+
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");
|
|
19871
20026
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
19872
20027
|
var MAX_DAYS = 7;
|
|
19873
20028
|
try {
|
|
@@ -19905,13 +20060,13 @@ function getDateStr2() {
|
|
|
19905
20060
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
19906
20061
|
}
|
|
19907
20062
|
var currentDate2 = getDateStr2();
|
|
19908
|
-
var currentFile =
|
|
20063
|
+
var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19909
20064
|
var writeCount2 = 0;
|
|
19910
20065
|
function checkRotation() {
|
|
19911
20066
|
const today = getDateStr2();
|
|
19912
20067
|
if (today !== currentDate2) {
|
|
19913
20068
|
currentDate2 = today;
|
|
19914
|
-
currentFile =
|
|
20069
|
+
currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19915
20070
|
cleanOldFiles();
|
|
19916
20071
|
}
|
|
19917
20072
|
}
|
|
@@ -19925,7 +20080,7 @@ function cleanOldFiles() {
|
|
|
19925
20080
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
19926
20081
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
19927
20082
|
try {
|
|
19928
|
-
fs8.unlinkSync(
|
|
20083
|
+
fs8.unlinkSync(path20.join(LOG_DIR2, file));
|
|
19929
20084
|
} catch {
|
|
19930
20085
|
}
|
|
19931
20086
|
}
|
|
@@ -20008,11 +20163,13 @@ function getRecentCommands(count = 50) {
|
|
|
20008
20163
|
cleanOldFiles();
|
|
20009
20164
|
|
|
20010
20165
|
// src/commands/router.ts
|
|
20166
|
+
var yaml = __toESM(require("js-yaml"));
|
|
20011
20167
|
init_logger();
|
|
20012
20168
|
|
|
20013
20169
|
// src/commands/mesh-coordinator.ts
|
|
20014
|
-
var
|
|
20170
|
+
var import_node_fs3 = require("fs");
|
|
20015
20171
|
var import_node_module2 = require("module");
|
|
20172
|
+
var os17 = __toESM(require("os"));
|
|
20016
20173
|
var import_node_path = require("path");
|
|
20017
20174
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
20018
20175
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
|
|
@@ -20034,8 +20191,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20034
20191
|
}
|
|
20035
20192
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
20036
20193
|
if (mcpConfig.mode === "auto_import") {
|
|
20037
|
-
const
|
|
20038
|
-
if (!
|
|
20194
|
+
const path27 = mcpConfig.path?.trim();
|
|
20195
|
+
if (!path27) {
|
|
20039
20196
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
20040
20197
|
}
|
|
20041
20198
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -20052,7 +20209,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20052
20209
|
return {
|
|
20053
20210
|
kind: "auto_import",
|
|
20054
20211
|
serverName,
|
|
20055
|
-
configPath: (
|
|
20212
|
+
configPath: resolveMcpConfigPath(path27, workspace),
|
|
20056
20213
|
configFormat: mcpConfig.format,
|
|
20057
20214
|
mcpServer
|
|
20058
20215
|
};
|
|
@@ -20086,6 +20243,13 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20086
20243
|
function renderMeshCoordinatorTemplate(template, values) {
|
|
20087
20244
|
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
|
|
20088
20245
|
}
|
|
20246
|
+
function resolveMcpConfigPath(configPath, workspace) {
|
|
20247
|
+
const trimmed = configPath.trim();
|
|
20248
|
+
if (trimmed === "~") return os17.homedir();
|
|
20249
|
+
if (trimmed.startsWith("~/")) return (0, import_node_path.join)(os17.homedir(), trimmed.slice(2));
|
|
20250
|
+
if ((0, import_node_path.isAbsolute)(trimmed)) return trimmed;
|
|
20251
|
+
return (0, import_node_path.join)(workspace, trimmed);
|
|
20252
|
+
}
|
|
20089
20253
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
20090
20254
|
const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
|
|
20091
20255
|
if (!entryPath) return null;
|
|
@@ -20129,15 +20293,15 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
20129
20293
|
}
|
|
20130
20294
|
function normalizeExistingPath(filePath) {
|
|
20131
20295
|
try {
|
|
20132
|
-
if (!(0,
|
|
20133
|
-
return
|
|
20296
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) return null;
|
|
20297
|
+
return import_node_fs3.realpathSync.native(filePath);
|
|
20134
20298
|
} catch {
|
|
20135
20299
|
return null;
|
|
20136
20300
|
}
|
|
20137
20301
|
}
|
|
20138
20302
|
|
|
20139
20303
|
// src/status/snapshot.ts
|
|
20140
|
-
var
|
|
20304
|
+
var os18 = __toESM(require("os"));
|
|
20141
20305
|
init_config();
|
|
20142
20306
|
init_terminal_screen();
|
|
20143
20307
|
init_logger();
|
|
@@ -20193,8 +20357,8 @@ function buildAvailableProviders(providerLoader) {
|
|
|
20193
20357
|
}
|
|
20194
20358
|
function buildMachineInfo(profile = "full") {
|
|
20195
20359
|
const base = {
|
|
20196
|
-
hostname:
|
|
20197
|
-
platform:
|
|
20360
|
+
hostname: os18.hostname(),
|
|
20361
|
+
platform: os18.platform()
|
|
20198
20362
|
};
|
|
20199
20363
|
if (profile === "live") {
|
|
20200
20364
|
return base;
|
|
@@ -20203,23 +20367,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
20203
20367
|
const memSnap2 = getHostMemorySnapshot();
|
|
20204
20368
|
return {
|
|
20205
20369
|
...base,
|
|
20206
|
-
arch:
|
|
20207
|
-
cpus:
|
|
20370
|
+
arch: os18.arch(),
|
|
20371
|
+
cpus: os18.cpus().length,
|
|
20208
20372
|
totalMem: memSnap2.totalMem,
|
|
20209
|
-
release:
|
|
20373
|
+
release: os18.release()
|
|
20210
20374
|
};
|
|
20211
20375
|
}
|
|
20212
20376
|
const memSnap = getHostMemorySnapshot();
|
|
20213
20377
|
return {
|
|
20214
20378
|
...base,
|
|
20215
|
-
arch:
|
|
20216
|
-
cpus:
|
|
20379
|
+
arch: os18.arch(),
|
|
20380
|
+
cpus: os18.cpus().length,
|
|
20217
20381
|
totalMem: memSnap.totalMem,
|
|
20218
20382
|
freeMem: memSnap.freeMem,
|
|
20219
20383
|
availableMem: memSnap.availableMem,
|
|
20220
|
-
loadavg:
|
|
20221
|
-
uptime:
|
|
20222
|
-
release:
|
|
20384
|
+
loadavg: os18.loadavg(),
|
|
20385
|
+
uptime: os18.uptime(),
|
|
20386
|
+
release: os18.release()
|
|
20223
20387
|
};
|
|
20224
20388
|
}
|
|
20225
20389
|
function parseMessageTime(value) {
|
|
@@ -20453,14 +20617,14 @@ function buildStatusSnapshot(options) {
|
|
|
20453
20617
|
var import_child_process8 = require("child_process");
|
|
20454
20618
|
var import_child_process9 = require("child_process");
|
|
20455
20619
|
var fs9 = __toESM(require("fs"));
|
|
20456
|
-
var
|
|
20457
|
-
var
|
|
20620
|
+
var os19 = __toESM(require("os"));
|
|
20621
|
+
var path21 = __toESM(require("path"));
|
|
20458
20622
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
20459
20623
|
function getUpgradeLogPath() {
|
|
20460
|
-
const home =
|
|
20461
|
-
const dir =
|
|
20624
|
+
const home = os19.homedir();
|
|
20625
|
+
const dir = path21.join(home, ".adhdev");
|
|
20462
20626
|
fs9.mkdirSync(dir, { recursive: true });
|
|
20463
|
-
return
|
|
20627
|
+
return path21.join(dir, "daemon-upgrade.log");
|
|
20464
20628
|
}
|
|
20465
20629
|
function appendUpgradeLog(message) {
|
|
20466
20630
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -20471,14 +20635,14 @@ function appendUpgradeLog(message) {
|
|
|
20471
20635
|
}
|
|
20472
20636
|
}
|
|
20473
20637
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
20474
|
-
const binDir =
|
|
20638
|
+
const binDir = path21.dirname(nodeExecutable);
|
|
20475
20639
|
if (platform10 === "win32") {
|
|
20476
|
-
const npmCliPath =
|
|
20640
|
+
const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
20477
20641
|
if (fs9.existsSync(npmCliPath)) {
|
|
20478
20642
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20479
20643
|
}
|
|
20480
20644
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
20481
|
-
const candidatePath =
|
|
20645
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20482
20646
|
if (fs9.existsSync(candidatePath)) {
|
|
20483
20647
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20484
20648
|
}
|
|
@@ -20486,7 +20650,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
20486
20650
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20487
20651
|
}
|
|
20488
20652
|
for (const candidate of ["npm"]) {
|
|
20489
|
-
const candidatePath =
|
|
20653
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20490
20654
|
if (fs9.existsSync(candidatePath)) {
|
|
20491
20655
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20492
20656
|
}
|
|
@@ -20503,13 +20667,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20503
20667
|
let currentDir = resolvedPath;
|
|
20504
20668
|
try {
|
|
20505
20669
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
20506
|
-
currentDir =
|
|
20670
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20507
20671
|
}
|
|
20508
20672
|
} catch {
|
|
20509
|
-
currentDir =
|
|
20673
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20510
20674
|
}
|
|
20511
20675
|
while (true) {
|
|
20512
|
-
const packageJsonPath =
|
|
20676
|
+
const packageJsonPath = path21.join(currentDir, "package.json");
|
|
20513
20677
|
try {
|
|
20514
20678
|
if (fs9.existsSync(packageJsonPath)) {
|
|
20515
20679
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -20520,7 +20684,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20520
20684
|
}
|
|
20521
20685
|
} catch {
|
|
20522
20686
|
}
|
|
20523
|
-
const parentDir =
|
|
20687
|
+
const parentDir = path21.dirname(currentDir);
|
|
20524
20688
|
if (parentDir === currentDir) {
|
|
20525
20689
|
return null;
|
|
20526
20690
|
}
|
|
@@ -20528,13 +20692,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20528
20692
|
}
|
|
20529
20693
|
}
|
|
20530
20694
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
20531
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
20532
|
-
if (
|
|
20695
|
+
const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
|
|
20696
|
+
if (path21.basename(nodeModulesDir) !== "node_modules") {
|
|
20533
20697
|
return null;
|
|
20534
20698
|
}
|
|
20535
|
-
const maybeLibDir =
|
|
20536
|
-
if (
|
|
20537
|
-
return
|
|
20699
|
+
const maybeLibDir = path21.dirname(nodeModulesDir);
|
|
20700
|
+
if (path21.basename(maybeLibDir) === "lib") {
|
|
20701
|
+
return path21.dirname(maybeLibDir);
|
|
20538
20702
|
}
|
|
20539
20703
|
return maybeLibDir;
|
|
20540
20704
|
}
|
|
@@ -20649,7 +20813,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
20649
20813
|
}
|
|
20650
20814
|
}
|
|
20651
20815
|
function stopSessionHostProcesses(appName) {
|
|
20652
|
-
const pidFile =
|
|
20816
|
+
const pidFile = path21.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
20653
20817
|
try {
|
|
20654
20818
|
if (fs9.existsSync(pidFile)) {
|
|
20655
20819
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -20666,7 +20830,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
20666
20830
|
}
|
|
20667
20831
|
}
|
|
20668
20832
|
function removeDaemonPidFile() {
|
|
20669
|
-
const pidFile =
|
|
20833
|
+
const pidFile = path21.join(os19.homedir(), ".adhdev", "daemon.pid");
|
|
20670
20834
|
try {
|
|
20671
20835
|
fs9.unlinkSync(pidFile);
|
|
20672
20836
|
} catch {
|
|
@@ -20677,7 +20841,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20677
20841
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20678
20842
|
if (!npmRoot) return;
|
|
20679
20843
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20680
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
20844
|
+
const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
|
|
20681
20845
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
20682
20846
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
20683
20847
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -20685,25 +20849,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20685
20849
|
}
|
|
20686
20850
|
if (pkgName.startsWith("@")) {
|
|
20687
20851
|
const [scope, name] = pkgName.split("/");
|
|
20688
|
-
const scopeDir =
|
|
20852
|
+
const scopeDir = path21.join(npmRoot, scope);
|
|
20689
20853
|
if (!fs9.existsSync(scopeDir)) return;
|
|
20690
20854
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
20691
20855
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
20692
|
-
fs9.rmSync(
|
|
20693
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
20856
|
+
fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
|
|
20857
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
|
|
20694
20858
|
}
|
|
20695
20859
|
} else {
|
|
20696
20860
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
20697
20861
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
20698
|
-
fs9.rmSync(
|
|
20699
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
20862
|
+
fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
|
|
20863
|
+
appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
|
|
20700
20864
|
}
|
|
20701
20865
|
}
|
|
20702
20866
|
if (fs9.existsSync(binDir)) {
|
|
20703
20867
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
20704
20868
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
20705
|
-
fs9.rmSync(
|
|
20706
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
20869
|
+
fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
|
|
20870
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
|
|
20707
20871
|
}
|
|
20708
20872
|
}
|
|
20709
20873
|
}
|
|
@@ -20804,6 +20968,22 @@ function normalizeReleaseChannel(value) {
|
|
|
20804
20968
|
function resolveUpgradeChannel(args) {
|
|
20805
20969
|
return normalizeReleaseChannel(args?.channel) || normalizeReleaseChannel(args?.updatePolicy?.channel) || normalizeReleaseChannel(args?.npmTag) || normalizeReleaseChannel(loadConfig().updateChannel) || "stable";
|
|
20806
20970
|
}
|
|
20971
|
+
function loadYamlModule() {
|
|
20972
|
+
return yaml;
|
|
20973
|
+
}
|
|
20974
|
+
function getMcpServersKey(format) {
|
|
20975
|
+
return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
|
|
20976
|
+
}
|
|
20977
|
+
function parseMeshCoordinatorMcpConfig(text, format) {
|
|
20978
|
+
if (!text.trim()) return {};
|
|
20979
|
+
if (format === "claude_mcp_json") return JSON.parse(text);
|
|
20980
|
+
const parsed = loadYamlModule().load(text);
|
|
20981
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
20982
|
+
}
|
|
20983
|
+
function serializeMeshCoordinatorMcpConfig(config, format) {
|
|
20984
|
+
if (format === "claude_mcp_json") return JSON.stringify(config, null, 2);
|
|
20985
|
+
return loadYamlModule().dump(config, { noRefs: true, lineWidth: 120 });
|
|
20986
|
+
}
|
|
20807
20987
|
var CHAT_COMMANDS = [
|
|
20808
20988
|
"send_chat",
|
|
20809
20989
|
"new_chat",
|
|
@@ -20902,6 +21082,40 @@ var DaemonCommandRouter = class {
|
|
|
20902
21082
|
constructor(deps) {
|
|
20903
21083
|
this.deps = deps;
|
|
20904
21084
|
}
|
|
21085
|
+
getCachedInlineMesh(meshId, inlineMesh) {
|
|
21086
|
+
if (inlineMesh && typeof inlineMesh === "object") {
|
|
21087
|
+
this.inlineMeshCache.set(meshId, inlineMesh);
|
|
21088
|
+
return inlineMesh;
|
|
21089
|
+
}
|
|
21090
|
+
return this.inlineMeshCache.get(meshId);
|
|
21091
|
+
}
|
|
21092
|
+
async getMeshForCommand(meshId, inlineMesh) {
|
|
21093
|
+
try {
|
|
21094
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21095
|
+
const mesh = getMesh3(meshId);
|
|
21096
|
+
if (mesh) return { mesh, inline: false };
|
|
21097
|
+
} catch {
|
|
21098
|
+
}
|
|
21099
|
+
const cached = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
21100
|
+
return cached ? { mesh: cached, inline: true } : null;
|
|
21101
|
+
}
|
|
21102
|
+
updateInlineMeshNode(meshId, mesh, node) {
|
|
21103
|
+
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
21104
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
|
|
21105
|
+
if (idx >= 0) mesh.nodes[idx] = node;
|
|
21106
|
+
else mesh.nodes.push(node);
|
|
21107
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21108
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21109
|
+
}
|
|
21110
|
+
removeInlineMeshNode(meshId, mesh, nodeId) {
|
|
21111
|
+
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
21112
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
|
|
21113
|
+
if (idx === -1) return false;
|
|
21114
|
+
mesh.nodes.splice(idx, 1);
|
|
21115
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21116
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21117
|
+
return true;
|
|
21118
|
+
}
|
|
20905
21119
|
async traceSessionHostAction(action, args, run, summarizeResult) {
|
|
20906
21120
|
const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
|
|
20907
21121
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
|
|
@@ -21601,13 +21815,94 @@ var DaemonCommandRouter = class {
|
|
|
21601
21815
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
21602
21816
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
21603
21817
|
try {
|
|
21604
|
-
const
|
|
21605
|
-
const
|
|
21818
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21819
|
+
const mesh = meshRecord?.mesh;
|
|
21820
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
21821
|
+
if (node?.isLocalWorktree && node.workspace) {
|
|
21822
|
+
try {
|
|
21823
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
21824
|
+
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
21825
|
+
if (repoRoot) {
|
|
21826
|
+
const { removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21827
|
+
await removeWorktree2(repoRoot, node.workspace);
|
|
21828
|
+
}
|
|
21829
|
+
} catch (e) {
|
|
21830
|
+
LOG.warn("MeshNode", `Worktree cleanup failed for ${nodeId}: ${e.message}`);
|
|
21831
|
+
}
|
|
21832
|
+
}
|
|
21833
|
+
let removed = false;
|
|
21834
|
+
if (meshRecord?.inline) {
|
|
21835
|
+
removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
|
|
21836
|
+
} else {
|
|
21837
|
+
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21838
|
+
removed = removeNode3(meshId, nodeId);
|
|
21839
|
+
}
|
|
21606
21840
|
return { success: true, removed };
|
|
21607
21841
|
} catch (e) {
|
|
21608
21842
|
return { success: false, error: e.message };
|
|
21609
21843
|
}
|
|
21610
21844
|
}
|
|
21845
|
+
case "clone_mesh_node": {
|
|
21846
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
21847
|
+
const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
|
|
21848
|
+
const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
|
|
21849
|
+
const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
|
|
21850
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
21851
|
+
if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
|
|
21852
|
+
if (!branch) return { success: false, error: "branch required" };
|
|
21853
|
+
try {
|
|
21854
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21855
|
+
const mesh = meshRecord?.mesh;
|
|
21856
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
21857
|
+
const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
|
|
21858
|
+
if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
|
|
21859
|
+
const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
|
|
21860
|
+
const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21861
|
+
const result = await createWorktree2({
|
|
21862
|
+
repoRoot,
|
|
21863
|
+
branch,
|
|
21864
|
+
baseBranch,
|
|
21865
|
+
meshName: mesh.name
|
|
21866
|
+
});
|
|
21867
|
+
let node;
|
|
21868
|
+
if (meshRecord.inline) {
|
|
21869
|
+
const { randomUUID: randomUUID8 } = await import("crypto");
|
|
21870
|
+
node = {
|
|
21871
|
+
id: `node_${randomUUID8().replace(/-/g, "")}`,
|
|
21872
|
+
workspace: result.worktreePath,
|
|
21873
|
+
repoRoot: result.worktreePath,
|
|
21874
|
+
daemonId: sourceNode.daemonId,
|
|
21875
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21876
|
+
policy: { ...sourceNode.policy || {} },
|
|
21877
|
+
isLocalWorktree: true,
|
|
21878
|
+
worktreeBranch: result.branch,
|
|
21879
|
+
clonedFromNodeId: sourceNodeId
|
|
21880
|
+
};
|
|
21881
|
+
this.updateInlineMeshNode(meshId, mesh, node);
|
|
21882
|
+
} else {
|
|
21883
|
+
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21884
|
+
node = addNode3(meshId, {
|
|
21885
|
+
workspace: result.worktreePath,
|
|
21886
|
+
repoRoot: result.worktreePath,
|
|
21887
|
+
daemonId: sourceNode.daemonId,
|
|
21888
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21889
|
+
isLocalWorktree: true,
|
|
21890
|
+
worktreeBranch: result.branch,
|
|
21891
|
+
clonedFromNodeId: sourceNodeId,
|
|
21892
|
+
policy: { ...sourceNode.policy || {} }
|
|
21893
|
+
});
|
|
21894
|
+
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
21895
|
+
}
|
|
21896
|
+
return {
|
|
21897
|
+
success: true,
|
|
21898
|
+
node,
|
|
21899
|
+
worktreePath: result.worktreePath,
|
|
21900
|
+
branch: result.branch
|
|
21901
|
+
};
|
|
21902
|
+
} catch (e) {
|
|
21903
|
+
return { success: false, error: e.message };
|
|
21904
|
+
}
|
|
21905
|
+
}
|
|
21611
21906
|
// ─── Mesh Coordinator Launch ───
|
|
21612
21907
|
case "launch_mesh_coordinator": {
|
|
21613
21908
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
@@ -21666,7 +21961,8 @@ var DaemonCommandRouter = class {
|
|
|
21666
21961
|
meshCoordinatorSetup: coordinatorSetup
|
|
21667
21962
|
};
|
|
21668
21963
|
}
|
|
21669
|
-
|
|
21964
|
+
const configFormat = coordinatorSetup.configFormat;
|
|
21965
|
+
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
21670
21966
|
return {
|
|
21671
21967
|
success: false,
|
|
21672
21968
|
code: "mesh_coordinator_unsupported",
|
|
@@ -21676,15 +21972,38 @@ var DaemonCommandRouter = class {
|
|
|
21676
21972
|
workspace
|
|
21677
21973
|
};
|
|
21678
21974
|
}
|
|
21679
|
-
|
|
21975
|
+
let systemPrompt = "";
|
|
21976
|
+
try {
|
|
21977
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
21978
|
+
} catch (error) {
|
|
21979
|
+
const message = error?.message || String(error);
|
|
21980
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
21981
|
+
return {
|
|
21982
|
+
success: false,
|
|
21983
|
+
code: "mesh_coordinator_prompt_failed",
|
|
21984
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
21985
|
+
meshId,
|
|
21986
|
+
cliType,
|
|
21987
|
+
workspace
|
|
21988
|
+
};
|
|
21989
|
+
}
|
|
21990
|
+
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3, mkdirSync: mkdirSync14 } = await import("fs");
|
|
21991
|
+
const { dirname: dirname9 } = await import("path");
|
|
21680
21992
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
21681
|
-
|
|
21993
|
+
mkdirSync14(dirname9(mcpConfigPath), { recursive: true });
|
|
21994
|
+
const hadExistingMcpConfig = existsSync23(mcpConfigPath);
|
|
21682
21995
|
let existingMcpConfig = {};
|
|
21683
21996
|
if (hadExistingMcpConfig) {
|
|
21684
21997
|
try {
|
|
21685
|
-
existingMcpConfig =
|
|
21998
|
+
existingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
|
|
21686
21999
|
copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
|
|
21687
|
-
} catch {
|
|
22000
|
+
} catch (error) {
|
|
22001
|
+
LOG.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error?.message || error}`);
|
|
22002
|
+
return {
|
|
22003
|
+
success: false,
|
|
22004
|
+
code: "mesh_coordinator_config_parse_failed",
|
|
22005
|
+
error: `Failed to parse existing MCP config at ${mcpConfigPath}`
|
|
22006
|
+
};
|
|
21688
22007
|
}
|
|
21689
22008
|
}
|
|
21690
22009
|
const mcpServerEntry = {
|
|
@@ -21697,24 +22016,25 @@ var DaemonCommandRouter = class {
|
|
|
21697
22016
|
ADHDEV_MCP_TRANSPORT: "ipc"
|
|
21698
22017
|
};
|
|
21699
22018
|
}
|
|
22019
|
+
const mcpServersKey = getMcpServersKey(configFormat);
|
|
22020
|
+
const existingServers = existingMcpConfig[mcpServersKey];
|
|
21700
22021
|
const mcpConfig = {
|
|
21701
22022
|
...existingMcpConfig,
|
|
21702
|
-
|
|
21703
|
-
...
|
|
22023
|
+
[mcpServersKey]: {
|
|
22024
|
+
...existingServers && typeof existingServers === "object" && !Array.isArray(existingServers) ? existingServers : {},
|
|
21704
22025
|
[coordinatorSetup.serverName]: mcpServerEntry
|
|
21705
22026
|
}
|
|
21706
22027
|
};
|
|
21707
|
-
writeFileSync12(mcpConfigPath,
|
|
22028
|
+
writeFileSync12(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
21708
22029
|
LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
21709
|
-
let systemPrompt = "";
|
|
21710
|
-
try {
|
|
21711
|
-
systemPrompt = buildCoordinatorSystemPrompt2({ mesh });
|
|
21712
|
-
} catch {
|
|
21713
|
-
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).`;
|
|
21714
|
-
}
|
|
21715
22030
|
const cliArgs = [];
|
|
22031
|
+
const launchEnv = {};
|
|
21716
22032
|
if (systemPrompt) {
|
|
21717
|
-
|
|
22033
|
+
if (configFormat === "hermes_config_yaml") {
|
|
22034
|
+
launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
|
|
22035
|
+
} else {
|
|
22036
|
+
cliArgs.push("--append-system-prompt", systemPrompt);
|
|
22037
|
+
}
|
|
21718
22038
|
}
|
|
21719
22039
|
if (cliType === "claude-cli") {
|
|
21720
22040
|
cliArgs.push("--mcp-config", coordinatorSetup.configPath);
|
|
@@ -21723,6 +22043,7 @@ var DaemonCommandRouter = class {
|
|
|
21723
22043
|
cliType,
|
|
21724
22044
|
dir: workspace,
|
|
21725
22045
|
cliArgs: cliArgs.length > 0 ? cliArgs : void 0,
|
|
22046
|
+
env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
|
|
21726
22047
|
settings: {
|
|
21727
22048
|
meshCoordinatorFor: meshId
|
|
21728
22049
|
}
|
|
@@ -23383,11 +23704,11 @@ var ProviderInstanceManager = class {
|
|
|
23383
23704
|
|
|
23384
23705
|
// src/providers/version-archive.ts
|
|
23385
23706
|
var fs11 = __toESM(require("fs"));
|
|
23386
|
-
var
|
|
23387
|
-
var
|
|
23707
|
+
var path22 = __toESM(require("path"));
|
|
23708
|
+
var os20 = __toESM(require("os"));
|
|
23388
23709
|
var import_child_process10 = require("child_process");
|
|
23389
23710
|
var import_os3 = require("os");
|
|
23390
|
-
var ARCHIVE_PATH =
|
|
23711
|
+
var ARCHIVE_PATH = path22.join(os20.homedir(), ".adhdev", "version-history.json");
|
|
23391
23712
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
23392
23713
|
var VersionArchive = class {
|
|
23393
23714
|
history = {};
|
|
@@ -23434,7 +23755,7 @@ var VersionArchive = class {
|
|
|
23434
23755
|
}
|
|
23435
23756
|
save() {
|
|
23436
23757
|
try {
|
|
23437
|
-
fs11.mkdirSync(
|
|
23758
|
+
fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
|
|
23438
23759
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
23439
23760
|
} catch {
|
|
23440
23761
|
}
|
|
@@ -23490,8 +23811,8 @@ function getVersion(binary, versionCommand) {
|
|
|
23490
23811
|
function checkPathExists2(paths) {
|
|
23491
23812
|
for (const p of paths) {
|
|
23492
23813
|
if (p.includes("*")) {
|
|
23493
|
-
const home =
|
|
23494
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
23814
|
+
const home = os20.homedir();
|
|
23815
|
+
const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
|
|
23495
23816
|
if (fs11.existsSync(resolved)) return resolved;
|
|
23496
23817
|
} else {
|
|
23497
23818
|
if (fs11.existsSync(p)) return p;
|
|
@@ -23501,7 +23822,7 @@ function checkPathExists2(paths) {
|
|
|
23501
23822
|
}
|
|
23502
23823
|
function getMacAppVersion(appPath) {
|
|
23503
23824
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
23504
|
-
const plistPath =
|
|
23825
|
+
const plistPath = path22.join(appPath, "Contents", "Info.plist");
|
|
23505
23826
|
if (!fs11.existsSync(plistPath)) return null;
|
|
23506
23827
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
23507
23828
|
return raw || null;
|
|
@@ -23527,7 +23848,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23527
23848
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
23528
23849
|
let resolvedBin = cliBin;
|
|
23529
23850
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
23530
|
-
const bundled =
|
|
23851
|
+
const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
23531
23852
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
23532
23853
|
}
|
|
23533
23854
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -23568,7 +23889,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23568
23889
|
// src/daemon/dev-server.ts
|
|
23569
23890
|
var http2 = __toESM(require("http"));
|
|
23570
23891
|
var fs15 = __toESM(require("fs"));
|
|
23571
|
-
var
|
|
23892
|
+
var path26 = __toESM(require("path"));
|
|
23572
23893
|
init_config();
|
|
23573
23894
|
|
|
23574
23895
|
// src/daemon/scaffold-template.ts
|
|
@@ -23919,7 +24240,7 @@ init_logger();
|
|
|
23919
24240
|
|
|
23920
24241
|
// src/daemon/dev-cdp-handlers.ts
|
|
23921
24242
|
var fs12 = __toESM(require("fs"));
|
|
23922
|
-
var
|
|
24243
|
+
var path23 = __toESM(require("path"));
|
|
23923
24244
|
init_logger();
|
|
23924
24245
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
23925
24246
|
const body = await ctx.readBody(req);
|
|
@@ -24098,17 +24419,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
24098
24419
|
return;
|
|
24099
24420
|
}
|
|
24100
24421
|
let scriptsPath = "";
|
|
24101
|
-
const directScripts =
|
|
24422
|
+
const directScripts = path23.join(dir, "scripts.js");
|
|
24102
24423
|
if (fs12.existsSync(directScripts)) {
|
|
24103
24424
|
scriptsPath = directScripts;
|
|
24104
24425
|
} else {
|
|
24105
|
-
const scriptsDir =
|
|
24426
|
+
const scriptsDir = path23.join(dir, "scripts");
|
|
24106
24427
|
if (fs12.existsSync(scriptsDir)) {
|
|
24107
24428
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
24108
|
-
return fs12.statSync(
|
|
24429
|
+
return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
|
|
24109
24430
|
}).sort().reverse();
|
|
24110
24431
|
for (const ver of versions) {
|
|
24111
|
-
const p =
|
|
24432
|
+
const p = path23.join(scriptsDir, ver, "scripts.js");
|
|
24112
24433
|
if (fs12.existsSync(p)) {
|
|
24113
24434
|
scriptsPath = p;
|
|
24114
24435
|
break;
|
|
@@ -24937,7 +25258,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
24937
25258
|
|
|
24938
25259
|
// src/daemon/dev-cli-debug.ts
|
|
24939
25260
|
var fs13 = __toESM(require("fs"));
|
|
24940
|
-
var
|
|
25261
|
+
var path24 = __toESM(require("path"));
|
|
24941
25262
|
function slugifyFixtureName(value) {
|
|
24942
25263
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24943
25264
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -24947,11 +25268,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
24947
25268
|
if (!providerDir) {
|
|
24948
25269
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
24949
25270
|
}
|
|
24950
|
-
return
|
|
25271
|
+
return path24.join(providerDir, "fixtures");
|
|
24951
25272
|
}
|
|
24952
25273
|
function readCliFixture(ctx, type, name) {
|
|
24953
25274
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
24954
|
-
const filePath =
|
|
25275
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
24955
25276
|
if (!fs13.existsSync(filePath)) {
|
|
24956
25277
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
24957
25278
|
}
|
|
@@ -25718,7 +26039,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
25718
26039
|
},
|
|
25719
26040
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
25720
26041
|
};
|
|
25721
|
-
const filePath =
|
|
26042
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
25722
26043
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
25723
26044
|
ctx.json(res, 200, {
|
|
25724
26045
|
saved: true,
|
|
@@ -25742,7 +26063,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
25742
26063
|
return;
|
|
25743
26064
|
}
|
|
25744
26065
|
const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
25745
|
-
const fullPath =
|
|
26066
|
+
const fullPath = path24.join(fixtureDir, file);
|
|
25746
26067
|
try {
|
|
25747
26068
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
25748
26069
|
return {
|
|
@@ -25878,8 +26199,8 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
25878
26199
|
|
|
25879
26200
|
// src/daemon/dev-auto-implement.ts
|
|
25880
26201
|
var fs14 = __toESM(require("fs"));
|
|
25881
|
-
var
|
|
25882
|
-
var
|
|
26202
|
+
var path25 = __toESM(require("path"));
|
|
26203
|
+
var os21 = __toESM(require("os"));
|
|
25883
26204
|
function getAutoImplPid(ctx) {
|
|
25884
26205
|
const pid = ctx.autoImplProcess?.pid;
|
|
25885
26206
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -25928,22 +26249,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
25928
26249
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
25929
26250
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
25930
26251
|
try {
|
|
25931
|
-
return fs14.statSync(
|
|
26252
|
+
return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
25932
26253
|
} catch {
|
|
25933
26254
|
return false;
|
|
25934
26255
|
}
|
|
25935
26256
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
25936
26257
|
if (versions.length === 0) return null;
|
|
25937
|
-
return
|
|
26258
|
+
return path25.join(scriptsDir, versions[0]);
|
|
25938
26259
|
}
|
|
25939
26260
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
25940
|
-
const canonicalUserDir =
|
|
25941
|
-
const desiredDir = requestedDir ?
|
|
25942
|
-
const upstreamRoot =
|
|
25943
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
26261
|
+
const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
26262
|
+
const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
|
|
26263
|
+
const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
|
|
26264
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
|
|
25944
26265
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
25945
26266
|
}
|
|
25946
|
-
if (
|
|
26267
|
+
if (path25.basename(desiredDir) !== type) {
|
|
25947
26268
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
25948
26269
|
}
|
|
25949
26270
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -25951,11 +26272,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
25951
26272
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
25952
26273
|
}
|
|
25953
26274
|
if (!fs14.existsSync(desiredDir)) {
|
|
25954
|
-
fs14.mkdirSync(
|
|
26275
|
+
fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
25955
26276
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
25956
26277
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
25957
26278
|
}
|
|
25958
|
-
const providerJson =
|
|
26279
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
25959
26280
|
if (!fs14.existsSync(providerJson)) {
|
|
25960
26281
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
25961
26282
|
}
|
|
@@ -25966,13 +26287,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
25966
26287
|
const refDir = ctx.findProviderDir(referenceType);
|
|
25967
26288
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
25968
26289
|
const referenceScripts = {};
|
|
25969
|
-
const scriptsDir =
|
|
26290
|
+
const scriptsDir = path25.join(refDir, "scripts");
|
|
25970
26291
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
25971
26292
|
if (!latestDir) return referenceScripts;
|
|
25972
26293
|
for (const file of fs14.readdirSync(latestDir)) {
|
|
25973
26294
|
if (!file.endsWith(".js")) continue;
|
|
25974
26295
|
try {
|
|
25975
|
-
referenceScripts[file] = fs14.readFileSync(
|
|
26296
|
+
referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
|
|
25976
26297
|
} catch {
|
|
25977
26298
|
}
|
|
25978
26299
|
}
|
|
@@ -26080,9 +26401,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
26080
26401
|
});
|
|
26081
26402
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
26082
26403
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
26083
|
-
const tmpDir =
|
|
26404
|
+
const tmpDir = path25.join(os21.tmpdir(), "adhdev-autoimpl");
|
|
26084
26405
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
26085
|
-
const promptFile =
|
|
26406
|
+
const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
26086
26407
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
26087
26408
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
26088
26409
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -26235,7 +26556,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
26235
26556
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
26236
26557
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
26237
26558
|
let shellCmd;
|
|
26238
|
-
const isWin =
|
|
26559
|
+
const isWin = os21.platform() === "win32";
|
|
26239
26560
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
26240
26561
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
26241
26562
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -26274,7 +26595,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
26274
26595
|
try {
|
|
26275
26596
|
const pty = require("node-pty");
|
|
26276
26597
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
26277
|
-
const isWin2 =
|
|
26598
|
+
const isWin2 = os21.platform() === "win32";
|
|
26278
26599
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
26279
26600
|
name: "xterm-256color",
|
|
26280
26601
|
cols: 120,
|
|
@@ -26514,7 +26835,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26514
26835
|
setMode: "set_mode.js"
|
|
26515
26836
|
};
|
|
26516
26837
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26517
|
-
const scriptsDir =
|
|
26838
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26518
26839
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26519
26840
|
if (latestScriptsDir) {
|
|
26520
26841
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26525,7 +26846,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26525
26846
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
26526
26847
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
26527
26848
|
try {
|
|
26528
|
-
const content = fs14.readFileSync(
|
|
26849
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26529
26850
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26530
26851
|
lines.push("```javascript");
|
|
26531
26852
|
lines.push(content);
|
|
@@ -26542,7 +26863,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26542
26863
|
lines.push("");
|
|
26543
26864
|
for (const file of refFiles) {
|
|
26544
26865
|
try {
|
|
26545
|
-
const content = fs14.readFileSync(
|
|
26866
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26546
26867
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26547
26868
|
lines.push("```javascript");
|
|
26548
26869
|
lines.push(content);
|
|
@@ -26583,10 +26904,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26583
26904
|
lines.push("");
|
|
26584
26905
|
}
|
|
26585
26906
|
}
|
|
26586
|
-
const docsDir =
|
|
26907
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26587
26908
|
const loadGuide = (name) => {
|
|
26588
26909
|
try {
|
|
26589
|
-
const p =
|
|
26910
|
+
const p = path25.join(docsDir, name);
|
|
26590
26911
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26591
26912
|
} catch {
|
|
26592
26913
|
}
|
|
@@ -26823,7 +27144,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26823
27144
|
parseApproval: "parse_approval.js"
|
|
26824
27145
|
};
|
|
26825
27146
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26826
|
-
const scriptsDir =
|
|
27147
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26827
27148
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26828
27149
|
if (latestScriptsDir) {
|
|
26829
27150
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26835,7 +27156,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26835
27156
|
if (!file.endsWith(".js")) continue;
|
|
26836
27157
|
if (!targetFileNames.has(file)) continue;
|
|
26837
27158
|
try {
|
|
26838
|
-
const content = fs14.readFileSync(
|
|
27159
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26839
27160
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26840
27161
|
lines.push("```javascript");
|
|
26841
27162
|
lines.push(content);
|
|
@@ -26851,7 +27172,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26851
27172
|
lines.push("");
|
|
26852
27173
|
for (const file of refFiles) {
|
|
26853
27174
|
try {
|
|
26854
|
-
const content = fs14.readFileSync(
|
|
27175
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26855
27176
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26856
27177
|
lines.push("```javascript");
|
|
26857
27178
|
lines.push(content);
|
|
@@ -26884,10 +27205,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26884
27205
|
lines.push("");
|
|
26885
27206
|
}
|
|
26886
27207
|
}
|
|
26887
|
-
const docsDir =
|
|
27208
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26888
27209
|
const loadGuide = (name) => {
|
|
26889
27210
|
try {
|
|
26890
|
-
const p =
|
|
27211
|
+
const p = path25.join(docsDir, name);
|
|
26891
27212
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26892
27213
|
} catch {
|
|
26893
27214
|
}
|
|
@@ -27334,8 +27655,8 @@ var DevServer = class _DevServer {
|
|
|
27334
27655
|
}
|
|
27335
27656
|
getEndpointList() {
|
|
27336
27657
|
return this.routes.map((r) => {
|
|
27337
|
-
const
|
|
27338
|
-
return `${r.method.padEnd(5)} ${
|
|
27658
|
+
const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
27659
|
+
return `${r.method.padEnd(5)} ${path27}`;
|
|
27339
27660
|
});
|
|
27340
27661
|
}
|
|
27341
27662
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -27623,12 +27944,12 @@ var DevServer = class _DevServer {
|
|
|
27623
27944
|
// ─── DevConsole SPA ───
|
|
27624
27945
|
getConsoleDistDir() {
|
|
27625
27946
|
const candidates = [
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27947
|
+
path26.resolve(__dirname, "../../web-devconsole/dist"),
|
|
27948
|
+
path26.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
27949
|
+
path26.join(process.cwd(), "packages/web-devconsole/dist")
|
|
27629
27950
|
];
|
|
27630
27951
|
for (const dir of candidates) {
|
|
27631
|
-
if (fs15.existsSync(
|
|
27952
|
+
if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
|
|
27632
27953
|
}
|
|
27633
27954
|
return null;
|
|
27634
27955
|
}
|
|
@@ -27638,7 +27959,7 @@ var DevServer = class _DevServer {
|
|
|
27638
27959
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
27639
27960
|
return;
|
|
27640
27961
|
}
|
|
27641
|
-
const htmlPath =
|
|
27962
|
+
const htmlPath = path26.join(distDir, "index.html");
|
|
27642
27963
|
try {
|
|
27643
27964
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
27644
27965
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -27663,15 +27984,15 @@ var DevServer = class _DevServer {
|
|
|
27663
27984
|
this.json(res, 404, { error: "Not found" });
|
|
27664
27985
|
return;
|
|
27665
27986
|
}
|
|
27666
|
-
const safePath =
|
|
27667
|
-
const filePath =
|
|
27987
|
+
const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
|
|
27988
|
+
const filePath = path26.join(distDir, safePath);
|
|
27668
27989
|
if (!filePath.startsWith(distDir)) {
|
|
27669
27990
|
this.json(res, 403, { error: "Forbidden" });
|
|
27670
27991
|
return;
|
|
27671
27992
|
}
|
|
27672
27993
|
try {
|
|
27673
27994
|
const content = fs15.readFileSync(filePath);
|
|
27674
|
-
const ext =
|
|
27995
|
+
const ext = path26.extname(filePath);
|
|
27675
27996
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
27676
27997
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
27677
27998
|
res.end(content);
|
|
@@ -27784,9 +28105,9 @@ var DevServer = class _DevServer {
|
|
|
27784
28105
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
27785
28106
|
if (entry.isDirectory()) {
|
|
27786
28107
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
27787
|
-
scan(
|
|
28108
|
+
scan(path26.join(d, entry.name), rel);
|
|
27788
28109
|
} else {
|
|
27789
|
-
const stat2 = fs15.statSync(
|
|
28110
|
+
const stat2 = fs15.statSync(path26.join(d, entry.name));
|
|
27790
28111
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
27791
28112
|
}
|
|
27792
28113
|
}
|
|
@@ -27809,7 +28130,7 @@ var DevServer = class _DevServer {
|
|
|
27809
28130
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27810
28131
|
return;
|
|
27811
28132
|
}
|
|
27812
|
-
const fullPath =
|
|
28133
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27813
28134
|
if (!fullPath.startsWith(dir)) {
|
|
27814
28135
|
this.json(res, 403, { error: "Forbidden" });
|
|
27815
28136
|
return;
|
|
@@ -27834,14 +28155,14 @@ var DevServer = class _DevServer {
|
|
|
27834
28155
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27835
28156
|
return;
|
|
27836
28157
|
}
|
|
27837
|
-
const fullPath =
|
|
28158
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27838
28159
|
if (!fullPath.startsWith(dir)) {
|
|
27839
28160
|
this.json(res, 403, { error: "Forbidden" });
|
|
27840
28161
|
return;
|
|
27841
28162
|
}
|
|
27842
28163
|
try {
|
|
27843
28164
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
27844
|
-
fs15.mkdirSync(
|
|
28165
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
27845
28166
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
27846
28167
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
27847
28168
|
this.providerLoader.reload();
|
|
@@ -27858,7 +28179,7 @@ var DevServer = class _DevServer {
|
|
|
27858
28179
|
return;
|
|
27859
28180
|
}
|
|
27860
28181
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
27861
|
-
const p =
|
|
28182
|
+
const p = path26.join(dir, name);
|
|
27862
28183
|
if (fs15.existsSync(p)) {
|
|
27863
28184
|
const source = fs15.readFileSync(p, "utf-8");
|
|
27864
28185
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -27879,8 +28200,8 @@ var DevServer = class _DevServer {
|
|
|
27879
28200
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
27880
28201
|
return;
|
|
27881
28202
|
}
|
|
27882
|
-
const target = fs15.existsSync(
|
|
27883
|
-
const targetPath =
|
|
28203
|
+
const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
28204
|
+
const targetPath = path26.join(dir, target);
|
|
27884
28205
|
try {
|
|
27885
28206
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
27886
28207
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -28027,7 +28348,7 @@ var DevServer = class _DevServer {
|
|
|
28027
28348
|
}
|
|
28028
28349
|
let targetDir;
|
|
28029
28350
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
28030
|
-
const jsonPath =
|
|
28351
|
+
const jsonPath = path26.join(targetDir, "provider.json");
|
|
28031
28352
|
if (fs15.existsSync(jsonPath)) {
|
|
28032
28353
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
28033
28354
|
return;
|
|
@@ -28039,8 +28360,8 @@ var DevServer = class _DevServer {
|
|
|
28039
28360
|
const createdFiles = ["provider.json"];
|
|
28040
28361
|
if (result.files) {
|
|
28041
28362
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
28042
|
-
const fullPath =
|
|
28043
|
-
fs15.mkdirSync(
|
|
28363
|
+
const fullPath = path26.join(targetDir, relPath);
|
|
28364
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
28044
28365
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
28045
28366
|
createdFiles.push(relPath);
|
|
28046
28367
|
}
|
|
@@ -28093,22 +28414,22 @@ var DevServer = class _DevServer {
|
|
|
28093
28414
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
28094
28415
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
28095
28416
|
try {
|
|
28096
|
-
return fs15.statSync(
|
|
28417
|
+
return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
28097
28418
|
} catch {
|
|
28098
28419
|
return false;
|
|
28099
28420
|
}
|
|
28100
28421
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
28101
28422
|
if (versions.length === 0) return null;
|
|
28102
|
-
return
|
|
28423
|
+
return path26.join(scriptsDir, versions[0]);
|
|
28103
28424
|
}
|
|
28104
28425
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
28105
|
-
const canonicalUserDir =
|
|
28106
|
-
const desiredDir = requestedDir ?
|
|
28107
|
-
const upstreamRoot =
|
|
28108
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
28426
|
+
const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
28427
|
+
const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
|
|
28428
|
+
const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
|
|
28429
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
|
|
28109
28430
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
28110
28431
|
}
|
|
28111
|
-
if (
|
|
28432
|
+
if (path26.basename(desiredDir) !== type) {
|
|
28112
28433
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
28113
28434
|
}
|
|
28114
28435
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -28116,11 +28437,11 @@ var DevServer = class _DevServer {
|
|
|
28116
28437
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
28117
28438
|
}
|
|
28118
28439
|
if (!fs15.existsSync(desiredDir)) {
|
|
28119
|
-
fs15.mkdirSync(
|
|
28440
|
+
fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
28120
28441
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
28121
28442
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
28122
28443
|
}
|
|
28123
|
-
const providerJson =
|
|
28444
|
+
const providerJson = path26.join(desiredDir, "provider.json");
|
|
28124
28445
|
if (!fs15.existsSync(providerJson)) {
|
|
28125
28446
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
28126
28447
|
}
|
|
@@ -28156,7 +28477,7 @@ var DevServer = class _DevServer {
|
|
|
28156
28477
|
setMode: "set_mode.js"
|
|
28157
28478
|
};
|
|
28158
28479
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28159
|
-
const scriptsDir =
|
|
28480
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28160
28481
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28161
28482
|
if (latestScriptsDir) {
|
|
28162
28483
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28167,7 +28488,7 @@ var DevServer = class _DevServer {
|
|
|
28167
28488
|
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
28168
28489
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
28169
28490
|
try {
|
|
28170
|
-
const content = fs15.readFileSync(
|
|
28491
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28171
28492
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28172
28493
|
lines.push("```javascript");
|
|
28173
28494
|
lines.push(content);
|
|
@@ -28184,7 +28505,7 @@ var DevServer = class _DevServer {
|
|
|
28184
28505
|
lines.push("");
|
|
28185
28506
|
for (const file of refFiles) {
|
|
28186
28507
|
try {
|
|
28187
|
-
const content = fs15.readFileSync(
|
|
28508
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28188
28509
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28189
28510
|
lines.push("```javascript");
|
|
28190
28511
|
lines.push(content);
|
|
@@ -28225,10 +28546,10 @@ var DevServer = class _DevServer {
|
|
|
28225
28546
|
lines.push("");
|
|
28226
28547
|
}
|
|
28227
28548
|
}
|
|
28228
|
-
const docsDir =
|
|
28549
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28229
28550
|
const loadGuide = (name) => {
|
|
28230
28551
|
try {
|
|
28231
|
-
const p =
|
|
28552
|
+
const p = path26.join(docsDir, name);
|
|
28232
28553
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28233
28554
|
} catch {
|
|
28234
28555
|
}
|
|
@@ -28402,7 +28723,7 @@ var DevServer = class _DevServer {
|
|
|
28402
28723
|
parseApproval: "parse_approval.js"
|
|
28403
28724
|
};
|
|
28404
28725
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28405
|
-
const scriptsDir =
|
|
28726
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28406
28727
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28407
28728
|
if (latestScriptsDir) {
|
|
28408
28729
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28414,7 +28735,7 @@ var DevServer = class _DevServer {
|
|
|
28414
28735
|
if (!file.endsWith(".js")) continue;
|
|
28415
28736
|
if (!targetFileNames.has(file)) continue;
|
|
28416
28737
|
try {
|
|
28417
|
-
const content = fs15.readFileSync(
|
|
28738
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28418
28739
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28419
28740
|
lines.push("```javascript");
|
|
28420
28741
|
lines.push(content);
|
|
@@ -28430,7 +28751,7 @@ var DevServer = class _DevServer {
|
|
|
28430
28751
|
lines.push("");
|
|
28431
28752
|
for (const file of refFiles) {
|
|
28432
28753
|
try {
|
|
28433
|
-
const content = fs15.readFileSync(
|
|
28754
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28434
28755
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28435
28756
|
lines.push("```javascript");
|
|
28436
28757
|
lines.push(content);
|
|
@@ -28463,10 +28784,10 @@ var DevServer = class _DevServer {
|
|
|
28463
28784
|
lines.push("");
|
|
28464
28785
|
}
|
|
28465
28786
|
}
|
|
28466
|
-
const docsDir =
|
|
28787
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28467
28788
|
const loadGuide = (name) => {
|
|
28468
28789
|
try {
|
|
28469
|
-
const p =
|
|
28790
|
+
const p = path26.join(docsDir, name);
|
|
28470
28791
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28471
28792
|
} catch {
|
|
28472
28793
|
}
|
|
@@ -29814,6 +30135,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29814
30135
|
createGitWorkspaceMonitor,
|
|
29815
30136
|
createInteractionId,
|
|
29816
30137
|
createMesh,
|
|
30138
|
+
createWorktree,
|
|
29817
30139
|
deleteMesh,
|
|
29818
30140
|
detectAllVersions,
|
|
29819
30141
|
detectCLIs,
|
|
@@ -29866,6 +30188,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29866
30188
|
launchWithCdp,
|
|
29867
30189
|
listHostedCliRuntimes,
|
|
29868
30190
|
listMeshes,
|
|
30191
|
+
listWorktrees,
|
|
29869
30192
|
loadConfig,
|
|
29870
30193
|
loadState,
|
|
29871
30194
|
logCommand,
|
|
@@ -29885,6 +30208,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29885
30208
|
normalizeSessionModalFields,
|
|
29886
30209
|
parsePorcelainV2Status,
|
|
29887
30210
|
parseProviderSourceConfigUpdate,
|
|
30211
|
+
parseWorktreeListOutput,
|
|
29888
30212
|
partitionSessionHostDiagnosticsSessions,
|
|
29889
30213
|
partitionSessionHostRecords,
|
|
29890
30214
|
prepareSessionChatTailUpdate,
|
|
@@ -29894,6 +30218,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29894
30218
|
recordDebugTrace,
|
|
29895
30219
|
registerExtensionProviders,
|
|
29896
30220
|
removeNode,
|
|
30221
|
+
removeWorktree,
|
|
29897
30222
|
resetConfig,
|
|
29898
30223
|
resetDebugRuntimeConfig,
|
|
29899
30224
|
resetState,
|
|
@@ -29903,6 +30228,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29903
30228
|
resolveGitRepository,
|
|
29904
30229
|
resolveSessionHostAppName,
|
|
29905
30230
|
resolveSessionHostAppNameResolution,
|
|
30231
|
+
resolveWorktreePath,
|
|
29906
30232
|
runAsyncBatch,
|
|
29907
30233
|
runGit,
|
|
29908
30234
|
saveConfig,
|