@open-mercato/cezar 0.1.5-pr506.357

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 (264) hide show
  1. package/README.md +573 -0
  2. package/dist/config.d.ts +144 -0
  3. package/dist/config.js +106 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/core/agent-runner.d.ts +169 -0
  6. package/dist/core/agent-runner.js +23 -0
  7. package/dist/core/agent-runner.js.map +1 -0
  8. package/dist/core/backend-detect.d.ts +16 -0
  9. package/dist/core/backend-detect.js +118 -0
  10. package/dist/core/backend-detect.js.map +1 -0
  11. package/dist/core/claude-cli-runner.d.ts +56 -0
  12. package/dist/core/claude-cli-runner.js +416 -0
  13. package/dist/core/claude-cli-runner.js.map +1 -0
  14. package/dist/core/claude-ui-mapper.d.ts +71 -0
  15. package/dist/core/claude-ui-mapper.js +567 -0
  16. package/dist/core/claude-ui-mapper.js.map +1 -0
  17. package/dist/core/codex-app-server-runner.d.ts +29 -0
  18. package/dist/core/codex-app-server-runner.js +489 -0
  19. package/dist/core/codex-app-server-runner.js.map +1 -0
  20. package/dist/core/codex-ui-mapper.d.ts +63 -0
  21. package/dist/core/codex-ui-mapper.js +491 -0
  22. package/dist/core/codex-ui-mapper.js.map +1 -0
  23. package/dist/core/ndjson.d.ts +6 -0
  24. package/dist/core/ndjson.js +23 -0
  25. package/dist/core/ndjson.js.map +1 -0
  26. package/dist/core/opencode-server-runner.d.ts +30 -0
  27. package/dist/core/opencode-server-runner.js +488 -0
  28. package/dist/core/opencode-server-runner.js.map +1 -0
  29. package/dist/core/opencode-ui-mapper.d.ts +105 -0
  30. package/dist/core/opencode-ui-mapper.js +588 -0
  31. package/dist/core/opencode-ui-mapper.js.map +1 -0
  32. package/dist/core/process-usage.d.ts +63 -0
  33. package/dist/core/process-usage.js +181 -0
  34. package/dist/core/process-usage.js.map +1 -0
  35. package/dist/core/runner-factory.d.ts +8 -0
  36. package/dist/core/runner-factory.js +22 -0
  37. package/dist/core/runner-factory.js.map +1 -0
  38. package/dist/core/tool-display.d.ts +30 -0
  39. package/dist/core/tool-display.js +156 -0
  40. package/dist/core/tool-display.js.map +1 -0
  41. package/dist/core/ui-events.d.ts +308 -0
  42. package/dist/core/ui-events.js +25 -0
  43. package/dist/core/ui-events.js.map +1 -0
  44. package/dist/core/usage.d.ts +11 -0
  45. package/dist/core/usage.js +15 -0
  46. package/dist/core/usage.js.map +1 -0
  47. package/dist/git-worktree.d.ts +88 -0
  48. package/dist/git-worktree.js +297 -0
  49. package/dist/git-worktree.js.map +1 -0
  50. package/dist/handoff.d.ts +62 -0
  51. package/dist/handoff.js +147 -0
  52. package/dist/handoff.js.map +1 -0
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.js +466 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/install-as-command.d.ts +39 -0
  57. package/dist/install-as-command.js +51 -0
  58. package/dist/install-as-command.js.map +1 -0
  59. package/dist/pack-check.d.ts +17 -0
  60. package/dist/pack-check.js +27 -0
  61. package/dist/pack-check.js.map +1 -0
  62. package/dist/paths.d.ts +23 -0
  63. package/dist/paths.js +34 -0
  64. package/dist/paths.js.map +1 -0
  65. package/dist/planner.d.ts +17 -0
  66. package/dist/planner.js +248 -0
  67. package/dist/planner.js.map +1 -0
  68. package/dist/release/snapshot.d.ts +64 -0
  69. package/dist/release/snapshot.js +75 -0
  70. package/dist/release/snapshot.js.map +1 -0
  71. package/dist/release/stable.d.ts +46 -0
  72. package/dist/release/stable.js +57 -0
  73. package/dist/release/stable.js.map +1 -0
  74. package/dist/runs/auto-name.d.ts +75 -0
  75. package/dist/runs/auto-name.js +168 -0
  76. package/dist/runs/auto-name.js.map +1 -0
  77. package/dist/runs/retention.d.ts +60 -0
  78. package/dist/runs/retention.js +86 -0
  79. package/dist/runs/retention.js.map +1 -0
  80. package/dist/runs/review-gate.d.ts +18 -0
  81. package/dist/runs/review-gate.js +21 -0
  82. package/dist/runs/review-gate.js.map +1 -0
  83. package/dist/runs/store.d.ts +408 -0
  84. package/dist/runs/store.js +526 -0
  85. package/dist/runs/store.js.map +1 -0
  86. package/dist/runs/task-refs.d.ts +24 -0
  87. package/dist/runs/task-refs.js +74 -0
  88. package/dist/runs/task-refs.js.map +1 -0
  89. package/dist/runs/ui-event-sink.d.ts +81 -0
  90. package/dist/runs/ui-event-sink.js +210 -0
  91. package/dist/runs/ui-event-sink.js.map +1 -0
  92. package/dist/server/capabilities.d.ts +33 -0
  93. package/dist/server/capabilities.js +43 -0
  94. package/dist/server/capabilities.js.map +1 -0
  95. package/dist/server/forge/github.d.ts +70 -0
  96. package/dist/server/forge/github.js +375 -0
  97. package/dist/server/forge/github.js.map +1 -0
  98. package/dist/server/forge/index.d.ts +24 -0
  99. package/dist/server/forge/index.js +45 -0
  100. package/dist/server/forge/index.js.map +1 -0
  101. package/dist/server/forge/types.d.ts +80 -0
  102. package/dist/server/forge/types.js +2 -0
  103. package/dist/server/forge/types.js.map +1 -0
  104. package/dist/server/git-changes.d.ts +195 -0
  105. package/dist/server/git-changes.js +497 -0
  106. package/dist/server/git-changes.js.map +1 -0
  107. package/dist/server/git.d.ts +26 -0
  108. package/dist/server/git.js +103 -0
  109. package/dist/server/git.js.map +1 -0
  110. package/dist/server/github.d.ts +8 -0
  111. package/dist/server/github.js +8 -0
  112. package/dist/server/github.js.map +1 -0
  113. package/dist/server/launch-key.d.ts +7 -0
  114. package/dist/server/launch-key.js +33 -0
  115. package/dist/server/launch-key.js.map +1 -0
  116. package/dist/server/open-in-app.d.ts +51 -0
  117. package/dist/server/open-in-app.js +189 -0
  118. package/dist/server/open-in-app.js.map +1 -0
  119. package/dist/server/open-in-terminal.d.ts +25 -0
  120. package/dist/server/open-in-terminal.js +120 -0
  121. package/dist/server/open-in-terminal.js.map +1 -0
  122. package/dist/server/pr.d.ts +7 -0
  123. package/dist/server/pr.js +7 -0
  124. package/dist/server/pr.js.map +1 -0
  125. package/dist/server/server.d.ts +41 -0
  126. package/dist/server/server.js +1390 -0
  127. package/dist/server/server.js.map +1 -0
  128. package/dist/server/static-ui.d.ts +49 -0
  129. package/dist/server/static-ui.js +92 -0
  130. package/dist/server/static-ui.js.map +1 -0
  131. package/dist/server/wsl.d.ts +25 -0
  132. package/dist/server/wsl.js +92 -0
  133. package/dist/server/wsl.js.map +1 -0
  134. package/dist/server-install/engine.d.ts +33 -0
  135. package/dist/server-install/engine.js +314 -0
  136. package/dist/server-install/engine.js.map +1 -0
  137. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  138. package/dist/server-install/platforms/macosx-ngrok.js +345 -0
  139. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  140. package/dist/server-install/platforms/ubuntu-vps.d.ts +39 -0
  141. package/dist/server-install/platforms/ubuntu-vps.js +746 -0
  142. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  143. package/dist/server-install/state.d.ts +26 -0
  144. package/dist/server-install/state.js +125 -0
  145. package/dist/server-install/state.js.map +1 -0
  146. package/dist/server-install/steps.d.ts +109 -0
  147. package/dist/server-install/steps.js +330 -0
  148. package/dist/server-install/steps.js.map +1 -0
  149. package/dist/server-install/strategies.d.ts +4 -0
  150. package/dist/server-install/strategies.js +20 -0
  151. package/dist/server-install/strategies.js.map +1 -0
  152. package/dist/server-install/types.d.ts +597 -0
  153. package/dist/server-install/types.js +98 -0
  154. package/dist/server-install/types.js.map +1 -0
  155. package/dist/server-install/ui.d.ts +42 -0
  156. package/dist/server-install/ui.js +130 -0
  157. package/dist/server-install/ui.js.map +1 -0
  158. package/dist/skills-banner.d.ts +21 -0
  159. package/dist/skills-banner.js +40 -0
  160. package/dist/skills-banner.js.map +1 -0
  161. package/dist/skills-remote.d.ts +35 -0
  162. package/dist/skills-remote.js +266 -0
  163. package/dist/skills-remote.js.map +1 -0
  164. package/dist/skills.d.ts +45 -0
  165. package/dist/skills.js +182 -0
  166. package/dist/skills.js.map +1 -0
  167. package/dist/todos.d.ts +63 -0
  168. package/dist/todos.js +168 -0
  169. package/dist/todos.js.map +1 -0
  170. package/dist/ui-state.d.ts +12 -0
  171. package/dist/ui-state.js +25 -0
  172. package/dist/ui-state.js.map +1 -0
  173. package/dist/update-check.d.ts +12 -0
  174. package/dist/update-check.js +41 -0
  175. package/dist/update-check.js.map +1 -0
  176. package/dist/workflows/load.d.ts +15 -0
  177. package/dist/workflows/load.js +56 -0
  178. package/dist/workflows/load.js.map +1 -0
  179. package/dist/workflows/run.d.ts +281 -0
  180. package/dist/workflows/run.js +1511 -0
  181. package/dist/workflows/run.js.map +1 -0
  182. package/dist/workflows/types.d.ts +307 -0
  183. package/dist/workflows/types.js +171 -0
  184. package/dist/workflows/types.js.map +1 -0
  185. package/package.json +90 -0
  186. package/scripts/check-pack.mjs +46 -0
  187. package/scripts/dev.mjs +74 -0
  188. package/scripts/install-as-command.mjs +120 -0
  189. package/scripts/mock-claude.mjs +310 -0
  190. package/scripts/release-snapshot.mjs +130 -0
  191. package/scripts/release.mjs +119 -0
  192. package/scripts/test-process-usage.mjs +47 -0
  193. package/web/dist/assets/arrow-left-BE957rJs.js +1 -0
  194. package/web/dist/assets/bundle-mjs-DLPpRFyl.js +1 -0
  195. package/web/dist/assets/centered-state-BddhEEtO.js +43 -0
  196. package/web/dist/assets/chunk-BO2N2NFS-f5igTtpB.js +131 -0
  197. package/web/dist/assets/command-CjhFbABo.js +1 -0
  198. package/web/dist/assets/compare-variants-Cs52IAEG.js +1 -0
  199. package/web/dist/assets/core-BuMqAF_1.js +12 -0
  200. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  201. package/web/dist/assets/dialog-DFvXTkFv.js +1 -0
  202. package/web/dist/assets/diff-view-C9b8AITq.js +4 -0
  203. package/web/dist/assets/diff-woXpYk--.js +1 -0
  204. package/web/dist/assets/dist-FBs4wmIY.js +1 -0
  205. package/web/dist/assets/dist-o_kVMXjg.js +1 -0
  206. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  207. package/web/dist/assets/file-BVuztAOd.js +1 -0
  208. package/web/dist/assets/folder-0pJ1NZ_S.js +1 -0
  209. package/web/dist/assets/git-pull-request-DJkAMT0f.js +1 -0
  210. package/web/dist/assets/git-toolbar-CwhQdx3J.js +1 -0
  211. package/web/dist/assets/github-D0rAX4-r.js +1 -0
  212. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  213. package/web/dist/assets/highlighted-body-OFNGDK62-DGHHie_q.js +1 -0
  214. package/web/dist/assets/highlighter-BKVEsACy.js +3 -0
  215. package/web/dist/assets/html-BY76lXLH.js +1 -0
  216. package/web/dist/assets/index-CEkI7QxN.css +2 -0
  217. package/web/dist/assets/index-CO2lH2et.js +11 -0
  218. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  219. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  220. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  221. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  222. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  223. package/web/dist/assets/json-qhed-kSA.js +1 -0
  224. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  225. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  226. package/web/dist/assets/lib-CNGa3Dig.js +1 -0
  227. package/web/dist/assets/loader-circle-BV3DO9mE.js +1 -0
  228. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  229. package/web/dist/assets/markdown-D4-ADgH9.js +1 -0
  230. package/web/dist/assets/mermaid-GHXKKRXX-DM2VsGBG.js +1 -0
  231. package/web/dist/assets/open-mercato-toBr6SOa.svg +11 -0
  232. package/web/dist/assets/prompt-templates-C7ptKvDd.js +15 -0
  233. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  234. package/web/dist/assets/react-dom-Ddtik4qM.js +1 -0
  235. package/web/dist/assets/refresh-cw-DCa-Rlwz.js +1 -0
  236. package/web/dist/assets/repo-git-DIhryGDx.js +1 -0
  237. package/web/dist/assets/run-diff-Dyow8B1q.js +3 -0
  238. package/web/dist/assets/run-header-jx9-18b8.js +1 -0
  239. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  240. package/web/dist/assets/search-x-CoCyl7zT.js +1 -0
  241. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  242. package/web/dist/assets/skill-detail-DB7x_FQp.js +1 -0
  243. package/web/dist/assets/skills-98vCroU8.js +1 -0
  244. package/web/dist/assets/skills-BKIoqD6K.js +1 -0
  245. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  246. package/web/dist/assets/square-terminal-B6PZX4Qp.js +1 -0
  247. package/web/dist/assets/tab-link-C5--YMQd.js +1 -0
  248. package/web/dist/assets/task-changes-ejxPGVJw.js +1 -0
  249. package/web/dist/assets/task-commits-C6GO5qT-.js +1 -0
  250. package/web/dist/assets/task-files-CatpCBXa.js +2 -0
  251. package/web/dist/assets/task-thread-BMbXDM3d.js +5 -0
  252. package/web/dist/assets/tasks-table-dgezlCcg.js +1 -0
  253. package/web/dist/assets/trash-2-CDtxmmc8.js +1 -0
  254. package/web/dist/assets/triangle-alert-6su4Js5O.js +1 -0
  255. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  256. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  257. package/web/dist/assets/upload-Bp7hQxll.js +1 -0
  258. package/web/dist/assets/use-desktop-CvTwojOJ.js +3 -0
  259. package/web/dist/assets/utils-rQGbOrwc.js +1 -0
  260. package/web/dist/assets/workflows-Dy2c6790.js +11 -0
  261. package/web/dist/assets/x-Br_jIDBw.js +1 -0
  262. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  263. package/web/dist/index.html +70 -0
  264. package/web/open-mercato.svg +11 -0
