@adhdev/daemon-core 0.9.76-rc.10 → 0.9.76-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/router.d.ts +4 -0
- package/dist/config/mesh-config.d.ts +3 -0
- package/dist/git/git-worktree.d.ts +64 -0
- package/dist/git/index.d.ts +2 -0
- package/dist/index.js +575 -295
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +595 -320
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +1 -0
- package/dist/repo-mesh-types.d.ts +4 -0
- package/package.json +1 -1
- package/src/commands/router.ts +151 -10
- package/src/config/mesh-config.ts +6 -0
- package/src/git/git-worktree.ts +214 -0
- package/src/git/index.ts +14 -0
- package/src/mesh/coordinator-prompt.ts +25 -10
- package/src/repo-mesh-types.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -46,6 +46,134 @@ var init_repo_mesh_types = __esm({
|
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
// src/git/git-worktree.ts
|
|
50
|
+
var git_worktree_exports = {};
|
|
51
|
+
__export(git_worktree_exports, {
|
|
52
|
+
createWorktree: () => createWorktree,
|
|
53
|
+
listWorktrees: () => listWorktrees,
|
|
54
|
+
parseWorktreeListOutput: () => parseWorktreeListOutput,
|
|
55
|
+
removeWorktree: () => removeWorktree,
|
|
56
|
+
resolveWorktreePath: () => resolveWorktreePath
|
|
57
|
+
});
|
|
58
|
+
function resolveWorktreePath(repoRoot, meshName, branch) {
|
|
59
|
+
const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
60
|
+
const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
61
|
+
const parentDir = path4.dirname(repoRoot);
|
|
62
|
+
return path4.join(parentDir, WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
63
|
+
}
|
|
64
|
+
async function createWorktree(opts) {
|
|
65
|
+
const { repoRoot, branch, baseBranch, meshName } = opts;
|
|
66
|
+
const targetDir = opts.targetDir || resolveWorktreePath(repoRoot, meshName, branch);
|
|
67
|
+
if ((0, import_node_fs2.existsSync)(targetDir)) {
|
|
68
|
+
throw new Error(`Worktree target directory already exists: ${targetDir}`);
|
|
69
|
+
}
|
|
70
|
+
await (0, import_promises3.mkdir)(path4.dirname(targetDir), { recursive: true });
|
|
71
|
+
const args = ["worktree", "add", targetDir, "-b", branch];
|
|
72
|
+
if (baseBranch) {
|
|
73
|
+
args.push(baseBranch);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await execFileAsync2("git", args, {
|
|
77
|
+
cwd: repoRoot,
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
timeout: GIT_TIMEOUT_MS,
|
|
80
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
81
|
+
windowsHide: true
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const stderr = typeof error.stderr === "string" ? error.stderr : "";
|
|
85
|
+
if (/already exists/i.test(stderr)) {
|
|
86
|
+
throw new Error(`Branch '${branch}' already exists or is checked out in another worktree`);
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`git worktree add failed: ${stderr.trim() || error.message}`);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
worktreePath: targetDir,
|
|
93
|
+
branch
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function removeWorktree(repoRoot, worktreePath) {
|
|
97
|
+
if (!(0, import_node_fs2.existsSync)(worktreePath)) {
|
|
98
|
+
await pruneWorktrees(repoRoot);
|
|
99
|
+
return { success: true, removedPath: worktreePath };
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
await execFileAsync2("git", ["worktree", "remove", worktreePath, "--force"], {
|
|
103
|
+
cwd: repoRoot,
|
|
104
|
+
encoding: "utf8",
|
|
105
|
+
timeout: GIT_TIMEOUT_MS,
|
|
106
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
107
|
+
windowsHide: true
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const stderr = typeof error.stderr === "string" ? error.stderr : "";
|
|
111
|
+
throw new Error(`git worktree remove failed: ${stderr.trim() || error.message}`);
|
|
112
|
+
}
|
|
113
|
+
return { success: true, removedPath: worktreePath };
|
|
114
|
+
}
|
|
115
|
+
async function listWorktrees(repoRoot) {
|
|
116
|
+
const { stdout } = await execFileAsync2("git", ["worktree", "list", "--porcelain"], {
|
|
117
|
+
cwd: repoRoot,
|
|
118
|
+
encoding: "utf8",
|
|
119
|
+
timeout: GIT_TIMEOUT_MS,
|
|
120
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
121
|
+
windowsHide: true
|
|
122
|
+
});
|
|
123
|
+
return parseWorktreeListOutput(stdout);
|
|
124
|
+
}
|
|
125
|
+
function parseWorktreeListOutput(output) {
|
|
126
|
+
const entries = [];
|
|
127
|
+
const blocks = output.trim().split(/\n\n+/);
|
|
128
|
+
for (const block of blocks) {
|
|
129
|
+
if (!block.trim()) continue;
|
|
130
|
+
const lines = block.trim().split("\n");
|
|
131
|
+
const entry = { path: "", head: "", branch: null, bare: false };
|
|
132
|
+
for (const line of lines) {
|
|
133
|
+
if (line.startsWith("worktree ")) {
|
|
134
|
+
entry.path = line.slice("worktree ".length).trim();
|
|
135
|
+
} else if (line.startsWith("HEAD ")) {
|
|
136
|
+
entry.head = line.slice("HEAD ".length).trim();
|
|
137
|
+
} else if (line.startsWith("branch ")) {
|
|
138
|
+
const ref = line.slice("branch ".length).trim();
|
|
139
|
+
entry.branch = ref.replace(/^refs\/heads\//, "");
|
|
140
|
+
} else if (line === "bare") {
|
|
141
|
+
entry.bare = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (entry.path) {
|
|
145
|
+
entries.push(entry);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return entries;
|
|
149
|
+
}
|
|
150
|
+
async function pruneWorktrees(repoRoot) {
|
|
151
|
+
try {
|
|
152
|
+
await execFileAsync2("git", ["worktree", "prune"], {
|
|
153
|
+
cwd: repoRoot,
|
|
154
|
+
encoding: "utf8",
|
|
155
|
+
timeout: GIT_TIMEOUT_MS,
|
|
156
|
+
windowsHide: true
|
|
157
|
+
});
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
var path4, import_promises3, import_node_fs2, import_node_child_process2, import_node_util2, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER;
|
|
162
|
+
var init_git_worktree = __esm({
|
|
163
|
+
"src/git/git-worktree.ts"() {
|
|
164
|
+
"use strict";
|
|
165
|
+
path4 = __toESM(require("path"));
|
|
166
|
+
import_promises3 = require("fs/promises");
|
|
167
|
+
import_node_fs2 = require("fs");
|
|
168
|
+
import_node_child_process2 = require("child_process");
|
|
169
|
+
import_node_util2 = require("util");
|
|
170
|
+
execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
171
|
+
WORKTREE_DIR_NAME = ".adhdev-worktrees";
|
|
172
|
+
GIT_TIMEOUT_MS = 3e4;
|
|
173
|
+
GIT_MAX_BUFFER = 4 * 1024 * 1024;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
49
177
|
// src/config/config.ts
|
|
50
178
|
var config_exports = {};
|
|
51
179
|
__export(config_exports, {
|
|
@@ -304,10 +432,10 @@ function getMeshConfigPath() {
|
|
|
304
432
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
305
433
|
}
|
|
306
434
|
function loadMeshConfig() {
|
|
307
|
-
const
|
|
308
|
-
if (!(0, import_fs2.existsSync)(
|
|
435
|
+
const path27 = getMeshConfigPath();
|
|
436
|
+
if (!(0, import_fs2.existsSync)(path27)) return { meshes: [] };
|
|
309
437
|
try {
|
|
310
|
-
const raw = JSON.parse((0, import_fs2.readFileSync)(
|
|
438
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path27, "utf-8"));
|
|
311
439
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
312
440
|
return raw;
|
|
313
441
|
} catch {
|
|
@@ -315,16 +443,16 @@ function loadMeshConfig() {
|
|
|
315
443
|
}
|
|
316
444
|
}
|
|
317
445
|
function saveMeshConfig(config) {
|
|
318
|
-
const
|
|
319
|
-
(0, import_fs2.writeFileSync)(
|
|
446
|
+
const path27 = getMeshConfigPath();
|
|
447
|
+
(0, import_fs2.writeFileSync)(path27, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
320
448
|
}
|
|
321
449
|
function normalizeRepoIdentity(remoteUrl) {
|
|
322
450
|
let identity = remoteUrl.trim();
|
|
323
451
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
324
452
|
try {
|
|
325
453
|
const url = new URL(identity);
|
|
326
|
-
const
|
|
327
|
-
return `${url.hostname}/${
|
|
454
|
+
const path27 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
455
|
+
return `${url.hostname}/${path27}`;
|
|
328
456
|
} catch {
|
|
329
457
|
}
|
|
330
458
|
}
|
|
@@ -399,9 +527,12 @@ function addNode(meshId, opts) {
|
|
|
399
527
|
id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
|
|
400
528
|
workspace: opts.workspace.trim(),
|
|
401
529
|
repoRoot: opts.repoRoot,
|
|
530
|
+
daemonId: opts.daemonId,
|
|
402
531
|
userOverrides: opts.userOverrides || {},
|
|
403
532
|
policy: opts.policy || {},
|
|
404
|
-
isLocalWorktree: opts.isLocalWorktree
|
|
533
|
+
isLocalWorktree: opts.isLocalWorktree,
|
|
534
|
+
worktreeBranch: opts.worktreeBranch,
|
|
535
|
+
clonedFromNodeId: opts.clonedFromNodeId
|
|
405
536
|
};
|
|
406
537
|
mesh.nodes.push(node);
|
|
407
538
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -449,7 +580,7 @@ __export(coordinator_prompt_exports, {
|
|
|
449
580
|
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt
|
|
450
581
|
});
|
|
451
582
|
function buildCoordinatorSystemPrompt(ctx) {
|
|
452
|
-
const { mesh, status, userInstruction } = ctx;
|
|
583
|
+
const { mesh, status, userInstruction, coordinatorCliType } = ctx;
|
|
453
584
|
const sections = [];
|
|
454
585
|
sections.push(`You are a **Repo Mesh Coordinator** \u2014 a technical team lead who orchestrates work across multiple agent sessions on a shared Git repository.
|
|
455
586
|
|
|
@@ -463,15 +594,15 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
|
463
594
|
} else {
|
|
464
595
|
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
465
596
|
}
|
|
466
|
-
sections.push(buildPolicySection(mesh.policy));
|
|
597
|
+
sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
|
|
467
598
|
sections.push(TOOLS_SECTION);
|
|
468
599
|
sections.push(WORKFLOW_SECTION);
|
|
469
|
-
sections.push(
|
|
600
|
+
sections.push(buildRulesSection(coordinatorCliType));
|
|
470
601
|
if (userInstruction) {
|
|
471
602
|
sections.push(`## Additional Context
|
|
472
603
|
${userInstruction}`);
|
|
473
604
|
}
|
|
474
|
-
if (mesh.coordinator
|
|
605
|
+
if (mesh.coordinator?.systemPromptSuffix) {
|
|
475
606
|
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
476
607
|
}
|
|
477
608
|
return sections.join("\n\n");
|
|
@@ -516,10 +647,29 @@ function buildPolicySection(policy) {
|
|
|
516
647
|
return `## Policy
|
|
517
648
|
${rules.join("\n")}`;
|
|
518
649
|
}
|
|
519
|
-
|
|
650
|
+
function buildRulesSection(coordinatorCliType) {
|
|
651
|
+
const coordinatorNote = coordinatorCliType ? `
|
|
652
|
+
- **Coordinator runtime is not a delegation default.** This coordinator is running as \`${coordinatorCliType}\`, but delegated node sessions must follow the user's requested provider, not the coordinator's own runtime.` : "";
|
|
653
|
+
return `## Rules
|
|
654
|
+
|
|
655
|
+
- **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
|
|
656
|
+
- **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
|
|
657
|
+
- **Respect explicit provider requests.** If the user names an agent/provider, pass the matching provider type to \`mesh_launch_session\`: Hermes \u2192 \`hermes-cli\`, Claude Code/Claude \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`. Never substitute \`claude-cli\` just because the coordinator itself is Claude Code.
|
|
658
|
+
- **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
|
|
659
|
+
- **Don't inspect code.** Trust the agent's output. Verify via \`mesh_git_status\`, not by reading source files.
|
|
660
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
661
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
662
|
+
- **Keep the user informed.** Report progress after each delegation round \u2014 one or two sentences, not a narration.
|
|
663
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
664
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.
|
|
665
|
+
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
666
|
+
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
667
|
+
}
|
|
668
|
+
var TOOLS_SECTION, WORKFLOW_SECTION;
|
|
520
669
|
var init_coordinator_prompt = __esm({
|
|
521
670
|
"src/mesh/coordinator-prompt.ts"() {
|
|
522
671
|
"use strict";
|
|
672
|
+
init_repo_mesh_types();
|
|
523
673
|
TOOLS_SECTION = `## Available Tools
|
|
524
674
|
|
|
525
675
|
| Tool | Purpose |
|
|
@@ -531,30 +681,23 @@ var init_coordinator_prompt = __esm({
|
|
|
531
681
|
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
532
682
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
533
683
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
534
|
-
| \`mesh_approve\` | Approve/reject a pending agent action
|
|
684
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
685
|
+
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
686
|
+
| \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
|
|
535
687
|
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
536
688
|
|
|
537
689
|
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
538
690
|
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
539
691
|
3. **Delegate** \u2014 For each task:
|
|
540
692
|
a. Pick the best node (consider: health, dirty state, current workload).
|
|
541
|
-
b. If
|
|
542
|
-
c.
|
|
693
|
+
b. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
|
|
694
|
+
c. If no session exists, call \`mesh_launch_session\` to start one.
|
|
695
|
+
d. Call \`mesh_send_task\` with a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
|
|
543
696
|
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
544
697
|
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
545
698
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
546
|
-
7. **
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
- **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
|
|
550
|
-
- **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
|
|
551
|
-
- **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
|
|
552
|
-
- **Don't inspect code.** Trust the agent's output. Verify via \`mesh_git_status\`, not by reading source files.
|
|
553
|
-
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
554
|
-
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
555
|
-
- **Keep the user informed.** Report progress after each delegation round \u2014 one or two sentences, not a narration.
|
|
556
|
-
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
557
|
-
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
699
|
+
7. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
700
|
+
8. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
558
701
|
}
|
|
559
702
|
});
|
|
560
703
|
|
|
@@ -573,13 +716,13 @@ function getDaemonLogDir() {
|
|
|
573
716
|
return LOG_DIR;
|
|
574
717
|
}
|
|
575
718
|
function getCurrentDaemonLogPath(date = /* @__PURE__ */ new Date()) {
|
|
576
|
-
return
|
|
719
|
+
return path10.join(LOG_DIR, `daemon-${date.toISOString().slice(0, 10)}.log`);
|
|
577
720
|
}
|
|
578
721
|
function checkDateRotation() {
|
|
579
722
|
const today = getDateStr();
|
|
580
723
|
if (today !== currentDate) {
|
|
581
724
|
currentDate = today;
|
|
582
|
-
currentLogFile =
|
|
725
|
+
currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
583
726
|
cleanOldLogs();
|
|
584
727
|
}
|
|
585
728
|
}
|
|
@@ -593,7 +736,7 @@ function cleanOldLogs() {
|
|
|
593
736
|
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
594
737
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
595
738
|
try {
|
|
596
|
-
fs2.unlinkSync(
|
|
739
|
+
fs2.unlinkSync(path10.join(LOG_DIR, file));
|
|
597
740
|
} catch {
|
|
598
741
|
}
|
|
599
742
|
}
|
|
@@ -709,17 +852,17 @@ function installGlobalInterceptor() {
|
|
|
709
852
|
writeToFile(`Log file: ${currentLogFile}`);
|
|
710
853
|
writeToFile(`Log level: ${currentLevel}`);
|
|
711
854
|
}
|
|
712
|
-
var fs2,
|
|
855
|
+
var fs2, path10, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
|
|
713
856
|
var init_logger = __esm({
|
|
714
857
|
"src/logging/logger.ts"() {
|
|
715
858
|
"use strict";
|
|
716
859
|
fs2 = __toESM(require("fs"));
|
|
717
|
-
|
|
860
|
+
path10 = __toESM(require("path"));
|
|
718
861
|
os4 = __toESM(require("os"));
|
|
719
862
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
720
863
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
721
864
|
currentLevel = "info";
|
|
722
|
-
LOG_DIR = process.platform === "win32" ?
|
|
865
|
+
LOG_DIR = process.platform === "win32" ? path10.join(process.env.LOCALAPPDATA || process.env.APPDATA || path10.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path10.join(os4.homedir(), "Library", "Logs", "adhdev") : path10.join(os4.homedir(), ".local", "share", "adhdev", "logs");
|
|
723
866
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
724
867
|
MAX_LOG_DAYS = 7;
|
|
725
868
|
try {
|
|
@@ -727,16 +870,16 @@ var init_logger = __esm({
|
|
|
727
870
|
} catch {
|
|
728
871
|
}
|
|
729
872
|
currentDate = getDateStr();
|
|
730
|
-
currentLogFile =
|
|
873
|
+
currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
731
874
|
cleanOldLogs();
|
|
732
875
|
try {
|
|
733
|
-
const oldLog =
|
|
876
|
+
const oldLog = path10.join(LOG_DIR, "daemon.log");
|
|
734
877
|
if (fs2.existsSync(oldLog)) {
|
|
735
878
|
const stat2 = fs2.statSync(oldLog);
|
|
736
879
|
const oldDate = stat2.mtime.toISOString().slice(0, 10);
|
|
737
|
-
fs2.renameSync(oldLog,
|
|
880
|
+
fs2.renameSync(oldLog, path10.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
738
881
|
}
|
|
739
|
-
const oldLogBackup =
|
|
882
|
+
const oldLogBackup = path10.join(LOG_DIR, "daemon.log.old");
|
|
740
883
|
if (fs2.existsSync(oldLogBackup)) {
|
|
741
884
|
fs2.unlinkSync(oldLogBackup);
|
|
742
885
|
}
|
|
@@ -768,7 +911,7 @@ var init_logger = __esm({
|
|
|
768
911
|
}
|
|
769
912
|
};
|
|
770
913
|
interceptorInstalled = false;
|
|
771
|
-
LOG_PATH =
|
|
914
|
+
LOG_PATH = path10.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
772
915
|
}
|
|
773
916
|
});
|
|
774
917
|
|
|
@@ -1236,9 +1379,9 @@ function buildCliScreenSnapshot(text) {
|
|
|
1236
1379
|
function findBinary(name) {
|
|
1237
1380
|
const trimmed = String(name || "").trim();
|
|
1238
1381
|
if (!trimmed) return trimmed;
|
|
1239
|
-
const expanded = trimmed.startsWith("~") ?
|
|
1240
|
-
if (
|
|
1241
|
-
return
|
|
1382
|
+
const expanded = trimmed.startsWith("~") ? path14.join(os9.homedir(), trimmed.slice(1)) : trimmed;
|
|
1383
|
+
if (path14.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
1384
|
+
return path14.isAbsolute(expanded) ? expanded : path14.resolve(expanded);
|
|
1242
1385
|
}
|
|
1243
1386
|
const isWin = os9.platform() === "win32";
|
|
1244
1387
|
try {
|
|
@@ -1254,7 +1397,7 @@ function findBinary(name) {
|
|
|
1254
1397
|
}
|
|
1255
1398
|
}
|
|
1256
1399
|
function isScriptBinary(binaryPath) {
|
|
1257
|
-
if (!
|
|
1400
|
+
if (!path14.isAbsolute(binaryPath)) return false;
|
|
1258
1401
|
try {
|
|
1259
1402
|
const fs16 = require("fs");
|
|
1260
1403
|
const resolved = fs16.realpathSync(binaryPath);
|
|
@@ -1270,7 +1413,7 @@ function isScriptBinary(binaryPath) {
|
|
|
1270
1413
|
}
|
|
1271
1414
|
}
|
|
1272
1415
|
function looksLikeMachOOrElf(filePath) {
|
|
1273
|
-
if (!
|
|
1416
|
+
if (!path14.isAbsolute(filePath)) return false;
|
|
1274
1417
|
try {
|
|
1275
1418
|
const fs16 = require("fs");
|
|
1276
1419
|
const resolved = fs16.realpathSync(filePath);
|
|
@@ -1359,12 +1502,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
1359
1502
|
}
|
|
1360
1503
|
};
|
|
1361
1504
|
}
|
|
1362
|
-
var os9,
|
|
1505
|
+
var os9, path14, import_child_process4, buildCliSpawnEnv;
|
|
1363
1506
|
var init_provider_cli_shared = __esm({
|
|
1364
1507
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
1365
1508
|
"use strict";
|
|
1366
1509
|
os9 = __toESM(require("os"));
|
|
1367
|
-
|
|
1510
|
+
path14 = __toESM(require("path"));
|
|
1368
1511
|
import_child_process4 = require("child_process");
|
|
1369
1512
|
init_spawn_env();
|
|
1370
1513
|
buildCliSpawnEnv = import_session_host_core.sanitizeSpawnEnv;
|
|
@@ -1495,9 +1638,9 @@ function resolveCliSpawnPlan(options) {
|
|
|
1495
1638
|
const allArgs = [...spawnConfig.args, ...extraArgs];
|
|
1496
1639
|
let shellCmd;
|
|
1497
1640
|
let shellArgs;
|
|
1498
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
1641
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path15.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1499
1642
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
1500
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
1643
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path15.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
1501
1644
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
1502
1645
|
if (useShell) {
|
|
1503
1646
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -1573,12 +1716,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
1573
1716
|
}
|
|
1574
1717
|
return "";
|
|
1575
1718
|
}
|
|
1576
|
-
var os10,
|
|
1719
|
+
var os10, path15, import_session_host_core2;
|
|
1577
1720
|
var init_provider_cli_runtime = __esm({
|
|
1578
1721
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
1579
1722
|
"use strict";
|
|
1580
1723
|
os10 = __toESM(require("os"));
|
|
1581
|
-
|
|
1724
|
+
path15 = __toESM(require("path"));
|
|
1582
1725
|
import_session_host_core2 = require("@adhdev/session-host-core");
|
|
1583
1726
|
init_provider_cli_shared();
|
|
1584
1727
|
}
|
|
@@ -3728,6 +3871,7 @@ __export(index_exports, {
|
|
|
3728
3871
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
|
|
3729
3872
|
createInteractionId: () => createInteractionId,
|
|
3730
3873
|
createMesh: () => createMesh,
|
|
3874
|
+
createWorktree: () => createWorktree,
|
|
3731
3875
|
deleteMesh: () => deleteMesh,
|
|
3732
3876
|
detectAllVersions: () => detectAllVersions,
|
|
3733
3877
|
detectCLIs: () => detectCLIs,
|
|
@@ -3780,6 +3924,7 @@ __export(index_exports, {
|
|
|
3780
3924
|
launchWithCdp: () => launchWithCdp,
|
|
3781
3925
|
listHostedCliRuntimes: () => listHostedCliRuntimes,
|
|
3782
3926
|
listMeshes: () => listMeshes,
|
|
3927
|
+
listWorktrees: () => listWorktrees,
|
|
3783
3928
|
loadConfig: () => loadConfig,
|
|
3784
3929
|
loadState: () => loadState,
|
|
3785
3930
|
logCommand: () => logCommand,
|
|
@@ -3799,6 +3944,7 @@ __export(index_exports, {
|
|
|
3799
3944
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
3800
3945
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
3801
3946
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
3947
|
+
parseWorktreeListOutput: () => parseWorktreeListOutput,
|
|
3802
3948
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
3803
3949
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
3804
3950
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
|
|
@@ -3808,6 +3954,7 @@ __export(index_exports, {
|
|
|
3808
3954
|
recordDebugTrace: () => recordDebugTrace,
|
|
3809
3955
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
3810
3956
|
removeNode: () => removeNode,
|
|
3957
|
+
removeWorktree: () => removeWorktree,
|
|
3811
3958
|
resetConfig: () => resetConfig,
|
|
3812
3959
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
3813
3960
|
resetState: () => resetState,
|
|
@@ -3817,6 +3964,7 @@ __export(index_exports, {
|
|
|
3817
3964
|
resolveGitRepository: () => resolveGitRepository,
|
|
3818
3965
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
3819
3966
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
|
|
3967
|
+
resolveWorktreePath: () => resolveWorktreePath,
|
|
3820
3968
|
runAsyncBatch: () => runAsyncBatch,
|
|
3821
3969
|
runGit: () => runGit,
|
|
3822
3970
|
saveConfig: () => saveConfig,
|
|
@@ -5176,20 +5324,23 @@ var TurnSnapshotTracker = class {
|
|
|
5176
5324
|
}
|
|
5177
5325
|
};
|
|
5178
5326
|
|
|
5327
|
+
// src/git/index.ts
|
|
5328
|
+
init_git_worktree();
|
|
5329
|
+
|
|
5179
5330
|
// src/index.ts
|
|
5180
5331
|
init_config();
|
|
5181
5332
|
|
|
5182
5333
|
// src/config/workspaces.ts
|
|
5183
5334
|
var fs = __toESM(require("fs"));
|
|
5184
5335
|
var os = __toESM(require("os"));
|
|
5185
|
-
var
|
|
5336
|
+
var path5 = __toESM(require("path"));
|
|
5186
5337
|
var import_crypto2 = require("crypto");
|
|
5187
5338
|
var MAX_WORKSPACES = 50;
|
|
5188
5339
|
function expandPath(p) {
|
|
5189
5340
|
const t = (p || "").trim();
|
|
5190
5341
|
if (!t) return "";
|
|
5191
|
-
if (t.startsWith("~")) return
|
|
5192
|
-
return
|
|
5342
|
+
if (t.startsWith("~")) return path5.join(os.homedir(), t.slice(1).replace(/^\//, ""));
|
|
5343
|
+
return path5.resolve(t);
|
|
5193
5344
|
}
|
|
5194
5345
|
function validateWorkspacePath(absPath) {
|
|
5195
5346
|
try {
|
|
@@ -5203,7 +5354,7 @@ function validateWorkspacePath(absPath) {
|
|
|
5203
5354
|
}
|
|
5204
5355
|
}
|
|
5205
5356
|
function defaultWorkspaceLabel(absPath) {
|
|
5206
|
-
const base =
|
|
5357
|
+
const base = path5.basename(absPath) || absPath;
|
|
5207
5358
|
return base;
|
|
5208
5359
|
}
|
|
5209
5360
|
function getDefaultWorkspacePath(config) {
|
|
@@ -5294,9 +5445,9 @@ function resolveIdeLaunchWorkspace(args, config) {
|
|
|
5294
5445
|
return getDefaultWorkspacePath(config) || void 0;
|
|
5295
5446
|
}
|
|
5296
5447
|
function findWorkspaceByPath(config, rawPath) {
|
|
5297
|
-
const abs =
|
|
5448
|
+
const abs = path5.resolve(expandPath(rawPath));
|
|
5298
5449
|
if (!abs) return void 0;
|
|
5299
|
-
return (config.workspaces || []).find((w) =>
|
|
5450
|
+
return (config.workspaces || []).find((w) => path5.resolve(expandPath(w.path)) === abs);
|
|
5300
5451
|
}
|
|
5301
5452
|
function addWorkspaceEntry(config, rawPath, label, options) {
|
|
5302
5453
|
const abs = expandPath(rawPath);
|
|
@@ -5312,7 +5463,7 @@ function addWorkspaceEntry(config, rawPath, label, options) {
|
|
|
5312
5463
|
const v = validateWorkspacePath(abs);
|
|
5313
5464
|
if (!v.ok) return { error: v.error };
|
|
5314
5465
|
const list = [...config.workspaces || []];
|
|
5315
|
-
if (list.some((w) =>
|
|
5466
|
+
if (list.some((w) => path5.resolve(w.path) === abs)) {
|
|
5316
5467
|
return { error: "Workspace already in list" };
|
|
5317
5468
|
}
|
|
5318
5469
|
if (list.length >= MAX_WORKSPACES) {
|
|
@@ -5346,7 +5497,7 @@ function setDefaultWorkspaceId(config, id) {
|
|
|
5346
5497
|
}
|
|
5347
5498
|
|
|
5348
5499
|
// src/config/recent-activity.ts
|
|
5349
|
-
var
|
|
5500
|
+
var path6 = __toESM(require("path"));
|
|
5350
5501
|
|
|
5351
5502
|
// src/providers/summary-metadata.ts
|
|
5352
5503
|
function normalizeSummaryItem(item) {
|
|
@@ -5415,9 +5566,9 @@ var MAX_ACTIVITY = 30;
|
|
|
5415
5566
|
function normalizeWorkspace(workspace) {
|
|
5416
5567
|
if (!workspace) return "";
|
|
5417
5568
|
try {
|
|
5418
|
-
return
|
|
5569
|
+
return path6.resolve(expandPath(workspace));
|
|
5419
5570
|
} catch {
|
|
5420
|
-
return
|
|
5571
|
+
return path6.resolve(workspace);
|
|
5421
5572
|
}
|
|
5422
5573
|
}
|
|
5423
5574
|
function buildRecentActivityKey(entry) {
|
|
@@ -5585,14 +5736,14 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
|
|
|
5585
5736
|
}
|
|
5586
5737
|
|
|
5587
5738
|
// src/config/saved-sessions.ts
|
|
5588
|
-
var
|
|
5739
|
+
var path7 = __toESM(require("path"));
|
|
5589
5740
|
var MAX_SAVED_SESSIONS = 500;
|
|
5590
5741
|
function normalizeWorkspace2(workspace) {
|
|
5591
5742
|
if (!workspace) return "";
|
|
5592
5743
|
try {
|
|
5593
|
-
return
|
|
5744
|
+
return path7.resolve(expandPath(workspace));
|
|
5594
5745
|
} catch {
|
|
5595
|
-
return
|
|
5746
|
+
return path7.resolve(workspace);
|
|
5596
5747
|
}
|
|
5597
5748
|
}
|
|
5598
5749
|
function buildSavedProviderSessionKey(providerSessionId) {
|
|
@@ -5771,7 +5922,7 @@ function resetState() {
|
|
|
5771
5922
|
var import_child_process = require("child_process");
|
|
5772
5923
|
var import_fs4 = require("fs");
|
|
5773
5924
|
var import_os2 = require("os");
|
|
5774
|
-
var
|
|
5925
|
+
var path8 = __toESM(require("path"));
|
|
5775
5926
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
5776
5927
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
5777
5928
|
function registerIDEDefinition(def) {
|
|
@@ -5790,9 +5941,9 @@ function getMergedDefinitions() {
|
|
|
5790
5941
|
function findCliCommand(command) {
|
|
5791
5942
|
const trimmed = String(command || "").trim();
|
|
5792
5943
|
if (!trimmed) return null;
|
|
5793
|
-
if (
|
|
5794
|
-
const candidate = trimmed.startsWith("~") ?
|
|
5795
|
-
const resolved =
|
|
5944
|
+
if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
5945
|
+
const candidate = trimmed.startsWith("~") ? path8.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
5946
|
+
const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
|
|
5796
5947
|
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
5797
5948
|
}
|
|
5798
5949
|
try {
|
|
@@ -5820,7 +5971,7 @@ function getIdeVersion(cliCommand) {
|
|
|
5820
5971
|
function checkPathExists(paths) {
|
|
5821
5972
|
const home = (0, import_os2.homedir)();
|
|
5822
5973
|
for (const p of paths) {
|
|
5823
|
-
const normalized = p.startsWith("~") ?
|
|
5974
|
+
const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
|
|
5824
5975
|
if (normalized.includes("*")) {
|
|
5825
5976
|
const username = home.split(/[\\/]/).pop() || "";
|
|
5826
5977
|
const resolved = normalized.replace("*", username);
|
|
@@ -5843,8 +5994,8 @@ async function detectIDEs(providerLoader) {
|
|
|
5843
5994
|
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
5844
5995
|
}
|
|
5845
5996
|
if (!resolvedCli && appPath && os21 === "win32") {
|
|
5846
|
-
const { dirname:
|
|
5847
|
-
const appDir =
|
|
5997
|
+
const { dirname: dirname9 } = await import("path");
|
|
5998
|
+
const appDir = dirname9(appPath);
|
|
5848
5999
|
const candidates = [
|
|
5849
6000
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
5850
6001
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -5878,7 +6029,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5878
6029
|
// src/detection/cli-detector.ts
|
|
5879
6030
|
var import_child_process2 = require("child_process");
|
|
5880
6031
|
var os2 = __toESM(require("os"));
|
|
5881
|
-
var
|
|
6032
|
+
var path9 = __toESM(require("path"));
|
|
5882
6033
|
var import_fs5 = require("fs");
|
|
5883
6034
|
function parseVersion(raw) {
|
|
5884
6035
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -5891,18 +6042,18 @@ function shellQuote(value) {
|
|
|
5891
6042
|
function expandHome(value) {
|
|
5892
6043
|
const trimmed = value.trim();
|
|
5893
6044
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
5894
|
-
return
|
|
6045
|
+
return path9.join(os2.homedir(), trimmed.slice(1));
|
|
5895
6046
|
}
|
|
5896
6047
|
function isExplicitCommandPath(command) {
|
|
5897
6048
|
const trimmed = command.trim();
|
|
5898
|
-
return
|
|
6049
|
+
return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
5899
6050
|
}
|
|
5900
6051
|
function resolveCommandPath(command) {
|
|
5901
6052
|
const trimmed = command.trim();
|
|
5902
6053
|
if (!trimmed) return null;
|
|
5903
6054
|
if (isExplicitCommandPath(trimmed)) {
|
|
5904
6055
|
const expanded = expandHome(trimmed);
|
|
5905
|
-
const candidate =
|
|
6056
|
+
const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
|
|
5906
6057
|
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
5907
6058
|
}
|
|
5908
6059
|
return null;
|
|
@@ -8171,9 +8322,9 @@ ${cleanBody}`;
|
|
|
8171
8322
|
|
|
8172
8323
|
// src/config/chat-history.ts
|
|
8173
8324
|
var fs3 = __toESM(require("fs"));
|
|
8174
|
-
var
|
|
8325
|
+
var path11 = __toESM(require("path"));
|
|
8175
8326
|
var os5 = __toESM(require("os"));
|
|
8176
|
-
var HISTORY_DIR =
|
|
8327
|
+
var HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
|
|
8177
8328
|
var RETAIN_DAYS = 30;
|
|
8178
8329
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
8179
8330
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -8336,7 +8487,7 @@ function extractSavedHistorySessionIdFromFile(file) {
|
|
|
8336
8487
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
8337
8488
|
return new Map(files.map((file) => {
|
|
8338
8489
|
try {
|
|
8339
|
-
const stat2 = fs3.statSync(
|
|
8490
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8340
8491
|
return [file, `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`];
|
|
8341
8492
|
} catch {
|
|
8342
8493
|
return [file, `${file}:missing`];
|
|
@@ -8347,7 +8498,7 @@ function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
|
8347
8498
|
return files.map((file) => fileSignatures.get(file) || `${file}:missing`).join("|");
|
|
8348
8499
|
}
|
|
8349
8500
|
function getSavedHistoryIndexFilePath(dir) {
|
|
8350
|
-
return
|
|
8501
|
+
return path11.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
8351
8502
|
}
|
|
8352
8503
|
function getSavedHistoryIndexLockPath(dir) {
|
|
8353
8504
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -8449,7 +8600,7 @@ function savePersistedSavedHistoryIndex(dir, entries) {
|
|
|
8449
8600
|
}
|
|
8450
8601
|
for (const file of Array.from(currentEntries.keys())) {
|
|
8451
8602
|
if (incomingFiles.has(file)) continue;
|
|
8452
|
-
if (!fs3.existsSync(
|
|
8603
|
+
if (!fs3.existsSync(path11.join(dir, file))) {
|
|
8453
8604
|
currentEntries.delete(file);
|
|
8454
8605
|
}
|
|
8455
8606
|
}
|
|
@@ -8475,7 +8626,7 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8475
8626
|
const indexStat = fs3.statSync(getSavedHistoryIndexFilePath(dir));
|
|
8476
8627
|
const files = listHistoryFiles(dir);
|
|
8477
8628
|
for (const file of files) {
|
|
8478
|
-
const stat2 = fs3.statSync(
|
|
8629
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8479
8630
|
if (stat2.mtimeMs > indexStat.mtimeMs) return true;
|
|
8480
8631
|
}
|
|
8481
8632
|
return false;
|
|
@@ -8485,14 +8636,14 @@ function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
|
8485
8636
|
}
|
|
8486
8637
|
function buildSavedHistoryFileSignature(dir, file) {
|
|
8487
8638
|
try {
|
|
8488
|
-
const stat2 = fs3.statSync(
|
|
8639
|
+
const stat2 = fs3.statSync(path11.join(dir, file));
|
|
8489
8640
|
return `${file}:${stat2.size}:${Math.trunc(stat2.mtimeMs)}`;
|
|
8490
8641
|
} catch {
|
|
8491
8642
|
return `${file}:missing`;
|
|
8492
8643
|
}
|
|
8493
8644
|
}
|
|
8494
8645
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
8495
|
-
const filePath =
|
|
8646
|
+
const filePath = path11.join(dir, file);
|
|
8496
8647
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
8497
8648
|
const currentEntry = entries.get(file) || null;
|
|
8498
8649
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -8565,7 +8716,7 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
8565
8716
|
function computeSavedHistoryFileSummary(dir, file) {
|
|
8566
8717
|
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
8567
8718
|
if (!historySessionId) return null;
|
|
8568
|
-
const filePath =
|
|
8719
|
+
const filePath = path11.join(dir, file);
|
|
8569
8720
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
8570
8721
|
const lines = content.split("\n").filter(Boolean);
|
|
8571
8722
|
let messageCount = 0;
|
|
@@ -8652,7 +8803,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
8652
8803
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
8653
8804
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
8654
8805
|
for (const file of files.slice().sort()) {
|
|
8655
|
-
const filePath =
|
|
8806
|
+
const filePath = path11.join(dir, file);
|
|
8656
8807
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
8657
8808
|
const cached = savedHistoryFileSummaryCache.get(filePath);
|
|
8658
8809
|
const persisted = persistedEntries.get(file);
|
|
@@ -8772,12 +8923,12 @@ var ChatHistoryWriter = class {
|
|
|
8772
8923
|
});
|
|
8773
8924
|
}
|
|
8774
8925
|
if (newMessages.length === 0) return;
|
|
8775
|
-
const dir =
|
|
8926
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8776
8927
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8777
8928
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8778
8929
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
8779
8930
|
const fileName = `${filePrefix}${date}.jsonl`;
|
|
8780
|
-
const filePath =
|
|
8931
|
+
const filePath = path11.join(dir, fileName);
|
|
8781
8932
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
8782
8933
|
fs3.appendFileSync(filePath, lines, "utf-8");
|
|
8783
8934
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -8868,11 +9019,11 @@ var ChatHistoryWriter = class {
|
|
|
8868
9019
|
const ws = String(workspace || "").trim();
|
|
8869
9020
|
if (!id || !ws) return;
|
|
8870
9021
|
try {
|
|
8871
|
-
const dir =
|
|
9022
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8872
9023
|
fs3.mkdirSync(dir, { recursive: true });
|
|
8873
9024
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8874
9025
|
const fileName = `${this.sanitize(id)}_${date}.jsonl`;
|
|
8875
|
-
const filePath =
|
|
9026
|
+
const filePath = path11.join(dir, fileName);
|
|
8876
9027
|
const record = {
|
|
8877
9028
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8878
9029
|
receivedAt: Date.now(),
|
|
@@ -8918,14 +9069,14 @@ var ChatHistoryWriter = class {
|
|
|
8918
9069
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
8919
9070
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
8920
9071
|
}
|
|
8921
|
-
const dir =
|
|
9072
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8922
9073
|
if (!fs3.existsSync(dir)) return;
|
|
8923
9074
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
8924
9075
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
8925
9076
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(fromPrefix) && file.endsWith(".jsonl"));
|
|
8926
9077
|
for (const file of files) {
|
|
8927
|
-
const sourcePath =
|
|
8928
|
-
const targetPath =
|
|
9078
|
+
const sourcePath = path11.join(dir, file);
|
|
9079
|
+
const targetPath = path11.join(dir, `${toPrefix}${file.slice(fromPrefix.length)}`);
|
|
8929
9080
|
const sourceLines = fs3.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
8930
9081
|
const rewritten = sourceLines.map((line) => {
|
|
8931
9082
|
try {
|
|
@@ -8959,13 +9110,13 @@ var ChatHistoryWriter = class {
|
|
|
8959
9110
|
const sessionId = String(historySessionId || "").trim();
|
|
8960
9111
|
if (!sessionId) return;
|
|
8961
9112
|
try {
|
|
8962
|
-
const dir =
|
|
9113
|
+
const dir = path11.join(HISTORY_DIR, this.sanitize(agentType));
|
|
8963
9114
|
if (!fs3.existsSync(dir)) return;
|
|
8964
9115
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
8965
9116
|
const files = fs3.readdirSync(dir).filter((file) => file.startsWith(prefix) && file.endsWith(".jsonl")).sort();
|
|
8966
9117
|
const seen = /* @__PURE__ */ new Set();
|
|
8967
9118
|
for (const file of files) {
|
|
8968
|
-
const filePath =
|
|
9119
|
+
const filePath = path11.join(dir, file);
|
|
8969
9120
|
const lines = fs3.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
8970
9121
|
const next = [];
|
|
8971
9122
|
for (const line of lines) {
|
|
@@ -9019,11 +9170,11 @@ var ChatHistoryWriter = class {
|
|
|
9019
9170
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
9020
9171
|
const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
9021
9172
|
for (const dir of agentDirs) {
|
|
9022
|
-
const dirPath =
|
|
9173
|
+
const dirPath = path11.join(HISTORY_DIR, dir.name);
|
|
9023
9174
|
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
9024
9175
|
let removedAny = false;
|
|
9025
9176
|
for (const file of files) {
|
|
9026
|
-
const filePath =
|
|
9177
|
+
const filePath = path11.join(dirPath, file);
|
|
9027
9178
|
const stat2 = fs3.statSync(filePath);
|
|
9028
9179
|
if (stat2.mtimeMs < cutoff) {
|
|
9029
9180
|
fs3.unlinkSync(filePath);
|
|
@@ -9073,13 +9224,13 @@ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeR
|
|
|
9073
9224
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
9074
9225
|
try {
|
|
9075
9226
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9076
|
-
const dir =
|
|
9227
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9077
9228
|
if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
|
|
9078
9229
|
const files = listHistoryFiles(dir, historySessionId);
|
|
9079
9230
|
const allMessages = [];
|
|
9080
9231
|
const seen = /* @__PURE__ */ new Set();
|
|
9081
9232
|
for (const file of files) {
|
|
9082
|
-
const filePath =
|
|
9233
|
+
const filePath = path11.join(dir, file);
|
|
9083
9234
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
9084
9235
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
9085
9236
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -9103,7 +9254,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
9103
9254
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
9104
9255
|
try {
|
|
9105
9256
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9106
|
-
const dir =
|
|
9257
|
+
const dir = path11.join(HISTORY_DIR, sanitized);
|
|
9107
9258
|
if (!fs3.existsSync(dir)) {
|
|
9108
9259
|
savedHistorySessionCache.delete(sanitized);
|
|
9109
9260
|
return { sessions: [], hasMore: false };
|
|
@@ -9164,11 +9315,11 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
9164
9315
|
}
|
|
9165
9316
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
9166
9317
|
try {
|
|
9167
|
-
const dir =
|
|
9318
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9168
9319
|
if (!fs3.existsSync(dir)) return null;
|
|
9169
9320
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
9170
9321
|
for (const file of files) {
|
|
9171
|
-
const lines = fs3.readFileSync(
|
|
9322
|
+
const lines = fs3.readFileSync(path11.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
9172
9323
|
for (const line of lines) {
|
|
9173
9324
|
try {
|
|
9174
9325
|
const parsed = JSON.parse(line);
|
|
@@ -9188,16 +9339,16 @@ function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
|
9188
9339
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
9189
9340
|
if (records.length === 0) return false;
|
|
9190
9341
|
try {
|
|
9191
|
-
const dir =
|
|
9342
|
+
const dir = path11.join(HISTORY_DIR, agentType);
|
|
9192
9343
|
fs3.mkdirSync(dir, { recursive: true });
|
|
9193
9344
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
9194
9345
|
for (const file of fs3.readdirSync(dir)) {
|
|
9195
9346
|
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
9196
|
-
fs3.unlinkSync(
|
|
9347
|
+
fs3.unlinkSync(path11.join(dir, file));
|
|
9197
9348
|
}
|
|
9198
9349
|
}
|
|
9199
9350
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
9200
|
-
const filePath =
|
|
9351
|
+
const filePath = path11.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
9201
9352
|
fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
9202
9353
|
`, "utf-8");
|
|
9203
9354
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -11534,7 +11685,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
11534
11685
|
// src/commands/chat-commands.ts
|
|
11535
11686
|
var fs4 = __toESM(require("fs"));
|
|
11536
11687
|
var os6 = __toESM(require("os"));
|
|
11537
|
-
var
|
|
11688
|
+
var path12 = __toESM(require("path"));
|
|
11538
11689
|
var import_node_crypto = require("crypto");
|
|
11539
11690
|
|
|
11540
11691
|
// src/providers/provider-input-support.ts
|
|
@@ -12045,7 +12196,7 @@ function buildDebugBundleText(bundle) {
|
|
|
12045
12196
|
}
|
|
12046
12197
|
function getChatDebugBundleDir() {
|
|
12047
12198
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
12048
|
-
return override ||
|
|
12199
|
+
return override || path12.join(os6.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
12049
12200
|
}
|
|
12050
12201
|
function safeBundleIdSegment(value, fallback) {
|
|
12051
12202
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -12078,7 +12229,7 @@ function storeChatDebugBundleOnDaemon(bundle, targetSessionId) {
|
|
|
12078
12229
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
12079
12230
|
const dir = getChatDebugBundleDir();
|
|
12080
12231
|
fs4.mkdirSync(dir, { recursive: true });
|
|
12081
|
-
const savedPath =
|
|
12232
|
+
const savedPath = path12.join(dir, `${bundleId}.json`);
|
|
12082
12233
|
const json = `${JSON.stringify(bundle, null, 2)}
|
|
12083
12234
|
`;
|
|
12084
12235
|
fs4.writeFileSync(savedPath, json, { encoding: "utf8", mode: 384 });
|
|
@@ -13222,7 +13373,7 @@ async function handleResolveAction(h, args) {
|
|
|
13222
13373
|
|
|
13223
13374
|
// src/commands/cdp-commands.ts
|
|
13224
13375
|
var fs5 = __toESM(require("fs"));
|
|
13225
|
-
var
|
|
13376
|
+
var path13 = __toESM(require("path"));
|
|
13226
13377
|
var os7 = __toESM(require("os"));
|
|
13227
13378
|
var KEY_TO_VK = {
|
|
13228
13379
|
Backspace: 8,
|
|
@@ -13479,25 +13630,25 @@ function resolveSafePath(requestedPath) {
|
|
|
13479
13630
|
const inputPath = rawPath || ".";
|
|
13480
13631
|
const home = os7.homedir();
|
|
13481
13632
|
if (inputPath.startsWith("~")) {
|
|
13482
|
-
return
|
|
13633
|
+
return path13.resolve(path13.join(home, inputPath.slice(1)));
|
|
13483
13634
|
}
|
|
13484
13635
|
if (process.platform === "win32") {
|
|
13485
13636
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
13486
|
-
if (
|
|
13487
|
-
return
|
|
13637
|
+
if (path13.win32.isAbsolute(normalized)) {
|
|
13638
|
+
return path13.win32.normalize(normalized);
|
|
13488
13639
|
}
|
|
13489
|
-
return
|
|
13640
|
+
return path13.win32.resolve(normalized);
|
|
13490
13641
|
}
|
|
13491
|
-
if (
|
|
13492
|
-
return
|
|
13642
|
+
if (path13.isAbsolute(inputPath)) {
|
|
13643
|
+
return path13.normalize(inputPath);
|
|
13493
13644
|
}
|
|
13494
|
-
return
|
|
13645
|
+
return path13.resolve(inputPath);
|
|
13495
13646
|
}
|
|
13496
13647
|
function listDirectoryEntriesSafe(dirPath) {
|
|
13497
13648
|
const entries = fs5.readdirSync(dirPath, { withFileTypes: true });
|
|
13498
13649
|
const files = [];
|
|
13499
13650
|
for (const entry of entries) {
|
|
13500
|
-
const entryPath =
|
|
13651
|
+
const entryPath = path13.join(dirPath, entry.name);
|
|
13501
13652
|
try {
|
|
13502
13653
|
if (entry.isDirectory()) {
|
|
13503
13654
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -13551,7 +13702,7 @@ async function handleFileRead(h, args) {
|
|
|
13551
13702
|
async function handleFileWrite(h, args) {
|
|
13552
13703
|
try {
|
|
13553
13704
|
const filePath = resolveSafePath(args?.path);
|
|
13554
|
-
fs5.mkdirSync(
|
|
13705
|
+
fs5.mkdirSync(path13.dirname(filePath), { recursive: true });
|
|
13555
13706
|
fs5.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
13556
13707
|
return { success: true, path: filePath };
|
|
13557
13708
|
} catch (e) {
|
|
@@ -14670,7 +14821,7 @@ var DaemonCommandHandler = class {
|
|
|
14670
14821
|
|
|
14671
14822
|
// src/commands/cli-manager.ts
|
|
14672
14823
|
var os13 = __toESM(require("os"));
|
|
14673
|
-
var
|
|
14824
|
+
var path17 = __toESM(require("path"));
|
|
14674
14825
|
var crypto4 = __toESM(require("crypto"));
|
|
14675
14826
|
var import_fs6 = require("fs");
|
|
14676
14827
|
var import_child_process6 = require("child_process");
|
|
@@ -14680,7 +14831,7 @@ init_config();
|
|
|
14680
14831
|
|
|
14681
14832
|
// src/providers/cli-provider-instance.ts
|
|
14682
14833
|
var os12 = __toESM(require("os"));
|
|
14683
|
-
var
|
|
14834
|
+
var path16 = __toESM(require("path"));
|
|
14684
14835
|
var crypto3 = __toESM(require("crypto"));
|
|
14685
14836
|
var fs6 = __toESM(require("fs"));
|
|
14686
14837
|
var import_node_module = require("module");
|
|
@@ -14739,7 +14890,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
14739
14890
|
var CachedDatabaseSync = null;
|
|
14740
14891
|
function getDatabaseSync() {
|
|
14741
14892
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
14742
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
14893
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path16.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
14743
14894
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
14744
14895
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
14745
14896
|
if (!CachedDatabaseSync) {
|
|
@@ -16805,11 +16956,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
16805
16956
|
// src/commands/cli-manager.ts
|
|
16806
16957
|
function isExplicitCommand(command) {
|
|
16807
16958
|
const trimmed = command.trim();
|
|
16808
|
-
return
|
|
16959
|
+
return path17.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
16809
16960
|
}
|
|
16810
16961
|
function expandExecutable(command) {
|
|
16811
16962
|
const trimmed = command.trim();
|
|
16812
|
-
return trimmed.startsWith("~") ?
|
|
16963
|
+
return trimmed.startsWith("~") ? path17.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
16813
16964
|
}
|
|
16814
16965
|
function commandExists(command) {
|
|
16815
16966
|
const trimmed = command.trim();
|
|
@@ -17090,7 +17241,7 @@ var DaemonCliManager = class {
|
|
|
17090
17241
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
17091
17242
|
const trimmed = (workingDir || "").trim();
|
|
17092
17243
|
if (!trimmed) throw new Error("working directory required");
|
|
17093
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
17244
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path17.resolve(trimmed);
|
|
17094
17245
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17095
17246
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
17096
17247
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -17591,11 +17742,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17591
17742
|
var import_child_process7 = require("child_process");
|
|
17592
17743
|
var net = __toESM(require("net"));
|
|
17593
17744
|
var os15 = __toESM(require("os"));
|
|
17594
|
-
var
|
|
17745
|
+
var path19 = __toESM(require("path"));
|
|
17595
17746
|
|
|
17596
17747
|
// src/providers/provider-loader.ts
|
|
17597
17748
|
var fs7 = __toESM(require("fs"));
|
|
17598
|
-
var
|
|
17749
|
+
var path18 = __toESM(require("path"));
|
|
17599
17750
|
var os14 = __toESM(require("os"));
|
|
17600
17751
|
var chokidar = __toESM(require("chokidar"));
|
|
17601
17752
|
init_logger();
|
|
@@ -17919,7 +18070,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17919
18070
|
try {
|
|
17920
18071
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
17921
18072
|
return ["ide", "extension", "cli", "acp"].some(
|
|
17922
|
-
(category) => fs7.existsSync(
|
|
18073
|
+
(category) => fs7.existsSync(path18.join(candidate, category))
|
|
17923
18074
|
);
|
|
17924
18075
|
} catch {
|
|
17925
18076
|
return false;
|
|
@@ -17927,20 +18078,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17927
18078
|
}
|
|
17928
18079
|
static hasProviderRootMarker(candidate) {
|
|
17929
18080
|
try {
|
|
17930
|
-
return fs7.existsSync(
|
|
18081
|
+
return fs7.existsSync(path18.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
17931
18082
|
} catch {
|
|
17932
18083
|
return false;
|
|
17933
18084
|
}
|
|
17934
18085
|
}
|
|
17935
18086
|
detectDefaultUserDir() {
|
|
17936
|
-
const fallback =
|
|
18087
|
+
const fallback = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17937
18088
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
17938
18089
|
const visited = /* @__PURE__ */ new Set();
|
|
17939
18090
|
for (const start of this.probeStarts) {
|
|
17940
|
-
let current =
|
|
18091
|
+
let current = path18.resolve(start);
|
|
17941
18092
|
while (!visited.has(current)) {
|
|
17942
18093
|
visited.add(current);
|
|
17943
|
-
const siblingCandidate =
|
|
18094
|
+
const siblingCandidate = path18.join(path18.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
17944
18095
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
17945
18096
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
17946
18097
|
if (envOptIn || hasMarker) {
|
|
@@ -17962,7 +18113,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17962
18113
|
return { path: siblingCandidate, source };
|
|
17963
18114
|
}
|
|
17964
18115
|
}
|
|
17965
|
-
const parent =
|
|
18116
|
+
const parent = path18.dirname(current);
|
|
17966
18117
|
if (parent === current) break;
|
|
17967
18118
|
current = parent;
|
|
17968
18119
|
}
|
|
@@ -17972,11 +18123,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
17972
18123
|
constructor(options) {
|
|
17973
18124
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
17974
18125
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
17975
|
-
this.defaultProvidersDir =
|
|
18126
|
+
this.defaultProvidersDir = path18.join(os14.homedir(), ".adhdev", "providers");
|
|
17976
18127
|
const detected = this.detectDefaultUserDir();
|
|
17977
18128
|
this.userDir = detected.path;
|
|
17978
18129
|
this.userDirSource = detected.source;
|
|
17979
|
-
this.upstreamDir =
|
|
18130
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
17980
18131
|
this.disableUpstream = false;
|
|
17981
18132
|
this.applySourceConfig({
|
|
17982
18133
|
userDir: options?.userDir,
|
|
@@ -18035,7 +18186,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18035
18186
|
this.userDir = detected.path;
|
|
18036
18187
|
this.userDirSource = detected.source;
|
|
18037
18188
|
}
|
|
18038
|
-
this.upstreamDir =
|
|
18189
|
+
this.upstreamDir = path18.join(this.defaultProvidersDir, ".upstream");
|
|
18039
18190
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
18040
18191
|
if (this.explicitProviderDir) {
|
|
18041
18192
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -18049,7 +18200,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18049
18200
|
* Canonical provider directory shape for a given root.
|
|
18050
18201
|
*/
|
|
18051
18202
|
getProviderDir(root, category, type) {
|
|
18052
|
-
return
|
|
18203
|
+
return path18.join(root, category, type);
|
|
18053
18204
|
}
|
|
18054
18205
|
/**
|
|
18055
18206
|
* Canonical user override directory for a provider.
|
|
@@ -18076,7 +18227,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18076
18227
|
resolveProviderFile(type, ...segments) {
|
|
18077
18228
|
const dir = this.findProviderDirInternal(type);
|
|
18078
18229
|
if (!dir) return null;
|
|
18079
|
-
return
|
|
18230
|
+
return path18.join(dir, ...segments);
|
|
18080
18231
|
}
|
|
18081
18232
|
/**
|
|
18082
18233
|
* Load all providers (3-tier priority)
|
|
@@ -18115,7 +18266,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18115
18266
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
18116
18267
|
try {
|
|
18117
18268
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
18118
|
-
(d) => fs7.statSync(
|
|
18269
|
+
(d) => fs7.statSync(path18.join(this.upstreamDir, d)).isDirectory()
|
|
18119
18270
|
);
|
|
18120
18271
|
} catch {
|
|
18121
18272
|
return false;
|
|
@@ -18612,8 +18763,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18612
18763
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
18613
18764
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
18614
18765
|
if (providerDir) {
|
|
18615
|
-
const fullDir =
|
|
18616
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18766
|
+
const fullDir = path18.join(providerDir, entry.scriptDir);
|
|
18767
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18617
18768
|
}
|
|
18618
18769
|
matched = true;
|
|
18619
18770
|
}
|
|
@@ -18628,8 +18779,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18628
18779
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18629
18780
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
18630
18781
|
if (providerDir) {
|
|
18631
|
-
const fullDir =
|
|
18632
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18782
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18783
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18633
18784
|
}
|
|
18634
18785
|
}
|
|
18635
18786
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -18646,8 +18797,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18646
18797
|
resolved._resolvedScriptDir = dirOverride;
|
|
18647
18798
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
18648
18799
|
if (providerDir) {
|
|
18649
|
-
const fullDir =
|
|
18650
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18800
|
+
const fullDir = path18.join(providerDir, dirOverride);
|
|
18801
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18651
18802
|
}
|
|
18652
18803
|
}
|
|
18653
18804
|
} else if (override.scripts) {
|
|
@@ -18663,8 +18814,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18663
18814
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18664
18815
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
18665
18816
|
if (providerDir) {
|
|
18666
|
-
const fullDir =
|
|
18667
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
18817
|
+
const fullDir = path18.join(providerDir, base.defaultScriptDir);
|
|
18818
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path18.join(fullDir, "scripts.js")) ? path18.join(fullDir, "scripts.js") : fullDir;
|
|
18668
18819
|
}
|
|
18669
18820
|
}
|
|
18670
18821
|
}
|
|
@@ -18696,14 +18847,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18696
18847
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
18697
18848
|
return null;
|
|
18698
18849
|
}
|
|
18699
|
-
const dir =
|
|
18850
|
+
const dir = path18.join(providerDir, scriptDir);
|
|
18700
18851
|
if (!fs7.existsSync(dir)) {
|
|
18701
18852
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
18702
18853
|
return null;
|
|
18703
18854
|
}
|
|
18704
18855
|
const cached = this.scriptsCache.get(dir);
|
|
18705
18856
|
if (cached) return cached;
|
|
18706
|
-
const scriptsJs =
|
|
18857
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
18707
18858
|
if (fs7.existsSync(scriptsJs)) {
|
|
18708
18859
|
try {
|
|
18709
18860
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -18745,7 +18896,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18745
18896
|
return;
|
|
18746
18897
|
}
|
|
18747
18898
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
18748
|
-
this.log(`File changed: ${
|
|
18899
|
+
this.log(`File changed: ${path18.basename(filePath)}, reloading...`);
|
|
18749
18900
|
this.reload();
|
|
18750
18901
|
}
|
|
18751
18902
|
};
|
|
@@ -18800,7 +18951,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18800
18951
|
}
|
|
18801
18952
|
const https = require("https");
|
|
18802
18953
|
const { execSync: execSync7 } = require("child_process");
|
|
18803
|
-
const metaPath =
|
|
18954
|
+
const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
18804
18955
|
let prevEtag = "";
|
|
18805
18956
|
let prevTimestamp = 0;
|
|
18806
18957
|
try {
|
|
@@ -18860,17 +19011,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18860
19011
|
return { updated: false };
|
|
18861
19012
|
}
|
|
18862
19013
|
this.log("Downloading latest providers from GitHub...");
|
|
18863
|
-
const tmpTar =
|
|
18864
|
-
const tmpExtract =
|
|
19014
|
+
const tmpTar = path18.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
19015
|
+
const tmpExtract = path18.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
18865
19016
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
18866
19017
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
18867
19018
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
18868
19019
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
18869
19020
|
const rootDir = extracted.find(
|
|
18870
|
-
(d) => fs7.statSync(
|
|
19021
|
+
(d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
18871
19022
|
);
|
|
18872
19023
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
18873
|
-
const sourceDir =
|
|
19024
|
+
const sourceDir = path18.join(tmpExtract, rootDir);
|
|
18874
19025
|
const backupDir = this.upstreamDir + ".bak";
|
|
18875
19026
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
18876
19027
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -18945,8 +19096,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18945
19096
|
copyDirRecursive(src, dest) {
|
|
18946
19097
|
fs7.mkdirSync(dest, { recursive: true });
|
|
18947
19098
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
18948
|
-
const srcPath =
|
|
18949
|
-
const destPath =
|
|
19099
|
+
const srcPath = path18.join(src, entry.name);
|
|
19100
|
+
const destPath = path18.join(dest, entry.name);
|
|
18950
19101
|
if (entry.isDirectory()) {
|
|
18951
19102
|
this.copyDirRecursive(srcPath, destPath);
|
|
18952
19103
|
} else {
|
|
@@ -18957,7 +19108,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18957
19108
|
/** .meta.json save */
|
|
18958
19109
|
writeMeta(metaPath, etag, timestamp) {
|
|
18959
19110
|
try {
|
|
18960
|
-
fs7.mkdirSync(
|
|
19111
|
+
fs7.mkdirSync(path18.dirname(metaPath), { recursive: true });
|
|
18961
19112
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
18962
19113
|
etag,
|
|
18963
19114
|
timestamp,
|
|
@@ -18974,7 +19125,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18974
19125
|
const scan = (d) => {
|
|
18975
19126
|
try {
|
|
18976
19127
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
18977
|
-
if (entry.isDirectory()) scan(
|
|
19128
|
+
if (entry.isDirectory()) scan(path18.join(d, entry.name));
|
|
18978
19129
|
else if (entry.name === "provider.json") count++;
|
|
18979
19130
|
}
|
|
18980
19131
|
} catch {
|
|
@@ -19202,17 +19353,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19202
19353
|
for (const root of searchRoots) {
|
|
19203
19354
|
if (!fs7.existsSync(root)) continue;
|
|
19204
19355
|
const candidate = this.getProviderDir(root, cat, type);
|
|
19205
|
-
if (fs7.existsSync(
|
|
19206
|
-
const catDir =
|
|
19356
|
+
if (fs7.existsSync(path18.join(candidate, "provider.json"))) return candidate;
|
|
19357
|
+
const catDir = path18.join(root, cat);
|
|
19207
19358
|
if (fs7.existsSync(catDir)) {
|
|
19208
19359
|
try {
|
|
19209
19360
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
19210
19361
|
if (!entry.isDirectory()) continue;
|
|
19211
|
-
const jsonPath =
|
|
19362
|
+
const jsonPath = path18.join(catDir, entry.name, "provider.json");
|
|
19212
19363
|
if (fs7.existsSync(jsonPath)) {
|
|
19213
19364
|
try {
|
|
19214
19365
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
19215
|
-
if (data.type === type) return
|
|
19366
|
+
if (data.type === type) return path18.join(catDir, entry.name);
|
|
19216
19367
|
} catch {
|
|
19217
19368
|
}
|
|
19218
19369
|
}
|
|
@@ -19229,7 +19380,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19229
19380
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
19230
19381
|
*/
|
|
19231
19382
|
buildScriptWrappersFromDir(dir) {
|
|
19232
|
-
const scriptsJs =
|
|
19383
|
+
const scriptsJs = path18.join(dir, "scripts.js");
|
|
19233
19384
|
if (fs7.existsSync(scriptsJs)) {
|
|
19234
19385
|
try {
|
|
19235
19386
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -19243,7 +19394,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19243
19394
|
for (const file of fs7.readdirSync(dir)) {
|
|
19244
19395
|
if (!file.endsWith(".js")) continue;
|
|
19245
19396
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
19246
|
-
const filePath =
|
|
19397
|
+
const filePath = path18.join(dir, file);
|
|
19247
19398
|
result[scriptName] = (...args) => {
|
|
19248
19399
|
try {
|
|
19249
19400
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -19303,7 +19454,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19303
19454
|
}
|
|
19304
19455
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
19305
19456
|
if (hasJson) {
|
|
19306
|
-
const jsonPath =
|
|
19457
|
+
const jsonPath = path18.join(d, "provider.json");
|
|
19307
19458
|
try {
|
|
19308
19459
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
19309
19460
|
const mod = JSON.parse(raw);
|
|
@@ -19324,7 +19475,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19324
19475
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
19325
19476
|
} else {
|
|
19326
19477
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
19327
|
-
const scriptsPath =
|
|
19478
|
+
const scriptsPath = path18.join(d, "scripts.js");
|
|
19328
19479
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
19329
19480
|
try {
|
|
19330
19481
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -19350,7 +19501,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19350
19501
|
if (!entry.isDirectory()) continue;
|
|
19351
19502
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
19352
19503
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
19353
|
-
scan(
|
|
19504
|
+
scan(path18.join(d, entry.name));
|
|
19354
19505
|
}
|
|
19355
19506
|
}
|
|
19356
19507
|
};
|
|
@@ -19675,8 +19826,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
19675
19826
|
const appNameMap = getMacAppIdentifiers();
|
|
19676
19827
|
const appName = appNameMap[ideId];
|
|
19677
19828
|
if (appName) {
|
|
19678
|
-
const storagePath =
|
|
19679
|
-
process.env.APPDATA ||
|
|
19829
|
+
const storagePath = path19.join(
|
|
19830
|
+
process.env.APPDATA || path19.join(os15.homedir(), "AppData", "Roaming"),
|
|
19680
19831
|
appName,
|
|
19681
19832
|
"storage.json"
|
|
19682
19833
|
);
|
|
@@ -19865,9 +20016,9 @@ init_logger();
|
|
|
19865
20016
|
|
|
19866
20017
|
// src/logging/command-log.ts
|
|
19867
20018
|
var fs8 = __toESM(require("fs"));
|
|
19868
|
-
var
|
|
20019
|
+
var path20 = __toESM(require("path"));
|
|
19869
20020
|
var os16 = __toESM(require("os"));
|
|
19870
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
20021
|
+
var LOG_DIR2 = process.platform === "win32" ? path20.join(process.env.LOCALAPPDATA || process.env.APPDATA || path20.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path20.join(os16.homedir(), "Library", "Logs", "adhdev") : path20.join(os16.homedir(), ".local", "share", "adhdev", "logs");
|
|
19871
20022
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
19872
20023
|
var MAX_DAYS = 7;
|
|
19873
20024
|
try {
|
|
@@ -19905,13 +20056,13 @@ function getDateStr2() {
|
|
|
19905
20056
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
19906
20057
|
}
|
|
19907
20058
|
var currentDate2 = getDateStr2();
|
|
19908
|
-
var currentFile =
|
|
20059
|
+
var currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19909
20060
|
var writeCount2 = 0;
|
|
19910
20061
|
function checkRotation() {
|
|
19911
20062
|
const today = getDateStr2();
|
|
19912
20063
|
if (today !== currentDate2) {
|
|
19913
20064
|
currentDate2 = today;
|
|
19914
|
-
currentFile =
|
|
20065
|
+
currentFile = path20.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
19915
20066
|
cleanOldFiles();
|
|
19916
20067
|
}
|
|
19917
20068
|
}
|
|
@@ -19925,7 +20076,7 @@ function cleanOldFiles() {
|
|
|
19925
20076
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
19926
20077
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
19927
20078
|
try {
|
|
19928
|
-
fs8.unlinkSync(
|
|
20079
|
+
fs8.unlinkSync(path20.join(LOG_DIR2, file));
|
|
19929
20080
|
} catch {
|
|
19930
20081
|
}
|
|
19931
20082
|
}
|
|
@@ -20011,7 +20162,7 @@ cleanOldFiles();
|
|
|
20011
20162
|
init_logger();
|
|
20012
20163
|
|
|
20013
20164
|
// src/commands/mesh-coordinator.ts
|
|
20014
|
-
var
|
|
20165
|
+
var import_node_fs3 = require("fs");
|
|
20015
20166
|
var import_node_module2 = require("module");
|
|
20016
20167
|
var import_node_path = require("path");
|
|
20017
20168
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
@@ -20034,8 +20185,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20034
20185
|
}
|
|
20035
20186
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
20036
20187
|
if (mcpConfig.mode === "auto_import") {
|
|
20037
|
-
const
|
|
20038
|
-
if (!
|
|
20188
|
+
const path27 = mcpConfig.path?.trim();
|
|
20189
|
+
if (!path27) {
|
|
20039
20190
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
20040
20191
|
}
|
|
20041
20192
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -20052,7 +20203,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20052
20203
|
return {
|
|
20053
20204
|
kind: "auto_import",
|
|
20054
20205
|
serverName,
|
|
20055
|
-
configPath: (0, import_node_path.join)(workspace,
|
|
20206
|
+
configPath: (0, import_node_path.join)(workspace, path27),
|
|
20056
20207
|
configFormat: mcpConfig.format,
|
|
20057
20208
|
mcpServer
|
|
20058
20209
|
};
|
|
@@ -20129,8 +20280,8 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
20129
20280
|
}
|
|
20130
20281
|
function normalizeExistingPath(filePath) {
|
|
20131
20282
|
try {
|
|
20132
|
-
if (!(0,
|
|
20133
|
-
return
|
|
20283
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) return null;
|
|
20284
|
+
return import_node_fs3.realpathSync.native(filePath);
|
|
20134
20285
|
} catch {
|
|
20135
20286
|
return null;
|
|
20136
20287
|
}
|
|
@@ -20454,13 +20605,13 @@ var import_child_process8 = require("child_process");
|
|
|
20454
20605
|
var import_child_process9 = require("child_process");
|
|
20455
20606
|
var fs9 = __toESM(require("fs"));
|
|
20456
20607
|
var os18 = __toESM(require("os"));
|
|
20457
|
-
var
|
|
20608
|
+
var path21 = __toESM(require("path"));
|
|
20458
20609
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
20459
20610
|
function getUpgradeLogPath() {
|
|
20460
20611
|
const home = os18.homedir();
|
|
20461
|
-
const dir =
|
|
20612
|
+
const dir = path21.join(home, ".adhdev");
|
|
20462
20613
|
fs9.mkdirSync(dir, { recursive: true });
|
|
20463
|
-
return
|
|
20614
|
+
return path21.join(dir, "daemon-upgrade.log");
|
|
20464
20615
|
}
|
|
20465
20616
|
function appendUpgradeLog(message) {
|
|
20466
20617
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -20471,14 +20622,14 @@ function appendUpgradeLog(message) {
|
|
|
20471
20622
|
}
|
|
20472
20623
|
}
|
|
20473
20624
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
20474
|
-
const binDir =
|
|
20625
|
+
const binDir = path21.dirname(nodeExecutable);
|
|
20475
20626
|
if (platform10 === "win32") {
|
|
20476
|
-
const npmCliPath =
|
|
20627
|
+
const npmCliPath = path21.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
20477
20628
|
if (fs9.existsSync(npmCliPath)) {
|
|
20478
20629
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20479
20630
|
}
|
|
20480
20631
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
20481
|
-
const candidatePath =
|
|
20632
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20482
20633
|
if (fs9.existsSync(candidatePath)) {
|
|
20483
20634
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20484
20635
|
}
|
|
@@ -20486,7 +20637,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
20486
20637
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
20487
20638
|
}
|
|
20488
20639
|
for (const candidate of ["npm"]) {
|
|
20489
|
-
const candidatePath =
|
|
20640
|
+
const candidatePath = path21.join(binDir, candidate);
|
|
20490
20641
|
if (fs9.existsSync(candidatePath)) {
|
|
20491
20642
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
20492
20643
|
}
|
|
@@ -20503,13 +20654,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20503
20654
|
let currentDir = resolvedPath;
|
|
20504
20655
|
try {
|
|
20505
20656
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
20506
|
-
currentDir =
|
|
20657
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20507
20658
|
}
|
|
20508
20659
|
} catch {
|
|
20509
|
-
currentDir =
|
|
20660
|
+
currentDir = path21.dirname(resolvedPath);
|
|
20510
20661
|
}
|
|
20511
20662
|
while (true) {
|
|
20512
|
-
const packageJsonPath =
|
|
20663
|
+
const packageJsonPath = path21.join(currentDir, "package.json");
|
|
20513
20664
|
try {
|
|
20514
20665
|
if (fs9.existsSync(packageJsonPath)) {
|
|
20515
20666
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -20520,7 +20671,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20520
20671
|
}
|
|
20521
20672
|
} catch {
|
|
20522
20673
|
}
|
|
20523
|
-
const parentDir =
|
|
20674
|
+
const parentDir = path21.dirname(currentDir);
|
|
20524
20675
|
if (parentDir === currentDir) {
|
|
20525
20676
|
return null;
|
|
20526
20677
|
}
|
|
@@ -20528,13 +20679,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
20528
20679
|
}
|
|
20529
20680
|
}
|
|
20530
20681
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
20531
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
20532
|
-
if (
|
|
20682
|
+
const nodeModulesDir = packageName.startsWith("@") ? path21.dirname(path21.dirname(packageRoot)) : path21.dirname(packageRoot);
|
|
20683
|
+
if (path21.basename(nodeModulesDir) !== "node_modules") {
|
|
20533
20684
|
return null;
|
|
20534
20685
|
}
|
|
20535
|
-
const maybeLibDir =
|
|
20536
|
-
if (
|
|
20537
|
-
return
|
|
20686
|
+
const maybeLibDir = path21.dirname(nodeModulesDir);
|
|
20687
|
+
if (path21.basename(maybeLibDir) === "lib") {
|
|
20688
|
+
return path21.dirname(maybeLibDir);
|
|
20538
20689
|
}
|
|
20539
20690
|
return maybeLibDir;
|
|
20540
20691
|
}
|
|
@@ -20649,7 +20800,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
20649
20800
|
}
|
|
20650
20801
|
}
|
|
20651
20802
|
function stopSessionHostProcesses(appName) {
|
|
20652
|
-
const pidFile =
|
|
20803
|
+
const pidFile = path21.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
20653
20804
|
try {
|
|
20654
20805
|
if (fs9.existsSync(pidFile)) {
|
|
20655
20806
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -20666,7 +20817,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
20666
20817
|
}
|
|
20667
20818
|
}
|
|
20668
20819
|
function removeDaemonPidFile() {
|
|
20669
|
-
const pidFile =
|
|
20820
|
+
const pidFile = path21.join(os18.homedir(), ".adhdev", "daemon.pid");
|
|
20670
20821
|
try {
|
|
20671
20822
|
fs9.unlinkSync(pidFile);
|
|
20672
20823
|
} catch {
|
|
@@ -20677,7 +20828,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20677
20828
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20678
20829
|
if (!npmRoot) return;
|
|
20679
20830
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
20680
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
20831
|
+
const binDir = process.platform === "win32" ? npmPrefix : path21.join(npmPrefix, "bin");
|
|
20681
20832
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
20682
20833
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
20683
20834
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -20685,25 +20836,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
20685
20836
|
}
|
|
20686
20837
|
if (pkgName.startsWith("@")) {
|
|
20687
20838
|
const [scope, name] = pkgName.split("/");
|
|
20688
|
-
const scopeDir =
|
|
20839
|
+
const scopeDir = path21.join(npmRoot, scope);
|
|
20689
20840
|
if (!fs9.existsSync(scopeDir)) return;
|
|
20690
20841
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
20691
20842
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
20692
|
-
fs9.rmSync(
|
|
20693
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
20843
|
+
fs9.rmSync(path21.join(scopeDir, entry), { recursive: true, force: true });
|
|
20844
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path21.join(scopeDir, entry)}`);
|
|
20694
20845
|
}
|
|
20695
20846
|
} else {
|
|
20696
20847
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
20697
20848
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
20698
|
-
fs9.rmSync(
|
|
20699
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
20849
|
+
fs9.rmSync(path21.join(npmRoot, entry), { recursive: true, force: true });
|
|
20850
|
+
appendUpgradeLog(`Removed stale staging dir: ${path21.join(npmRoot, entry)}`);
|
|
20700
20851
|
}
|
|
20701
20852
|
}
|
|
20702
20853
|
if (fs9.existsSync(binDir)) {
|
|
20703
20854
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
20704
20855
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
20705
|
-
fs9.rmSync(
|
|
20706
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
20856
|
+
fs9.rmSync(path21.join(binDir, entry), { recursive: true, force: true });
|
|
20857
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path21.join(binDir, entry)}`);
|
|
20707
20858
|
}
|
|
20708
20859
|
}
|
|
20709
20860
|
}
|
|
@@ -20902,6 +21053,40 @@ var DaemonCommandRouter = class {
|
|
|
20902
21053
|
constructor(deps) {
|
|
20903
21054
|
this.deps = deps;
|
|
20904
21055
|
}
|
|
21056
|
+
getCachedInlineMesh(meshId, inlineMesh) {
|
|
21057
|
+
if (inlineMesh && typeof inlineMesh === "object") {
|
|
21058
|
+
this.inlineMeshCache.set(meshId, inlineMesh);
|
|
21059
|
+
return inlineMesh;
|
|
21060
|
+
}
|
|
21061
|
+
return this.inlineMeshCache.get(meshId);
|
|
21062
|
+
}
|
|
21063
|
+
async getMeshForCommand(meshId, inlineMesh) {
|
|
21064
|
+
try {
|
|
21065
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21066
|
+
const mesh = getMesh3(meshId);
|
|
21067
|
+
if (mesh) return { mesh, inline: false };
|
|
21068
|
+
} catch {
|
|
21069
|
+
}
|
|
21070
|
+
const cached = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
21071
|
+
return cached ? { mesh: cached, inline: true } : null;
|
|
21072
|
+
}
|
|
21073
|
+
updateInlineMeshNode(meshId, mesh, node) {
|
|
21074
|
+
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
21075
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
|
|
21076
|
+
if (idx >= 0) mesh.nodes[idx] = node;
|
|
21077
|
+
else mesh.nodes.push(node);
|
|
21078
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21079
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21080
|
+
}
|
|
21081
|
+
removeInlineMeshNode(meshId, mesh, nodeId) {
|
|
21082
|
+
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
21083
|
+
const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
|
|
21084
|
+
if (idx === -1) return false;
|
|
21085
|
+
mesh.nodes.splice(idx, 1);
|
|
21086
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21087
|
+
this.inlineMeshCache.set(meshId, mesh);
|
|
21088
|
+
return true;
|
|
21089
|
+
}
|
|
20905
21090
|
async traceSessionHostAction(action, args, run, summarizeResult) {
|
|
20906
21091
|
const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
|
|
20907
21092
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
|
|
@@ -21601,13 +21786,94 @@ var DaemonCommandRouter = class {
|
|
|
21601
21786
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
21602
21787
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
21603
21788
|
try {
|
|
21604
|
-
const
|
|
21605
|
-
const
|
|
21789
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21790
|
+
const mesh = meshRecord?.mesh;
|
|
21791
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
21792
|
+
if (node?.isLocalWorktree && node.workspace) {
|
|
21793
|
+
try {
|
|
21794
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
21795
|
+
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
21796
|
+
if (repoRoot) {
|
|
21797
|
+
const { removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21798
|
+
await removeWorktree2(repoRoot, node.workspace);
|
|
21799
|
+
}
|
|
21800
|
+
} catch (e) {
|
|
21801
|
+
LOG.warn("MeshNode", `Worktree cleanup failed for ${nodeId}: ${e.message}`);
|
|
21802
|
+
}
|
|
21803
|
+
}
|
|
21804
|
+
let removed = false;
|
|
21805
|
+
if (meshRecord?.inline) {
|
|
21806
|
+
removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
|
|
21807
|
+
} else {
|
|
21808
|
+
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21809
|
+
removed = removeNode3(meshId, nodeId);
|
|
21810
|
+
}
|
|
21606
21811
|
return { success: true, removed };
|
|
21607
21812
|
} catch (e) {
|
|
21608
21813
|
return { success: false, error: e.message };
|
|
21609
21814
|
}
|
|
21610
21815
|
}
|
|
21816
|
+
case "clone_mesh_node": {
|
|
21817
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
21818
|
+
const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
|
|
21819
|
+
const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
|
|
21820
|
+
const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
|
|
21821
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
21822
|
+
if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
|
|
21823
|
+
if (!branch) return { success: false, error: "branch required" };
|
|
21824
|
+
try {
|
|
21825
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
21826
|
+
const mesh = meshRecord?.mesh;
|
|
21827
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
21828
|
+
const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
|
|
21829
|
+
if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
|
|
21830
|
+
const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
|
|
21831
|
+
const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
21832
|
+
const result = await createWorktree2({
|
|
21833
|
+
repoRoot,
|
|
21834
|
+
branch,
|
|
21835
|
+
baseBranch,
|
|
21836
|
+
meshName: mesh.name
|
|
21837
|
+
});
|
|
21838
|
+
let node;
|
|
21839
|
+
if (meshRecord.inline) {
|
|
21840
|
+
const { randomUUID: randomUUID8 } = await import("crypto");
|
|
21841
|
+
node = {
|
|
21842
|
+
id: `node_${randomUUID8().replace(/-/g, "")}`,
|
|
21843
|
+
workspace: result.worktreePath,
|
|
21844
|
+
repoRoot: result.worktreePath,
|
|
21845
|
+
daemonId: sourceNode.daemonId,
|
|
21846
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21847
|
+
policy: { ...sourceNode.policy || {} },
|
|
21848
|
+
isLocalWorktree: true,
|
|
21849
|
+
worktreeBranch: result.branch,
|
|
21850
|
+
clonedFromNodeId: sourceNodeId
|
|
21851
|
+
};
|
|
21852
|
+
this.updateInlineMeshNode(meshId, mesh, node);
|
|
21853
|
+
} else {
|
|
21854
|
+
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
21855
|
+
node = addNode3(meshId, {
|
|
21856
|
+
workspace: result.worktreePath,
|
|
21857
|
+
repoRoot: result.worktreePath,
|
|
21858
|
+
daemonId: sourceNode.daemonId,
|
|
21859
|
+
userOverrides: { ...sourceNode.userOverrides || {} },
|
|
21860
|
+
isLocalWorktree: true,
|
|
21861
|
+
worktreeBranch: result.branch,
|
|
21862
|
+
clonedFromNodeId: sourceNodeId,
|
|
21863
|
+
policy: { ...sourceNode.policy || {} }
|
|
21864
|
+
});
|
|
21865
|
+
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
21866
|
+
}
|
|
21867
|
+
return {
|
|
21868
|
+
success: true,
|
|
21869
|
+
node,
|
|
21870
|
+
worktreePath: result.worktreePath,
|
|
21871
|
+
branch: result.branch
|
|
21872
|
+
};
|
|
21873
|
+
} catch (e) {
|
|
21874
|
+
return { success: false, error: e.message };
|
|
21875
|
+
}
|
|
21876
|
+
}
|
|
21611
21877
|
// ─── Mesh Coordinator Launch ───
|
|
21612
21878
|
case "launch_mesh_coordinator": {
|
|
21613
21879
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
@@ -21676,9 +21942,24 @@ var DaemonCommandRouter = class {
|
|
|
21676
21942
|
workspace
|
|
21677
21943
|
};
|
|
21678
21944
|
}
|
|
21679
|
-
|
|
21945
|
+
let systemPrompt = "";
|
|
21946
|
+
try {
|
|
21947
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
21948
|
+
} catch (error) {
|
|
21949
|
+
const message = error?.message || String(error);
|
|
21950
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
21951
|
+
return {
|
|
21952
|
+
success: false,
|
|
21953
|
+
code: "mesh_coordinator_prompt_failed",
|
|
21954
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
21955
|
+
meshId,
|
|
21956
|
+
cliType,
|
|
21957
|
+
workspace
|
|
21958
|
+
};
|
|
21959
|
+
}
|
|
21960
|
+
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3 } = await import("fs");
|
|
21680
21961
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
21681
|
-
const hadExistingMcpConfig =
|
|
21962
|
+
const hadExistingMcpConfig = existsSync23(mcpConfigPath);
|
|
21682
21963
|
let existingMcpConfig = {};
|
|
21683
21964
|
if (hadExistingMcpConfig) {
|
|
21684
21965
|
try {
|
|
@@ -21706,12 +21987,6 @@ var DaemonCommandRouter = class {
|
|
|
21706
21987
|
};
|
|
21707
21988
|
writeFileSync12(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
|
|
21708
21989
|
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
21990
|
const cliArgs = [];
|
|
21716
21991
|
if (systemPrompt) {
|
|
21717
21992
|
cliArgs.push("--append-system-prompt", systemPrompt);
|
|
@@ -23383,11 +23658,11 @@ var ProviderInstanceManager = class {
|
|
|
23383
23658
|
|
|
23384
23659
|
// src/providers/version-archive.ts
|
|
23385
23660
|
var fs11 = __toESM(require("fs"));
|
|
23386
|
-
var
|
|
23661
|
+
var path22 = __toESM(require("path"));
|
|
23387
23662
|
var os19 = __toESM(require("os"));
|
|
23388
23663
|
var import_child_process10 = require("child_process");
|
|
23389
23664
|
var import_os3 = require("os");
|
|
23390
|
-
var ARCHIVE_PATH =
|
|
23665
|
+
var ARCHIVE_PATH = path22.join(os19.homedir(), ".adhdev", "version-history.json");
|
|
23391
23666
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
23392
23667
|
var VersionArchive = class {
|
|
23393
23668
|
history = {};
|
|
@@ -23434,7 +23709,7 @@ var VersionArchive = class {
|
|
|
23434
23709
|
}
|
|
23435
23710
|
save() {
|
|
23436
23711
|
try {
|
|
23437
|
-
fs11.mkdirSync(
|
|
23712
|
+
fs11.mkdirSync(path22.dirname(ARCHIVE_PATH), { recursive: true });
|
|
23438
23713
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
23439
23714
|
} catch {
|
|
23440
23715
|
}
|
|
@@ -23491,7 +23766,7 @@ function checkPathExists2(paths) {
|
|
|
23491
23766
|
for (const p of paths) {
|
|
23492
23767
|
if (p.includes("*")) {
|
|
23493
23768
|
const home = os19.homedir();
|
|
23494
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
23769
|
+
const resolved = p.replace(/\*/g, home.split(path22.sep).pop() || "");
|
|
23495
23770
|
if (fs11.existsSync(resolved)) return resolved;
|
|
23496
23771
|
} else {
|
|
23497
23772
|
if (fs11.existsSync(p)) return p;
|
|
@@ -23501,7 +23776,7 @@ function checkPathExists2(paths) {
|
|
|
23501
23776
|
}
|
|
23502
23777
|
function getMacAppVersion(appPath) {
|
|
23503
23778
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
23504
|
-
const plistPath =
|
|
23779
|
+
const plistPath = path22.join(appPath, "Contents", "Info.plist");
|
|
23505
23780
|
if (!fs11.existsSync(plistPath)) return null;
|
|
23506
23781
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
23507
23782
|
return raw || null;
|
|
@@ -23527,7 +23802,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23527
23802
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
23528
23803
|
let resolvedBin = cliBin;
|
|
23529
23804
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
23530
|
-
const bundled =
|
|
23805
|
+
const bundled = path22.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
23531
23806
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
23532
23807
|
}
|
|
23533
23808
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -23568,7 +23843,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
23568
23843
|
// src/daemon/dev-server.ts
|
|
23569
23844
|
var http2 = __toESM(require("http"));
|
|
23570
23845
|
var fs15 = __toESM(require("fs"));
|
|
23571
|
-
var
|
|
23846
|
+
var path26 = __toESM(require("path"));
|
|
23572
23847
|
init_config();
|
|
23573
23848
|
|
|
23574
23849
|
// src/daemon/scaffold-template.ts
|
|
@@ -23919,7 +24194,7 @@ init_logger();
|
|
|
23919
24194
|
|
|
23920
24195
|
// src/daemon/dev-cdp-handlers.ts
|
|
23921
24196
|
var fs12 = __toESM(require("fs"));
|
|
23922
|
-
var
|
|
24197
|
+
var path23 = __toESM(require("path"));
|
|
23923
24198
|
init_logger();
|
|
23924
24199
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
23925
24200
|
const body = await ctx.readBody(req);
|
|
@@ -24098,17 +24373,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
24098
24373
|
return;
|
|
24099
24374
|
}
|
|
24100
24375
|
let scriptsPath = "";
|
|
24101
|
-
const directScripts =
|
|
24376
|
+
const directScripts = path23.join(dir, "scripts.js");
|
|
24102
24377
|
if (fs12.existsSync(directScripts)) {
|
|
24103
24378
|
scriptsPath = directScripts;
|
|
24104
24379
|
} else {
|
|
24105
|
-
const scriptsDir =
|
|
24380
|
+
const scriptsDir = path23.join(dir, "scripts");
|
|
24106
24381
|
if (fs12.existsSync(scriptsDir)) {
|
|
24107
24382
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
24108
|
-
return fs12.statSync(
|
|
24383
|
+
return fs12.statSync(path23.join(scriptsDir, d)).isDirectory();
|
|
24109
24384
|
}).sort().reverse();
|
|
24110
24385
|
for (const ver of versions) {
|
|
24111
|
-
const p =
|
|
24386
|
+
const p = path23.join(scriptsDir, ver, "scripts.js");
|
|
24112
24387
|
if (fs12.existsSync(p)) {
|
|
24113
24388
|
scriptsPath = p;
|
|
24114
24389
|
break;
|
|
@@ -24937,7 +25212,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
24937
25212
|
|
|
24938
25213
|
// src/daemon/dev-cli-debug.ts
|
|
24939
25214
|
var fs13 = __toESM(require("fs"));
|
|
24940
|
-
var
|
|
25215
|
+
var path24 = __toESM(require("path"));
|
|
24941
25216
|
function slugifyFixtureName(value) {
|
|
24942
25217
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24943
25218
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -24947,11 +25222,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
24947
25222
|
if (!providerDir) {
|
|
24948
25223
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
24949
25224
|
}
|
|
24950
|
-
return
|
|
25225
|
+
return path24.join(providerDir, "fixtures");
|
|
24951
25226
|
}
|
|
24952
25227
|
function readCliFixture(ctx, type, name) {
|
|
24953
25228
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
24954
|
-
const filePath =
|
|
25229
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
24955
25230
|
if (!fs13.existsSync(filePath)) {
|
|
24956
25231
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
24957
25232
|
}
|
|
@@ -25718,7 +25993,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
25718
25993
|
},
|
|
25719
25994
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
25720
25995
|
};
|
|
25721
|
-
const filePath =
|
|
25996
|
+
const filePath = path24.join(fixtureDir, `${name}.json`);
|
|
25722
25997
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
25723
25998
|
ctx.json(res, 200, {
|
|
25724
25999
|
saved: true,
|
|
@@ -25742,7 +26017,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
25742
26017
|
return;
|
|
25743
26018
|
}
|
|
25744
26019
|
const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
25745
|
-
const fullPath =
|
|
26020
|
+
const fullPath = path24.join(fixtureDir, file);
|
|
25746
26021
|
try {
|
|
25747
26022
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
25748
26023
|
return {
|
|
@@ -25878,7 +26153,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
25878
26153
|
|
|
25879
26154
|
// src/daemon/dev-auto-implement.ts
|
|
25880
26155
|
var fs14 = __toESM(require("fs"));
|
|
25881
|
-
var
|
|
26156
|
+
var path25 = __toESM(require("path"));
|
|
25882
26157
|
var os20 = __toESM(require("os"));
|
|
25883
26158
|
function getAutoImplPid(ctx) {
|
|
25884
26159
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -25928,22 +26203,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
25928
26203
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
25929
26204
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
25930
26205
|
try {
|
|
25931
|
-
return fs14.statSync(
|
|
26206
|
+
return fs14.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
25932
26207
|
} catch {
|
|
25933
26208
|
return false;
|
|
25934
26209
|
}
|
|
25935
26210
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
25936
26211
|
if (versions.length === 0) return null;
|
|
25937
|
-
return
|
|
26212
|
+
return path25.join(scriptsDir, versions[0]);
|
|
25938
26213
|
}
|
|
25939
26214
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
25940
|
-
const canonicalUserDir =
|
|
25941
|
-
const desiredDir = requestedDir ?
|
|
25942
|
-
const upstreamRoot =
|
|
25943
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
26215
|
+
const canonicalUserDir = path25.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
26216
|
+
const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
|
|
26217
|
+
const upstreamRoot = path25.resolve(ctx.providerLoader.getUpstreamDir());
|
|
26218
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
|
|
25944
26219
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
25945
26220
|
}
|
|
25946
|
-
if (
|
|
26221
|
+
if (path25.basename(desiredDir) !== type) {
|
|
25947
26222
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
25948
26223
|
}
|
|
25949
26224
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -25951,11 +26226,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
25951
26226
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
25952
26227
|
}
|
|
25953
26228
|
if (!fs14.existsSync(desiredDir)) {
|
|
25954
|
-
fs14.mkdirSync(
|
|
26229
|
+
fs14.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
25955
26230
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
25956
26231
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
25957
26232
|
}
|
|
25958
|
-
const providerJson =
|
|
26233
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
25959
26234
|
if (!fs14.existsSync(providerJson)) {
|
|
25960
26235
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
25961
26236
|
}
|
|
@@ -25966,13 +26241,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
25966
26241
|
const refDir = ctx.findProviderDir(referenceType);
|
|
25967
26242
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
25968
26243
|
const referenceScripts = {};
|
|
25969
|
-
const scriptsDir =
|
|
26244
|
+
const scriptsDir = path25.join(refDir, "scripts");
|
|
25970
26245
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
25971
26246
|
if (!latestDir) return referenceScripts;
|
|
25972
26247
|
for (const file of fs14.readdirSync(latestDir)) {
|
|
25973
26248
|
if (!file.endsWith(".js")) continue;
|
|
25974
26249
|
try {
|
|
25975
|
-
referenceScripts[file] = fs14.readFileSync(
|
|
26250
|
+
referenceScripts[file] = fs14.readFileSync(path25.join(latestDir, file), "utf-8");
|
|
25976
26251
|
} catch {
|
|
25977
26252
|
}
|
|
25978
26253
|
}
|
|
@@ -26080,9 +26355,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
26080
26355
|
});
|
|
26081
26356
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
26082
26357
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
26083
|
-
const tmpDir =
|
|
26358
|
+
const tmpDir = path25.join(os20.tmpdir(), "adhdev-autoimpl");
|
|
26084
26359
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
26085
|
-
const promptFile =
|
|
26360
|
+
const promptFile = path25.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
26086
26361
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
26087
26362
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
26088
26363
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -26514,7 +26789,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26514
26789
|
setMode: "set_mode.js"
|
|
26515
26790
|
};
|
|
26516
26791
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26517
|
-
const scriptsDir =
|
|
26792
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26518
26793
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26519
26794
|
if (latestScriptsDir) {
|
|
26520
26795
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26525,7 +26800,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26525
26800
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
26526
26801
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
26527
26802
|
try {
|
|
26528
|
-
const content = fs14.readFileSync(
|
|
26803
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26529
26804
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26530
26805
|
lines.push("```javascript");
|
|
26531
26806
|
lines.push(content);
|
|
@@ -26542,7 +26817,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26542
26817
|
lines.push("");
|
|
26543
26818
|
for (const file of refFiles) {
|
|
26544
26819
|
try {
|
|
26545
|
-
const content = fs14.readFileSync(
|
|
26820
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26546
26821
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26547
26822
|
lines.push("```javascript");
|
|
26548
26823
|
lines.push(content);
|
|
@@ -26583,10 +26858,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
26583
26858
|
lines.push("");
|
|
26584
26859
|
}
|
|
26585
26860
|
}
|
|
26586
|
-
const docsDir =
|
|
26861
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26587
26862
|
const loadGuide = (name) => {
|
|
26588
26863
|
try {
|
|
26589
|
-
const p =
|
|
26864
|
+
const p = path25.join(docsDir, name);
|
|
26590
26865
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26591
26866
|
} catch {
|
|
26592
26867
|
}
|
|
@@ -26823,7 +27098,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26823
27098
|
parseApproval: "parse_approval.js"
|
|
26824
27099
|
};
|
|
26825
27100
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
26826
|
-
const scriptsDir =
|
|
27101
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
26827
27102
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
26828
27103
|
if (latestScriptsDir) {
|
|
26829
27104
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -26835,7 +27110,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26835
27110
|
if (!file.endsWith(".js")) continue;
|
|
26836
27111
|
if (!targetFileNames.has(file)) continue;
|
|
26837
27112
|
try {
|
|
26838
|
-
const content = fs14.readFileSync(
|
|
27113
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26839
27114
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
26840
27115
|
lines.push("```javascript");
|
|
26841
27116
|
lines.push(content);
|
|
@@ -26851,7 +27126,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26851
27126
|
lines.push("");
|
|
26852
27127
|
for (const file of refFiles) {
|
|
26853
27128
|
try {
|
|
26854
|
-
const content = fs14.readFileSync(
|
|
27129
|
+
const content = fs14.readFileSync(path25.join(latestScriptsDir, file), "utf-8");
|
|
26855
27130
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
26856
27131
|
lines.push("```javascript");
|
|
26857
27132
|
lines.push(content);
|
|
@@ -26884,10 +27159,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26884
27159
|
lines.push("");
|
|
26885
27160
|
}
|
|
26886
27161
|
}
|
|
26887
|
-
const docsDir =
|
|
27162
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
26888
27163
|
const loadGuide = (name) => {
|
|
26889
27164
|
try {
|
|
26890
|
-
const p =
|
|
27165
|
+
const p = path25.join(docsDir, name);
|
|
26891
27166
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
26892
27167
|
} catch {
|
|
26893
27168
|
}
|
|
@@ -27334,8 +27609,8 @@ var DevServer = class _DevServer {
|
|
|
27334
27609
|
}
|
|
27335
27610
|
getEndpointList() {
|
|
27336
27611
|
return this.routes.map((r) => {
|
|
27337
|
-
const
|
|
27338
|
-
return `${r.method.padEnd(5)} ${
|
|
27612
|
+
const path27 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
27613
|
+
return `${r.method.padEnd(5)} ${path27}`;
|
|
27339
27614
|
});
|
|
27340
27615
|
}
|
|
27341
27616
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -27623,12 +27898,12 @@ var DevServer = class _DevServer {
|
|
|
27623
27898
|
// ─── DevConsole SPA ───
|
|
27624
27899
|
getConsoleDistDir() {
|
|
27625
27900
|
const candidates = [
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27901
|
+
path26.resolve(__dirname, "../../web-devconsole/dist"),
|
|
27902
|
+
path26.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
27903
|
+
path26.join(process.cwd(), "packages/web-devconsole/dist")
|
|
27629
27904
|
];
|
|
27630
27905
|
for (const dir of candidates) {
|
|
27631
|
-
if (fs15.existsSync(
|
|
27906
|
+
if (fs15.existsSync(path26.join(dir, "index.html"))) return dir;
|
|
27632
27907
|
}
|
|
27633
27908
|
return null;
|
|
27634
27909
|
}
|
|
@@ -27638,7 +27913,7 @@ var DevServer = class _DevServer {
|
|
|
27638
27913
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
27639
27914
|
return;
|
|
27640
27915
|
}
|
|
27641
|
-
const htmlPath =
|
|
27916
|
+
const htmlPath = path26.join(distDir, "index.html");
|
|
27642
27917
|
try {
|
|
27643
27918
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
27644
27919
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -27663,15 +27938,15 @@ var DevServer = class _DevServer {
|
|
|
27663
27938
|
this.json(res, 404, { error: "Not found" });
|
|
27664
27939
|
return;
|
|
27665
27940
|
}
|
|
27666
|
-
const safePath =
|
|
27667
|
-
const filePath =
|
|
27941
|
+
const safePath = path26.normalize(pathname).replace(/^\.\.\//, "");
|
|
27942
|
+
const filePath = path26.join(distDir, safePath);
|
|
27668
27943
|
if (!filePath.startsWith(distDir)) {
|
|
27669
27944
|
this.json(res, 403, { error: "Forbidden" });
|
|
27670
27945
|
return;
|
|
27671
27946
|
}
|
|
27672
27947
|
try {
|
|
27673
27948
|
const content = fs15.readFileSync(filePath);
|
|
27674
|
-
const ext =
|
|
27949
|
+
const ext = path26.extname(filePath);
|
|
27675
27950
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
27676
27951
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
27677
27952
|
res.end(content);
|
|
@@ -27784,9 +28059,9 @@ var DevServer = class _DevServer {
|
|
|
27784
28059
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
27785
28060
|
if (entry.isDirectory()) {
|
|
27786
28061
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
27787
|
-
scan(
|
|
28062
|
+
scan(path26.join(d, entry.name), rel);
|
|
27788
28063
|
} else {
|
|
27789
|
-
const stat2 = fs15.statSync(
|
|
28064
|
+
const stat2 = fs15.statSync(path26.join(d, entry.name));
|
|
27790
28065
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
27791
28066
|
}
|
|
27792
28067
|
}
|
|
@@ -27809,7 +28084,7 @@ var DevServer = class _DevServer {
|
|
|
27809
28084
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27810
28085
|
return;
|
|
27811
28086
|
}
|
|
27812
|
-
const fullPath =
|
|
28087
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27813
28088
|
if (!fullPath.startsWith(dir)) {
|
|
27814
28089
|
this.json(res, 403, { error: "Forbidden" });
|
|
27815
28090
|
return;
|
|
@@ -27834,14 +28109,14 @@ var DevServer = class _DevServer {
|
|
|
27834
28109
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
27835
28110
|
return;
|
|
27836
28111
|
}
|
|
27837
|
-
const fullPath =
|
|
28112
|
+
const fullPath = path26.resolve(dir, path26.normalize(filePath));
|
|
27838
28113
|
if (!fullPath.startsWith(dir)) {
|
|
27839
28114
|
this.json(res, 403, { error: "Forbidden" });
|
|
27840
28115
|
return;
|
|
27841
28116
|
}
|
|
27842
28117
|
try {
|
|
27843
28118
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
27844
|
-
fs15.mkdirSync(
|
|
28119
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
27845
28120
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
27846
28121
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
27847
28122
|
this.providerLoader.reload();
|
|
@@ -27858,7 +28133,7 @@ var DevServer = class _DevServer {
|
|
|
27858
28133
|
return;
|
|
27859
28134
|
}
|
|
27860
28135
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
27861
|
-
const p =
|
|
28136
|
+
const p = path26.join(dir, name);
|
|
27862
28137
|
if (fs15.existsSync(p)) {
|
|
27863
28138
|
const source = fs15.readFileSync(p, "utf-8");
|
|
27864
28139
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -27879,8 +28154,8 @@ var DevServer = class _DevServer {
|
|
|
27879
28154
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
27880
28155
|
return;
|
|
27881
28156
|
}
|
|
27882
|
-
const target = fs15.existsSync(
|
|
27883
|
-
const targetPath =
|
|
28157
|
+
const target = fs15.existsSync(path26.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
28158
|
+
const targetPath = path26.join(dir, target);
|
|
27884
28159
|
try {
|
|
27885
28160
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
27886
28161
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -28027,7 +28302,7 @@ var DevServer = class _DevServer {
|
|
|
28027
28302
|
}
|
|
28028
28303
|
let targetDir;
|
|
28029
28304
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
28030
|
-
const jsonPath =
|
|
28305
|
+
const jsonPath = path26.join(targetDir, "provider.json");
|
|
28031
28306
|
if (fs15.existsSync(jsonPath)) {
|
|
28032
28307
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
28033
28308
|
return;
|
|
@@ -28039,8 +28314,8 @@ var DevServer = class _DevServer {
|
|
|
28039
28314
|
const createdFiles = ["provider.json"];
|
|
28040
28315
|
if (result.files) {
|
|
28041
28316
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
28042
|
-
const fullPath =
|
|
28043
|
-
fs15.mkdirSync(
|
|
28317
|
+
const fullPath = path26.join(targetDir, relPath);
|
|
28318
|
+
fs15.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
28044
28319
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
28045
28320
|
createdFiles.push(relPath);
|
|
28046
28321
|
}
|
|
@@ -28093,22 +28368,22 @@ var DevServer = class _DevServer {
|
|
|
28093
28368
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
28094
28369
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
28095
28370
|
try {
|
|
28096
|
-
return fs15.statSync(
|
|
28371
|
+
return fs15.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
28097
28372
|
} catch {
|
|
28098
28373
|
return false;
|
|
28099
28374
|
}
|
|
28100
28375
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
28101
28376
|
if (versions.length === 0) return null;
|
|
28102
|
-
return
|
|
28377
|
+
return path26.join(scriptsDir, versions[0]);
|
|
28103
28378
|
}
|
|
28104
28379
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
28105
|
-
const canonicalUserDir =
|
|
28106
|
-
const desiredDir = requestedDir ?
|
|
28107
|
-
const upstreamRoot =
|
|
28108
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
28380
|
+
const canonicalUserDir = path26.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
28381
|
+
const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
|
|
28382
|
+
const upstreamRoot = path26.resolve(this.providerLoader.getUpstreamDir());
|
|
28383
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
|
|
28109
28384
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
28110
28385
|
}
|
|
28111
|
-
if (
|
|
28386
|
+
if (path26.basename(desiredDir) !== type) {
|
|
28112
28387
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
28113
28388
|
}
|
|
28114
28389
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -28116,11 +28391,11 @@ var DevServer = class _DevServer {
|
|
|
28116
28391
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
28117
28392
|
}
|
|
28118
28393
|
if (!fs15.existsSync(desiredDir)) {
|
|
28119
|
-
fs15.mkdirSync(
|
|
28394
|
+
fs15.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
28120
28395
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
28121
28396
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
28122
28397
|
}
|
|
28123
|
-
const providerJson =
|
|
28398
|
+
const providerJson = path26.join(desiredDir, "provider.json");
|
|
28124
28399
|
if (!fs15.existsSync(providerJson)) {
|
|
28125
28400
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
28126
28401
|
}
|
|
@@ -28156,7 +28431,7 @@ var DevServer = class _DevServer {
|
|
|
28156
28431
|
setMode: "set_mode.js"
|
|
28157
28432
|
};
|
|
28158
28433
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28159
|
-
const scriptsDir =
|
|
28434
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28160
28435
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28161
28436
|
if (latestScriptsDir) {
|
|
28162
28437
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28167,7 +28442,7 @@ var DevServer = class _DevServer {
|
|
|
28167
28442
|
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
28168
28443
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
28169
28444
|
try {
|
|
28170
|
-
const content = fs15.readFileSync(
|
|
28445
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28171
28446
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28172
28447
|
lines.push("```javascript");
|
|
28173
28448
|
lines.push(content);
|
|
@@ -28184,7 +28459,7 @@ var DevServer = class _DevServer {
|
|
|
28184
28459
|
lines.push("");
|
|
28185
28460
|
for (const file of refFiles) {
|
|
28186
28461
|
try {
|
|
28187
|
-
const content = fs15.readFileSync(
|
|
28462
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28188
28463
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28189
28464
|
lines.push("```javascript");
|
|
28190
28465
|
lines.push(content);
|
|
@@ -28225,10 +28500,10 @@ var DevServer = class _DevServer {
|
|
|
28225
28500
|
lines.push("");
|
|
28226
28501
|
}
|
|
28227
28502
|
}
|
|
28228
|
-
const docsDir =
|
|
28503
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28229
28504
|
const loadGuide = (name) => {
|
|
28230
28505
|
try {
|
|
28231
|
-
const p =
|
|
28506
|
+
const p = path26.join(docsDir, name);
|
|
28232
28507
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28233
28508
|
} catch {
|
|
28234
28509
|
}
|
|
@@ -28402,7 +28677,7 @@ var DevServer = class _DevServer {
|
|
|
28402
28677
|
parseApproval: "parse_approval.js"
|
|
28403
28678
|
};
|
|
28404
28679
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28405
|
-
const scriptsDir =
|
|
28680
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28406
28681
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
28407
28682
|
if (latestScriptsDir) {
|
|
28408
28683
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28414,7 +28689,7 @@ var DevServer = class _DevServer {
|
|
|
28414
28689
|
if (!file.endsWith(".js")) continue;
|
|
28415
28690
|
if (!targetFileNames.has(file)) continue;
|
|
28416
28691
|
try {
|
|
28417
|
-
const content = fs15.readFileSync(
|
|
28692
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28418
28693
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28419
28694
|
lines.push("```javascript");
|
|
28420
28695
|
lines.push(content);
|
|
@@ -28430,7 +28705,7 @@ var DevServer = class _DevServer {
|
|
|
28430
28705
|
lines.push("");
|
|
28431
28706
|
for (const file of refFiles) {
|
|
28432
28707
|
try {
|
|
28433
|
-
const content = fs15.readFileSync(
|
|
28708
|
+
const content = fs15.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28434
28709
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28435
28710
|
lines.push("```javascript");
|
|
28436
28711
|
lines.push(content);
|
|
@@ -28463,10 +28738,10 @@ var DevServer = class _DevServer {
|
|
|
28463
28738
|
lines.push("");
|
|
28464
28739
|
}
|
|
28465
28740
|
}
|
|
28466
|
-
const docsDir =
|
|
28741
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28467
28742
|
const loadGuide = (name) => {
|
|
28468
28743
|
try {
|
|
28469
|
-
const p =
|
|
28744
|
+
const p = path26.join(docsDir, name);
|
|
28470
28745
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
28471
28746
|
} catch {
|
|
28472
28747
|
}
|
|
@@ -29814,6 +30089,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29814
30089
|
createGitWorkspaceMonitor,
|
|
29815
30090
|
createInteractionId,
|
|
29816
30091
|
createMesh,
|
|
30092
|
+
createWorktree,
|
|
29817
30093
|
deleteMesh,
|
|
29818
30094
|
detectAllVersions,
|
|
29819
30095
|
detectCLIs,
|
|
@@ -29866,6 +30142,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29866
30142
|
launchWithCdp,
|
|
29867
30143
|
listHostedCliRuntimes,
|
|
29868
30144
|
listMeshes,
|
|
30145
|
+
listWorktrees,
|
|
29869
30146
|
loadConfig,
|
|
29870
30147
|
loadState,
|
|
29871
30148
|
logCommand,
|
|
@@ -29885,6 +30162,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29885
30162
|
normalizeSessionModalFields,
|
|
29886
30163
|
parsePorcelainV2Status,
|
|
29887
30164
|
parseProviderSourceConfigUpdate,
|
|
30165
|
+
parseWorktreeListOutput,
|
|
29888
30166
|
partitionSessionHostDiagnosticsSessions,
|
|
29889
30167
|
partitionSessionHostRecords,
|
|
29890
30168
|
prepareSessionChatTailUpdate,
|
|
@@ -29894,6 +30172,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29894
30172
|
recordDebugTrace,
|
|
29895
30173
|
registerExtensionProviders,
|
|
29896
30174
|
removeNode,
|
|
30175
|
+
removeWorktree,
|
|
29897
30176
|
resetConfig,
|
|
29898
30177
|
resetDebugRuntimeConfig,
|
|
29899
30178
|
resetState,
|
|
@@ -29903,6 +30182,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
29903
30182
|
resolveGitRepository,
|
|
29904
30183
|
resolveSessionHostAppName,
|
|
29905
30184
|
resolveSessionHostAppNameResolution,
|
|
30185
|
+
resolveWorktreePath,
|
|
29906
30186
|
runAsyncBatch,
|
|
29907
30187
|
runGit,
|
|
29908
30188
|
saveConfig,
|