kaizen-agent 0.5.0 → 0.6.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/README.md +8 -3
- package/cli/install.ts +68 -11
- package/cli/release.sh +34 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -239,9 +239,14 @@ Agent Skills standard, so the same workflow runs under any of them:
|
|
|
239
239
|
| Antigravity | Skills | Parallel agents where available, else sequentially |
|
|
240
240
|
| OpenCode, Cursor, Gemini CLI | Skills | Sequentially, one session |
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
agent and it picks
|
|
242
|
+
An agent counts as present if it has a config directory or a command on your PATH.
|
|
243
|
+
Only what is already there is touched — installing does not create `~/.opencode` for
|
|
244
|
+
someone who does not use OpenCode. Install again after adding an agent and it picks
|
|
245
|
+
the new one up.
|
|
246
|
+
|
|
247
|
+
**No agent yet?** kaizen does nothing on its own — it is a workflow an agent runs.
|
|
248
|
+
If none is found, the installer says so and offers the list above, opening the
|
|
249
|
+
install page for whichever you pick. Install it, run `kaizen` again, and carry on.
|
|
245
250
|
|
|
246
251
|
The stage agents and slash commands are Claude Code's own formats and are not copied
|
|
247
252
|
elsewhere; under the others you invoke the skill by name. `.kaizen/` is plain files
|
package/cli/install.ts
CHANGED
|
@@ -27,18 +27,75 @@ const c = {
|
|
|
27
27
|
// Skills standard, so every one of these can run the workflow; agents/ and
|
|
28
28
|
// commands/ are Claude Code's own formats and go nowhere else.
|
|
29
29
|
const AGENTS = [
|
|
30
|
-
{ name: "Claude Code", dir: ".claude", full: true
|
|
31
|
-
|
|
32
|
-
{ name: "
|
|
33
|
-
|
|
34
|
-
{ name: "
|
|
35
|
-
|
|
30
|
+
{ name: "Claude Code", dir: ".claude", cmd: "claude", full: true,
|
|
31
|
+
docs: "https://docs.claude.com/en/docs/claude-code" },
|
|
32
|
+
{ name: "Codex", dir: ".codex", cmd: "codex", full: false,
|
|
33
|
+
docs: "https://github.com/openai/codex" },
|
|
34
|
+
{ name: "Antigravity", dir: ".agents", cmd: "agy", full: false,
|
|
35
|
+
docs: "https://antigravity.google" },
|
|
36
|
+
{ name: "OpenCode", dir: ".opencode", cmd: "opencode", full: false,
|
|
37
|
+
docs: "https://opencode.ai" },
|
|
38
|
+
{ name: "Cursor", dir: ".cursor", cmd: "cursor", full: false,
|
|
39
|
+
docs: "https://cursor.com" },
|
|
40
|
+
{ name: "Gemini CLI", dir: ".gemini", cmd: "gemini", full: false,
|
|
41
|
+
docs: "https://github.com/google-gemini/gemini-cli" },
|
|
36
42
|
];
|
|
37
43
|
|
|
38
|
-
//
|
|
39
|
-
// who
|
|
40
|
-
//
|
|
41
|
-
const
|
|
44
|
+
// An agent counts as present if it has a directory or a command. The directory
|
|
45
|
+
// alone misses someone who installed the agent and has not run it yet; the command
|
|
46
|
+
// alone misses one that is not on this shell's PATH.
|
|
47
|
+
const onPath = new Set(
|
|
48
|
+
AGENTS.filter((a) => Bun.which(a.cmd)).map((a) => a.dir),
|
|
49
|
+
);
|
|
50
|
+
const found = (r: string) =>
|
|
51
|
+
AGENTS.filter((a) => existsSync(join(r, a.dir)) || onPath.has(a.dir));
|
|
52
|
+
|
|
53
|
+
// Nothing to install into. kaizen is a workflow an agent runs; on its own it does
|
|
54
|
+
// nothing, so send them to the agent first rather than laying out files no reader
|
|
55
|
+
// will ever load.
|
|
56
|
+
if (!found(home).length && !args.has("--force")) {
|
|
57
|
+
await noAgent();
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function noAgent() {
|
|
62
|
+
console.log(` ${c.bold("No AI coding agent found on this machine.")}\n`);
|
|
63
|
+
console.log(` ${c.dim("kaizen is a workflow that an agent runs — it plans, you approve, it builds,")}`);
|
|
64
|
+
console.log(` ${c.dim("and a second agent reviews. So an agent has to be installed first.")}\n`);
|
|
65
|
+
|
|
66
|
+
if (!interactive) {
|
|
67
|
+
for (const a of AGENTS) console.log(` ${a.name.padEnd(14)} ${a.docs}`);
|
|
68
|
+
console.log(`\n ${c.dim("Install one, then run this again.")}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const pick = await select("Which one would you like to install?", [
|
|
73
|
+
...AGENTS.map((a) => ({ label: a.name, hint: a.docs, value: a as (typeof AGENTS)[number] | null })),
|
|
74
|
+
{ label: "None of these — just show me the list", hint: "", value: null },
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
if (!pick) {
|
|
78
|
+
for (const a of AGENTS) console.log(` ${a.name.padEnd(14)} ${a.docs}`);
|
|
79
|
+
console.log(`\n ${c.dim("Install one, then run this again.")}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log(` ${c.bold(pick.name)}`);
|
|
84
|
+
console.log(` ${c.cyan(pick.docs)}\n`);
|
|
85
|
+
const opened = await openUrl(pick.docs);
|
|
86
|
+
console.log(opened
|
|
87
|
+
? ` ${c.dim("Opened in your browser. Install it, then run")} ${c.cyan("kaizen")} ${c.dim("again.")}`
|
|
88
|
+
: ` ${c.dim("Open that page to install it, then run")} ${c.cyan("kaizen")} ${c.dim("again.")}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Best effort: a headless box or a locked-down desktop has no opener, and the URL
|
|
92
|
+
// is printed either way.
|
|
93
|
+
async function openUrl(url: string) {
|
|
94
|
+
const opener = process.platform === "darwin" ? "open"
|
|
95
|
+
: process.platform === "win32" ? "start" : "xdg-open";
|
|
96
|
+
if (!Bun.which(opener)) return false;
|
|
97
|
+
try { await Bun.$`${opener} ${url}`.quiet(); return true; } catch { return false; }
|
|
98
|
+
}
|
|
42
99
|
|
|
43
100
|
if (wantSettings) {
|
|
44
101
|
const { settings } = await import("./settings.ts");
|
|
@@ -52,7 +109,7 @@ if (wantSettings) {
|
|
|
52
109
|
if (interactive && !upgrade && Bun.argv.length === 2) {
|
|
53
110
|
const repoDir = await resolveRepoQuietly();
|
|
54
111
|
const here = found(home);
|
|
55
|
-
const linked = here.every((a) =>
|
|
112
|
+
const linked = here.length > 0 && here.every((a) =>
|
|
56
113
|
["kaizen", "kaizen-help"].every((n) => existsSync(join(home, a.dir, "skills", n))));
|
|
57
114
|
if (linked) {
|
|
58
115
|
const { dashboard } = await import("./dashboard.ts");
|
package/cli/release.sh
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Runs after `npm publish`: tag the published version and open a GitHub release
|
|
3
|
+
# for it, so a version can never exist on npm with nothing to read on GitHub.
|
|
4
|
+
#
|
|
5
|
+
# Never fails the publish. The package is already public by the time this runs;
|
|
6
|
+
# exiting non-zero here would report a failure that did not happen.
|
|
7
|
+
set -u
|
|
8
|
+
v="${npm_package_version:-$(node -p "require('./package.json').version" 2>/dev/null)}"
|
|
9
|
+
[ -n "$v" ] || { echo "release: no version, skipping"; exit 0; }
|
|
10
|
+
tag="v$v"
|
|
11
|
+
|
|
12
|
+
git rev-parse --git-dir >/dev/null 2>&1 || { echo "release: not a git checkout, skipping"; exit 0; }
|
|
13
|
+
|
|
14
|
+
if git rev-parse "$tag" >/dev/null 2>&1; then
|
|
15
|
+
echo "release: $tag already tagged"
|
|
16
|
+
else
|
|
17
|
+
git tag -a "$tag" -m "kaizen-agent $tag" || { echo "release: could not tag"; exit 0; }
|
|
18
|
+
git push origin "$tag" >/dev/null 2>&1 || echo "release: tag made but not pushed"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
command -v gh >/dev/null 2>&1 || { echo "release: gh not installed — tag pushed, write the release by hand"; exit 0; }
|
|
22
|
+
gh auth status >/dev/null 2>&1 || { echo "release: gh not logged in — tag pushed, write the release by hand"; exit 0; }
|
|
23
|
+
|
|
24
|
+
if gh release view "$tag" >/dev/null 2>&1; then
|
|
25
|
+
echo "release: $tag already released"
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# --generate-notes lists the commits since the last tag. Good enough to never be
|
|
30
|
+
# empty; rewrite it with what actually changed when the release matters.
|
|
31
|
+
gh release create "$tag" --title "$tag" --generate-notes >/dev/null 2>&1 \
|
|
32
|
+
&& echo "release: published $tag https://github.com/hfadhlullah/kaizen/releases/tag/$tag" \
|
|
33
|
+
|| echo "release: tag pushed, release not created"
|
|
34
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaizen-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.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": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"install-links": "bun run cli/install.ts",
|
|
20
|
-
"check": "bun run cli/install.ts --check"
|
|
20
|
+
"check": "bun run cli/install.ts --check",
|
|
21
|
+
"postpublish": "sh cli/release.sh"
|
|
21
22
|
},
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|