@@ -0,0 +1,144 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Optional advanced config at `.ai/cezar/config.json`. Zero-config rule:
4
+ * a missing file behaves exactly like the default below, an unreadable or
5
+ * invalid file degrades to the default too (never blocks startup). The key
6
+ * can be overridden or emptied (`"skillsRepos": []` disables team skills).
7
+ */
8
+ declare const skillsRepoSchema: z.ZodObject<{
9
+ /** `owner/name` (GitHub shorthand), a full git URL, or a local/file:// path. */
10
+ repo: z.ZodString;
11
+ ref: z.ZodDefault<z.ZodString>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ repo: string;
14
+ ref: string;
15
+ }, {
16
+ repo: string;
17
+ ref?: string | undefined;
18
+ }>;
19
+ export type SkillsRepoSource = z.infer<typeof skillsRepoSchema>;
20
+ export declare const DEFAULT_SKILLS_REPOS: SkillsRepoSource[];
21
+ declare const configSchema: z.ZodObject<{
22
+ skillsRepos: z.ZodDefault<z.ZodArray<z.ZodObject<{
23
+ /** `owner/name` (GitHub shorthand), a full git URL, or a local/file:// path. */
24
+ repo: z.ZodString;
25
+ ref: z.ZodDefault<z.ZodString>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ repo: string;
28
+ ref: string;
29
+ }, {
30
+ repo: string;
31
+ ref?: string | undefined;
32
+ }>, "many">>;
33
+ /** How many tasks may run at once (spec 006). Non-git dirs always run 1. */
34
+ maxParallel: z.ZodDefault<z.ZodNumber>;
35
+ /**
36
+ * Count-based worktree retention (#483): keep the last N *finished*
37
+ * worktrees materialized on disk; reclaim older ones (directory only — the
38
+ * `cez/<id8>` branch is kept, so the work stays recoverable). 0 = unlimited
39
+ * (never auto-reclaim). Default 10. `.catch(10)` keeps it additive-safe: a
40
+ * bad value degrades to the default instead of discarding the rest.
41
+ */
42
+ worktreeRetention: z.ZodCatch<z.ZodDefault<z.ZodNumber>>;
43
+ /**
44
+ * Per-task memory ceiling in MiB (whole process tree). When a running task's
45
+ * RSS crosses this the engine pauses it with a warning and lets the queue
46
+ * advance (#memory-guard). 0 / unset = no limit. `.catch(undefined)` keeps
47
+ * the key additive-safe: a bad value degrades to "no limit".
48
+ */
49
+ memoryLimitMb: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
50
+ /**
51
+ * Which agent backend a task uses unless overridden per task (GUI) or per
52
+ * step (workflow). The GUI only offers runners actually installed; this is
53
+ * the preselected default. Also the runner the chain planner uses.
54
+ */
55
+ defaultRunner: z.ZodDefault<z.ZodEnum<["claude", "codex", "opencode"]>>;
56
+ /** Model for the chain planner (spec 008) — cheap but reliable at JSON. */
57
+ plannerModel: z.ZodDefault<z.ZodString>;
58
+ /** Model for the task namer (spec 2026-07-17-task-auto-naming) — the cheapest
59
+ * alias that answers strict JSON; naming is fire-and-forget and never blocks. */
60
+ namerModel: z.ZodDefault<z.ZodString>;
61
+ /** Live title updates: refresh the display title through the namer on each
62
+ * turn end. Absent = the `CEZ_TITLE_UPDATES` env decides (default ON — owner
63
+ * decision on PR #479). */
64
+ liveTitleUpdates: z.ZodOptional<z.ZodBoolean>;
65
+ /** Optional diff-first review gate (#489): when a successful run with changes
66
+ * should park at `review` for a human. Absent = the `CEZ_REVIEW_GATE` env
67
+ * decides (default OFF — the deliberate inverse of `liveTitleUpdates`).
68
+ * Autonomous runs always skip the gate regardless of this. */
69
+ reviewGate: z.ZodOptional<z.ZodBoolean>;
70
+ /**
71
+ * Branch task worktrees fork from and draft PRs target (e.g. `develop`).
72
+ * Unset = the branch currently checked out. Settable from the Repo tab.
73
+ */
74
+ baseBranch: z.ZodOptional<z.ZodString>;
75
+ /**
76
+ * Default extra system prompt applied to every run's agent steps (claude:
77
+ * `--append-system-prompt`; codex/opencode: prepended to the opening user
78
+ * message — the AgentRunSpec seam handles the per-backend delivery).
79
+ * Settings is the single edit place; `POST /api/runs` can override it per
80
+ * run (`systemPrompt`). `.catch(undefined)` keeps the key additive-safe: a
81
+ * bad value degrades to unset without discarding the rest of the config.
82
+ */
83
+ systemPrompt: z.ZodCatch<z.ZodOptional<z.ZodString>>;
84
+ /**
85
+ * Per-runner default model preset (Settings → Agents, redesign R6 1.5): the
86
+ * model id the composer preselects for that runner. Missing = auto (the
87
+ * runner decides). A capability (`model`), never a vendor config format.
88
+ * `.catch(undefined)` keeps the key additive-safe like `systemPrompt`: a
89
+ * bad value degrades to unset without discarding the rest of the config.
90
+ */
91
+ defaultModels: z.ZodCatch<z.ZodOptional<z.ZodObject<{
92
+ claude: z.ZodOptional<z.ZodString>;
93
+ codex: z.ZodOptional<z.ZodString>;
94
+ opencode: z.ZodOptional<z.ZodString>;
95
+ }, "strip", z.ZodTypeAny, {
96
+ claude?: string | undefined;
97
+ codex?: string | undefined;
98
+ opencode?: string | undefined;
99
+ }, {
100
+ claude?: string | undefined;
101
+ codex?: string | undefined;
102
+ opencode?: string | undefined;
103
+ }>>>;
104
+ }, "strip", z.ZodTypeAny, {
105
+ skillsRepos: {
106
+ repo: string;
107
+ ref: string;
108
+ }[];
109
+ maxParallel: number;
110
+ worktreeRetention: number;
111
+ defaultRunner: "claude" | "codex" | "opencode";
112
+ plannerModel: string;
113
+ namerModel: string;
114
+ memoryLimitMb?: number | undefined;
115
+ liveTitleUpdates?: boolean | undefined;
116
+ reviewGate?: boolean | undefined;
117
+ baseBranch?: string | undefined;
118
+ systemPrompt?: string | undefined;
119
+ defaultModels?: {
120
+ claude?: string | undefined;
121
+ codex?: string | undefined;
122
+ opencode?: string | undefined;
123
+ } | undefined;
124
+ }, {
125
+ skillsRepos?: {
126
+ repo: string;
127
+ ref?: string | undefined;
128
+ }[] | undefined;
129
+ maxParallel?: number | undefined;
130
+ worktreeRetention?: unknown;
131
+ memoryLimitMb?: unknown;
132
+ defaultRunner?: "claude" | "codex" | "opencode" | undefined;
133
+ plannerModel?: string | undefined;
134
+ namerModel?: string | undefined;
135
+ liveTitleUpdates?: boolean | undefined;
136
+ reviewGate?: boolean | undefined;
137
+ baseBranch?: string | undefined;
138
+ systemPrompt?: unknown;
139
+ defaultModels?: unknown;
140
+ }>;
141
+ export type CezConfig = z.infer<typeof configSchema>;
142
+ /** Read `.ai/cezar/config.json` on demand — never cached, never throws. */
143
+ export declare function loadConfig(repoRoot: string): Promise<CezConfig>;
144
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,106 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { z } from 'zod';
4
+ /**
5
+ * Optional advanced config at `.ai/cezar/config.json`. Zero-config rule:
6
+ * a missing file behaves exactly like the default below, an unreadable or
7
+ * invalid file degrades to the default too (never blocks startup). The key
8
+ * can be overridden or emptied (`"skillsRepos": []` disables team skills).
9
+ */
10
+ const skillsRepoSchema = z.object({
11
+ /** `owner/name` (GitHub shorthand), a full git URL, or a local/file:// path. */
12
+ repo: z.string().min(1),
13
+ ref: z.string().min(1).default('main'),
14
+ });
15
+ export const DEFAULT_SKILLS_REPOS = [
16
+ { repo: 'open-mercato/skills', ref: 'main' },
17
+ ];
18
+ const configSchema = z.object({
19
+ skillsRepos: z.array(skillsRepoSchema).default(DEFAULT_SKILLS_REPOS),
20
+ /** How many tasks may run at once (spec 006). Non-git dirs always run 1. */
21
+ maxParallel: z.number().int().min(1).max(16).default(2),
22
+ /**
23
+ * Count-based worktree retention (#483): keep the last N *finished*
24
+ * worktrees materialized on disk; reclaim older ones (directory only — the
25
+ * `cez/<id8>` branch is kept, so the work stays recoverable). 0 = unlimited
26
+ * (never auto-reclaim). Default 10. `.catch(10)` keeps it additive-safe: a
27
+ * bad value degrades to the default instead of discarding the rest.
28
+ */
29
+ worktreeRetention: z.number().int().min(0).max(1000).default(10).catch(10),
30
+ /**
31
+ * Per-task memory ceiling in MiB (whole process tree). When a running task's
32
+ * RSS crosses this the engine pauses it with a warning and lets the queue
33
+ * advance (#memory-guard). 0 / unset = no limit. `.catch(undefined)` keeps
34
+ * the key additive-safe: a bad value degrades to "no limit".
35
+ */
36
+ memoryLimitMb: z.number().int().min(0).max(1_048_576).optional().catch(undefined),
37
+ /**
38
+ * Which agent backend a task uses unless overridden per task (GUI) or per
39
+ * step (workflow). The GUI only offers runners actually installed; this is
40
+ * the preselected default. Also the runner the chain planner uses.
41
+ */
42
+ defaultRunner: z.enum(['claude', 'codex', 'opencode']).default('claude'),
43
+ /** Model for the chain planner (spec 008) — cheap but reliable at JSON. */
44
+ plannerModel: z.string().min(1).default('sonnet'),
45
+ /** Model for the task namer (spec 2026-07-17-task-auto-naming) — the cheapest
46
+ * alias that answers strict JSON; naming is fire-and-forget and never blocks. */
47
+ namerModel: z.string().min(1).default('haiku'),
48
+ /** Live title updates: refresh the display title through the namer on each
49
+ * turn end. Absent = the `CEZ_TITLE_UPDATES` env decides (default ON — owner
50
+ * decision on PR #479). */
51
+ liveTitleUpdates: z.boolean().optional(),
52
+ /** Optional diff-first review gate (#489): when a successful run with changes
53
+ * should park at `review` for a human. Absent = the `CEZ_REVIEW_GATE` env
54
+ * decides (default OFF — the deliberate inverse of `liveTitleUpdates`).
55
+ * Autonomous runs always skip the gate regardless of this. */
56
+ reviewGate: z.boolean().optional(),
57
+ /**
58
+ * Branch task worktrees fork from and draft PRs target (e.g. `develop`).
59
+ * Unset = the branch currently checked out. Settable from the Repo tab.
60
+ */
61
+ baseBranch: z.string().trim().min(1).optional(),
62
+ /**
63
+ * Default extra system prompt applied to every run's agent steps (claude:
64
+ * `--append-system-prompt`; codex/opencode: prepended to the opening user
65
+ * message — the AgentRunSpec seam handles the per-backend delivery).
66
+ * Settings is the single edit place; `POST /api/runs` can override it per
67
+ * run (`systemPrompt`). `.catch(undefined)` keeps the key additive-safe: a
68
+ * bad value degrades to unset without discarding the rest of the config.
69
+ */
70
+ systemPrompt: z.string().trim().min(1).max(20_000).optional().catch(undefined),
71
+ /**
72
+ * Per-runner default model preset (Settings → Agents, redesign R6 1.5): the
73
+ * model id the composer preselects for that runner. Missing = auto (the
74
+ * runner decides). A capability (`model`), never a vendor config format.
75
+ * `.catch(undefined)` keeps the key additive-safe like `systemPrompt`: a
76
+ * bad value degrades to unset without discarding the rest of the config.
77
+ */
78
+ defaultModels: z
79
+ .object({
80
+ claude: z.string().trim().min(1).max(200).optional(),
81
+ codex: z.string().trim().min(1).max(200).optional(),
82
+ opencode: z.string().trim().min(1).max(200).optional(),
83
+ })
84
+ .optional()
85
+ .catch(undefined),
86
+ });
87
+ /** Read `.ai/cezar/config.json` on demand — never cached, never throws. */
88
+ export async function loadConfig(repoRoot) {
89
+ let raw;
90
+ try {
91
+ raw = await readFile(join(repoRoot, '.ai/cezar', 'config.json'), 'utf8');
92
+ }
93
+ catch {
94
+ return configSchema.parse({});
95
+ }
96
+ try {
97
+ const parsed = configSchema.safeParse(JSON.parse(raw));
98
+ if (parsed.success)
99
+ return parsed.data;
100
+ }
101
+ catch {
102
+ // fall through — malformed JSON degrades to the default
103
+ }
104
+ return configSchema.parse({});
105
+ }
106
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * The backend-agnostic seam for running one agent task. Adapted from
3
+ * @cezar/core's `agents/agent-runner.ts`, trimmed for single-user local use:
4
+ * no token-budget circuit breaker, no zod response schemas — one run is one
5
+ * agent-CLI session streaming normalized events.
6
+ *
7
+ * Three interchangeable backends implement this seam, each as a persistent
8
+ * process so multi-turn follow-ups, `waiting`, interrupt and resume all work:
9
+ * - `claude` — Claude Code CLI, stream-json over stdin/stdout;
10
+ * - `codex` — `codex app-server`, JSON-RPC 2.0 (JSONL) over stdin/stdout;
11
+ * - `opencode` — `opencode serve`, HTTP + SSE.
12
+ */
13
+ import type { UiEvent } from './ui-events.js';
14
+ /** `claude-cli` is the legacy id kept so old run records still parse. */
15
+ export type AgentBackend = 'claude' | 'codex' | 'opencode' | 'claude-cli';
16
+ /** The user-selectable runners (what config/GUI expose). */
17
+ export type RunnerId = 'claude' | 'codex' | 'opencode';
18
+ export declare const RUNNER_IDS: readonly RunnerId[];
19
+ export interface AgentRunSpec {
20
+ /** Appended to the CLI's default system prompt (`--append-system-prompt`). */
21
+ systemPrompt?: string;
22
+ userPrompt: string;
23
+ /** Image blocks delivered with the first user message — screenshots pasted
24
+ * into the new-task form (spec 002's paste path, at task start). */
25
+ images?: ContentBlock[];
26
+ /** The directory the agent runs in — also the only writable root. */
27
+ cwd: string;
28
+ /** Tool allowlist; the CLI is default-deny for anything not listed — but
29
+ * the zero-config default (`DEFAULT_ALLOWED_TOOLS`) includes `Bash`
30
+ * unrestricted unless `bashAllowlist` is set, so treat the default as
31
+ * full shell access in `cwd`, not a sandboxed allowlist (#430). */
32
+ allowedTools?: string[];
33
+ /** When `Bash` is allowed, restrict it to commands starting with one of these. */
34
+ bashAllowlist?: string[];
35
+ /** Extra directories the agent may read/write besides `cwd`. */
36
+ additionalDirectories?: string[];
37
+ /** Extra env vars for the agent process (merged over `process.env`) —
38
+ * e.g. CEZ_HANDOFF_FILE / CEZ_TODOS_FILE / CEZ_TASK_ID (spec 007). */
39
+ env?: Record<string, string>;
40
+ model?: string;
41
+ /** Wall-clock kill switch for the run (ms). */
42
+ timeoutMs?: number;
43
+ /**
44
+ * Stable session id (UUID) so the user can take over interactively later:
45
+ * `cd <repo> && claude --resume <sessionId>`.
46
+ */
47
+ sessionId?: string;
48
+ /**
49
+ * Spawn `claude --resume <sessionId>` instead of starting a fresh session —
50
+ * picks up the on-disk conversation (used by "Continue" after a run ends).
51
+ */
52
+ resume?: boolean;
53
+ }
54
+ /**
55
+ * Backends without a dedicated system-prompt channel (codex app-server,
56
+ * opencode serve) deliver `spec.systemPrompt` as a leading block of the
57
+ * opening user message — the documented per-backend mapping (spec §protocol
58
+ * v2: claude = `--append-system-prompt`, codex/opencode = prepended here).
59
+ */
60
+ export declare function prependSystemPrompt(systemPrompt: string | undefined, userPrompt: string): string;
61
+ /** One content block of a user message — mirrors the Anthropic wire format
62
+ * so it can be written to the claude CLI's stdin verbatim. */
63
+ export type ContentBlock = {
64
+ type: 'text';
65
+ text: string;
66
+ } | {
67
+ type: 'image';
68
+ source: {
69
+ type: 'base64';
70
+ media_type: string;
71
+ data: string;
72
+ };
73
+ };
74
+ /** Normalized event stream — the GUI renders these, the store persists them. */
75
+ export type AgentEvent = {
76
+ type: 'text';
77
+ text: string;
78
+ } | {
79
+ type: 'tool-call';
80
+ id: string;
81
+ tool: string;
82
+ input: unknown;
83
+ } | {
84
+ type: 'tool-result';
85
+ toolCallId: string;
86
+ result: string;
87
+ isError: boolean;
88
+ }
89
+ /** An image inside a tool result (screenshot tools, Read on a PNG…) —
90
+ * raw base64 here; the run manager persists it and re-emits a URL. */
91
+ | {
92
+ type: 'image';
93
+ mediaType: string;
94
+ data: string;
95
+ } | {
96
+ type: 'token-usage';
97
+ tokensUsed: number;
98
+ } | {
99
+ type: 'cost';
100
+ usd: number;
101
+ }
102
+ /** The backend's real session id, once known — codex threads and opencode
103
+ * sessions mint their own id, so the run manager persists this to enable
104
+ * resume ("Continue") and "open in CLI". Claude's equals `spec.sessionId`. */
105
+ | {
106
+ type: 'session';
107
+ sessionId: string;
108
+ } | {
109
+ type: 'turn-end';
110
+ } | {
111
+ type: 'note';
112
+ message: string;
113
+ } | {
114
+ type: 'done';
115
+ } | {
116
+ type: 'error';
117
+ message: string;
118
+ };
119
+ export interface AgentToolCallRecord {
120
+ id: string;
121
+ name: string;
122
+ input: unknown;
123
+ }
124
+ export interface AgentRunResult {
125
+ /** Concatenated assistant text across the run, trimmed. */
126
+ text: string;
127
+ toolCalls: AgentToolCallRecord[];
128
+ /** Cost-weighted token usage; 0 when the backend surfaced no telemetry. */
129
+ tokensUsed: number;
130
+ sessionId?: string;
131
+ }
132
+ export interface SessionOptions {
133
+ /** Close the session shortly after the first turn ends (single-turn
134
+ * behavior, used for non-interactive workflow steps). Interactive
135
+ * sessions omit this and control `end()` themselves. */
136
+ autoEndAfterFirstTurn?: boolean;
137
+ /** Protocol-v2 channel: receives the normalized `UiEvent` stream emitted
138
+ * ALONGSIDE the v1 `AgentEvent`s (additive — v1 keeps flowing unchanged).
139
+ * RunManager consumption lands in R2 step 2.1. */
140
+ onUiEvent?: (event: UiEvent) => void;
141
+ }
142
+ /**
143
+ * A live agent session over one spawned backend process. The process stays
144
+ * alive between turns and reads further user messages — that's what makes
145
+ * mid-task follow-ups possible. Implemented identically by every backend
146
+ * (claude stdin, codex app-server, opencode serve).
147
+ */
148
+ export interface AgentSession {
149
+ /** Resolves when the backend process exits — the session is fully over. */
150
+ result: Promise<AgentRunResult>;
151
+ /** OS pid of the spawned backend process — the root of the run's process
152
+ * tree (agents spawn Bash children under it). Absent when the spawn
153
+ * failed before a pid existed. Feeds live resource telemetry (#348). */
154
+ readonly pid?: number;
155
+ /** Write a user message into the live session. False when it is closed. */
156
+ sendMessage(content: ContentBlock[]): boolean;
157
+ /** Graceful close: end input, then a SIGTERM→SIGKILL watchdog. */
158
+ end(): void;
159
+ /** Hard stop (used by cancel). */
160
+ interrupt(): void;
161
+ /** True while the session still accepts messages. */
162
+ readonly open: boolean;
163
+ }
164
+ export interface AgentRunner {
165
+ readonly backend: AgentBackend;
166
+ run(spec: AgentRunSpec, onEvent?: (event: AgentEvent) => void): Promise<AgentRunResult>;
167
+ startSession(spec: AgentRunSpec, onEvent?: (event: AgentEvent) => void, opts?: SessionOptions): AgentSession;
168
+ interrupt(): Promise<void>;
169
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The backend-agnostic seam for running one agent task. Adapted from
3
+ * @cezar/core's `agents/agent-runner.ts`, trimmed for single-user local use:
4
+ * no token-budget circuit breaker, no zod response schemas — one run is one
5
+ * agent-CLI session streaming normalized events.
6
+ *
7
+ * Three interchangeable backends implement this seam, each as a persistent
8
+ * process so multi-turn follow-ups, `waiting`, interrupt and resume all work:
9
+ * - `claude` — Claude Code CLI, stream-json over stdin/stdout;
10
+ * - `codex` — `codex app-server`, JSON-RPC 2.0 (JSONL) over stdin/stdout;
11
+ * - `opencode` — `opencode serve`, HTTP + SSE.
12
+ */
13
+ export const RUNNER_IDS = ['claude', 'codex', 'opencode'];
14
+ /**
15
+ * Backends without a dedicated system-prompt channel (codex app-server,
16
+ * opencode serve) deliver `spec.systemPrompt` as a leading block of the
17
+ * opening user message — the documented per-backend mapping (spec §protocol
18
+ * v2: claude = `--append-system-prompt`, codex/opencode = prepended here).
19
+ */
20
+ export function prependSystemPrompt(systemPrompt, userPrompt) {
21
+ return systemPrompt ? `${systemPrompt}\n\n---\n\n${userPrompt}` : userPrompt;
22
+ }
23
+ //# sourceMappingURL=agent-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../src/core/agent-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,CAAC,MAAM,UAAU,GAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAsC/E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAgC,EAAE,UAAkB;IACtF,OAAO,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,cAAc,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface BackendCheck {
2
+ name: 'claude' | 'codex' | 'opencode' | 'gh' | 'git';
3
+ available: boolean;
4
+ version?: string;
5
+ hint?: string;
6
+ }
7
+ /**
8
+ * Probe the host for everything cez leans on: the agent CLIs (`claude`, and
9
+ * the optional `codex` / `opencode` alternatives), `gh` (GitHub auth for PR
10
+ * creation) and `git`. Nothing is required except at least one agent CLI — the
11
+ * GUI degrades gracefully, only offers the runners that are present, and shows
12
+ * the hints for the rest.
13
+ */
14
+ export declare function detectEnvironment(): Promise<BackendCheck[]>;
15
+ /** The host's GitHub token: logged-in `gh` first, `GITHUB_TOKEN` fallback. */
16
+ export declare function readHostGithubToken(): Promise<string | null>;
@@ -0,0 +1,118 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const exec = promisify(execFile);
4
+ /**
5
+ * Probe the host for everything cez leans on: the agent CLIs (`claude`, and
6
+ * the optional `codex` / `opencode` alternatives), `gh` (GitHub auth for PR
7
+ * creation) and `git`. Nothing is required except at least one agent CLI — the
8
+ * GUI degrades gracefully, only offers the runners that are present, and shows
9
+ * the hints for the rest.
10
+ */
11
+ export async function detectEnvironment() {
12
+ return Promise.all([probeClaude(), probeCodex(), probeOpencode(), probeGh(), probeGit()]);
13
+ }
14
+ async function probeClaude() {
15
+ if (process.env.CEZ_DRY_RUN === '1') {
16
+ return { name: 'claude', available: true, version: 'mock (CEZ_DRY_RUN=1)' };
17
+ }
18
+ try {
19
+ const { stdout } = await exec('claude', ['--version'], { timeout: 10_000 });
20
+ const version = stdout.trim();
21
+ // A generic `claude` binary (a shell wrapper, an unrelated tool) can shadow
22
+ // the real CLI on $PATH — reject anything that doesn't match the banner.
23
+ if (!/^\d+\.\d+|^claude(\s+code)?\s+version\s+\d+\.\d+/i.test(version)) {
24
+ return {
25
+ name: 'claude',
26
+ available: false,
27
+ hint: `\`claude\` is on PATH but doesn't look like Claude Code (got: ${version.slice(0, 80)})`,
28
+ };
29
+ }
30
+ return {
31
+ name: 'claude',
32
+ available: true,
33
+ version,
34
+ hint: 'if not authenticated, run `claude` once and log in',
35
+ };
36
+ }
37
+ catch {
38
+ return {
39
+ name: 'claude',
40
+ available: false,
41
+ hint: 'install Claude Code (npm i -g @anthropic-ai/claude-code) and log in',
42
+ };
43
+ }
44
+ }
45
+ async function probeCodex() {
46
+ const bin = process.env.CEZ_CODEX_BIN ?? 'codex';
47
+ try {
48
+ const { stdout } = await exec(bin, ['--version'], { timeout: 10_000 });
49
+ return {
50
+ name: 'codex',
51
+ available: true,
52
+ version: stdout.trim(),
53
+ hint: 'if not authenticated, run `codex` once and log in',
54
+ };
55
+ }
56
+ catch {
57
+ return {
58
+ name: 'codex',
59
+ available: false,
60
+ hint: 'optional: install the Codex CLI (npm i -g @openai/codex) and log in to use the Codex runner',
61
+ };
62
+ }
63
+ }
64
+ async function probeOpencode() {
65
+ const bin = process.env.CEZ_OPENCODE_BIN ?? 'opencode';
66
+ try {
67
+ const { stdout } = await exec(bin, ['--version'], { timeout: 10_000 });
68
+ return {
69
+ name: 'opencode',
70
+ available: true,
71
+ version: stdout.trim(),
72
+ hint: 'if no provider is configured, run `opencode` once to set one up',
73
+ };
74
+ }
75
+ catch {
76
+ return {
77
+ name: 'opencode',
78
+ available: false,
79
+ hint: 'optional: install OpenCode (https://opencode.ai) and configure a provider to use the OpenCode runner',
80
+ };
81
+ }
82
+ }
83
+ async function probeGh() {
84
+ try {
85
+ const { stdout } = await exec('gh', ['auth', 'token'], { timeout: 10_000 });
86
+ return { name: 'gh', available: stdout.trim().length > 0, version: 'authenticated' };
87
+ }
88
+ catch {
89
+ return {
90
+ name: 'gh',
91
+ available: false,
92
+ hint: 'install the GitHub CLI and run `gh auth login` (only needed for PR creation)',
93
+ };
94
+ }
95
+ }
96
+ async function probeGit() {
97
+ try {
98
+ const { stdout } = await exec('git', ['--version'], { timeout: 10_000 });
99
+ return { name: 'git', available: true, version: stdout.trim() };
100
+ }
101
+ catch {
102
+ return { name: 'git', available: false, hint: 'install git' };
103
+ }
104
+ }
105
+ /** The host's GitHub token: logged-in `gh` first, `GITHUB_TOKEN` fallback. */
106
+ export async function readHostGithubToken() {
107
+ try {
108
+ const { stdout } = await exec('gh', ['auth', 'token'], { timeout: 10_000 });
109
+ const token = stdout.trim();
110
+ if (token)
111
+ return token;
112
+ }
113
+ catch {
114
+ // fall through to the env var
115
+ }
116
+ return process.env.GITHUB_TOKEN?.trim() || null;
117
+ }
118
+ //# sourceMappingURL=backend-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-detect.js","sourceRoot":"","sources":["../../src/core/backend-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { AgentEvent, AgentRunResult, AgentRunSpec, AgentRunner, AgentSession, SessionOptions } from './agent-runner.js';
2
+ export type { AgentSession, SessionOptions } from './agent-runner.js';
3
+ /** Default wall-clock cap for a single run before SIGTERM → SIGKILL.
4
+ * Interactive sessions pass `timeoutMs: 0` to disable it entirely. */
5
+ export declare const DEFAULT_RUN_TIMEOUT_MS: number;
6
+ /** Grace period between SIGTERM and SIGKILL when a timeout fires. */
7
+ export declare const KILL_GRACE_MS = 10000;
8
+ /** After `end()` closes stdin: claude in stream-json mode can ignore EOF and
9
+ * hang (janitor-confirmed CLI bug) — escalate SIGTERM, then SIGKILL. */
10
+ export declare const EOF_TERM_GRACE_MS = 8000;
11
+ export declare const EOF_KILL_GRACE_MS = 4000;
12
+ /** Reopen window after a turn ends before an auto-ended session closes stdin. */
13
+ export declare const AUTO_END_DELAY_MS = 250;
14
+ export interface ClaudeCliRunnerOptions {
15
+ /** Override the binary name/path; defaults to `claude` on PATH. */
16
+ bin?: string;
17
+ /** Wall-clock timeout for a run (ms); per-spec `timeoutMs` still wins. */
18
+ timeoutMs?: number;
19
+ }
20
+ /**
21
+ * `AgentRunner` over the Claude Code CLI in headless stream-json mode. Auth =
22
+ * the host's logged-in Pro/Max subscription (no API key needed). Sandboxing is
23
+ * `--allowedTools` (default-deny for anything not listed) + running inside the
24
+ * repo `cwd`; `Bash` is narrowed to `Bash(<prefix>:*)` patterns only when
25
+ * `bashAllowlist` is set — the zero-config default has no allowlist, so `Bash`
26
+ * is unrestricted shell access (#430).
27
+ *
28
+ * Session mechanics (multi-turn stdin, EOF watchdog, reopen window) follow
29
+ * github-janitor's `claudeRunner.ts`; the original single-turn adaptation
30
+ * came from @cezar/core's `ClaudeCodeCliRunner`.
31
+ */
32
+ export declare class ClaudeCliRunner implements AgentRunner {
33
+ readonly backend: "claude";
34
+ private readonly bin;
35
+ private readonly timeoutMs;
36
+ private lastSession;
37
+ constructor(opts?: ClaudeCliRunnerOptions);
38
+ /** One-shot run: start a session and auto-end it after the first turn. */
39
+ run(spec: AgentRunSpec, onEvent?: (event: AgentEvent) => void): Promise<AgentRunResult>;
40
+ interrupt(): Promise<void>;
41
+ startSession(spec: AgentRunSpec, onEvent?: (event: AgentEvent) => void, opts?: SessionOptions): AgentSession;
42
+ }
43
+ /**
44
+ * Build the headless argv. `--input-format stream-json` reads user messages
45
+ * from stdin; `--output-format stream-json --verbose` gives per-event NDJSON;
46
+ * `--permission-mode dontAsk` keeps headless runs non-interactive: tools in
47
+ * `--allowedTools` proceed and everything else is denied instead of prompting.
48
+ * `CEZ_APPROVAL_GATE=1` opts back into Claude's approval UI (#435).
49
+ */
50
+ export declare function buildClaudeArgs(spec: AgentRunSpec, env?: NodeJS.ProcessEnv): string[];
51
+ /**
52
+ * Map `allowedTools` onto claude's `--allowedTools` syntax. `Bash` with a
53
+ * `bashAllowlist` becomes one `Bash(<prefix>:*)` entry per allowed prefix;
54
+ * `Bash` with no allowlist stays plain `Bash`.
55
+ */
56
+ export declare function buildAllowedTools(allowedTools: string[], bashAllowlist?: string[]): string[];