kaizen-agent 0.7.2 → 0.7.3
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 +75 -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`,
|
|
@@ -392,6 +409,43 @@ function installLauncher() {
|
|
|
392
409
|
|
|
393
410
|
const inProject = process.cwd() !== home;
|
|
394
411
|
const kaizenDir = join(process.cwd(), ".kaizen");
|
|
412
|
+
const globalKaizen = join(home, ".kaizen");
|
|
413
|
+
const globalConfig = join(globalKaizen, "config.yml");
|
|
414
|
+
const hasConfig = (args.has("onboard") || args.has("--onboard"))
|
|
415
|
+
? false
|
|
416
|
+
: (inProject ? existsSync(localConfig) : existsSync(globalConfig));
|
|
417
|
+
|
|
418
|
+
let presetChoice: PresetName | null = presetArg;
|
|
419
|
+
if (!hasConfig && !presetChoice && interactive) {
|
|
420
|
+
presetChoice = await select("Choose workflow preset", [
|
|
421
|
+
{
|
|
422
|
+
label: "Medium (Recommended)",
|
|
423
|
+
hint: "balanced — subagents, plan approval, auto-fix high/critical",
|
|
424
|
+
value: "medium",
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
label: "Low",
|
|
428
|
+
hint: "inline & manual — lite runner, inline builder, manual approvals, no auto-fix",
|
|
429
|
+
value: "low",
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
label: "Ultra",
|
|
433
|
+
hint: "autonomous — subagents, auto mode, auto-fix all findings (up to 4 rounds)",
|
|
434
|
+
value: "ultra",
|
|
435
|
+
},
|
|
436
|
+
]);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if ((!existsSync(globalConfig) && presetChoice) || (presetArg && !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 target = presetChoice ?? "medium";
|
|
445
|
+
const conf = applyPreset(base, target, def);
|
|
446
|
+
writeFileSync(globalConfig, conf);
|
|
447
|
+
step(`configured ${c.bold(target)} preset in ${tilde(globalConfig)}`);
|
|
448
|
+
}
|
|
395
449
|
|
|
396
450
|
// A .kaizen/ in a parent already owns this folder's state, and setting up a child
|
|
397
451
|
// would shadow it, hiding the parent's runs and leaving the child out of the root
|
|
@@ -413,25 +467,35 @@ function kaizenAbove() {
|
|
|
413
467
|
}
|
|
414
468
|
|
|
415
469
|
if (inProject && !kaizenAbove()) {
|
|
416
|
-
const now =
|
|
417
|
-
?
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
470
|
+
const now = root === process.cwd()
|
|
471
|
+
? true
|
|
472
|
+
: interactive
|
|
473
|
+
? await select(`Set up ${basename(process.cwd())}/ for kaizen now`, [
|
|
474
|
+
// "Not now" leads: the offer now appears in any folder outside home, so the
|
|
475
|
+
// safe answer is the one under the cursor.
|
|
476
|
+
{ label: "Not now", hint: "the first /kaizen run will do it", value: false },
|
|
477
|
+
{ label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
|
|
478
|
+
])
|
|
479
|
+
: false;
|
|
480
|
+
if (now) initProject(presetChoice);
|
|
425
481
|
} else if (existsSync(kaizenDir)) {
|
|
426
482
|
step(`${basename(process.cwd())}/.kaizen already set up`);
|
|
427
483
|
}
|
|
428
484
|
|
|
429
|
-
function initProject() {
|
|
485
|
+
function initProject(preset?: PresetName | null) {
|
|
430
486
|
mkdirSync(kaizenDir, { recursive: true });
|
|
431
487
|
for (const f of readdirSync(join(repo, "skills/kaizen")).filter((f) => f.startsWith("spec"))) {
|
|
432
488
|
copyFileSync(join(repo, "skills/kaizen", f), join(kaizenDir, f));
|
|
433
489
|
}
|
|
434
|
-
|
|
490
|
+
const defPath = join(repo, "skills/kaizen/config.default.yml");
|
|
491
|
+
const def = readFileSync(defPath, "utf8");
|
|
492
|
+
let chosen: PresetName = preset ?? "medium";
|
|
493
|
+
if (!preset && existsSync(globalConfig)) {
|
|
494
|
+
const detected = detectPreset(readFileSync(globalConfig, "utf8"), def);
|
|
495
|
+
if (detected !== "custom") chosen = detected;
|
|
496
|
+
}
|
|
497
|
+
const configContent = applyPreset(def, chosen, def);
|
|
498
|
+
writeFileSync(join(kaizenDir, "config.yml"), configContent);
|
|
435
499
|
|
|
436
500
|
// Run state is local; the workflow itself is shared, so those files stay tracked.
|
|
437
501
|
// 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 |
|