kanbot 0.5.0 → 0.5.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
@@ -26,11 +26,11 @@ Full docs: [docs/](./docs/00-index.md). Demo video: [docs/assets/demo.mp4](./doc
26
26
  | **Ready** | Moving a card here approves the plan. Cards are picked top-down. |
27
27
  | **In Progress** | An agent implements it in its own worktree and opens a PR. |
28
28
  | **Review** | Two agent reviews, with fixes. Then you're notified. Comment on the PR and an agent addresses it. CI failures and merge conflicts are fixed too. |
29
- | **Done** | You merge, or approve and kanbot merges ([`merge.onApproval`](./docs/11-identity.md#merge-on-approval)). |
29
+ | **Done** | You merge, or approve and kanbot merges ([`merge.onApproval`](./docs/12-identity.md#merge-on-approval)). |
30
30
 
31
31
  A Bun daemon polls the board and runs one `claude -p` / `codex exec` process per job. GitHub is the only state, so you can restart it any time. Agents never get a GitHub token; the daemon makes every comment, push and PR. Only collaborators with write access can steer agents.
32
32
 
33
- kanbot talks as you by default. Run `kanbot app create` to have it talk as its own bot instead, so you can tell its messages apart and approve its PRs. Commits stay yours. With `merge.onApproval`, approving a PR merges it. [More](./docs/11-identity.md)
33
+ kanbot talks as you by default. Run `kanbot app create` to have it talk as its own bot instead, so you can tell its messages apart and approve its PRs. Commits stay yours. With `merge.onApproval`, approving a PR merges it. [More](./docs/12-identity.md)
34
34
 
35
35
  ## Setup
36
36
 
@@ -64,19 +64,19 @@ For a guided setup, run `bunx kanbot skills install` and ask your agent "help me
64
64
 
65
65
  - **Capture ideas by chatting.** Ask your agent to file an idea; the `kanbot-idea` skill shapes it and puts it in Ideas. [More](./docs/03-capturing-ideas.md)
66
66
  - **Your own PRs.** Label a PR `kanbot-review` for agent review without a card. Commits to `main` that break kanbot PRs get merged in and fixed. [More](./docs/04-outside-the-board.md)
67
- - **Project memory.** Corrections you give on PRs become facts agents read on every job. [More](./docs/08-project-memory.md)
68
- - **Copilot review.** Optionally add GitHub Copilot as a cloud reviewer. [More](./docs/12-copilot-review.md)
67
+ - **Project memory.** Corrections you give on PRs become facts agents read on every job. [More](./docs/09-project-memory.md)
68
+ - **Copilot review.** Optionally add GitHub Copilot as a cloud reviewer. [More](./docs/13-copilot-review.md)
69
69
 
70
70
  ## Customizing
71
71
 
72
72
  - `.kanbot/config.yml`: concurrency, timeouts, notifications, column names.
73
73
  - `.kanbot/agents/*.md`: agent definitions. Run `kanbot sync` after editing; don't edit the generated `.claude/` or `.codex/` files.
74
- - `.agents/skills/`: skills shared by agents. Fill in `project-conventions` first.
74
+ - `.agents/skills/`: skills shared by agents. Fill in [`project-conventions`](./docs/08-project-conventions.md) first.
75
75
  - `capabilities` in config: your own skills and agents for building, testing and reviewing. [More](./docs/05-capabilities.md)
76
76
 
77
77
  ## Upgrading
78
78
 
79
- `bunx kanbot@latest upgrade` updates agents and skills you haven't edited. For edited ones, it writes the new version next to yours as `<file>.kanbot-new` to merge. See [Upgrading](./docs/13-upgrading.md).
79
+ `bunx kanbot@latest upgrade` updates agents and skills you haven't edited. For edited ones, it writes the new version next to yours as `<file>.kanbot-new` to merge. See [Upgrading](./docs/14-upgrading.md).
80
80
 
81
81
  ## Shell completion
82
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kanbot",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Run an autonomous dev team (Claude Code or Codex) from a GitHub Project board",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env bun
2
2
  import { runCommand, runMain } from "citty";
3
3
  import { formatError } from "./errors.ts";
4
+ import { log } from "./log.ts";
4
5
  import { main } from "./main.ts";
6
+ import { versionNotice } from "./templates.ts";
5
7
 
6
8
  const args = process.argv.slice(2);
7
9
  const usage =
@@ -13,6 +15,11 @@ const usage =
13
15
  if (usage) {
14
16
  await runMain(main);
15
17
  } else {
18
+ // These set the version themselves, report it, or print shell code.
19
+ if (!["init", "upgrade", "doctor", "completion"].includes(args[0] ?? "")) {
20
+ const notice = await versionNotice(process.cwd());
21
+ if (notice) log.warn(notice);
22
+ }
16
23
  try {
17
24
  await runCommand(main, { rawArgs: args });
18
25
  } catch (e) {
@@ -21,7 +21,13 @@ import {
21
21
  type McpServer,
22
22
  readMcpServers,
23
23
  } from "../providers/mcp.ts";
24
- import { NEW_SUFFIX, pendingMerges, planUpgrade } from "../templates.ts";
24
+ import {
25
+ FILL_IN,
26
+ NEW_SUFFIX,
27
+ pendingMerges,
28
+ planUpgrade,
29
+ unfilledTemplates,
30
+ } from "../templates.ts";
25
31
  import { REPO_LABELS } from "./board.ts";
26
32
 
27
33
  type Check = {
@@ -323,6 +329,31 @@ export default defineCommand({
323
329
  fix: `merge each into the file next to it and delete it (kanbot-admin skill can help)`,
324
330
  });
325
331
 
332
+ const unfilled = await unfilledTemplates(root);
333
+ for (const path of FILL_IN) {
334
+ const u = unfilled.find((x) => x.path === path);
335
+ const conventions = path.includes("project-conventions");
336
+ add({
337
+ name: `${path} filled in`,
338
+ ok: true,
339
+ warn: !!u,
340
+ detail: u?.detail,
341
+ why: u
342
+ ? conventions
343
+ ? "Every agent reads it first for commands and conventions. Until it's filled in, they guess."
344
+ : "Agents fix failing CI, so it should run your real install, lint and test commands."
345
+ : undefined,
346
+ fix: u
347
+ ? conventions
348
+ ? "replace each <placeholder> and delete the TEMPLATE note (kanbot-guide skill can help)"
349
+ : "replace the starter steps with your stack's commands"
350
+ : undefined,
351
+ docs: conventions
352
+ ? "project-conventions#fill-it-in"
353
+ : "getting-started#set-up-a-repository",
354
+ });
355
+ }
356
+
326
357
  section(`Pushed to origin/${config.baseBranch}`);
327
358
  await git(root, "fetch", "origin", config.baseBranch).catch(() => {});
328
359
  const tree = await git(
@@ -5,7 +5,7 @@ import { loadAgents } from "../agents/load.ts";
5
5
  import { sync } from "../agents/sync.ts";
6
6
  import { askCapabilities, compact, ownWorkers } from "../capabilities.ts";
7
7
  import { configPath, saveConfig, writeConfigSchema } from "../config.ts";
8
- import { UserError } from "../errors.ts";
8
+ import { DOCS_URL, UserError } from "../errors.ts";
9
9
  import { run } from "../github/gh.ts";
10
10
  import { log } from "../log.ts";
11
11
  import { applyUpgrade, NEW_SUFFIX, planUpgrade } from "../templates.ts";
@@ -111,6 +111,7 @@ export default defineCommand({
111
111
  console.log(`
112
112
  Next steps:
113
113
  1. Review AGENTS.md and fill in .agents/skills/project-conventions/SKILL.md
114
+ (ask your agent to draft it; see ${DOCS_URL}/project-conventions)
114
115
  2. Adjust .github/workflows/ci.yml to your stack (agents fix failing CI)
115
116
  3. Map your own skills under capabilities in .kanbot/config.yml (kanbot-guide can help)
116
117
  4. kanbot board create # board and labels; enable the workflows it prints
@@ -18,13 +18,15 @@
18
18
  ],
19
19
  ".agents/skills/kanbot-guide/SKILL.md": [
20
20
  "1251194ba34a8b6eae8508037b0a76c60d7a26b8",
21
+ "1329454d5b81912e856591caa036c93f88ef8c69",
21
22
  "2c6c77a225c5b880eff023d4b3c1305bfc91bfb3",
22
23
  "2ccb86b12e5af121b79ef9f53c2a35dbbdb2ddeb",
23
24
  "53c73b1be4a1e8d863a52043eae4ca911c8be71b",
24
25
  "a24c0a655d6485e65bd5dea2a71f3afe67f04404",
25
26
  "b5a2d074ea61f2552890ca1d78bf8a043d7b73b3",
26
27
  "bde0364d60525598bbb28f1648d06d1407c62a73",
27
- "cf3e95d137a5a58a273262bca6ba25fbc95fa037"
28
+ "cf3e95d137a5a58a273262bca6ba25fbc95fa037",
29
+ "f9b76db4afbad14ad9d14dff805c71703099bdeb"
28
30
  ],
29
31
  ".agents/skills/kanbot-idea/SKILL.md": [
30
32
  "8ab28cec8d3f30250ffe080106d0de8e3c2eaa8a",
package/src/templates.ts CHANGED
@@ -54,6 +54,18 @@ export async function readManifest(root: string): Promise<Manifest | null> {
54
54
  return (await file.exists()) ? ((await file.json()) as Manifest) : null;
55
55
  }
56
56
 
57
+ /** Warning when this repo's templates and the running kanbot differ in version. */
58
+ export async function versionNotice(root: string, current = pkg.version) {
59
+ const installed = (await readManifest(root).catch(() => null))?.version;
60
+ if (!installed) return null;
61
+ const order = Bun.semver.order(installed, current);
62
+ if (order < 0)
63
+ return `kanbot ${current} is out, this repo has ${installed}. Run \`kanbot upgrade\` to get the new agents, skills and workflows.`;
64
+ if (order > 0)
65
+ return `This repo uses kanbot ${installed}, but you run ${current}. Use \`bunx kanbot@latest\`.`;
66
+ return null;
67
+ }
68
+
57
69
  async function writeManifest(root: string, files: Record<string, string>) {
58
70
  const sorted = Object.fromEntries(
59
71
  Object.entries(files).sort(([a], [b]) => a.localeCompare(b)),
@@ -191,3 +203,54 @@ export async function pendingMerges(root: string, dir = TEMPLATES) {
191
203
  const paths = [...(await listTemplates(dir)).keys()];
192
204
  return paths.filter((p) => existsSync(join(root, `${p}${NEW_SUFFIX}`)));
193
205
  }
206
+
207
+ /** User templates you are meant to fill in after install. */
208
+ export const FILL_IN = [
209
+ ".agents/skills/project-conventions/SKILL.md",
210
+ ".github/workflows/ci.yml",
211
+ ];
212
+
213
+ const clip = (s: string) => (s.length > 72 ? `${s.slice(0, 71)}…` : s);
214
+
215
+ export type Unfilled = { path: string; detail: string };
216
+
217
+ /**
218
+ * Fill-in templates still unedited, or still holding the template's
219
+ * `<placeholder>`s. Missing files are left to other checks.
220
+ */
221
+ export async function unfilledTemplates(
222
+ root: string,
223
+ opts: Pick<Options, "templates" | "known"> = {},
224
+ ): Promise<Unfilled[]> {
225
+ const templates = await listTemplates(opts.templates);
226
+ const known: Record<string, string[]> = opts.known ?? knownHashes;
227
+ const out: Unfilled[] = [];
228
+ for (const path of FILL_IN) {
229
+ const tpl = templates.get(path);
230
+ const file = Bun.file(join(root, path));
231
+ if (!tpl || !(await file.exists())) continue;
232
+ const bytes = await file.bytes();
233
+ const current = hash(bytes);
234
+ if (current === hash(tpl) || (known[path] ?? []).includes(current)) {
235
+ out.push({ path, detail: "unchanged from the template" });
236
+ continue;
237
+ }
238
+ const placeholders = new Set(
239
+ new TextDecoder().decode(tpl).match(/<[^<>`\n]+>/g) ?? [],
240
+ );
241
+ const left = new TextDecoder()
242
+ .decode(bytes)
243
+ .split("\n")
244
+ .flatMap((line, i) =>
245
+ [...placeholders].some((p) => line.includes(p))
246
+ ? [`line ${i + 1}: ${clip(line.trim())}`]
247
+ : [],
248
+ );
249
+ if (left.length)
250
+ out.push({
251
+ path,
252
+ detail: `${left.length} line(s) with placeholders left:\n${left.slice(0, 5).join("\n")}${left.length > 5 ? "\n…" : ""}`,
253
+ });
254
+ }
255
+ return out;
256
+ }
@@ -12,22 +12,23 @@ Explain in plain words. Ask before choosing for them; give a recommendation with
12
12
 
13
13
  ## Docs
14
14
 
15
- | Question | Slug |
16
- | --------------------------------------------- | ------------------- |
17
- | How do I install and set up a repo? | `getting-started` |
18
- | How does a card move across the board? | `workflow` |
19
- | How do I file ideas by chatting? | `capturing-ideas` |
20
- | My own PRs, local sessions, direct commits? | `outside-the-board` |
21
- | Which agents are there, how do I change them? | `agents` |
22
- | Skills? | `skills` |
23
- | Project memory, facts from corrections | `project-memory` |
24
- | Claude or Codex? | `providers` |
25
- | Every config field, labels, notifications | `configuration` |
26
- | Using our own skills and agents for the work | `capabilities` |
27
- | Copilot as an extra reviewer | `copilot-review` |
28
- | Bot or user identity, merge by approving | `identity` |
29
- | Upgrading and `.kanbot-new` files | `upgrading` |
30
- | Every command and flag | `usage` |
15
+ | Question | Slug |
16
+ | --------------------------------------------- | --------------------- |
17
+ | How do I install and set up a repo? | `getting-started` |
18
+ | How does a card move across the board? | `workflow` |
19
+ | How do I add or file ideas? | `capturing-ideas` |
20
+ | My own PRs, local sessions, direct commits? | `outside-the-board` |
21
+ | Which agents are there, how do I change them? | `agents` |
22
+ | Skills? | `skills` |
23
+ | Filling in stack, commands and rules | `project-conventions` |
24
+ | Project memory, facts from corrections | `project-memory` |
25
+ | Claude or Codex? | `providers` |
26
+ | Every config field, labels, notifications | `configuration` |
27
+ | Using our own skills and agents for the work | `capabilities` |
28
+ | Copilot as an extra reviewer | `copilot-review` |
29
+ | Bot or user identity, merge by approving | `identity` |
30
+ | Upgrading and `.kanbot-new` files | `upgrading` |
31
+ | Every command and flag | `usage` |
31
32
 
32
33
  ## Board flow
33
34
 
@@ -43,7 +44,7 @@ Go step by step. Run each command, check its output, then go on. If `.kanbot/con
43
44
 
44
45
  1. **Requirements.** Bun 1.3+, `gh` logged in, `claude` or `codex` logged in with a subscription (not an API key). Run `gh auth refresh -s project`.
45
46
  2. **Provider.** Ask which subscription they have, then `bunx kanbot init --provider claude|codex` in the repo root.
46
- 3. **Conventions.** Fill in `.agents/skills/project-conventions/SKILL.md` with them: stack, commands to test, lint and typecheck. Adjust `.github/workflows/ci.yml` to run the same. Every agent reads this first.
47
+ 3. **Conventions.** Fill in `.agents/skills/project-conventions/SKILL.md` with them: stack, commands to test, lint and typecheck. Adjust `.github/workflows/ci.yml` to run the same. Every agent reads this first. Draft it from manifests and CI, ask what you can't find, and have them run each command. Link `project-conventions`.
47
48
  4. **Capabilities.** kanbot runs the process; the repo's own skills and agents do the work. Ask which skills they have for proving acceptance criteria (`verify`), technical review (`review`) and something a human can try (`preview`), and map them under `capabilities` in `.kanbot/config.yml`. See [Capabilities](#capabilities).
48
49
  5. **Board.** `kanbot board create`, or `kanbot board link --owner <login> --number <n>` for an existing project. Have them enable the four built-in project workflows it prints; they can't be set through the API.
49
50
  6. **Options.** Go through [Choose options](#choose-options). For app mode, run `kanbot app create` and have them install the app on the repo.