kaizen-agent 1.3.7 → 1.3.9

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/dashboard.ts CHANGED
@@ -437,7 +437,12 @@ export async function dashboard(
437
437
  async function sync() {
438
438
  const before = knownProjects().length;
439
439
  const started = Date.now();
440
- const found = findProjects(home);
440
+ // Only searching under $HOME misses every project on another drive or mount,
441
+ // which on Windows is most of them. The folder the dashboard was opened in is
442
+ // searched too, and it is where the projects being worked on actually are.
443
+ const roots = [home, dirname(state ?? process.cwd()), process.cwd()]
444
+ .filter((d, i, all) => all.indexOf(d) === i);
445
+ const found = [...new Set(roots.flatMap((r) => findProjects(r)))];
441
446
  for (const dir of found) remember(dir);
442
447
  const added = knownProjects().length - before;
443
448
  await report([
@@ -445,7 +450,7 @@ export async function dashboard(
445
450
  "",
446
451
  ...found.map((d) => " " + c.dim(tilde(d))),
447
452
  "",
448
- c.dim(`${found.length} found in ${((Date.now() - started) / 1000).toFixed(1)}s under ${tilde(home)}`),
453
+ c.dim(`${found.length} found in ${((Date.now() - started) / 1000).toFixed(1)}s under ${roots.map(tilde).join(", ")}`),
449
454
  c.dim(`the list lives in ${tilde(join(home, ".kaizen", "projects"))} and can be edited`),
450
455
  ]);
451
456
  }
@@ -1311,7 +1316,9 @@ function findProjects(root: string, depth = 4): string[] {
1311
1316
  try { entries = readdirSync(dir); } catch { return; }
1312
1317
  // $HOME holds ~/.kaizen, the global state, which is not a project and must not
1313
1318
  // stop the walk before it has looked at anything.
1314
- if (dir !== root && entries.includes(".kaizen")) { found.push(dir); return; }
1319
+ // A project can hold projects of its own -- a monorepo, or a folder of them --
1320
+ // so finding one is not a reason to stop looking underneath it.
1321
+ if (dir !== root && entries.includes(".kaizen")) found.push(dir);
1315
1322
  if (left === 0) return;
1316
1323
  for (const name of entries) {
1317
1324
  if (name.startsWith(".") || name === "node_modules") continue;
package/cli/install.ts CHANGED
@@ -165,7 +165,18 @@ if (upgrade && !existsSync(join(dirname(import.meta.dir), ".git"))) {
165
165
  const now = versionOf(dirname(import.meta.dir));
166
166
  if (latest && latest !== now) {
167
167
  step(`fetching kaizen ${latest} from npm`);
168
- await Bun.$`${process.execPath} x kaizen-agent@${latest} --yes`.catch(() => {});
168
+ // --force so a stale package manifest cannot resolve the version away, and the
169
+ // failure is printed rather than swallowed: a silent catch here looked exactly
170
+ // like a successful upgrade that changed nothing.
171
+ const r = await Bun.$`${process.execPath} x --force kaizen-agent@${latest} --yes`
172
+ .quiet().nothrow();
173
+ const out = clean(r.stdout.toString() + r.stderr.toString()).filter((l) => l.trim());
174
+ for (const l of out) console.log(l.startsWith(" ") ? l : ` ${l}`);
175
+ if (r.exitCode !== 0) {
176
+ console.log(`\n ${c.bold(`could not fetch kaizen ${latest}`)}`);
177
+ console.log(` ${c.dim("try:")} ${c.cyan(`bunx kaizen-agent@${latest}`)}\n`);
178
+ process.exit(1);
179
+ }
169
180
  process.exit(0);
170
181
  }
171
182
  }
@@ -344,14 +355,17 @@ async function resolveRepo() {
344
355
  }
345
356
  return dest;
346
357
  }
347
- if (Bun.which("git")) {
358
+ // Cloning needs an empty directory, and a copy made on a machine that had no git
359
+ // is anything but: installing git later must not turn every run into a fatal.
360
+ // An existing directory is updated in place whichever way it was made.
361
+ if (Bun.which("git") && !existsSync(dest)) {
348
362
  step(`cloning into ${tilde(dest)}`);
349
363
  await Bun.$`git clone --quiet ${REPO_URL} ${dest}`;
350
364
  return dest;
351
365
  }
352
- // No git: the bunx download already holds everything a clone would, so copy it
353
- // in place. Upgrades then come from re-running bunx rather than a pull.
354
- step(`copying into ${tilde(dest)} ${c.dim("(no git)")}`);
366
+ // The bunx download already holds everything a clone would, so copy it in place.
367
+ // Upgrades then come from re-running bunx rather than a pull.
368
+ step(`copying into ${tilde(dest)} ${c.dim(existsSync(dest) ? "(over the copy already there)" : "(no git)")}`);
355
369
  cpSync(here, dest, {
356
370
  recursive: true, dereference: true,
357
371
  filter: (src) => basename(src) !== "node_modules",
@@ -682,6 +696,28 @@ async function clearBunxCache() {
682
696
  }
683
697
  }
684
698
  } catch { /* an unreadable temp directory is not worth failing an upgrade over */ }
699
+
700
+ // bun caches the package manifest too, which is what answers "no version
701
+ // matching 1.3.7 found (but package exists)" hours after it was published.
702
+ // Only kaizen's own entries go: another package's cache is not ours to clear.
703
+ // Where that cache lives depends on the platform and on how bun was installed,
704
+ // so try the lot; a directory that is not there reads as an empty one.
705
+ const caches = [
706
+ process.env.BUN_INSTALL_CACHE_DIR,
707
+ join(process.env.BUN_INSTALL ?? join(home, ".bun"), "install", "cache"),
708
+ join(process.env.XDG_CACHE_HOME ?? join(home, ".cache"), "bun"),
709
+ process.env.LOCALAPPDATA ? join(process.env.LOCALAPPDATA, "bun", "install", "cache") : null,
710
+ ].filter((d): d is string => Boolean(d));
711
+ for (const dir of caches) {
712
+ try {
713
+ for (const name of readdirSync(dir)) {
714
+ if (!name.includes("kaizen-agent")) continue;
715
+ rmSync(join(dir, name), { recursive: true, force: true });
716
+ removed++;
717
+ }
718
+ } catch { /* no cache directory is the same as an empty one */ }
719
+ }
720
+
685
721
  step(removed ? `cleared ${removed} cached copy of the installer` : "no installer cache to clear");
686
722
  }
687
723
  function tilde(p: string) { return p.startsWith(home) ? "~" + p.slice(home.length) : p; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaizen-agent",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
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": {