kaizen-agent 1.3.0 → 1.3.2
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 +4 -3
- package/cli/dashboard.ts +6 -2
- package/cli/install.ts +22 -18
- package/cli/settings.ts +5 -2
- package/package.json +1 -1
- package/skills/kaizen/README.md +5 -3
- package/skills/kaizen/SKILL.md +9 -6
- package/skills/kaizen/adapters.md +3 -3
- package/skills/kaizen/config.default.yml +4 -2
package/README.md
CHANGED
|
@@ -463,7 +463,6 @@ Everything a run knows lives in files next to the work, not in a chat window:
|
|
|
463
463
|
|
|
464
464
|
```
|
|
465
465
|
.kaizen/
|
|
466
|
-
config.yml # how much it asks you, what it fixes on its own
|
|
467
466
|
memory.md # what past reviews learned about this project
|
|
468
467
|
runs/2026-09-07-onboarding-email/
|
|
469
468
|
00-request.md # what you asked, word for word
|
|
@@ -480,7 +479,7 @@ in one can be finished in another. See [adapters.md](https://github.com/hfadhlul
|
|
|
480
479
|
|
|
481
480
|
## Settings
|
|
482
481
|
|
|
483
|
-
|
|
482
|
+
`~/.kaizen/config.yml` — one file, every project. The three worth knowing:
|
|
484
483
|
|
|
485
484
|
| Setting | Default | Meaning |
|
|
486
485
|
|---|---|---|
|
|
@@ -499,7 +498,7 @@ opens a full-screen browser over the whole file — arrows to move and change, e
|
|
|
499
498
|
change written as you make it, esc to close:
|
|
500
499
|
|
|
501
500
|
```
|
|
502
|
-
kaizen settings
|
|
501
|
+
kaizen settings ~/.kaizen/config.yml
|
|
503
502
|
|
|
504
503
|
› preset medium
|
|
505
504
|
mode approve
|
|
@@ -517,6 +516,8 @@ change written as you make it, esc to close:
|
|
|
517
516
|
↑↓ move · ←→ change · esc close saved preset = medium
|
|
518
517
|
```
|
|
519
518
|
|
|
519
|
+
One project can differ: put a `.kaizen/config.yml` in it with just the keys to
|
|
520
|
+
override, and it wins there while everything else follows the global file.
|
|
520
521
|
It edits each line in place, so the comment above every key survives. `/kaizen-config`
|
|
521
522
|
does the same thing from inside your agent if you would rather not leave it. Everything is also
|
|
522
523
|
in [`config.default.yml`](https://github.com/hfadhlullah/kaizen/blob/main/skills/kaizen/config.default.yml),
|
package/cli/dashboard.ts
CHANGED
|
@@ -140,8 +140,12 @@ function readMouse(rest: string): { ev: MouseEv; len: number } | null {
|
|
|
140
140
|
const WHEEL_UP = 64, WHEEL_DOWN = 65;
|
|
141
141
|
const isClick = (e: MouseEv) => e.press && e.button === 0;
|
|
142
142
|
|
|
143
|
+
// Re-sent even when this module thinks it is already armed: settings runs as an
|
|
144
|
+
// action, tracks arming with its own flag, and turns reporting off in the terminal
|
|
145
|
+
// on the way out. Enabling twice costs nothing; trusting the stale flag costs the
|
|
146
|
+
// mouse for the rest of the session.
|
|
143
147
|
function mouseOn() {
|
|
144
|
-
if (!mouseWanted
|
|
148
|
+
if (!mouseWanted) return;
|
|
145
149
|
process.stdout.write("\x1b[?1000h\x1b[?1006h");
|
|
146
150
|
mouseArmed = true;
|
|
147
151
|
}
|
|
@@ -208,7 +212,7 @@ export async function dashboard(
|
|
|
208
212
|
{ key: "backlog", label: "Backlog", hint: "what runs noticed and did not do" },
|
|
209
213
|
] : []),
|
|
210
214
|
{ key: "settings", label: "Settings", hint: "modes, approvals, who builds" },
|
|
211
|
-
...(state && !existsSync(join(state, "
|
|
215
|
+
...(state && !existsSync(join(state, "spec.md"))
|
|
212
216
|
? [{ key: "init", label: "Set up this project", hint: "write .kaizen/ here" }] : []),
|
|
213
217
|
...(!state ? [{ key: "init", label: "Set up this project", hint: "write .kaizen/ here" }] : []),
|
|
214
218
|
{ key: "upgrade", label: "Upgrade", hint: "pull, relink, clear the installer cache" },
|
package/cli/install.ts
CHANGED
|
@@ -271,9 +271,11 @@ const root = await chooseRoot();
|
|
|
271
271
|
const presetChoice = await choosePreset();
|
|
272
272
|
const targets = found(root);
|
|
273
273
|
|
|
274
|
-
|
|
274
|
+
// null means "leave the config alone": an upgrade or a --yes run never asked, and
|
|
275
|
+
// answering "medium" for the user overwrote whatever preset they had chosen.
|
|
276
|
+
async function choosePreset(): Promise<PresetName | null> {
|
|
275
277
|
if (presetArg) return presetArg;
|
|
276
|
-
if (!interactive) return
|
|
278
|
+
if (!interactive) return null;
|
|
277
279
|
|
|
278
280
|
return select("Choose workflow preset", [
|
|
279
281
|
{
|
|
@@ -467,14 +469,22 @@ const kaizenDir = join(process.cwd(), ".kaizen");
|
|
|
467
469
|
const globalKaizen = join(home, ".kaizen");
|
|
468
470
|
const globalConfig = join(globalKaizen, "config.yml");
|
|
469
471
|
|
|
470
|
-
|
|
472
|
+
// Always global: a project keeps no config of its own, so ~/.kaizen/config.yml is
|
|
473
|
+
// what every project follows.
|
|
474
|
+
{
|
|
471
475
|
mkdirSync(globalKaizen, { recursive: true });
|
|
472
476
|
const defPath = join(repo, "skills/kaizen/config.default.yml");
|
|
473
477
|
const def = readFileSync(defPath, "utf8");
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
+
const existing = existsSync(globalConfig) ? readFileSync(globalConfig, "utf8") : null;
|
|
479
|
+
if (presetChoice) {
|
|
480
|
+
writeFileSync(globalConfig, applyPreset(existing ?? def, presetChoice, def));
|
|
481
|
+
step(`configured ${c.bold(presetChoice)} preset in ${tilde(globalConfig)}`);
|
|
482
|
+
} else if (!existing) {
|
|
483
|
+
writeFileSync(globalConfig, def);
|
|
484
|
+
step(`wrote ${tilde(globalConfig)}`);
|
|
485
|
+
} else {
|
|
486
|
+
step(`kept your settings in ${tilde(globalConfig)} ${c.dim(`(${detectPreset(existing, def)})`)}`);
|
|
487
|
+
}
|
|
478
488
|
}
|
|
479
489
|
|
|
480
490
|
// A .kaizen/ in a parent already owns this folder's state, and setting up a child
|
|
@@ -507,25 +517,19 @@ if (inProject && !kaizenAbove()) {
|
|
|
507
517
|
{ label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
|
|
508
518
|
])
|
|
509
519
|
: false;
|
|
510
|
-
if (now) initProject(
|
|
520
|
+
if (now) initProject();
|
|
511
521
|
} else if (existsSync(kaizenDir)) {
|
|
512
522
|
step(`${basename(process.cwd())}/.kaizen already set up`);
|
|
513
523
|
}
|
|
514
524
|
|
|
515
|
-
function initProject(
|
|
525
|
+
function initProject() {
|
|
516
526
|
mkdirSync(kaizenDir, { recursive: true });
|
|
517
527
|
for (const f of readdirSync(join(repo, "skills/kaizen")).filter((f) => f.startsWith("spec"))) {
|
|
518
528
|
copyFileSync(join(repo, "skills/kaizen", f), join(kaizenDir, f));
|
|
519
529
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
if (!preset && existsSync(globalConfig)) {
|
|
524
|
-
const detected = detectPreset(readFileSync(globalConfig, "utf8"), def);
|
|
525
|
-
if (detected !== "custom") chosen = detected;
|
|
526
|
-
}
|
|
527
|
-
const configContent = applyPreset(def, chosen, def);
|
|
528
|
-
writeFileSync(join(kaizenDir, "config.yml"), configContent);
|
|
530
|
+
// No config.yml here on purpose: a project without one follows
|
|
531
|
+
// ~/.kaizen/config.yml, so a setting changed once applies everywhere. Write one
|
|
532
|
+
// only to make this project deliberately different.
|
|
529
533
|
|
|
530
534
|
// Run state is local; the workflow itself is shared, so those files stay tracked.
|
|
531
535
|
// Nothing to ignore where there is no git, so a plain folder gets no .gitignore.
|
package/cli/settings.ts
CHANGED
|
@@ -256,11 +256,14 @@ export async function settings(repoRoot: string, standalone = true) {
|
|
|
256
256
|
if (standalone) console.log(` ${c.green("+")} settings saved to ${tilde(file)}\n`);
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
// The nearest .kaizen wins, exactly as the workflow resolves it.
|
|
259
|
+
// The nearest .kaizen/config.yml wins, exactly as the workflow resolves it. A
|
|
260
|
+
// project that has not written one of its own is edited globally, so one setting
|
|
261
|
+
// changed in ~/.kaizen/config.yml reaches every project.
|
|
260
262
|
function locate() {
|
|
261
263
|
let dir = process.cwd();
|
|
262
264
|
for (;;) {
|
|
263
|
-
|
|
265
|
+
const conf = join(dir, ".kaizen", "config.yml");
|
|
266
|
+
if (existsSync(conf)) return conf;
|
|
264
267
|
if (existsSync(join(dir, ".git"))) break;
|
|
265
268
|
const up = dirname(dir);
|
|
266
269
|
if (up === dir) break;
|
package/package.json
CHANGED
package/skills/kaizen/README.md
CHANGED
|
@@ -189,9 +189,11 @@ software or writing?"
|
|
|
189
189
|
|
|
190
190
|
## Configuration
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
Your settings live in `~/.kaizen/config.yml` and apply to every project — `/kaizen
|
|
193
|
+
config` edits that file. To make one project different, copy
|
|
194
|
+
[`config.default.yml`](config.default.yml) to `.kaizen/config.yml` there and override
|
|
195
|
+
only the keys you care about; anything absent falls back to the global file, then to
|
|
196
|
+
the defaults.
|
|
195
197
|
|
|
196
198
|
| Key | Default | Change it when |
|
|
197
199
|
|---|---|---|
|
package/skills/kaizen/SKILL.md
CHANGED
|
@@ -60,10 +60,12 @@ If the user typed `/kaizen` with no argument and a run is in progress, treat it
|
|
|
60
60
|
1. Locate the state directory: `.kaizen/` in the project folder's root, else
|
|
61
61
|
`~/.kaizen/` keyed by working directory. If neither exists and the user is starting
|
|
62
62
|
work, run `/kaizen init` first: it creates `.kaizen/` with a copy of the `spec*.md`
|
|
63
|
-
files
|
|
63
|
+
files and — where the folder is a git repository — the gitignore entry
|
|
64
64
|
(see [`adapters.md`](adapters.md)).
|
|
65
|
-
2. Read
|
|
66
|
-
|
|
65
|
+
2. Read the config in this order, each file filling in the keys the one before it
|
|
66
|
+
does not set: `.kaizen/config.yml`, then `~/.kaizen/config.yml`, then
|
|
67
|
+
`config.default.yml` in this skill. A project usually has no `config.yml` of its
|
|
68
|
+
own, so the global one is what settings changes reach. `runner` decides whether this run dispatches subagents at
|
|
67
69
|
all; read it before the first stage, not when you reach one.
|
|
68
70
|
3. Read `.kaizen/runs/<current>/state.json` if a run is active. Never assume the
|
|
69
71
|
stage from conversation memory — the run may have been advanced by another tool
|
|
@@ -73,11 +75,12 @@ If the user typed `/kaizen` with no argument and a run is in progress, treat it
|
|
|
73
75
|
|
|
74
76
|
## Settings
|
|
75
77
|
|
|
76
|
-
`/kaizen config` reads `.kaizen/config.yml`,
|
|
77
|
-
|
|
78
|
+
`/kaizen config` reads the same chain — `.kaizen/config.yml`, then `~/.kaizen/config.yml`,
|
|
79
|
+
then `config.default.yml` — and prints the current value of each setting below with a
|
|
78
80
|
one-line meaning. Then it offers the settings as choices — the tool's structured
|
|
79
81
|
question mechanism, one option per legal value, never free text — and writes back
|
|
80
|
-
whichever the user picks.
|
|
82
|
+
whichever the user picks. Write to whichever file in the chain already exists,
|
|
83
|
+
nearest first, so a change lands globally unless this project keeps its own config.
|
|
81
84
|
|
|
82
85
|
| Setting | Values | What it decides |
|
|
83
86
|
|---|---|---|
|
|
@@ -24,7 +24,7 @@ Codex reads `AGENTS.md` from the repository root. Append:
|
|
|
24
24
|
|
|
25
25
|
Non-trivial work in this repo follows the staged workflow in
|
|
26
26
|
`.kaizen/spec.md`: plan, human approval, implement, independent review, bounded
|
|
27
|
-
fix loop. Read that file before starting, and read `.kaizen/config.yml` for the
|
|
27
|
+
fix loop. Read that file before starting, and read the config chain (`.kaizen/config.yml`, `~/.kaizen/config.yml`, `config.default.yml`) for the
|
|
28
28
|
mode and approval settings.
|
|
29
29
|
|
|
30
30
|
Run state lives in `.kaizen/runs/<id>/`. Always read `state.json` first and
|
|
@@ -38,7 +38,7 @@ from its stage file, and write its artifact before moving on. When reviewing, ju
|
|
|
38
38
|
diff on its own terms rather than defending the reasoning you used while writing it.
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
Copy `spec*.md`
|
|
41
|
+
Copy `spec*.md` into `.kaizen/` so the reference resolves
|
|
42
42
|
without this skill installed.
|
|
43
43
|
|
|
44
44
|
## Antigravity
|
|
@@ -64,7 +64,7 @@ completes. A stale `state.json` is the one way this breaks.
|
|
|
64
64
|
|
|
65
65
|
## Installing the adapter files
|
|
66
66
|
|
|
67
|
-
`/kaizen init` writes `.kaizen/` with the `spec*.md` files
|
|
67
|
+
`/kaizen init` writes `.kaizen/` with the `spec*.md` files into the
|
|
68
68
|
project folder, plus the gitignore entry when that folder is a git repository.
|
|
69
69
|
`/kaizen install` additionally offers to append the `AGENTS.md` block above.
|
|
70
70
|
`.kaizen/spec*.md` and `.kaizen/config.yml` should be committed even though run state
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
# Kaizen defaults.
|
|
2
|
-
#
|
|
1
|
+
# Kaizen defaults. Settings live in ~/.kaizen/config.yml and apply to every project.
|
|
2
|
+
# To make one project different, copy this to .kaizen/config.yml there and override
|
|
3
|
+
# only the keys you care about; anything absent falls back to the global file, then
|
|
4
|
+
# to this one.
|
|
3
5
|
|
|
4
6
|
# Quick preset: low | medium | ultra | custom
|
|
5
7
|
# Selecting low, medium, or ultra applies its bundled defaults for runner, executor,
|