@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.
Files changed (247) hide show
  1. package/README.md +109 -14
  2. package/dist/agent-config/catalog.d.ts +64 -0
  3. package/dist/agent-config/catalog.js +205 -0
  4. package/dist/agent-config/catalog.js.map +1 -0
  5. package/dist/agent-config/files.d.ts +46 -0
  6. package/dist/agent-config/files.js +119 -0
  7. package/dist/agent-config/files.js.map +1 -0
  8. package/dist/agent-config/seed.d.ts +7 -0
  9. package/dist/agent-config/seed.js +90 -0
  10. package/dist/agent-config/seed.js.map +1 -0
  11. package/dist/agent-config/service.d.ts +44 -0
  12. package/dist/agent-config/service.js +71 -0
  13. package/dist/agent-config/service.js.map +1 -0
  14. package/dist/agent-config/validate.d.ts +21 -0
  15. package/dist/agent-config/validate.js +76 -0
  16. package/dist/agent-config/validate.js.map +1 -0
  17. package/dist/config.d.ts +34 -4
  18. package/dist/config.js +97 -2
  19. package/dist/config.js.map +1 -1
  20. package/dist/core/agent-env.js +21 -15
  21. package/dist/core/agent-env.js.map +1 -1
  22. package/dist/core/agent-runner.d.ts +16 -6
  23. package/dist/core/agent-runner.js +15 -3
  24. package/dist/core/agent-runner.js.map +1 -1
  25. package/dist/core/ask.d.ts +184 -0
  26. package/dist/core/ask.js +97 -0
  27. package/dist/core/ask.js.map +1 -0
  28. package/dist/core/backend-detect.d.ts +5 -5
  29. package/dist/core/backend-detect.js +37 -5
  30. package/dist/core/backend-detect.js.map +1 -1
  31. package/dist/core/claude-cli-runner.d.ts +17 -2
  32. package/dist/core/claude-cli-runner.js +8 -3
  33. package/dist/core/claude-cli-runner.js.map +1 -1
  34. package/dist/core/claude-ui-mapper.d.ts +9 -0
  35. package/dist/core/claude-ui-mapper.js +34 -3
  36. package/dist/core/claude-ui-mapper.js.map +1 -1
  37. package/dist/core/codex-app-server-runner.d.ts +15 -3
  38. package/dist/core/codex-app-server-runner.js +158 -127
  39. package/dist/core/codex-app-server-runner.js.map +1 -1
  40. package/dist/core/codex-app-server-transport.d.ts +30 -0
  41. package/dist/core/codex-app-server-transport.js +136 -0
  42. package/dist/core/codex-app-server-transport.js.map +1 -0
  43. package/dist/core/codex-model-catalog.d.ts +10 -0
  44. package/dist/core/codex-model-catalog.js +110 -0
  45. package/dist/core/codex-model-catalog.js.map +1 -0
  46. package/dist/core/codex-ui-mapper.d.ts +47 -2
  47. package/dist/core/codex-ui-mapper.js +247 -29
  48. package/dist/core/codex-ui-mapper.js.map +1 -1
  49. package/dist/core/model-identity.d.ts +113 -0
  50. package/dist/core/model-identity.js +119 -0
  51. package/dist/core/model-identity.js.map +1 -0
  52. package/dist/core/model-presets.d.ts +15 -0
  53. package/dist/core/model-presets.js +43 -0
  54. package/dist/core/model-presets.js.map +1 -0
  55. package/dist/core/opencode-server-runner.d.ts +1 -1
  56. package/dist/core/opencode-server-runner.js +7 -12
  57. package/dist/core/opencode-server-runner.js.map +1 -1
  58. package/dist/core/opencode-ui-mapper.d.ts +11 -7
  59. package/dist/core/opencode-ui-mapper.js +62 -19
  60. package/dist/core/opencode-ui-mapper.js.map +1 -1
  61. package/dist/core/pi-runner.d.ts +40 -0
  62. package/dist/core/pi-runner.js +49 -0
  63. package/dist/core/pi-runner.js.map +1 -0
  64. package/dist/core/process-usage.d.ts +3 -0
  65. package/dist/core/process-usage.js +12 -0
  66. package/dist/core/process-usage.js.map +1 -1
  67. package/dist/core/runner-factory.js +3 -0
  68. package/dist/core/runner-factory.js.map +1 -1
  69. package/dist/core/runner-model-catalog.d.ts +28 -0
  70. package/dist/core/runner-model-catalog.js +62 -0
  71. package/dist/core/runner-model-catalog.js.map +1 -0
  72. package/dist/core/secret-redaction.js.map +1 -1
  73. package/dist/core/tool-display.d.ts +2 -2
  74. package/dist/core/tool-display.js +24 -6
  75. package/dist/core/tool-display.js.map +1 -1
  76. package/dist/core/ui-events.d.ts +29 -2
  77. package/dist/git-worktree.d.ts +37 -4
  78. package/dist/git-worktree.js +175 -12
  79. package/dist/git-worktree.js.map +1 -1
  80. package/dist/handoff.d.ts +2 -2
  81. package/dist/handoff.js +2 -0
  82. package/dist/handoff.js.map +1 -1
  83. package/dist/index.js +55 -5
  84. package/dist/index.js.map +1 -1
  85. package/dist/install-as-command.d.ts +1 -1
  86. package/dist/install-as-command.js.map +1 -1
  87. package/dist/paths.d.ts +32 -2
  88. package/dist/paths.js +47 -2
  89. package/dist/paths.js.map +1 -1
  90. package/dist/runs/auto-name.js.map +1 -1
  91. package/dist/runs/retention.js.map +1 -1
  92. package/dist/runs/review-gate.js.map +1 -1
  93. package/dist/runs/store.d.ts +154 -60
  94. package/dist/runs/store.js +103 -19
  95. package/dist/runs/store.js.map +1 -1
  96. package/dist/runs/task-markers.d.ts +6 -2
  97. package/dist/runs/task-markers.js +25 -4
  98. package/dist/runs/task-markers.js.map +1 -1
  99. package/dist/runs/ui-event-sink.js.map +1 -1
  100. package/dist/server/capabilities.d.ts +22 -6
  101. package/dist/server/capabilities.js +85 -8
  102. package/dist/server/capabilities.js.map +1 -1
  103. package/dist/server/checkout.d.ts +128 -0
  104. package/dist/server/checkout.js +296 -0
  105. package/dist/server/checkout.js.map +1 -0
  106. package/dist/server/forge/github.d.ts +281 -10
  107. package/dist/server/forge/github.js +539 -23
  108. package/dist/server/forge/github.js.map +1 -1
  109. package/dist/server/forge/types.d.ts +48 -1
  110. package/dist/server/fs-browse.d.ts +105 -0
  111. package/dist/server/fs-browse.js +182 -0
  112. package/dist/server/fs-browse.js.map +1 -0
  113. package/dist/server/git-changes.d.ts +12 -3
  114. package/dist/server/git-changes.js +23 -5
  115. package/dist/server/git-changes.js.map +1 -1
  116. package/dist/server/github.d.ts +1 -1
  117. package/dist/server/open-in-app.d.ts +2 -1
  118. package/dist/server/open-in-app.js +1 -0
  119. package/dist/server/open-in-app.js.map +1 -1
  120. package/dist/server/project-context.d.ts +103 -0
  121. package/dist/server/project-context.js +153 -0
  122. package/dist/server/project-context.js.map +1 -0
  123. package/dist/server/server.d.ts +110 -0
  124. package/dist/server/server.js +1557 -215
  125. package/dist/server/server.js.map +1 -1
  126. package/dist/server/wsl.js.map +1 -1
  127. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -1
  128. package/dist/server-install/platforms/ubuntu-vps.js +7 -0
  129. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
  130. package/dist/server-install/state.js.map +1 -1
  131. package/dist/server-install/steps.js +6 -2
  132. package/dist/server-install/steps.js.map +1 -1
  133. package/dist/server-install/types.d.ts +28 -28
  134. package/dist/server-install/ui.js.map +1 -1
  135. package/dist/skills-banner.js.map +1 -1
  136. package/dist/skills-remote.d.ts +10 -4
  137. package/dist/skills-remote.js +31 -14
  138. package/dist/skills-remote.js.map +1 -1
  139. package/dist/skills.d.ts +29 -0
  140. package/dist/skills.js +72 -14
  141. package/dist/skills.js.map +1 -1
  142. package/dist/todos.d.ts +9 -7
  143. package/dist/todos.js +38 -19
  144. package/dist/todos.js.map +1 -1
  145. package/dist/workflows/run.d.ts +145 -10
  146. package/dist/workflows/run.js +608 -66
  147. package/dist/workflows/run.js.map +1 -1
  148. package/dist/workflows/types.d.ts +42 -42
  149. package/dist/workflows/types.js +2 -1
  150. package/dist/workflows/types.js.map +1 -1
  151. package/dist/workspace/config.d.ts +251 -0
  152. package/dist/workspace/config.js +162 -0
  153. package/dist/workspace/config.js.map +1 -0
  154. package/dist/workspace/migrations.d.ts +45 -0
  155. package/dist/workspace/migrations.js +132 -0
  156. package/dist/workspace/migrations.js.map +1 -0
  157. package/dist/workspace/projects-cli.d.ts +23 -0
  158. package/dist/workspace/projects-cli.js +105 -0
  159. package/dist/workspace/projects-cli.js.map +1 -0
  160. package/dist/workspace/projects.d.ts +81 -0
  161. package/dist/workspace/projects.js +214 -0
  162. package/dist/workspace/projects.js.map +1 -0
  163. package/dist/workspace/semaphore.d.ts +77 -0
  164. package/dist/workspace/semaphore.js +57 -0
  165. package/dist/workspace/semaphore.js.map +1 -0
  166. package/dist/workspace/ui-state.d.ts +23 -0
  167. package/dist/workspace/ui-state.js +42 -0
  168. package/dist/workspace/ui-state.js.map +1 -0
  169. package/package.json +3 -2
  170. package/scripts/mock-claude.mjs +136 -2
  171. package/web/dist/assets/arrow-left-CnSdp92h.js +1 -0
  172. package/web/dist/assets/centered-state-NF79blq7.js +43 -0
  173. package/web/dist/assets/{chunk-BO2N2NFS-BN7h-q1E.js → chunk-BO2N2NFS-DtrdTCWa.js} +4 -4
  174. package/web/dist/assets/commit-list-CL8vSWGw.js +1 -0
  175. package/web/dist/assets/compare-variants-mI-MnhuR.js +1 -0
  176. package/web/dist/assets/diff-view-Bhfvnnn9.js +6 -0
  177. package/web/dist/assets/dist-COA_NSud.js +1 -0
  178. package/web/dist/assets/ellipsis-vertical-CNnSLn5a.js +1 -0
  179. package/web/dist/assets/{file-tuE95HNX.js → file-D4GBh1ao.js} +1 -1
  180. package/web/dist/assets/{git-pull-request-BztcgsRZ.js → git-pull-request-DnR8Xh4_.js} +1 -1
  181. package/web/dist/assets/git-toolbar-rVtFyL4t.js +1 -0
  182. package/web/dist/assets/github-_t0ceKcO.js +1 -0
  183. package/web/dist/assets/{highlighted-body-OFNGDK62-CJIHtxqW.js → highlighted-body-OFNGDK62-BuFJwunK.js} +1 -1
  184. package/web/dist/assets/{image-preview-Ca0UgThg.js → image-preview-DEhW0TFz.js} +1 -1
  185. package/web/dist/assets/index-BfXFhAGQ.js +30 -0
  186. package/web/dist/assets/index-Mov2Rrbw.css +2 -0
  187. package/web/dist/assets/lib-DPEZDBUN.js +1 -0
  188. package/web/dist/assets/mermaid-GHXKKRXX-CN2zQue0.js +1 -0
  189. package/web/dist/assets/project-router-CBzGUqvS.js +1 -0
  190. package/web/dist/assets/{refresh-cw-B4NW5q60.js → refresh-cw-BT8E96Tm.js} +1 -1
  191. package/web/dist/assets/repo-git-C3dJiX3j.js +1 -0
  192. package/web/dist/assets/{run-diff-BKpV1kGk.js → run-diff-HEZcHwRr.js} +3 -3
  193. package/web/dist/assets/run-header-DldbROhB.js +1 -0
  194. package/web/dist/assets/{search-x-C6xG26dv.js → search-x-BDjaMrzG.js} +1 -1
  195. package/web/dist/assets/skill-empty-hint-DTUSp6Vl.js +1 -0
  196. package/web/dist/assets/skills-BIg29xLt.js +1 -0
  197. package/web/dist/assets/{square-terminal-D9l_Xx7B.js → square-terminal-Ckjjn0vb.js} +1 -1
  198. package/web/dist/assets/tab-link-DTQ9FBZY.js +1 -0
  199. package/web/dist/assets/task-changes-DRhQVnFN.js +1 -0
  200. package/web/dist/assets/task-commits-5StODPII.js +1 -0
  201. package/web/dist/assets/task-files-BuylxobG.js +2 -0
  202. package/web/dist/assets/task-thread-DnHR0k7k.js +9 -0
  203. package/web/dist/assets/textarea-Bj_LCreg.js +1 -0
  204. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  205. package/web/dist/assets/{trash-2-De8Z5Y5-.js → trash-2-DAyZ0VSi.js} +1 -1
  206. package/web/dist/assets/{triangle-alert-DJUyRhTV.js → triangle-alert-Uy8rokUh.js} +1 -1
  207. package/web/dist/assets/{upload-yxUM9nk5.js → upload-CDdyPPo_.js} +1 -1
  208. package/web/dist/assets/use-desktop-TyHAXhMR.js +3 -0
  209. package/web/dist/assets/utils-B8s5qIcK.js +1 -0
  210. package/web/dist/assets/workflows-CwDYZLvG.js +11 -0
  211. package/web/dist/assets/zoomable-image-PEDOqyLQ.js +1 -0
  212. package/web/dist/index.html +10 -19
  213. package/web/dist/assets/arrow-left-bEsJ-6jp.js +0 -1
  214. package/web/dist/assets/centered-state-DzJJpXgm.js +0 -43
  215. package/web/dist/assets/command-eBgVGftz.js +0 -1
  216. package/web/dist/assets/compare-variants-DhqGJuHF.js +0 -1
  217. package/web/dist/assets/dialog-Bf1Cpc3n.js +0 -1
  218. package/web/dist/assets/diff-view-Cqc8LRkj.js +0 -4
  219. package/web/dist/assets/dist-M2QYGAcm.js +0 -1
  220. package/web/dist/assets/dist-ZAIqO3UX.js +0 -1
  221. package/web/dist/assets/folder-20ea3OVM.js +0 -1
  222. package/web/dist/assets/git-toolbar-DAlBoSP5.js +0 -1
  223. package/web/dist/assets/github--sfM4X3j.js +0 -1
  224. package/web/dist/assets/highlighter-ZVyRi_Cx.js +0 -3
  225. package/web/dist/assets/index-DlKq8gF4.css +0 -2
  226. package/web/dist/assets/index-h4gyDJyh.js +0 -11
  227. package/web/dist/assets/loader-circle-Bnw4ga19.js +0 -1
  228. package/web/dist/assets/markdown-DxmCMr30.js +0 -1
  229. package/web/dist/assets/mermaid-GHXKKRXX-DghlHZS5.js +0 -1
  230. package/web/dist/assets/prompt-templates-CsGr-FXH.js +0 -15
  231. package/web/dist/assets/repo-git-CHF2oip_.js +0 -1
  232. package/web/dist/assets/run-header-3CGn6FAM.js +0 -1
  233. package/web/dist/assets/skill-detail-DsD4-dGp.js +0 -1
  234. package/web/dist/assets/skill-empty-hint-Cl3ESoPu.js +0 -1
  235. package/web/dist/assets/skills-5kRcjM1J.js +0 -1
  236. package/web/dist/assets/skills-B13iqWAN.js +0 -1
  237. package/web/dist/assets/tab-link-DkVxOa-q.js +0 -1
  238. package/web/dist/assets/task-changes-DtMiVVwO.js +0 -1
  239. package/web/dist/assets/task-commits-VbSLn_tW.js +0 -1
  240. package/web/dist/assets/task-files-qYDBG3Mx.js +0 -2
  241. package/web/dist/assets/task-thread-BfGERKlB.js +0 -7
  242. package/web/dist/assets/tasks-table-C5fwJmZ7.js +0 -1
  243. package/web/dist/assets/use-desktop-6PwFeCW3.js +0 -3
  244. package/web/dist/assets/utils-CzkLr94M.js +0 -1
  245. package/web/dist/assets/workflows-CnTcKlfV.js +0 -11
  246. package/web/dist/assets/x-DaR4ZfE-.js +0 -1
  247. 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
