@open-mercato/cezar 0.8.0 → 0.9.0-pr470.650
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/README.md +109 -14
- package/dist/agent-config/catalog.d.ts +64 -0
- package/dist/agent-config/catalog.js +205 -0
- package/dist/agent-config/catalog.js.map +1 -0
- package/dist/agent-config/files.d.ts +46 -0
- package/dist/agent-config/files.js +119 -0
- package/dist/agent-config/files.js.map +1 -0
- package/dist/agent-config/seed.d.ts +7 -0
- package/dist/agent-config/seed.js +90 -0
- package/dist/agent-config/seed.js.map +1 -0
- package/dist/agent-config/service.d.ts +44 -0
- package/dist/agent-config/service.js +71 -0
- package/dist/agent-config/service.js.map +1 -0
- package/dist/agent-config/validate.d.ts +21 -0
- package/dist/agent-config/validate.js +76 -0
- package/dist/agent-config/validate.js.map +1 -0
- package/dist/config.d.ts +34 -4
- package/dist/config.js +97 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-env.js +21 -15
- package/dist/core/agent-env.js.map +1 -1
- package/dist/core/agent-runner.d.ts +16 -6
- package/dist/core/agent-runner.js +15 -3
- package/dist/core/agent-runner.js.map +1 -1
- package/dist/core/ask.d.ts +184 -0
- package/dist/core/ask.js +97 -0
- package/dist/core/ask.js.map +1 -0
- package/dist/core/backend-detect.d.ts +5 -5
- package/dist/core/backend-detect.js +37 -5
- package/dist/core/backend-detect.js.map +1 -1
- package/dist/core/claude-cli-runner.d.ts +17 -2
- package/dist/core/claude-cli-runner.js +8 -3
- package/dist/core/claude-cli-runner.js.map +1 -1
- package/dist/core/claude-ui-mapper.d.ts +9 -0
- package/dist/core/claude-ui-mapper.js +34 -3
- package/dist/core/claude-ui-mapper.js.map +1 -1
- package/dist/core/codex-app-server-runner.d.ts +15 -3
- package/dist/core/codex-app-server-runner.js +158 -127
- package/dist/core/codex-app-server-runner.js.map +1 -1
- package/dist/core/codex-app-server-transport.d.ts +30 -0
- package/dist/core/codex-app-server-transport.js +136 -0
- package/dist/core/codex-app-server-transport.js.map +1 -0
- package/dist/core/codex-model-catalog.d.ts +10 -0
- package/dist/core/codex-model-catalog.js +110 -0
- package/dist/core/codex-model-catalog.js.map +1 -0
- package/dist/core/codex-ui-mapper.d.ts +47 -2
- package/dist/core/codex-ui-mapper.js +247 -29
- package/dist/core/codex-ui-mapper.js.map +1 -1
- package/dist/core/model-identity.d.ts +113 -0
- package/dist/core/model-identity.js +119 -0
- package/dist/core/model-identity.js.map +1 -0
- package/dist/core/model-presets.d.ts +15 -0
- package/dist/core/model-presets.js +43 -0
- package/dist/core/model-presets.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +1 -1
- package/dist/core/opencode-server-runner.js +7 -12
- package/dist/core/opencode-server-runner.js.map +1 -1
- package/dist/core/opencode-ui-mapper.d.ts +11 -7
- package/dist/core/opencode-ui-mapper.js +62 -19
- package/dist/core/opencode-ui-mapper.js.map +1 -1
- package/dist/core/pi-runner.d.ts +40 -0
- package/dist/core/pi-runner.js +49 -0
- package/dist/core/pi-runner.js.map +1 -0
- package/dist/core/process-usage.d.ts +3 -0
- package/dist/core/process-usage.js +12 -0
- package/dist/core/process-usage.js.map +1 -1
- package/dist/core/runner-factory.js +3 -0
- package/dist/core/runner-factory.js.map +1 -1
- package/dist/core/runner-model-catalog.d.ts +28 -0
- package/dist/core/runner-model-catalog.js +62 -0
- package/dist/core/runner-model-catalog.js.map +1 -0
- package/dist/core/secret-redaction.js.map +1 -1
- package/dist/core/tool-display.d.ts +2 -2
- package/dist/core/tool-display.js +24 -6
- package/dist/core/tool-display.js.map +1 -1
- package/dist/core/ui-events.d.ts +29 -2
- package/dist/git-worktree.d.ts +37 -4
- package/dist/git-worktree.js +175 -12
- package/dist/git-worktree.js.map +1 -1
- package/dist/handoff.d.ts +2 -2
- package/dist/handoff.js +2 -0
- package/dist/handoff.js.map +1 -1
- package/dist/index.js +55 -5
- package/dist/index.js.map +1 -1
- package/dist/install-as-command.d.ts +1 -1
- package/dist/install-as-command.js.map +1 -1
- package/dist/paths.d.ts +32 -2
- package/dist/paths.js +47 -2
- package/dist/paths.js.map +1 -1
- package/dist/runs/auto-name.js.map +1 -1
- package/dist/runs/retention.js.map +1 -1
- package/dist/runs/review-gate.js.map +1 -1
- package/dist/runs/store.d.ts +154 -60
- package/dist/runs/store.js +103 -19
- package/dist/runs/store.js.map +1 -1
- package/dist/runs/task-markers.d.ts +6 -2
- package/dist/runs/task-markers.js +25 -4
- package/dist/runs/task-markers.js.map +1 -1
- package/dist/runs/ui-event-sink.js.map +1 -1
- package/dist/server/capabilities.d.ts +22 -6
- package/dist/server/capabilities.js +85 -8
- package/dist/server/capabilities.js.map +1 -1
- package/dist/server/checkout.d.ts +128 -0
- package/dist/server/checkout.js +296 -0
- package/dist/server/checkout.js.map +1 -0
- package/dist/server/forge/github.d.ts +281 -10
- package/dist/server/forge/github.js +539 -23
- package/dist/server/forge/github.js.map +1 -1
- package/dist/server/forge/types.d.ts +48 -1
- package/dist/server/fs-browse.d.ts +105 -0
- package/dist/server/fs-browse.js +182 -0
- package/dist/server/fs-browse.js.map +1 -0
- package/dist/server/git-changes.d.ts +12 -3
- package/dist/server/git-changes.js +23 -5
- package/dist/server/git-changes.js.map +1 -1
- package/dist/server/github.d.ts +1 -1
- package/dist/server/open-in-app.d.ts +2 -1
- package/dist/server/open-in-app.js +1 -0
- package/dist/server/open-in-app.js.map +1 -1
- package/dist/server/project-context.d.ts +103 -0
- package/dist/server/project-context.js +153 -0
- package/dist/server/project-context.js.map +1 -0
- package/dist/server/server.d.ts +110 -0
- package/dist/server/server.js +1557 -215
- package/dist/server/server.js.map +1 -1
- package/dist/server/wsl.js.map +1 -1
- package/dist/server-install/platforms/macosx-ngrok.js.map +1 -1
- package/dist/server-install/platforms/ubuntu-vps.js +7 -0
- package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
- package/dist/server-install/state.js.map +1 -1
- package/dist/server-install/steps.js +6 -2
- package/dist/server-install/steps.js.map +1 -1
- package/dist/server-install/types.d.ts +28 -28
- package/dist/server-install/ui.js.map +1 -1
- package/dist/skills-banner.js.map +1 -1
- package/dist/skills-remote.d.ts +10 -4
- package/dist/skills-remote.js +31 -14
- package/dist/skills-remote.js.map +1 -1
- package/dist/skills.d.ts +29 -0
- package/dist/skills.js +72 -14
- package/dist/skills.js.map +1 -1
- package/dist/todos.d.ts +9 -7
- package/dist/todos.js +38 -19
- package/dist/todos.js.map +1 -1
- package/dist/workflows/run.d.ts +145 -10
- package/dist/workflows/run.js +608 -66
- package/dist/workflows/run.js.map +1 -1
- package/dist/workflows/types.d.ts +42 -42
- package/dist/workflows/types.js +2 -1
- package/dist/workflows/types.js.map +1 -1
- package/dist/workspace/config.d.ts +251 -0
- package/dist/workspace/config.js +162 -0
- package/dist/workspace/config.js.map +1 -0
- package/dist/workspace/migrations.d.ts +45 -0
- package/dist/workspace/migrations.js +132 -0
- package/dist/workspace/migrations.js.map +1 -0
- package/dist/workspace/projects-cli.d.ts +23 -0
- package/dist/workspace/projects-cli.js +105 -0
- package/dist/workspace/projects-cli.js.map +1 -0
- package/dist/workspace/projects.d.ts +81 -0
- package/dist/workspace/projects.js +214 -0
- package/dist/workspace/projects.js.map +1 -0
- package/dist/workspace/semaphore.d.ts +77 -0
- package/dist/workspace/semaphore.js +57 -0
- package/dist/workspace/semaphore.js.map +1 -0
- package/dist/workspace/ui-state.d.ts +23 -0
- package/dist/workspace/ui-state.js +42 -0
- package/dist/workspace/ui-state.js.map +1 -0
- package/package.json +3 -2
- package/scripts/mock-claude.mjs +136 -2
- package/web/dist/assets/arrow-left-CnSdp92h.js +1 -0
- package/web/dist/assets/centered-state-NF79blq7.js +43 -0
- package/web/dist/assets/{chunk-BO2N2NFS-BN7h-q1E.js → chunk-BO2N2NFS-DtrdTCWa.js} +4 -4
- package/web/dist/assets/commit-list-CL8vSWGw.js +1 -0
- package/web/dist/assets/compare-variants-mI-MnhuR.js +1 -0
- package/web/dist/assets/diff-view-Bhfvnnn9.js +6 -0
- package/web/dist/assets/dist-COA_NSud.js +1 -0
- package/web/dist/assets/ellipsis-vertical-CNnSLn5a.js +1 -0
- package/web/dist/assets/{file-tuE95HNX.js → file-D4GBh1ao.js} +1 -1
- package/web/dist/assets/{git-pull-request-BztcgsRZ.js → git-pull-request-DnR8Xh4_.js} +1 -1
- package/web/dist/assets/git-toolbar-rVtFyL4t.js +1 -0
- package/web/dist/assets/github-_t0ceKcO.js +1 -0
- package/web/dist/assets/{highlighted-body-OFNGDK62-CJIHtxqW.js → highlighted-body-OFNGDK62-BuFJwunK.js} +1 -1
- package/web/dist/assets/{image-preview-Ca0UgThg.js → image-preview-DEhW0TFz.js} +1 -1
- package/web/dist/assets/index-BfXFhAGQ.js +30 -0
- package/web/dist/assets/index-Mov2Rrbw.css +2 -0
- package/web/dist/assets/lib-DPEZDBUN.js +1 -0
- package/web/dist/assets/mermaid-GHXKKRXX-CN2zQue0.js +1 -0
- package/web/dist/assets/project-router-CBzGUqvS.js +1 -0
- package/web/dist/assets/{refresh-cw-B4NW5q60.js → refresh-cw-BT8E96Tm.js} +1 -1
- package/web/dist/assets/repo-git-C3dJiX3j.js +1 -0
- package/web/dist/assets/{run-diff-BKpV1kGk.js → run-diff-HEZcHwRr.js} +3 -3
- package/web/dist/assets/run-header-DldbROhB.js +1 -0
- package/web/dist/assets/{search-x-C6xG26dv.js → search-x-BDjaMrzG.js} +1 -1
- package/web/dist/assets/skill-empty-hint-DTUSp6Vl.js +1 -0
- package/web/dist/assets/skills-BIg29xLt.js +1 -0
- package/web/dist/assets/{square-terminal-D9l_Xx7B.js → square-terminal-Ckjjn0vb.js} +1 -1
- package/web/dist/assets/tab-link-DTQ9FBZY.js +1 -0
- package/web/dist/assets/task-changes-DRhQVnFN.js +1 -0
- package/web/dist/assets/task-commits-5StODPII.js +1 -0
- package/web/dist/assets/task-files-BuylxobG.js +2 -0
- package/web/dist/assets/task-thread-DnHR0k7k.js +9 -0
- package/web/dist/assets/textarea-Bj_LCreg.js +1 -0
- package/web/dist/assets/toml-CcmNWLt0.js +1 -0
- package/web/dist/assets/{trash-2-De8Z5Y5-.js → trash-2-DAyZ0VSi.js} +1 -1
- package/web/dist/assets/{triangle-alert-DJUyRhTV.js → triangle-alert-Uy8rokUh.js} +1 -1
- package/web/dist/assets/{upload-yxUM9nk5.js → upload-CDdyPPo_.js} +1 -1
- package/web/dist/assets/use-desktop-TyHAXhMR.js +3 -0
- package/web/dist/assets/utils-B8s5qIcK.js +1 -0
- package/web/dist/assets/workflows-CwDYZLvG.js +11 -0
- package/web/dist/assets/zoomable-image-PEDOqyLQ.js +1 -0
- package/web/dist/index.html +10 -19
- package/web/dist/assets/arrow-left-bEsJ-6jp.js +0 -1
- package/web/dist/assets/centered-state-DzJJpXgm.js +0 -43
- package/web/dist/assets/command-eBgVGftz.js +0 -1
- package/web/dist/assets/compare-variants-DhqGJuHF.js +0 -1
- package/web/dist/assets/dialog-Bf1Cpc3n.js +0 -1
- package/web/dist/assets/diff-view-Cqc8LRkj.js +0 -4
- package/web/dist/assets/dist-M2QYGAcm.js +0 -1
- package/web/dist/assets/dist-ZAIqO3UX.js +0 -1
- package/web/dist/assets/folder-20ea3OVM.js +0 -1
- package/web/dist/assets/git-toolbar-DAlBoSP5.js +0 -1
- package/web/dist/assets/github--sfM4X3j.js +0 -1
- package/web/dist/assets/highlighter-ZVyRi_Cx.js +0 -3
- package/web/dist/assets/index-DlKq8gF4.css +0 -2
- package/web/dist/assets/index-h4gyDJyh.js +0 -11
- package/web/dist/assets/loader-circle-Bnw4ga19.js +0 -1
- package/web/dist/assets/markdown-DxmCMr30.js +0 -1
- package/web/dist/assets/mermaid-GHXKKRXX-DghlHZS5.js +0 -1
- package/web/dist/assets/prompt-templates-CsGr-FXH.js +0 -15
- package/web/dist/assets/repo-git-CHF2oip_.js +0 -1
- package/web/dist/assets/run-header-3CGn6FAM.js +0 -1
- package/web/dist/assets/skill-detail-DsD4-dGp.js +0 -1
- package/web/dist/assets/skill-empty-hint-Cl3ESoPu.js +0 -1
- package/web/dist/assets/skills-5kRcjM1J.js +0 -1
- package/web/dist/assets/skills-B13iqWAN.js +0 -1
- package/web/dist/assets/tab-link-DkVxOa-q.js +0 -1
- package/web/dist/assets/task-changes-DtMiVVwO.js +0 -1
- package/web/dist/assets/task-commits-VbSLn_tW.js +0 -1
- package/web/dist/assets/task-files-qYDBG3Mx.js +0 -2
- package/web/dist/assets/task-thread-BfGERKlB.js +0 -7
- package/web/dist/assets/tasks-table-C5fwJmZ7.js +0 -1
- package/web/dist/assets/use-desktop-6PwFeCW3.js +0 -3
- package/web/dist/assets/utils-CzkLr94M.js +0 -1
- package/web/dist/assets/workflows-CnTcKlfV.js +0 -11
- package/web/dist/assets/x-DaR4ZfE-.js +0 -1
- package/web/dist/assets/zoomable-image-B-76XMUw.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/agent-config/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy the seeded personal-layer files from `repoRoot` into `worktreeCwd`.
|
|
3
|
+
* Guards every file with `git check-ignore` so a file the user genuinely tracked
|
|
4
|
+
* (against the vendor's advice) is neither copied nor excluded. Returns the
|
|
5
|
+
* repo-relative paths actually seeded, for the caller's note. Never throws.
|
|
6
|
+
*/
|
|
7
|
+
export declare function seedAgentConfigLocalLayer(repoRoot: string, worktreeCwd: string, env?: NodeJS.ProcessEnv): Promise<string[]>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, relative } from 'node:path';
|
|
4
|
+
import { agentHomePaths } from '../paths.js';
|
|
5
|
+
import { CONFIG_FILES } from './catalog.js';
|
|
6
|
+
/**
|
|
7
|
+
* Seed the agents' gitignored personal config layer into a run's worktree
|
|
8
|
+
* (spec #404 §"The worktree problem"). A run's cwd is a worktree, so a repo-root
|
|
9
|
+
* edit to a gitignored file (`.claude/settings.local.json`, `CLAUDE.local.md`)
|
|
10
|
+
* would never reach the agent — the file does not exist there. Copying it in,
|
|
11
|
+
* and excluding it via the shared `info/exclude`, makes the personal layer take
|
|
12
|
+
* effect immediately without ever committing it. Mirrors `materializeSkillDir`.
|
|
13
|
+
*
|
|
14
|
+
* Only Claude's gitignored layer is seeded (the only vendor with a documented
|
|
15
|
+
* untracked personal file). Tracked files keep honest "applies after commit"
|
|
16
|
+
* semantics and are never touched here.
|
|
17
|
+
*/
|
|
18
|
+
function git(cwd, args) {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
execFile('git', args, { cwd, encoding: 'utf8' }, (err, stdout) => resolve({ ok: !err, stdout: stdout ?? '' }));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function fileExists(path) {
|
|
24
|
+
try {
|
|
25
|
+
await readFile(path);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Append `line` to `info/exclude` only if it is not already present (idempotent across runs). */
|
|
33
|
+
async function ensureExcluded(commonGitDir, line) {
|
|
34
|
+
const excludePath = join(commonGitDir, 'info', 'exclude');
|
|
35
|
+
let current = '';
|
|
36
|
+
try {
|
|
37
|
+
current = await readFile(excludePath, 'utf8');
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// no exclude file yet — created below
|
|
41
|
+
}
|
|
42
|
+
const lines = current.split('\n').map((l) => l.trim());
|
|
43
|
+
if (lines.includes(line))
|
|
44
|
+
return;
|
|
45
|
+
await mkdir(dirname(excludePath), { recursive: true });
|
|
46
|
+
const sep = current.length === 0 || current.endsWith('\n') ? '' : '\n';
|
|
47
|
+
await writeFile(excludePath, `${current}${sep}${line}\n`, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Copy the seeded personal-layer files from `repoRoot` into `worktreeCwd`.
|
|
51
|
+
* Guards every file with `git check-ignore` so a file the user genuinely tracked
|
|
52
|
+
* (against the vendor's advice) is neither copied nor excluded. Returns the
|
|
53
|
+
* repo-relative paths actually seeded, for the caller's note. Never throws.
|
|
54
|
+
*/
|
|
55
|
+
export async function seedAgentConfigLocalLayer(repoRoot, worktreeCwd, env = process.env) {
|
|
56
|
+
if (worktreeCwd === repoRoot)
|
|
57
|
+
return [];
|
|
58
|
+
const home = agentHomePaths(env);
|
|
59
|
+
const seeded = [];
|
|
60
|
+
const commonDir = await git(worktreeCwd, ['rev-parse', '--git-common-dir']);
|
|
61
|
+
if (!commonDir.ok)
|
|
62
|
+
return [];
|
|
63
|
+
const commonGitDir = commonDir.stdout.trim();
|
|
64
|
+
const absCommonGitDir = commonGitDir.startsWith('/') ? commonGitDir : join(worktreeCwd, commonGitDir);
|
|
65
|
+
for (const def of CONFIG_FILES) {
|
|
66
|
+
if (!def.seeded)
|
|
67
|
+
continue;
|
|
68
|
+
const src = def.resolve(repoRoot, home);
|
|
69
|
+
const rel = relative(repoRoot, src);
|
|
70
|
+
// Never seed something outside the repo, or that isn't there.
|
|
71
|
+
if (rel.startsWith('..') || !(await fileExists(src)))
|
|
72
|
+
continue;
|
|
73
|
+
// Only seed a genuinely-ignored file — never force-exclude a tracked one.
|
|
74
|
+
const ignored = await git(repoRoot, ['check-ignore', '-q', '--', rel]);
|
|
75
|
+
if (!ignored.ok)
|
|
76
|
+
continue;
|
|
77
|
+
const dest = join(worktreeCwd, rel);
|
|
78
|
+
try {
|
|
79
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
80
|
+
await copyFile(src, dest);
|
|
81
|
+
await ensureExcluded(absCommonGitDir, rel);
|
|
82
|
+
seeded.push(rel);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// best-effort: a seed failure must not fail the run
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return seeded;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/agent-config/seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ConfigFileDef } from './catalog.js';
|
|
2
|
+
/**
|
|
3
|
+
* Assembles the `GET /api/agent-config` payload: every catalog file's current
|
|
4
|
+
* on-disk state plus, locally, a read-only listing of the MCP servers Claude
|
|
5
|
+
* keeps in its own state file (`~/.claude.json`). In hosted mode (`editable`
|
|
6
|
+
* false) writes are refused server-side and the `~/.claude.json` listing is
|
|
7
|
+
* withheld — it is host state a hosted client is not trusted to see.
|
|
8
|
+
*/
|
|
9
|
+
export interface ConfigFileListing {
|
|
10
|
+
id: string;
|
|
11
|
+
runners: ConfigFileDef['runners'];
|
|
12
|
+
kind: ConfigFileDef['kind'];
|
|
13
|
+
scope: ConfigFileDef['scope'];
|
|
14
|
+
label: string;
|
|
15
|
+
path: string;
|
|
16
|
+
format: ConfigFileDef['format'];
|
|
17
|
+
tracked: ConfigFileDef['tracked'];
|
|
18
|
+
seeded: boolean;
|
|
19
|
+
holdsMcp: boolean;
|
|
20
|
+
precedence: string;
|
|
21
|
+
hotReload?: string;
|
|
22
|
+
docsUrl: string;
|
|
23
|
+
exists: boolean;
|
|
24
|
+
size: number;
|
|
25
|
+
/** sha256 of the bytes, or null when absent. */
|
|
26
|
+
version: string | null;
|
|
27
|
+
/** False in hosted mode (whole feature) — the client renders read-only up front. */
|
|
28
|
+
writable: boolean;
|
|
29
|
+
readOnlyReason?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface UserMcpListing {
|
|
32
|
+
path: string;
|
|
33
|
+
servers: string[];
|
|
34
|
+
readable: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface AgentConfigListing {
|
|
37
|
+
editable: boolean;
|
|
38
|
+
files: ConfigFileListing[];
|
|
39
|
+
/** null in hosted mode (host-state disclosure guard). */
|
|
40
|
+
userMcp: UserMcpListing | null;
|
|
41
|
+
}
|
|
42
|
+
/** Read the user-scope MCP server *names* from ~/.claude.json — never its contents, never for writing. */
|
|
43
|
+
export declare function readUserMcpServers(env: NodeJS.ProcessEnv): Promise<UserMcpListing>;
|
|
44
|
+
export declare function listAgentConfig(repoRoot: string, env: NodeJS.ProcessEnv, editable: boolean): Promise<AgentConfigListing>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { agentHomePaths } from '../paths.js';
|
|
4
|
+
import { CONFIG_FILES } from './catalog.js';
|
|
5
|
+
import { hashBytes, statConfigPath } from './files.js';
|
|
6
|
+
const HOSTED_REASON = 'agent config is edited from the machine that owns the checkout (this cockpit runs in hosted mode)';
|
|
7
|
+
/** ~/.claude.json can be large (per-project history); cap the read. */
|
|
8
|
+
const CLAUDE_JSON_CAP = 2 * 1024 * 1024;
|
|
9
|
+
async function versionOf(path, exists) {
|
|
10
|
+
if (!exists)
|
|
11
|
+
return null;
|
|
12
|
+
try {
|
|
13
|
+
return hashBytes(await readFile(path, 'utf8'));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Read the user-scope MCP server *names* from ~/.claude.json — never its contents, never for writing. */
|
|
20
|
+
export async function readUserMcpServers(env) {
|
|
21
|
+
// ~/.claude.json is a sibling of ~/.claude/ — Claude's own MCP state file.
|
|
22
|
+
const path = join(dirname(agentHomePaths(env).claude), '.claude.json');
|
|
23
|
+
try {
|
|
24
|
+
const { size } = await statConfigPath(path);
|
|
25
|
+
if (size > CLAUDE_JSON_CAP)
|
|
26
|
+
return { path, servers: [], readable: false };
|
|
27
|
+
const raw = await readFile(path, 'utf8');
|
|
28
|
+
const parsed = JSON.parse(raw);
|
|
29
|
+
const servers = parsed.mcpServers && typeof parsed.mcpServers === 'object' ? Object.keys(parsed.mcpServers) : [];
|
|
30
|
+
return { path, servers, readable: true };
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
// ENOENT → readable (no servers); anything else → not readable
|
|
34
|
+
if (err.code === 'ENOENT')
|
|
35
|
+
return { path, servers: [], readable: true };
|
|
36
|
+
return { path, servers: [], readable: false };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function listAgentConfig(repoRoot, env, editable) {
|
|
40
|
+
const home = agentHomePaths(env);
|
|
41
|
+
const files = await Promise.all(CONFIG_FILES.map(async (def) => {
|
|
42
|
+
const path = def.resolve(repoRoot, home);
|
|
43
|
+
const { exists, size } = await statConfigPath(path);
|
|
44
|
+
return {
|
|
45
|
+
id: def.id,
|
|
46
|
+
runners: def.runners,
|
|
47
|
+
kind: def.kind,
|
|
48
|
+
scope: def.scope,
|
|
49
|
+
label: def.label,
|
|
50
|
+
path,
|
|
51
|
+
format: def.format,
|
|
52
|
+
tracked: def.tracked,
|
|
53
|
+
seeded: Boolean(def.seeded),
|
|
54
|
+
holdsMcp: Boolean(def.holdsMcp),
|
|
55
|
+
precedence: def.precedence,
|
|
56
|
+
hotReload: def.hotReload,
|
|
57
|
+
docsUrl: def.docsUrl,
|
|
58
|
+
exists,
|
|
59
|
+
size,
|
|
60
|
+
version: await versionOf(path, exists),
|
|
61
|
+
writable: editable,
|
|
62
|
+
readOnlyReason: editable ? undefined : HOSTED_REASON,
|
|
63
|
+
};
|
|
64
|
+
}));
|
|
65
|
+
return {
|
|
66
|
+
editable,
|
|
67
|
+
files,
|
|
68
|
+
userMcp: editable ? await readUserMcpServers(env) : null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/agent-config/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ConfigFormat } from './catalog.js';
|
|
2
|
+
/**
|
|
3
|
+
* On save, cezar proves a config file PARSES in its own format — refusing to
|
|
4
|
+
* write bytes that would break the user's agent — but it never checks the
|
|
5
|
+
* vendor's *schema* (that is the drift a raw editor exists to avoid) and it
|
|
6
|
+
* never re-serializes: a valid file is written back byte-for-byte as typed.
|
|
7
|
+
*/
|
|
8
|
+
export interface ValidationResult {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
/** Human-readable parser message when `ok` is false. */
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Strip `//` line and slash-star block comments from JSONC, string-aware so a
|
|
15
|
+
* `//` or `/*` inside a JSON string is preserved. Whitespace-preserving (spans
|
|
16
|
+
* are blanked, not removed) so parser error offsets still line up with the
|
|
17
|
+
* source. Only used to validate — the original bytes are what gets written.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stripJsonComments(input: string): string;
|
|
20
|
+
/** Validate `content` against `format`. Markdown is always valid; empty is always valid (a new file). */
|
|
21
|
+
export declare function validateConfig(content: string, format: ConfigFormat): ValidationResult;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { parse as parseToml } from 'smol-toml';
|
|
2
|
+
/**
|
|
3
|
+
* Strip `//` line and slash-star block comments from JSONC, string-aware so a
|
|
4
|
+
* `//` or `/*` inside a JSON string is preserved. Whitespace-preserving (spans
|
|
5
|
+
* are blanked, not removed) so parser error offsets still line up with the
|
|
6
|
+
* source. Only used to validate — the original bytes are what gets written.
|
|
7
|
+
*/
|
|
8
|
+
export function stripJsonComments(input) {
|
|
9
|
+
let out = '';
|
|
10
|
+
let inString = false;
|
|
11
|
+
let escaped = false;
|
|
12
|
+
for (let i = 0; i < input.length; i++) {
|
|
13
|
+
const ch = input[i];
|
|
14
|
+
if (inString) {
|
|
15
|
+
out += ch;
|
|
16
|
+
if (escaped)
|
|
17
|
+
escaped = false;
|
|
18
|
+
else if (ch === '\\')
|
|
19
|
+
escaped = true;
|
|
20
|
+
else if (ch === '"')
|
|
21
|
+
inString = false;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (ch === '"') {
|
|
25
|
+
inString = true;
|
|
26
|
+
out += ch;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (ch === '/' && input[i + 1] === '/') {
|
|
30
|
+
// Line comment runs to EOL; nothing follows it on the line, so dropping the
|
|
31
|
+
// body doesn't shift any later token — only the newline must be preserved.
|
|
32
|
+
while (i < input.length && input[i] !== '\n')
|
|
33
|
+
i++;
|
|
34
|
+
out += input[i] === '\n' ? '\n' : '';
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (ch === '/' && input[i + 1] === '*') {
|
|
38
|
+
out += ' '; // the opening `/*`, blanked in place so same-line offsets after it hold
|
|
39
|
+
i += 2;
|
|
40
|
+
while (i < input.length && !(input[i] === '*' && input[i + 1] === '/')) {
|
|
41
|
+
out += input[i] === '\n' ? '\n' : ' ';
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
i++; // land on the closing '/'
|
|
45
|
+
out += ' '; // the closing `*/`
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
out += ch;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
/** Validate `content` against `format`. Markdown is always valid; empty is always valid (a new file). */
|
|
53
|
+
export function validateConfig(content, format) {
|
|
54
|
+
if (format === 'markdown')
|
|
55
|
+
return { ok: true };
|
|
56
|
+
if (content.trim() === '')
|
|
57
|
+
return { ok: true };
|
|
58
|
+
try {
|
|
59
|
+
switch (format) {
|
|
60
|
+
case 'json':
|
|
61
|
+
JSON.parse(content);
|
|
62
|
+
return { ok: true };
|
|
63
|
+
case 'jsonc':
|
|
64
|
+
JSON.parse(stripJsonComments(content));
|
|
65
|
+
return { ok: true };
|
|
66
|
+
case 'toml':
|
|
67
|
+
parseToml(content);
|
|
68
|
+
return { ok: true };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
73
|
+
}
|
|
74
|
+
return { ok: true };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/agent-config/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ declare const skillsRepoSchema: z.ZodObject<{
|
|
|
18
18
|
}>;
|
|
19
19
|
export type SkillsRepoSource = z.infer<typeof skillsRepoSchema>;
|
|
20
20
|
export declare const DEFAULT_SKILLS_REPOS: SkillsRepoSource[];
|
|
21
|
+
/** Last-resort retention when neither the repo nor the workspace says anything. */
|
|
22
|
+
export declare const DEFAULT_WORKTREE_RETENTION = 10;
|
|
21
23
|
declare const configSchema: z.ZodObject<{
|
|
22
24
|
skillsRepos: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
23
25
|
/** `owner/name` (GitHub shorthand), a full git URL, or a local/file:// path. */
|
|
@@ -52,7 +54,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
52
54
|
* step (workflow). The GUI only offers runners actually installed; this is
|
|
53
55
|
* the preselected default. Also the runner the chain planner uses.
|
|
54
56
|
*/
|
|
55
|
-
defaultRunner: z.ZodDefault<z.ZodEnum<["claude", "codex", "opencode"]>>;
|
|
57
|
+
defaultRunner: z.ZodDefault<z.ZodEnum<["claude", "codex", "opencode", "pi"]>>;
|
|
56
58
|
/** Model for the chain planner (spec 008) — cheap but reliable at JSON. */
|
|
57
59
|
plannerModel: z.ZodDefault<z.ZodString>;
|
|
58
60
|
/** Model for the task namer (spec 2026-07-17-task-auto-naming) — the cheapest
|
|
@@ -92,14 +94,17 @@ declare const configSchema: z.ZodObject<{
|
|
|
92
94
|
claude: z.ZodOptional<z.ZodString>;
|
|
93
95
|
codex: z.ZodOptional<z.ZodString>;
|
|
94
96
|
opencode: z.ZodOptional<z.ZodString>;
|
|
97
|
+
pi: z.ZodOptional<z.ZodString>;
|
|
95
98
|
}, "strip", z.ZodTypeAny, {
|
|
96
99
|
claude?: string | undefined;
|
|
97
100
|
codex?: string | undefined;
|
|
98
101
|
opencode?: string | undefined;
|
|
102
|
+
pi?: string | undefined;
|
|
99
103
|
}, {
|
|
100
104
|
claude?: string | undefined;
|
|
101
105
|
codex?: string | undefined;
|
|
102
106
|
opencode?: string | undefined;
|
|
107
|
+
pi?: string | undefined;
|
|
103
108
|
}>>>;
|
|
104
109
|
}, "strip", z.ZodTypeAny, {
|
|
105
110
|
skillsRepos: {
|
|
@@ -108,10 +113,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
108
113
|
}[];
|
|
109
114
|
maxParallel: number;
|
|
110
115
|
worktreeRetention: number;
|
|
111
|
-
|
|
116
|
+
memoryLimitMb?: number | undefined;
|
|
117
|
+
defaultRunner: "claude" | "codex" | "opencode" | "pi";
|
|
112
118
|
plannerModel: string;
|
|
113
119
|
namerModel: string;
|
|
114
|
-
memoryLimitMb?: number | undefined;
|
|
115
120
|
liveTitleUpdates?: boolean | undefined;
|
|
116
121
|
reviewGate?: boolean | undefined;
|
|
117
122
|
baseBranch?: string | undefined;
|
|
@@ -120,6 +125,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
120
125
|
claude?: string | undefined;
|
|
121
126
|
codex?: string | undefined;
|
|
122
127
|
opencode?: string | undefined;
|
|
128
|
+
pi?: string | undefined;
|
|
123
129
|
} | undefined;
|
|
124
130
|
}, {
|
|
125
131
|
skillsRepos?: {
|
|
@@ -129,7 +135,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
129
135
|
maxParallel?: number | undefined;
|
|
130
136
|
worktreeRetention?: unknown;
|
|
131
137
|
memoryLimitMb?: unknown;
|
|
132
|
-
defaultRunner?: "claude" | "codex" | "opencode" | undefined;
|
|
138
|
+
defaultRunner?: "claude" | "codex" | "opencode" | "pi" | undefined;
|
|
133
139
|
plannerModel?: string | undefined;
|
|
134
140
|
namerModel?: string | undefined;
|
|
135
141
|
liveTitleUpdates?: boolean | undefined;
|
|
@@ -141,4 +147,28 @@ declare const configSchema: z.ZodObject<{
|
|
|
141
147
|
export type CezConfig = z.infer<typeof configSchema>;
|
|
142
148
|
/** Read `.ai/cezar/config.json` on demand — never cached, never throws. */
|
|
143
149
|
export declare function loadConfig(repoRoot: string): Promise<CezConfig>;
|
|
150
|
+
/**
|
|
151
|
+
* The default skills repos that are *opt-in per skill* (the "import OM skills"
|
|
152
|
+
* flow): the set of repo identifiers a user must explicitly import from before
|
|
153
|
+
* their skills join the catalog. This is exactly `DEFAULT_SKILLS_REPOS` when the
|
|
154
|
+
* repo has NOT configured its own `skillsRepos` — the zero-config majority — and
|
|
155
|
+
* empty once a repo takes control by setting `skillsRepos` (then everything it
|
|
156
|
+
* lists auto-loads, unchanged).
|
|
157
|
+
*
|
|
158
|
+
* `loadConfig` cannot answer this: the schema's `.default(DEFAULT_SKILLS_REPOS)`
|
|
159
|
+
* materializes the key, so a parsed config can't tell "the user chose these" from
|
|
160
|
+
* "the user said nothing". So we probe the raw file for the key's presence — the
|
|
161
|
+
* same reason `ownWorktreeRetention` below reads the raw JSON.
|
|
162
|
+
*/
|
|
163
|
+
export declare function gatedSkillsRepos(repoRoot: string): Promise<Set<string>>;
|
|
164
|
+
/**
|
|
165
|
+
* Effective worktree retention for a repo (#483 + spec
|
|
166
|
+
* 2026-07-20-multi-project-workspace). Precedence, exactly what Settings →
|
|
167
|
+
* Worktrees promises: the repo's own `worktreeRetention` wins whenever it sets
|
|
168
|
+
* one; otherwise the workspace's `resources.worktreeRetentionDefault` seeds it;
|
|
169
|
+
* an absent/unreadable workspace config keeps the historical 10. Every
|
|
170
|
+
* enforcement site (boot sweeps, terminal transitions, the reclaim route) must
|
|
171
|
+
* go through here so the setting can never be a lie.
|
|
172
|
+
*/
|
|
173
|
+
export declare function resolveWorktreeRetention(repoRoot: string): Promise<number>;
|
|
144
174
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { loadWorkspaceConfig } from './workspace/config.js';
|
|
5
|
+
import { RUNNER_IDS } from './core/agent-runner.js';
|
|
4
6
|
/**
|
|
5
7
|
* Optional advanced config at `.ai/cezar/config.json`. Zero-config rule:
|
|
6
8
|
* a missing file behaves exactly like the default below, an unreadable or
|
|
@@ -15,6 +17,12 @@ const skillsRepoSchema = z.object({
|
|
|
15
17
|
export const DEFAULT_SKILLS_REPOS = [
|
|
16
18
|
{ repo: 'open-mercato/skills', ref: 'main' },
|
|
17
19
|
];
|
|
20
|
+
/** Last-resort retention when neither the repo nor the workspace says anything. */
|
|
21
|
+
export const DEFAULT_WORKTREE_RETENTION = 10;
|
|
22
|
+
/** Bounds for `worktreeRetention` — shared with the presence probe below, so the
|
|
23
|
+
* "does this repo set its own?" question is answered by the same rule the
|
|
24
|
+
* schema enforces (and mirrors the workspace default's bounds). */
|
|
25
|
+
const worktreeRetentionSchema = z.number().int().min(0).max(1000);
|
|
18
26
|
const configSchema = z.object({
|
|
19
27
|
skillsRepos: z.array(skillsRepoSchema).default(DEFAULT_SKILLS_REPOS),
|
|
20
28
|
/** How many tasks may run at once (spec 006). Non-git dirs always run 1. */
|
|
@@ -26,7 +34,7 @@ const configSchema = z.object({
|
|
|
26
34
|
* (never auto-reclaim). Default 10. `.catch(10)` keeps it additive-safe: a
|
|
27
35
|
* bad value degrades to the default instead of discarding the rest.
|
|
28
36
|
*/
|
|
29
|
-
worktreeRetention:
|
|
37
|
+
worktreeRetention: worktreeRetentionSchema.default(DEFAULT_WORKTREE_RETENTION).catch(DEFAULT_WORKTREE_RETENTION),
|
|
30
38
|
/**
|
|
31
39
|
* Per-task memory ceiling in MiB (whole process tree). When a running task's
|
|
32
40
|
* RSS crosses this the engine pauses it with a warning and lets the queue
|
|
@@ -39,7 +47,7 @@ const configSchema = z.object({
|
|
|
39
47
|
* step (workflow). The GUI only offers runners actually installed; this is
|
|
40
48
|
* the preselected default. Also the runner the chain planner uses.
|
|
41
49
|
*/
|
|
42
|
-
defaultRunner: z.enum(
|
|
50
|
+
defaultRunner: z.enum(RUNNER_IDS).default('claude'),
|
|
43
51
|
/** Model for the chain planner (spec 008) — cheap but reliable at JSON. */
|
|
44
52
|
plannerModel: z.string().min(1).default('sonnet'),
|
|
45
53
|
/** Model for the task namer (spec 2026-07-17-task-auto-naming) — the cheapest
|
|
@@ -80,6 +88,7 @@ const configSchema = z.object({
|
|
|
80
88
|
claude: z.string().trim().min(1).max(200).optional(),
|
|
81
89
|
codex: z.string().trim().min(1).max(200).optional(),
|
|
82
90
|
opencode: z.string().trim().min(1).max(200).optional(),
|
|
91
|
+
pi: z.string().trim().min(1).max(200).optional(),
|
|
83
92
|
})
|
|
84
93
|
.optional()
|
|
85
94
|
.catch(undefined),
|
|
@@ -103,4 +112,90 @@ export async function loadConfig(repoRoot) {
|
|
|
103
112
|
}
|
|
104
113
|
return configSchema.parse({});
|
|
105
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The repo's OWN `worktreeRetention`, or `undefined` when it doesn't set one.
|
|
117
|
+
*
|
|
118
|
+
* `loadConfig` cannot answer this: the schema's `.default(10).catch(10)`
|
|
119
|
+
* materializes the key, so a parsed config can't tell "the user chose 10" from
|
|
120
|
+
* "the user said nothing". So we probe the raw file — a key that is absent (or
|
|
121
|
+
* carries a value the schema would refuse) means the repo has no opinion, and
|
|
122
|
+
* the workspace default gets to seed it.
|
|
123
|
+
*/
|
|
124
|
+
async function ownWorktreeRetention(repoRoot) {
|
|
125
|
+
let raw;
|
|
126
|
+
try {
|
|
127
|
+
raw = await readFile(join(repoRoot, '.ai/cezar', 'config.json'), 'utf8');
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return undefined; // no file — nothing set
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const parsed = JSON.parse(raw);
|
|
134
|
+
if (!parsed || typeof parsed !== 'object')
|
|
135
|
+
return undefined;
|
|
136
|
+
const value = parsed.worktreeRetention;
|
|
137
|
+
if (value === undefined)
|
|
138
|
+
return undefined;
|
|
139
|
+
const field = worktreeRetentionSchema.safeParse(value);
|
|
140
|
+
return field.success ? field.data : undefined;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return undefined; // malformed JSON — same as unset
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The default skills repos that are *opt-in per skill* (the "import OM skills"
|
|
148
|
+
* flow): the set of repo identifiers a user must explicitly import from before
|
|
149
|
+
* their skills join the catalog. This is exactly `DEFAULT_SKILLS_REPOS` when the
|
|
150
|
+
* repo has NOT configured its own `skillsRepos` — the zero-config majority — and
|
|
151
|
+
* empty once a repo takes control by setting `skillsRepos` (then everything it
|
|
152
|
+
* lists auto-loads, unchanged).
|
|
153
|
+
*
|
|
154
|
+
* `loadConfig` cannot answer this: the schema's `.default(DEFAULT_SKILLS_REPOS)`
|
|
155
|
+
* materializes the key, so a parsed config can't tell "the user chose these" from
|
|
156
|
+
* "the user said nothing". So we probe the raw file for the key's presence — the
|
|
157
|
+
* same reason `ownWorktreeRetention` below reads the raw JSON.
|
|
158
|
+
*/
|
|
159
|
+
export async function gatedSkillsRepos(repoRoot) {
|
|
160
|
+
const none = new Set();
|
|
161
|
+
let raw;
|
|
162
|
+
try {
|
|
163
|
+
raw = await readFile(join(repoRoot, '.ai/cezar', 'config.json'), 'utf8');
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// No file — the defaults are in effect, so they are the opt-in set.
|
|
167
|
+
return new Set(DEFAULT_SKILLS_REPOS.map((r) => r.repo));
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(raw);
|
|
171
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
172
|
+
return new Set(DEFAULT_SKILLS_REPOS.map((r) => r.repo));
|
|
173
|
+
}
|
|
174
|
+
// The user took control of the source list — nothing is gated; a value the
|
|
175
|
+
// schema would refuse degrades to the default too (same as `loadConfig`).
|
|
176
|
+
if (parsed.skillsRepos !== undefined)
|
|
177
|
+
return none;
|
|
178
|
+
return new Set(DEFAULT_SKILLS_REPOS.map((r) => r.repo));
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Malformed JSON degrades to the default (which loadConfig also does).
|
|
182
|
+
return new Set(DEFAULT_SKILLS_REPOS.map((r) => r.repo));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Effective worktree retention for a repo (#483 + spec
|
|
187
|
+
* 2026-07-20-multi-project-workspace). Precedence, exactly what Settings →
|
|
188
|
+
* Worktrees promises: the repo's own `worktreeRetention` wins whenever it sets
|
|
189
|
+
* one; otherwise the workspace's `resources.worktreeRetentionDefault` seeds it;
|
|
190
|
+
* an absent/unreadable workspace config keeps the historical 10. Every
|
|
191
|
+
* enforcement site (boot sweeps, terminal transitions, the reclaim route) must
|
|
192
|
+
* go through here so the setting can never be a lie.
|
|
193
|
+
*/
|
|
194
|
+
export async function resolveWorktreeRetention(repoRoot) {
|
|
195
|
+
const own = await ownWorktreeRetention(repoRoot);
|
|
196
|
+
if (own !== undefined)
|
|
197
|
+
return own;
|
|
198
|
+
const workspace = await loadWorkspaceConfig().catch(() => null);
|
|
199
|
+
return workspace?.resources.worktreeRetentionDefault ?? DEFAULT_WORKTREE_RETENTION;
|
|
200
|
+
}
|
|
106
201
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/core/agent-env.js
CHANGED
|
@@ -192,26 +192,32 @@ const BASE_ALLOW_PREFIXES = [
|
|
|
192
192
|
'MISE_',
|
|
193
193
|
'COMPOSER_',
|
|
194
194
|
];
|
|
195
|
+
/** The provider credentials a backend that selects models as `provider/model` may need — it can
|
|
196
|
+
* be pointed at any of them, so none can be pruned without breaking a legitimate model id. */
|
|
197
|
+
const MULTI_PROVIDER_PREFIXES = [
|
|
198
|
+
'OPENAI_',
|
|
199
|
+
'ANTHROPIC_',
|
|
200
|
+
'AZURE_OPENAI_',
|
|
201
|
+
'OPENROUTER_',
|
|
202
|
+
'GROQ_',
|
|
203
|
+
'MISTRAL_',
|
|
204
|
+
'GEMINI_',
|
|
205
|
+
'GOOGLE_GENERATIVE_AI_',
|
|
206
|
+
'DEEPSEEK_',
|
|
207
|
+
'XAI_',
|
|
208
|
+
'PERPLEXITY_',
|
|
209
|
+
'TOGETHER_',
|
|
210
|
+
'FIREWORKS_',
|
|
211
|
+
];
|
|
195
212
|
/** Per-backend auth/config the runner genuinely needs, by prefix. */
|
|
196
213
|
const BACKEND_ALLOW_PREFIXES = {
|
|
197
214
|
claude: ['ANTHROPIC_', 'CLAUDE_'],
|
|
198
215
|
'claude-cli': ['ANTHROPIC_', 'CLAUDE_'],
|
|
199
216
|
codex: ['OPENAI_', 'CODEX_', 'AZURE_OPENAI_'],
|
|
200
|
-
opencode:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
'OPENROUTER_',
|
|
205
|
-
'GROQ_',
|
|
206
|
-
'MISTRAL_',
|
|
207
|
-
'GEMINI_',
|
|
208
|
-
'GOOGLE_GENERATIVE_AI_',
|
|
209
|
-
'DEEPSEEK_',
|
|
210
|
-
'XAI_',
|
|
211
|
-
'PERPLEXITY_',
|
|
212
|
-
'TOGETHER_',
|
|
213
|
-
'FIREWORKS_',
|
|
214
|
-
],
|
|
217
|
+
opencode: MULTI_PROVIDER_PREFIXES,
|
|
218
|
+
// pi drives a Claude-compatible CLI but selects models as `provider/model` (#387), so it
|
|
219
|
+
// needs both the Claude-side config and any provider a `provider/model` id can name.
|
|
220
|
+
pi: ['PI_', 'CLAUDE_', ...MULTI_PROVIDER_PREFIXES],
|
|
215
221
|
};
|
|
216
222
|
/** `gh` handoff (draft PRs) works in every backend — the one credential the
|
|
217
223
|
* project deliberately keeps in the environment (AGENTS.md "No secrets in
|