kaizen-agent 0.7.2 → 0.7.4
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 +32 -19
- package/cli/install.ts +74 -11
- package/cli/settings.ts +115 -11
- package/package.json +1 -1
- package/skills/kaizen/SKILL.md +1 -0
- package/skills/kaizen/config.default.yml +5 -0
- package/skills/kaizen-help/SKILL.md +1 -0
package/README.md
CHANGED
|
@@ -252,28 +252,37 @@ The stage agents and slash commands are Claude Code's own formats and are not co
|
|
|
252
252
|
elsewhere; under the others you invoke the skill by name. `.kaizen/` is plain files
|
|
253
253
|
either way, so a run started in one tool can be finished in another.
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
Run `kaizen` anytime to open the terminal dashboard:
|
|
256
256
|
|
|
257
257
|
```
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
258
|
+
⠀⠀⠀⣰⠖⠾⣟⣛⠋⢉⣩⠽⢛⡽⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
259
|
+
⠀⠀⢰⢻⠀⠀⢀⡬⠟⠉⢀⠴⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
260
|
+
⠀⢠⠇⣾⡠⠞⢩⠤⢄⡚⣁⣀⣀⣀⢀⣠⠤⡄⠀⠀⠀⠀⠀⠀ █ █ ▄▀█ █ ▀▀█ █▀▀ █▄ █
|
|
261
|
+
⢠⣏⠔⣫⣀⡤⢸⠀⠀⠉⠁⠀⠀⠈⠉⠀⠀⡇⠀⠀⠀⠀⠀⠀ █▀▄ █▀█ █ ▄▀ ██▄ █ ▀█
|
|
262
|
+
⢾⠥⢾⡅⢧⠀⢸⠃⡤⠖⠢⡀⢀⠔⠲⢤⠘⡇⠀⠀⣀⣀⠀⠀ █ █ █ █ █ █▄▄ █▄▄ █ █
|
|
263
|
+
⠀⠀⠈⣇⠈⢠⣫⠞⠀⠘⢱⢣⡜⡎⠃⠀⠳⣝⡄⢠⠇⢻⢉⣷
|
|
264
|
+
⠀⠀⠀⠘⢆⠀⠑⢦⣀⡀⠈⠓⠚⠁⢀⣀⣤⣊⣠⢾⡀⢠⣿⠃ 0.7.2 plan · approve · build · review
|
|
265
|
+
⠀⠀⠀⠀⠈⠓⢄⠀⠀⠉⣉⣭⣭⣉⠉⠀⠈⢀⣠⢔⡩⠥⢥⡀ ~/Projects/app
|
|
266
|
+
⠀⠀⠀⠀⠀⠀⢠⡇⠀⡞⠁⠀⠀⠈⢳⠀⢰⣍⣠⠚⠧⡀⠀⡷ Claude Code, Codex, Antigravity, OpenCode, Gemini CLI
|
|
267
|
+
⠀⠀⠀⠀⠀⠀⠸⡇⠀⣇⠀⠀⠀⠀⣸⠀⢠⡏⠀⠀⢀⣳⠞⠁
|
|
268
|
+
⠀⠀⠀⠀⠀⠀⠀⠳⣀⣨⠥⠤⠶⠾⣅⣀⠞⠉⠉⠉⠉⠀⠀⠀
|
|
269
|
+
|
|
270
|
+
╭─ Runs ──────────────────────────────────╮ ╭─ Backlog — 4 open ──────────────────────────╮
|
|
271
|
+
│ ● fix-discount waiting on you │ │ cart.py:12 low use > not >= │
|
|
272
|
+
│ ● cache-headers in review │ │ headline med legal review │
|
|
273
|
+
│ ● 3 done │ │ … 2 more │
|
|
274
|
+
╰─────────────────────────────────────────╯ ╰─────────────────────────────────────────────╯
|
|
275
|
+
|
|
276
|
+
› All projects every project kaizen knows about
|
|
277
|
+
Runs
|
|
278
|
+
Backlog
|
|
279
|
+
Settings
|
|
270
280
|
Upgrade
|
|
271
281
|
Quit
|
|
272
282
|
```
|
|
273
283
|
|
|
274
|
-
It
|
|
275
|
-
|
|
276
|
-
PATH, so updating later is:
|
|
284
|
+
It monitors your runs and backlog across all your projects without having to open an agent.
|
|
285
|
+
Installing puts the `kaizen` command on your PATH, so updating later is:
|
|
277
286
|
|
|
278
287
|
```bash
|
|
279
288
|
kaizen upgrade
|
|
@@ -408,17 +417,20 @@ change written as you make it, esc to close:
|
|
|
408
417
|
```
|
|
409
418
|
kaizen settings ~/Projects/app/.kaizen/config.yml
|
|
410
419
|
|
|
420
|
+
› preset medium
|
|
411
421
|
mode approve
|
|
412
|
-
|
|
422
|
+
runner full
|
|
423
|
+
build.executor subagent
|
|
413
424
|
approvals.plan true
|
|
414
425
|
approvals.review false
|
|
426
|
+
auto_fix.enabled true
|
|
415
427
|
auto_fix.min_severity high
|
|
416
428
|
auto_fix.max_iterations 2
|
|
417
429
|
...
|
|
418
430
|
|
|
419
|
-
|
|
431
|
+
Quick preset — low: inline & manual, medium: balanced, ultra: autonomous subagents
|
|
420
432
|
|
|
421
|
-
↑↓ move · ←→ change · esc close saved
|
|
433
|
+
↑↓ move · ←→ change · esc close saved preset = medium
|
|
422
434
|
```
|
|
423
435
|
|
|
424
436
|
It edits each line in place, so the comment above every key survives. `/kaizen-config`
|
|
@@ -442,6 +454,7 @@ with a comment on each key, if you would rather edit the file.
|
|
|
442
454
|
| `--project` | Into the current directory only |
|
|
443
455
|
| `--check` | Report what is linked, exit non-zero if anything is missing |
|
|
444
456
|
| `--force` | Replace a real file sitting where a link belongs |
|
|
457
|
+
| `--preset <name>` | Pre-select workflow preset (`low`, `medium`, or `ultra`) |
|
|
445
458
|
| `--yes` | Take every default, ask nothing |
|
|
446
459
|
| `--verbose` | List every link instead of a one-line summary |
|
|
447
460
|
| `upgrade` | Pull, relink, and clear the installer cache. No prompts. |
|
package/cli/install.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from "node:fs";
|
|
6
6
|
import { join, dirname, basename } from "node:path";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
|
+
import { applyPreset, detectPreset, PRESETS, type PresetName } from "./settings.ts";
|
|
8
9
|
|
|
9
10
|
const home = homedir();
|
|
10
11
|
const REPO_URL = "https://github.com/hfadhlullah/kaizen.git";
|
|
@@ -16,6 +17,22 @@ const force = args.has("--force");
|
|
|
16
17
|
const verbose = args.has("--verbose");
|
|
17
18
|
const interactive = process.stdin.isTTY && !check && !upgrade && !args.has("--yes");
|
|
18
19
|
|
|
20
|
+
function parsePresetArg(): PresetName | null {
|
|
21
|
+
for (const a of Bun.argv.slice(2)) {
|
|
22
|
+
if (a.startsWith("--preset=")) {
|
|
23
|
+
const v = a.split("=")[1]?.toLowerCase();
|
|
24
|
+
if (v === "low" || v === "medium" || v === "ultra") return v as PresetName;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const idx = Bun.argv.indexOf("--preset");
|
|
28
|
+
if (idx !== -1 && Bun.argv[idx + 1]) {
|
|
29
|
+
const v = Bun.argv[idx + 1]?.toLowerCase();
|
|
30
|
+
if (v === "low" || v === "medium" || v === "ultra") return v as PresetName;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const presetArg = parsePresetArg();
|
|
35
|
+
|
|
19
36
|
const c = {
|
|
20
37
|
dim: (s: string) => `\x1b[2m${s}\x1b[0m`,
|
|
21
38
|
bold: (s: string) => `\x1b[1m${s}\x1b[0m`,
|
|
@@ -250,8 +267,32 @@ async function anyKey() {
|
|
|
250
267
|
|
|
251
268
|
const repo = await resolveRepo();
|
|
252
269
|
const root = await chooseRoot();
|
|
270
|
+
const presetChoice = await choosePreset();
|
|
253
271
|
const targets = found(root);
|
|
254
272
|
|
|
273
|
+
async function choosePreset(): Promise<PresetName> {
|
|
274
|
+
if (presetArg) return presetArg;
|
|
275
|
+
if (!interactive) return "medium";
|
|
276
|
+
|
|
277
|
+
return select("Choose workflow preset", [
|
|
278
|
+
{
|
|
279
|
+
label: "Medium (Recommended)",
|
|
280
|
+
hint: "balanced — subagents, plan approval, auto-fix high/critical",
|
|
281
|
+
value: "medium",
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
label: "Low",
|
|
285
|
+
hint: "inline & manual — lite runner, inline builder, manual approvals, no auto-fix",
|
|
286
|
+
value: "low",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
label: "Ultra",
|
|
290
|
+
hint: "autonomous — subagents, auto mode, auto-fix all findings (up to 4 rounds)",
|
|
291
|
+
value: "ultra",
|
|
292
|
+
},
|
|
293
|
+
]);
|
|
294
|
+
}
|
|
295
|
+
|
|
255
296
|
// ---------------------------------------------------------------- repo
|
|
256
297
|
|
|
257
298
|
// Settings only needs the clone's default config, not a pull.
|
|
@@ -392,6 +433,18 @@ function installLauncher() {
|
|
|
392
433
|
|
|
393
434
|
const inProject = process.cwd() !== home;
|
|
394
435
|
const kaizenDir = join(process.cwd(), ".kaizen");
|
|
436
|
+
const globalKaizen = join(home, ".kaizen");
|
|
437
|
+
const globalConfig = join(globalKaizen, "config.yml");
|
|
438
|
+
|
|
439
|
+
if (!args.has("--project")) {
|
|
440
|
+
mkdirSync(globalKaizen, { recursive: true });
|
|
441
|
+
const defPath = join(repo, "skills/kaizen/config.default.yml");
|
|
442
|
+
const def = readFileSync(defPath, "utf8");
|
|
443
|
+
const base = existsSync(globalConfig) ? readFileSync(globalConfig, "utf8") : def;
|
|
444
|
+
const conf = applyPreset(base, presetChoice, def);
|
|
445
|
+
writeFileSync(globalConfig, conf);
|
|
446
|
+
step(`configured ${c.bold(presetChoice)} preset in ${tilde(globalConfig)}`);
|
|
447
|
+
}
|
|
395
448
|
|
|
396
449
|
// A .kaizen/ in a parent already owns this folder's state, and setting up a child
|
|
397
450
|
// would shadow it, hiding the parent's runs and leaving the child out of the root
|
|
@@ -413,25 +466,35 @@ function kaizenAbove() {
|
|
|
413
466
|
}
|
|
414
467
|
|
|
415
468
|
if (inProject && !kaizenAbove()) {
|
|
416
|
-
const now =
|
|
417
|
-
?
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
469
|
+
const now = root === process.cwd()
|
|
470
|
+
? true
|
|
471
|
+
: interactive
|
|
472
|
+
? await select(`Set up ${basename(process.cwd())}/ for kaizen now`, [
|
|
473
|
+
// "Not now" leads: the offer now appears in any folder outside home, so the
|
|
474
|
+
// safe answer is the one under the cursor.
|
|
475
|
+
{ label: "Not now", hint: "the first /kaizen run will do it", value: false },
|
|
476
|
+
{ label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
|
|
477
|
+
])
|
|
478
|
+
: false;
|
|
479
|
+
if (now) initProject(presetChoice);
|
|
425
480
|
} else if (existsSync(kaizenDir)) {
|
|
426
481
|
step(`${basename(process.cwd())}/.kaizen already set up`);
|
|
427
482
|
}
|
|
428
483
|
|
|
429
|
-
function initProject() {
|
|
484
|
+
function initProject(preset?: PresetName | null) {
|
|
430
485
|
mkdirSync(kaizenDir, { recursive: true });
|
|
431
486
|
for (const f of readdirSync(join(repo, "skills/kaizen")).filter((f) => f.startsWith("spec"))) {
|
|
432
487
|
copyFileSync(join(repo, "skills/kaizen", f), join(kaizenDir, f));
|
|
433
488
|
}
|
|
434
|
-
|
|
489
|
+
const defPath = join(repo, "skills/kaizen/config.default.yml");
|
|
490
|
+
const def = readFileSync(defPath, "utf8");
|
|
491
|
+
let chosen: PresetName = preset ?? "medium";
|
|
492
|
+
if (!preset && existsSync(globalConfig)) {
|
|
493
|
+
const detected = detectPreset(readFileSync(globalConfig, "utf8"), def);
|
|
494
|
+
if (detected !== "custom") chosen = detected;
|
|
495
|
+
}
|
|
496
|
+
const configContent = applyPreset(def, chosen, def);
|
|
497
|
+
writeFileSync(join(kaizenDir, "config.yml"), configContent);
|
|
435
498
|
|
|
436
499
|
// Run state is local; the workflow itself is shared, so those files stay tracked.
|
|
437
500
|
// Nothing to ignore where there is no git, so a plain folder gets no .gitignore.
|
package/cli/settings.ts
CHANGED
|
@@ -6,7 +6,94 @@ import { homedir } from "node:os";
|
|
|
6
6
|
|
|
7
7
|
type Setting = { key: string; values: string[]; help: string };
|
|
8
8
|
|
|
9
|
+
export type PresetName = "low" | "medium" | "ultra";
|
|
10
|
+
|
|
11
|
+
export const PRESETS: Record<PresetName, {
|
|
12
|
+
label: string;
|
|
13
|
+
hint: string;
|
|
14
|
+
settings: Record<string, string>;
|
|
15
|
+
}> = {
|
|
16
|
+
low: {
|
|
17
|
+
label: "Low",
|
|
18
|
+
hint: "inline & manual — lite runner, inline builder, manual approvals, no auto-fix",
|
|
19
|
+
settings: {
|
|
20
|
+
mode: "approve",
|
|
21
|
+
runner: "lite",
|
|
22
|
+
"build.executor": "inline",
|
|
23
|
+
"approvals.plan": "true",
|
|
24
|
+
"approvals.review": "true",
|
|
25
|
+
"approvals.each_file": "false",
|
|
26
|
+
"auto_fix.enabled": "false",
|
|
27
|
+
"auto_fix.min_severity": "high",
|
|
28
|
+
"auto_fix.max_iterations": "1",
|
|
29
|
+
"git.auto_commit": "false",
|
|
30
|
+
"git.branch_before_implement": "false",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
medium: {
|
|
34
|
+
label: "Medium",
|
|
35
|
+
hint: "balanced (recommended) — full runner, subagents, plan approval, auto-fix high/critical",
|
|
36
|
+
settings: {
|
|
37
|
+
mode: "approve",
|
|
38
|
+
runner: "full",
|
|
39
|
+
"build.executor": "subagent",
|
|
40
|
+
"approvals.plan": "true",
|
|
41
|
+
"approvals.review": "false",
|
|
42
|
+
"approvals.each_file": "false",
|
|
43
|
+
"auto_fix.enabled": "true",
|
|
44
|
+
"auto_fix.min_severity": "high",
|
|
45
|
+
"auto_fix.max_iterations": "2",
|
|
46
|
+
"git.auto_commit": "false",
|
|
47
|
+
"git.branch_before_implement": "true",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
ultra: {
|
|
51
|
+
label: "Ultra",
|
|
52
|
+
hint: "autonomous — full runner, subagents, auto mode, auto-fix all findings (up to 4 rounds)",
|
|
53
|
+
settings: {
|
|
54
|
+
mode: "auto",
|
|
55
|
+
runner: "full",
|
|
56
|
+
"build.executor": "subagent",
|
|
57
|
+
"approvals.plan": "false",
|
|
58
|
+
"approvals.review": "false",
|
|
59
|
+
"approvals.each_file": "false",
|
|
60
|
+
"auto_fix.enabled": "true",
|
|
61
|
+
"auto_fix.min_severity": "low",
|
|
62
|
+
"auto_fix.max_iterations": "4",
|
|
63
|
+
"git.auto_commit": "true",
|
|
64
|
+
"git.branch_before_implement": "true",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export function detectPreset(text: string, defaults?: string): PresetName | "custom" {
|
|
70
|
+
for (const name of ["low", "medium", "ultra"] as const) {
|
|
71
|
+
const p = PRESETS[name];
|
|
72
|
+
let match = true;
|
|
73
|
+
for (const [k, expected] of Object.entries(p.settings)) {
|
|
74
|
+
const actual = read(text, k) ?? (defaults ? read(defaults, k) : null);
|
|
75
|
+
if (actual !== expected) {
|
|
76
|
+
match = false;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (match) return name;
|
|
81
|
+
}
|
|
82
|
+
return "custom";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function applyPreset(text: string, preset: PresetName, defaults: string): string {
|
|
86
|
+
let updated = text;
|
|
87
|
+
const p = PRESETS[preset];
|
|
88
|
+
for (const [k, v] of Object.entries(p.settings)) {
|
|
89
|
+
updated = write(updated, k, v, defaults);
|
|
90
|
+
}
|
|
91
|
+
updated = write(updated, "preset", preset, defaults);
|
|
92
|
+
return updated;
|
|
93
|
+
}
|
|
94
|
+
|
|
9
95
|
const SETTINGS: Setting[] = [
|
|
96
|
+
{ key: "preset", values: ["low", "medium", "ultra", "custom"], help: "Quick preset — low: inline & manual, medium: balanced, ultra: autonomous subagents" },
|
|
10
97
|
{ key: "mode", values: ["approve", "auto", "plan-only", "review-only"], help: "Where a run stops" },
|
|
11
98
|
{ key: "runner", values: ["full", "lite"], help: "full: every stage its own cold agent. lite: this session runs them all, cheaper, reviewer has seen the work" },
|
|
12
99
|
{ key: "build.executor", values: ["subagent", "inline", "ask"], help: "Who carries out the approved plan" },
|
|
@@ -42,10 +129,15 @@ export async function settings(repoRoot: string, standalone = true) {
|
|
|
42
129
|
const { stdin, stdout } = process;
|
|
43
130
|
if (!stdin.isTTY) { console.log(`Settings live in ${file}`); return; }
|
|
44
131
|
|
|
132
|
+
const defaults = readFileSync(join(repoRoot, "skills/kaizen/config.default.yml"), "utf8");
|
|
45
133
|
let active = 0, saved = "";
|
|
46
134
|
const draw = () => {
|
|
47
135
|
const text = readFileSync(file, "utf8");
|
|
48
|
-
const
|
|
136
|
+
const currentPreset = detectPreset(text, defaults);
|
|
137
|
+
const rows = SETTINGS.map((s) => ({
|
|
138
|
+
s,
|
|
139
|
+
value: s.key === "preset" ? currentPreset : (read(text, s.key) ?? c.dim("(default)")),
|
|
140
|
+
}));
|
|
49
141
|
const width = Math.max(...SETTINGS.map((s) => s.key.length)) + 4;
|
|
50
142
|
|
|
51
143
|
stdout.write("\x1b[H\x1b[2J"); // home, clear
|
|
@@ -84,16 +176,28 @@ export async function settings(repoRoot: string, standalone = true) {
|
|
|
84
176
|
const step = rest.startsWith("\x1b[D") ? -1 : 1;
|
|
85
177
|
const s = SETTINGS[active]!;
|
|
86
178
|
const text = readFileSync(file, "utf8");
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
179
|
+
if (s.key === "preset") {
|
|
180
|
+
const current = detectPreset(text, defaults);
|
|
181
|
+
const cycle: PresetName[] = ["low", "medium", "ultra"];
|
|
182
|
+
const at = cycle.indexOf(current as PresetName);
|
|
183
|
+
const next = cycle[((at < 0 ? 0 : at) + step + cycle.length) % cycle.length]!;
|
|
184
|
+
const updated = applyPreset(text, next, defaults);
|
|
185
|
+
writeFileSync(file, updated);
|
|
186
|
+
saved = c.green(`applied preset: ${next}`);
|
|
187
|
+
} else {
|
|
188
|
+
const now = read(text, s.key) ?? s.values[0]!;
|
|
189
|
+
const at = s.values.indexOf(now);
|
|
190
|
+
const next = s.values[((at < 0 ? 0 : at) + step + s.values.length) % s.values.length]!;
|
|
191
|
+
let updated = write(text, s.key, next, defaults);
|
|
192
|
+
const detected = detectPreset(updated, defaults);
|
|
193
|
+
updated = write(updated, "preset", detected, defaults);
|
|
194
|
+
writeFileSync(file, updated);
|
|
195
|
+
// Only claim a save that happened. Reporting one that did not is worse
|
|
196
|
+
// than failing loudly: the setting reads back unchanged and nobody knows why.
|
|
197
|
+
saved = read(updated, s.key) === next
|
|
198
|
+
? c.green(`saved ${s.key} = ${next || '""'} (preset: ${detected})`)
|
|
199
|
+
: `\x1b[33mcould not write ${s.key}\x1b[0m`;
|
|
200
|
+
}
|
|
97
201
|
if (!rest.startsWith("\r")) i += 2;
|
|
98
202
|
} else if (rest.startsWith("k")) active = (active - 1 + SETTINGS.length) % SETTINGS.length;
|
|
99
203
|
else if (rest.startsWith("j")) active = (active + 1) % SETTINGS.length;
|
package/package.json
CHANGED
package/skills/kaizen/SKILL.md
CHANGED
|
@@ -81,6 +81,7 @@ whichever the user picks.
|
|
|
81
81
|
|
|
82
82
|
| Setting | Values | What it decides |
|
|
83
83
|
|---|---|---|
|
|
84
|
+
| `preset` | `low`, `medium`, `ultra` | Quick preset: low (inline/manual), medium (balanced), ultra (autonomous) |
|
|
84
85
|
| `mode` | `approve`, `auto`, `plan-only`, `review-only` | Where a run stops |
|
|
85
86
|
| `runner` | `full`, `lite` | Whether each stage is its own cold agent, or this session runs them all |
|
|
86
87
|
| `build.executor` | `subagent`, `inline`, `ask` | Who carries out the approved plan |
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Kaizen defaults. Copy to .kaizen/config.yml in a repository and override only the
|
|
2
2
|
# keys you care about; anything absent falls back to this file.
|
|
3
3
|
|
|
4
|
+
# Quick preset: low | medium | ultra | custom
|
|
5
|
+
# Selecting low, medium, or ultra applies its bundled defaults for runner, executor,
|
|
6
|
+
# approvals, and auto-fix. Modifying individual keys sets this to custom.
|
|
7
|
+
preset: medium
|
|
8
|
+
|
|
4
9
|
# plan-only | approve | auto | review-only
|
|
5
10
|
mode: approve
|
|
6
11
|
|
|
@@ -75,6 +75,7 @@ Each iteration is written to `runs/<id>/05-iterations/`.
|
|
|
75
75
|
|
|
76
76
|
| Key | Default | Meaning |
|
|
77
77
|
|---|---|---|
|
|
78
|
+
| `preset` | `medium` | Quick preset (`low`, `medium`, `ultra`, `custom`) |
|
|
78
79
|
| `mode` | `approve` | Default run mode |
|
|
79
80
|
| `runner` | `full` | `full`: each stage a cold subagent. `lite`: this session runs every stage |
|
|
80
81
|
| `approvals.plan` | `true` | Stop after the plan |
|