- defaultRunner: "claude" | "codex" | "opencode";
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: z.number().int().min(0).max(1000).default(10).catch(10),
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(['claude', 'codex', 'opencode']).default('claude'),
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
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
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;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,gFAAgF;IAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACvC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,EAAE,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE;CAC7C,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C;;oEAEoE;AACpE,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAElE,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC;IACpE,4EAA4E;IAC5E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD;;;;;;OAMG;IACH,iBAAiB,EAAE,uBAAuB,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC;IAChH;;;;;OAKG;IACH,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IACjF;;;;OAIG;IACH,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACnD,2EAA2E;IAC3E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjD;sFACkF;IAClF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9C;;gCAE4B;IAC5B,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC;;;mEAG+D;IAC/D,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAClC;;;OAGG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/C;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9E;;;;;;OAMG;IACH,aAAa,EAAE,CAAC;SACb,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QACtD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;KACjD,CAAC;SACD,QAAQ,EAAE;SACV,KAAK,CAAC,SAAS,CAAC;CACpB,CAAC,CAAC;AAIH,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IAClD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,CAAC,wBAAwB;IAC5C,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC5D,MAAM,KAAK,GAAI,MAAkC,CAAC,iBAAiB,CAAC;QACpE,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,KAAK,GAAG,uBAAuB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,CAAC,iCAAiC;IACrD,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,2EAA2E;QAC3E,0EAA0E;QAC1E,IAAK,MAAkC,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC/E,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,QAAgB;IAC7D,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,SAAS,EAAE,SAAS,CAAC,wBAAwB,IAAI,0BAA0B,CAAC;AACrF,CAAC"}
@@ -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
- 'OPENAI_',
202
- 'ANTHROPIC_',
203
- 'AZURE_OPENAI_',
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