@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.
- package/README.md +573 -0
- package/dist/config.d.ts +144 -0
- package/dist/config.js +106 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-runner.d.ts +169 -0
- package/dist/core/agent-runner.js +23 -0
- package/dist/core/agent-runner.js.map +1 -0
- package/dist/core/backend-detect.d.ts +16 -0
- package/dist/core/backend-detect.js +118 -0
- package/dist/core/backend-detect.js.map +1 -0
- package/dist/core/claude-cli-runner.d.ts +56 -0
- package/dist/core/claude-cli-runner.js +416 -0
- package/dist/core/claude-cli-runner.js.map +1 -0
- package/dist/core/claude-ui-mapper.d.ts +71 -0
- package/dist/core/claude-ui-mapper.js +567 -0
- package/dist/core/claude-ui-mapper.js.map +1 -0
- package/dist/core/codex-app-server-runner.d.ts +29 -0
- package/dist/core/codex-app-server-runner.js +489 -0
- package/dist/core/codex-app-server-runner.js.map +1 -0
- package/dist/core/codex-ui-mapper.d.ts +63 -0
- package/dist/core/codex-ui-mapper.js +491 -0
- package/dist/core/codex-ui-mapper.js.map +1 -0
- package/dist/core/ndjson.d.ts +6 -0
- package/dist/core/ndjson.js +23 -0
- package/dist/core/ndjson.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +30 -0
- package/dist/core/opencode-server-runner.js +488 -0
- package/dist/core/opencode-server-runner.js.map +1 -0
- package/dist/core/opencode-ui-mapper.d.ts +105 -0
- package/dist/core/opencode-ui-mapper.js +588 -0
- package/dist/core/opencode-ui-mapper.js.map +1 -0
- package/dist/core/process-usage.d.ts +63 -0
- package/dist/core/process-usage.js +181 -0
- package/dist/core/process-usage.js.map +1 -0
- package/dist/core/runner-factory.d.ts +8 -0
- package/dist/core/runner-factory.js +22 -0
- package/dist/core/runner-factory.js.map +1 -0
- package/dist/core/tool-display.d.ts +30 -0
- package/dist/core/tool-display.js +156 -0
- package/dist/core/tool-display.js.map +1 -0
- package/dist/core/ui-events.d.ts +308 -0
- package/dist/core/ui-events.js +25 -0
- package/dist/core/ui-events.js.map +1 -0
- package/dist/core/usage.d.ts +11 -0
- package/dist/core/usage.js +15 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/git-worktree.d.ts +88 -0
- package/dist/git-worktree.js +297 -0
- package/dist/git-worktree.js.map +1 -0
- package/dist/handoff.d.ts +62 -0
- package/dist/handoff.js +147 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +466 -0
- package/dist/index.js.map +1 -0
- package/dist/install-as-command.d.ts +39 -0
- package/dist/install-as-command.js +51 -0
- package/dist/install-as-command.js.map +1 -0
- package/dist/pack-check.d.ts +17 -0
- package/dist/pack-check.js +27 -0
- package/dist/pack-check.js.map +1 -0
- package/dist/paths.d.ts +23 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/planner.d.ts +17 -0
- package/dist/planner.js +248 -0
- package/dist/planner.js.map +1 -0
- package/dist/release/snapshot.d.ts +64 -0
- package/dist/release/snapshot.js +75 -0
- package/dist/release/snapshot.js.map +1 -0
- package/dist/release/stable.d.ts +46 -0
- package/dist/release/stable.js +57 -0
- package/dist/release/stable.js.map +1 -0
- package/dist/runs/auto-name.d.ts +75 -0
- package/dist/runs/auto-name.js +168 -0
- package/dist/runs/auto-name.js.map +1 -0
- package/dist/runs/retention.d.ts +60 -0
- package/dist/runs/retention.js +86 -0
- package/dist/runs/retention.js.map +1 -0
- package/dist/runs/review-gate.d.ts +18 -0
- package/dist/runs/review-gate.js +21 -0
- package/dist/runs/review-gate.js.map +1 -0
- package/dist/runs/store.d.ts +408 -0
- package/dist/runs/store.js +526 -0
- package/dist/runs/store.js.map +1 -0
- package/dist/runs/task-refs.d.ts +24 -0
- package/dist/runs/task-refs.js +74 -0
- package/dist/runs/task-refs.js.map +1 -0
- package/dist/runs/ui-event-sink.d.ts +81 -0
- package/dist/runs/ui-event-sink.js +210 -0
- package/dist/runs/ui-event-sink.js.map +1 -0
- package/dist/server/capabilities.d.ts +33 -0
- package/dist/server/capabilities.js +43 -0
- package/dist/server/capabilities.js.map +1 -0
- package/dist/server/forge/github.d.ts +70 -0
- package/dist/server/forge/github.js +375 -0
- package/dist/server/forge/github.js.map +1 -0
- package/dist/server/forge/index.d.ts +24 -0
- package/dist/server/forge/index.js +45 -0
- package/dist/server/forge/index.js.map +1 -0
- package/dist/server/forge/types.d.ts +80 -0
- package/dist/server/forge/types.js +2 -0
- package/dist/server/forge/types.js.map +1 -0
- package/dist/server/git-changes.d.ts +195 -0
- package/dist/server/git-changes.js +497 -0
- package/dist/server/git-changes.js.map +1 -0
- package/dist/server/git.d.ts +26 -0
- package/dist/server/git.js +103 -0
- package/dist/server/git.js.map +1 -0
- package/dist/server/github.d.ts +8 -0
- package/dist/server/github.js +8 -0
- package/dist/server/github.js.map +1 -0
- package/dist/server/launch-key.d.ts +7 -0
- package/dist/server/launch-key.js +33 -0
- package/dist/server/launch-key.js.map +1 -0
- package/dist/server/open-in-app.d.ts +51 -0
- package/dist/server/open-in-app.js +189 -0
- package/dist/server/open-in-app.js.map +1 -0
- package/dist/server/open-in-terminal.d.ts +25 -0
- package/dist/server/open-in-terminal.js +120 -0
- package/dist/server/open-in-terminal.js.map +1 -0
- package/dist/server/pr.d.ts +7 -0
- package/dist/server/pr.js +7 -0
- package/dist/server/pr.js.map +1 -0
- package/dist/server/server.d.ts +41 -0
- package/dist/server/server.js +1390 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/static-ui.d.ts +49 -0
- package/dist/server/static-ui.js +92 -0
- package/dist/server/static-ui.js.map +1 -0
- package/dist/server/wsl.d.ts +25 -0
- package/dist/server/wsl.js +92 -0
- package/dist/server/wsl.js.map +1 -0
- package/dist/server-install/engine.d.ts +33 -0
- package/dist/server-install/engine.js +314 -0
- package/dist/server-install/engine.js.map +1 -0
- package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
- package/dist/server-install/platforms/macosx-ngrok.js +345 -0
- package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
- package/dist/server-install/platforms/ubuntu-vps.d.ts +39 -0
- package/dist/server-install/platforms/ubuntu-vps.js +746 -0
- package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
- package/dist/server-install/state.d.ts +26 -0
- package/dist/server-install/state.js +125 -0
- package/dist/server-install/state.js.map +1 -0
- package/dist/server-install/steps.d.ts +109 -0
- package/dist/server-install/steps.js +330 -0
- package/dist/server-install/steps.js.map +1 -0
- package/dist/server-install/strategies.d.ts +4 -0
- package/dist/server-install/strategies.js +20 -0
- package/dist/server-install/strategies.js.map +1 -0
- package/dist/server-install/types.d.ts +597 -0
- package/dist/server-install/types.js +98 -0
- package/dist/server-install/types.js.map +1 -0
- package/dist/server-install/ui.d.ts +42 -0
- package/dist/server-install/ui.js +130 -0
- package/dist/server-install/ui.js.map +1 -0
- package/dist/skills-banner.d.ts +21 -0
- package/dist/skills-banner.js +40 -0
- package/dist/skills-banner.js.map +1 -0
- package/dist/skills-remote.d.ts +35 -0
- package/dist/skills-remote.js +266 -0
- package/dist/skills-remote.js.map +1 -0
- package/dist/skills.d.ts +45 -0
- package/dist/skills.js +182 -0
- package/dist/skills.js.map +1 -0
- package/dist/todos.d.ts +63 -0
- package/dist/todos.js +168 -0
- package/dist/todos.js.map +1 -0
- package/dist/ui-state.d.ts +12 -0
- package/dist/ui-state.js +25 -0
- package/dist/ui-state.js.map +1 -0
- package/dist/update-check.d.ts +12 -0
- package/dist/update-check.js +41 -0
- package/dist/update-check.js.map +1 -0
- package/dist/workflows/load.d.ts +15 -0
- package/dist/workflows/load.js +56 -0
- package/dist/workflows/load.js.map +1 -0
- package/dist/workflows/run.d.ts +281 -0
- package/dist/workflows/run.js +1511 -0
- package/dist/workflows/run.js.map +1 -0
- package/dist/workflows/types.d.ts +307 -0
- package/dist/workflows/types.js +171 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +90 -0
- package/scripts/check-pack.mjs +46 -0
- package/scripts/dev.mjs +74 -0
- package/scripts/install-as-command.mjs +120 -0
- package/scripts/mock-claude.mjs +310 -0
- package/scripts/release-snapshot.mjs +130 -0
- package/scripts/release.mjs +119 -0
- package/scripts/test-process-usage.mjs +47 -0
- package/web/dist/assets/arrow-left-BE957rJs.js +1 -0
- package/web/dist/assets/bundle-mjs-DLPpRFyl.js +1 -0
- package/web/dist/assets/centered-state-BddhEEtO.js +43 -0
- package/web/dist/assets/chunk-BO2N2NFS-f5igTtpB.js +131 -0
- package/web/dist/assets/command-CjhFbABo.js +1 -0
- package/web/dist/assets/compare-variants-Cs52IAEG.js +1 -0
- package/web/dist/assets/core-BuMqAF_1.js +12 -0
- package/web/dist/assets/css-BsVw1vtW.js +1 -0
- package/web/dist/assets/dialog-DFvXTkFv.js +1 -0
- package/web/dist/assets/diff-view-C9b8AITq.js +4 -0
- package/web/dist/assets/diff-woXpYk--.js +1 -0
- package/web/dist/assets/dist-FBs4wmIY.js +1 -0
- package/web/dist/assets/dist-o_kVMXjg.js +1 -0
- package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
- package/web/dist/assets/file-BVuztAOd.js +1 -0
- package/web/dist/assets/folder-0pJ1NZ_S.js +1 -0
- package/web/dist/assets/git-pull-request-DJkAMT0f.js +1 -0
- package/web/dist/assets/git-toolbar-CwhQdx3J.js +1 -0
- package/web/dist/assets/github-D0rAX4-r.js +1 -0
- package/web/dist/assets/go-rLFTqkRN.js +1 -0
- package/web/dist/assets/highlighted-body-OFNGDK62-DGHHie_q.js +1 -0
- package/web/dist/assets/highlighter-BKVEsACy.js +3 -0
- package/web/dist/assets/html-BY76lXLH.js +1 -0
- package/web/dist/assets/index-CEkI7QxN.css +2 -0
- package/web/dist/assets/index-CO2lH2et.js +11 -0
- package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
- package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/web/dist/assets/json-qhed-kSA.js +1 -0
- package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
- package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
- package/web/dist/assets/lib-CNGa3Dig.js +1 -0
- package/web/dist/assets/loader-circle-BV3DO9mE.js +1 -0
- package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
- package/web/dist/assets/markdown-D4-ADgH9.js +1 -0
- package/web/dist/assets/mermaid-GHXKKRXX-DM2VsGBG.js +1 -0
- package/web/dist/assets/open-mercato-toBr6SOa.svg +11 -0
- package/web/dist/assets/prompt-templates-C7ptKvDd.js +15 -0
- package/web/dist/assets/python-gzcpVVnB.js +1 -0
- package/web/dist/assets/react-dom-Ddtik4qM.js +1 -0
- package/web/dist/assets/refresh-cw-DCa-Rlwz.js +1 -0
- package/web/dist/assets/repo-git-DIhryGDx.js +1 -0
- package/web/dist/assets/run-diff-Dyow8B1q.js +3 -0
- package/web/dist/assets/run-header-jx9-18b8.js +1 -0
- package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
- package/web/dist/assets/search-x-CoCyl7zT.js +1 -0
- package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
- package/web/dist/assets/skill-detail-DB7x_FQp.js +1 -0
- package/web/dist/assets/skills-98vCroU8.js +1 -0
- package/web/dist/assets/skills-BKIoqD6K.js +1 -0
- package/web/dist/assets/sql-BsFa4tDR.js +1 -0
- package/web/dist/assets/square-terminal-B6PZX4Qp.js +1 -0
- package/web/dist/assets/tab-link-C5--YMQd.js +1 -0
- package/web/dist/assets/task-changes-ejxPGVJw.js +1 -0
- package/web/dist/assets/task-commits-C6GO5qT-.js +1 -0
- package/web/dist/assets/task-files-CatpCBXa.js +2 -0
- package/web/dist/assets/task-thread-BMbXDM3d.js +5 -0
- package/web/dist/assets/tasks-table-dgezlCcg.js +1 -0
- package/web/dist/assets/trash-2-CDtxmmc8.js +1 -0
- package/web/dist/assets/triangle-alert-6su4Js5O.js +1 -0
- package/web/dist/assets/tsx-udAQXfEw.js +1 -0
- package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
- package/web/dist/assets/upload-Bp7hQxll.js +1 -0
- package/web/dist/assets/use-desktop-CvTwojOJ.js +3 -0
- package/web/dist/assets/utils-rQGbOrwc.js +1 -0
- package/web/dist/assets/workflows-Dy2c6790.js +11 -0
- package/web/dist/assets/x-Br_jIDBw.js +1 -0
- package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
- package/web/dist/index.html +70 -0
- package/web/open-mercato.svg +11 -0
package/dist/config.d.ts
ADDED
|
@@ -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[];
|