kaizen-agent 0.6.0 → 0.7.0

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/cli/install.ts CHANGED
@@ -287,10 +287,10 @@ async function chooseRoot() {
287
287
  if (args.has("--project")) return process.cwd();
288
288
  if (args.has("--global") || !interactive) return home;
289
289
  // A project install only means something in a project. Standing in the home
290
- // directory it is the global install under another name, and outside a
291
- // repository there is nothing for it to belong to.
290
+ // directory it is the global install under another name; any other folder is
291
+ // a project worth installing into, git repository or not.
292
292
  const cwd = process.cwd();
293
- if (cwd === home || !existsSync(join(cwd, ".git"))) return home;
293
+ if (cwd === home) return home;
294
294
 
295
295
  const names = (r: string) => found(r).map((a) => a.name).join(", ");
296
296
  return select("Install kaizen for", [
@@ -390,22 +390,43 @@ function installLauncher() {
390
390
  }
391
391
  }
392
392
 
393
- const inGitRepo = existsSync(join(process.cwd(), ".git"));
393
+ const inProject = process.cwd() !== home;
394
394
  const kaizenDir = join(process.cwd(), ".kaizen");
395
395
 
396
- if (inGitRepo && !existsSync(kaizenDir)) {
396
+ // A .kaizen/ in a parent already owns this folder's state, and setting up a child
397
+ // would shadow it, hiding the parent's runs and leaving the child out of the root
398
+ // .gitignore. Deliberately not shared with cli/dashboard.ts locate(): that one
399
+ // resolves which state directory to read and so falls back to a global ~/.kaizen,
400
+ // while this one decides whether a folder is already owned and must stop *before*
401
+ // $HOME — a global ~/.kaizen would otherwise suppress the setup offer for every
402
+ // non-repo folder under the home directory. Do not re-sync the two walks.
403
+ function kaizenAbove() {
404
+ let dir = process.cwd();
405
+ for (;;) {
406
+ if (dir === home) return false;
407
+ if (existsSync(join(dir, ".kaizen"))) return true;
408
+ if (existsSync(join(dir, ".git"))) return false;
409
+ const up = dirname(dir);
410
+ if (up === dir) return false;
411
+ dir = up;
412
+ }
413
+ }
414
+
415
+ if (inProject && !kaizenAbove()) {
397
416
  const now = interactive
398
417
  ? await select(`Set up ${basename(process.cwd())}/ for kaizen now`, [
399
- { label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
418
+ // "Not now" leads: the offer now appears in any folder outside home, so the
419
+ // safe answer is the one under the cursor.
400
420
  { label: "Not now", hint: "the first /kaizen run will do it", value: false },
421
+ { label: "Yes", hint: "writes .kaizen/ and a CLAUDE.md line so it runs by default", value: true },
401
422
  ])
402
423
  : false;
403
- if (now) initRepo();
424
+ if (now) initProject();
404
425
  } else if (existsSync(kaizenDir)) {
405
426
  step(`${basename(process.cwd())}/.kaizen already set up`);
406
427
  }
407
428
 
408
- function initRepo() {
429
+ function initProject() {
409
430
  mkdirSync(kaizenDir, { recursive: true });
410
431
  for (const f of readdirSync(join(repo, "skills/kaizen")).filter((f) => f.startsWith("spec"))) {
411
432
  copyFileSync(join(repo, "skills/kaizen", f), join(kaizenDir, f));
@@ -413,13 +434,18 @@ function initRepo() {
413
434
  copyFileSync(join(repo, "skills/kaizen/config.default.yml"), join(kaizenDir, "config.yml"));
414
435
 
415
436
  // Run state is local; the workflow itself is shared, so those files stay tracked.
416
- const rules = ".kaizen/*\n!.kaizen/spec*.md\n!.kaizen/config.yml\n";
417
- const gi = join(process.cwd(), ".gitignore");
418
- const current = existsSync(gi) ? readFileSync(gi, "utf8") : "";
419
- if (!current.includes(".kaizen/*")) {
420
- appendFileSync(gi, (current && !current.endsWith("\n") ? "\n" : "") + "\n# kaizen run state\n" + rules);
437
+ // Nothing to ignore where there is no git, so a plain folder gets no .gitignore.
438
+ let ignored = false;
439
+ if (existsSync(join(process.cwd(), ".git"))) {
440
+ const rules = ".kaizen/*\n!.kaizen/spec*.md\n!.kaizen/config.yml\n";
441
+ const gi = join(process.cwd(), ".gitignore");
442
+ const current = existsSync(gi) ? readFileSync(gi, "utf8") : "";
443
+ if (!current.includes(".kaizen/*")) {
444
+ appendFileSync(gi, (current && !current.endsWith("\n") ? "\n" : "") + "\n# kaizen run state\n" + rules);
445
+ ignored = true;
446
+ }
421
447
  }
422
- step("wrote .kaizen/ and the gitignore entry");
448
+ step(ignored ? "wrote .kaizen/ and the gitignore entry" : "wrote .kaizen/");
423
449
  writePointer();
424
450
  }
425
451
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Install .kaizen/ (spec, config, gitignore entry) into the current repository
2
+ description: Set up this project folder for kaizen (spec, config, and a gitignore entry when it is a git repo)
3
3
  ---
4
4
 
5
5
  Invoke the `kaizen` skill with argument `init`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaizen-agent",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Staged workflow for AI agents \u2014 code, writing, research, operations: plan, human approval, build, independent review, bounded fix loop.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,7 +47,7 @@ Porting the workflow to Codex or Antigravity is covered in [`adapters.md`](adapt
47
47
  | `/kaizen reject <reason>` | Reject it; the reason is fed back to the stage that produced it |
48
48
  | `/kaizen abort` | Mark the current run abandoned |
49
49
  | `/kaizen config` | Show this project's settings and change them, one picker per setting |
50
- | `/kaizen init` | Install `.kaizen/` with the `spec*.md` files, config, and the gitignore entry into the current repository |
50
+ | `/kaizen init` | Set up this project folder: `.kaizen/` with the `spec*.md` files, config, and — in a git repo — the gitignore entry |
51
51
  | `/kaizen install` | Install the workflow itself globally or per-project (see below) |
52
52
 
53
53
  If the user typed `/kaizen` with no argument and a run is in progress, treat it as
@@ -55,10 +55,11 @@ If the user typed `/kaizen` with no argument and a run is in progress, treat it
55
55
 
56
56
  ## Before doing anything
57
57
 
58
- 1. Locate the state directory: `.kaizen/` in the repository root, else `~/.kaizen/`
59
- keyed by working directory. If neither exists and the user is starting work, run
60
- `/kaizen init` first: it creates `.kaizen/` with a copy of the `spec*.md` files, a config, and
61
- the gitignore entry (see [`adapters.md`](adapters.md)).
58
+ 1. Locate the state directory: `.kaizen/` in the project folder's root, else
59
+ `~/.kaizen/` keyed by working directory. If neither exists and the user is starting
60
+ work, run `/kaizen init` first: it creates `.kaizen/` with a copy of the `spec*.md`
61
+ files, a config, and — where the folder is a git repository — the gitignore entry
62
+ (see [`adapters.md`](adapters.md)).
62
63
  2. Read `.kaizen/config.yml`, falling back to `config.default.yml` in this skill for
63
64
  any key it does not set.
64
65
  3. Read `.kaizen/runs/<current>/state.json` if a run is active. Never assume the
@@ -293,9 +294,11 @@ shown automatically.
293
294
  }
294
295
  ```
295
296
 
296
- `init` adds a gitignore entry that ignores run state but keeps the workflow: it
297
- ignores `.kaizen/*` and un-ignores `.kaizen/spec*.md` and `.kaizen/config.yml`, which
298
- are meant to be committed (see [`adapters.md`](adapters.md)).
297
+ In a git repository, `init` also adds a gitignore entry that ignores run state but
298
+ keeps the workflow: it ignores `.kaizen/*` and un-ignores `.kaizen/spec*.md` and
299
+ `.kaizen/config.yml`, which are meant to be committed (see
300
+ [`adapters.md`](adapters.md)). A project folder that is not a repository gets no
301
+ gitignore.
299
302
 
300
303
  ## Install
301
304
 
@@ -64,8 +64,9 @@ 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, `config.yml`, and the gitignore
68
- entry. `/kaizen install` additionally offers to append the `AGENTS.md` block above.
67
+ `/kaizen init` writes `.kaizen/` with the `spec*.md` files and `config.yml` into the
68
+ project folder, plus the gitignore entry when that folder is a git repository.
69
+ `/kaizen install` additionally offers to append the `AGENTS.md` block above.
69
70
  `.kaizen/spec*.md` and `.kaizen/config.yml` should be committed even though run state
70
71
  is ignored — the workflow is shared, the run data is not:
71
72
 
@@ -55,12 +55,27 @@ review:
55
55
  # Additional checks per track, chosen by what the run actually is. The planner may
56
56
  # name a track not listed here; the reviewer then derives its checks from the
57
57
  # track's "what would make it wrong".
58
+ # Each check below is one question the reviewer asks; the line beside it says which.
58
59
  track_checks:
60
+ # security - no new way in, no secret or user data exposed
61
+ # reuse_simplification - nothing rebuilt that the codebase already had
62
+ # test_coverage - the changed behaviour has a check that fails when it breaks
59
63
  software: [security, reuse_simplification, test_coverage]
60
64
  # blast_radius and regression are universal — see spec-review.md — not listed here.
65
+ # completeness - every part the piece promises is actually present
66
+ # claim_accuracy - every checkable claim traced to a source
67
+ # reader_usability - its intended reader can act on it without asking
61
68
  writing: [completeness, claim_accuracy, reader_usability]
69
+ # audience_fit - written for the people who will actually read it
70
+ # voice_consistency - reads as the same voice as the surrounding material
62
71
  communication: [claim_accuracy, audience_fit, voice_consistency]
72
+ # prerequisites - everything needed before step one is stated
73
+ # rollback - a way back exists for every step that changes something
74
+ # executability - someone else can run it start to finish unaided
63
75
  operations: [prerequisites, rollback, executability]
76
+ # evidence_support - the conclusion follows from evidence shown, not asserted
77
+ # selection_bias - the evidence was not picked to fit the answer
78
+ # alternatives - the readings that were rejected are named and why
64
79
  research: [evidence_support, selection_bias, alternatives]
65
80
  # Let the reviewer append durable lessons to .kaizen/memory.md.
66
81
  write_memory: true
@@ -90,6 +105,8 @@ state:
90
105
 
91
106
  git:
92
107
  # Never commit, push, or open a PR unless the user explicitly asks.
108
+ # Ignored when the project is not a git repository.
93
109
  auto_commit: false
94
110
  # Create a branch before the implement stage when on the default branch.
111
+ # Ignored when the project is not a git repository.
95
112
  branch_before_implement: true
@@ -35,6 +35,9 @@ Rules:
35
35
  abstraction, a new file, a new section — is allowed, and costs one written line
36
36
  saying what it serves. The line is the price of the technique, not a request for
37
37
  permission. No line means the reviewer records a finding.
38
+ - The `git.*` settings apply only where the work sits in a git repository. In a plain
39
+ folder there is no branch to make and no commit to skip, and that absence is not a
40
+ finding.
38
41
 
39
42
  **Baseline first, in any track with an existing suite of checks.** Before changing
40
43
  anything, run whatever already proves the existing material correct — the test suite,
@@ -31,7 +31,7 @@ anything.
31
31
  | `/kaizen reject <reason>` | Reject it; the reason decides revise (back to planner) vs kill (abandon) |
32
32
  | `/kaizen abort` | Mark the current run abandoned |
33
33
  | `/kaizen config` | Show this project's settings and change them, one picker per setting |
34
- | `/kaizen init` | Install `.kaizen/` with `spec.md`, config, and the gitignore entry into the current repository |
34
+ | `/kaizen init` | Set up this project folder: `.kaizen/` with `spec.md`, config, and — in a git repo — the gitignore entry |
35
35
  | `/kaizen install` | Install the workflow itself globally or per-project |
36
36
 
37
37
  `/kaizen` with no argument: `status` if a run is in progress, else ask what to build.