kaizen-agent 1.3.0 → 1.3.1

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 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
- `.kaizen/config.yml`, written when the project is set up. The three worth knowing:
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 ~/Projects/app/.kaizen/config.yml
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
@@ -208,7 +208,7 @@ export async function dashboard(
208
208
  { key: "backlog", label: "Backlog", hint: "what runs noticed and did not do" },
209
209
  ] : []),
210
210
  { key: "settings", label: "Settings", hint: "modes, approvals, who builds" },
211
- ...(state && !existsSync(join(state, "config.yml"))
211
+ ...(state && !existsSync(join(state, "spec.md"))
212
212
  ? [{ key: "init", label: "Set up this project", hint: "write .kaizen/ here" }] : []),
213
213
  ...(!state ? [{ key: "init", label: "Set up this project", hint: "write .kaizen/ here" }] : []),
214
214
  { key: "upgrade", label: "Upgrade", hint: "pull, relink, clear the installer cache" },
package/cli/install.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from "node:fs";
7
7
  import { join, dirname, basename } from "node:path";
8
8
  import { homedir, tmpdir } from "node:os";
9
- import { applyPreset, detectPreset, PRESETS, type PresetName } from "./settings.ts";
9
+ import { applyPreset, PRESETS, type PresetName } from "./settings.ts";
10
10
 
11
11
  const home = homedir();
12
12
  const REPO_URL = "https://github.com/hfadhlullah/kaizen.git";
@@ -467,7 +467,9 @@ const kaizenDir = join(process.cwd(), ".kaizen");
467
467
  const globalKaizen = join(home, ".kaizen");
468
468
  const globalConfig = join(globalKaizen, "config.yml");
469
469
 
470
- if (!args.has("--project")) {
470
+ // Always global: a project keeps no config of its own, so ~/.kaizen/config.yml is
471
+ // what every project follows.
472
+ {
471
473
  mkdirSync(globalKaizen, { recursive: true });
472
474
  const defPath = join(repo, "skills/kaizen/config.default.yml");
473
475
  const def = readFileSync(defPath, "utf8");
@@ -507,25 +509,19 @@ if (inProject && !kaizenAbove()) {
507
509
  { label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
508
510
  ])
509
511
  : false;
510
- if (now) initProject(presetChoice);
512
+ if (now) initProject();
511
513
  } else if (existsSync(kaizenDir)) {
512
514
  step(`${basename(process.cwd())}/.kaizen already set up`);
513
515
  }
514
516
 
515
- function initProject(preset?: PresetName | null) {
517
+ function initProject() {
516
518
  mkdirSync(kaizenDir, { recursive: true });
517
519
  for (const f of readdirSync(join(repo, "skills/kaizen")).filter((f) => f.startsWith("spec"))) {
518
520
  copyFileSync(join(repo, "skills/kaizen", f), join(kaizenDir, f));
519
521
  }
520
- const defPath = join(repo, "skills/kaizen/config.default.yml");
521
- const def = readFileSync(defPath, "utf8");
522
- let chosen: PresetName = preset ?? "medium";
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);
522
+ // No config.yml here on purpose: a project without one follows
523
+ // ~/.kaizen/config.yml, so a setting changed once applies everywhere. Write one
524
+ // only to make this project deliberately different.
529
525
 
530
526
  // Run state is local; the workflow itself is shared, so those files stay tracked.
531
527
  // 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
- if (existsSync(join(dir, ".kaizen"))) return join(dir, ".kaizen", "config.yml");
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaizen-agent",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Staged workflow for AI agents — code, writing, research, operations: plan, human approval, build, independent review, bounded fix loop.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -189,9 +189,11 @@ software or writing?"
189
189
 
190
190
  ## Configuration
191
191
 
192
- Defaults live in [`config.default.yml`](config.default.yml). Copy it to
193
- `.kaizen/config.yml` in a repository and override only the keys you care about;
194
- anything absent falls back to the defaults.
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
  |---|---|---|
@@ -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, a config, and — where the folder is a git repository — the gitignore entry
63
+ files and — where the folder is a git repository — the gitignore entry
64
64
  (see [`adapters.md`](adapters.md)).
65
- 2. Read `.kaizen/config.yml`, falling back to `config.default.yml` in this skill for
66
- any key it does not set. `runner` decides whether this run dispatches subagents at
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`, falling back to `config.default.yml` for
77
- anything it does not set, and prints the current value of each setting below with a
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` and `config.yml` into `.kaizen/` so the reference resolves
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 and `config.yml` into the
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. Copy to .kaizen/config.yml in a repository and override only the
2
- # keys you care about; anything absent falls back to this file.
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,