@boopkit/cli 0.4.1 → 0.6.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
@@ -102,8 +102,11 @@ Pick what the product needs. `boop add <name>` handles the wiring — npm depend
102
102
  | `coding` | Development conventions and coding skills for AI agents |
103
103
  | `testing` | Jest setup and testing skills (TDD workflow, Express testing patterns) |
104
104
  | `project-mgmt` | Beads issue-tracking and planning skills |
105
- | `product-design` | Feature-requirements and product-design skills |
106
- | `skills` | Skill-authoring guidance for extending the skill library |
105
+ | `product-design` | Product design skills — feature requirements, engineering design, documentation, design thought-partnership, and technical prose |
106
+ | `ux` | UX judgement (purpose + visual) and the app-UI evaluation and delivery workflows |
107
+ | `skills` | Skill-authoring and skill-discovery guidance for extending the skill library |
108
+
109
+ > For the full list of the skills each capability ships — with a one-line description of what each covers — see **`docs/skills.md`**, bundled in the package (run `npm view @boopkit/cli` or open it in your `node_modules/@boopkit/cli/docs/` after install).
107
110
 
108
111
  ### Demo
109
112
 
@@ -138,11 +141,11 @@ Flags:
138
141
 
139
142
  Boop is built for agent-assisted work — the skills and conventions ship with the code so your agent has real guidance, not just a blank repo. Every scaffolded project includes:
140
143
 
141
- - **Skills** — every capability installs skill folders into `skills/`. These are focused, task-specific instructions (each folder contains a `SKILL.md`, e.g. `skills/rest-api-design/SKILL.md`, `skills/tdd-light/SKILL.md`) that tell an agent the conventions this project uses.
144
+ - **Skills** — every capability installs skill folders into `skills/`. These are focused, task-specific instructions (each folder contains a `SKILL.md`, e.g. `skills/boop-api-rest-api-design/SKILL.md`, `skills/boop-testing-tdd-light/SKILL.md`) that tell an agent the conventions this project uses. See the bundled **`docs/skills.md`** for the full index of what each capability ships.
142
145
  - **`boop status`** — after `boop init` or `boop add`, run `boop status`. It prints every capability's post-install steps. Hand this to your agent and say "finish setup."
143
146
  - **`boop loop`** — Uses Claude for 'unattended work', building working code and UI from your specifications.
144
- - `prefix` mode: Plan work as a tree of issues, then `boop loop --prefix <id>` processes them one at a time, each in its own Claude Code session. Dry-run by default; budget-capped; resumes unfinished work. See [docs/loop.md](docs/loop.md).
145
- - `workflow` mode: Provide your spec and the bundled `feature-dev-workflow` skill to `boop loop --work <spec> --flow <skill>`. It processes the spec requirements into a technical design, a set of linked tasks and then continuously processes issues until the work is complete. See [docs/loop.md](docs/loop.md#workflow-mode).
147
+ - `prefix` mode: Plan work as a tree of issues, then `boop loop --prefix <id>` processes them one at a time, each in its own Claude Code session. Dry-run by default; budget-capped; resumes unfinished work. See the bundled `docs/loop.md`.
148
+ - `workflow` mode: Provide your spec and the bundled `feature-dev-workflow` skill to `boop loop --work <spec> --flow <skill>`. It processes the spec requirements into a technical design, a set of linked tasks and then continuously processes issues until the work is complete. See the bundled `docs/loop.md`.
146
149
 
147
150
  The workflow is designed so a human sets direction, an agent does the implementation, and boop provides the rails.
148
151
 
@@ -175,12 +178,13 @@ Boop itself is light — Node and npm. The other requirements come from whicheve
175
178
  - **SendGrid account** — if `email` is installed
176
179
  - **AWS S3 bucket** — if `cloud-storage` is installed
177
180
 
178
- ## Links
181
+ ## Bundled docs
182
+
183
+ These ship inside the package (under `docs/`) — open them after install in `node_modules/@boopkit/cli/docs/`:
179
184
 
180
- - **[docs/init.md](docs/init.md)** — detailed `boop init` walkthrough
181
- - **[docs/loop.md](docs/loop.md)** — automated agent workflow
182
- - **[GitHub repo](https://github.com/boop-labs/boop)** — source and issues
183
- - **[Contributing](https://github.com/boop-labs/boop/blob/main/CONTRIBUTING.md)** — dev setup, architecture, how to add a capability
185
+ - **`docs/init.md`** — detailed `boop init` walkthrough
186
+ - **`docs/loop.md`** — automated agent workflow
187
+ - **`docs/skills.md`** — index of every capability's agent skills
184
188
 
185
189
  ## License
186
190
 
@@ -111,6 +111,13 @@
111
111
  "web"
112
112
  ]
113
113
  },
114
+ {
115
+ "name": "ux",
116
+ "description": "UX design judgement and the discovery/delivery workflows that operate it",
117
+ "type": "development",
118
+ "package": "@boopkit/cap-ux",
119
+ "requires": []
120
+ },
114
121
  {
115
122
  "name": "web",
116
123
  "description": "Web UI with Handlebars + Tailwind",
@@ -1,18 +1,19 @@
1
1
  {
2
- "@boopkit/cap-api": "0.4.0",
3
- "@boopkit/cap-background-jobs": "0.4.0",
2
+ "@boopkit/cap-api": "0.4.2",
3
+ "@boopkit/cap-background-jobs": "0.4.1",
4
4
  "@boopkit/cap-cloud-storage": "0.4.0",
5
- "@boopkit/cap-coding": "0.4.0",
6
- "@boopkit/cap-database": "0.4.0",
5
+ "@boopkit/cap-coding": "0.4.2",
6
+ "@boopkit/cap-database": "0.4.3",
7
7
  "@boopkit/cap-email": "0.4.1",
8
8
  "@boopkit/cap-hello": "0.4.0",
9
9
  "@boopkit/cap-noticeboard": "0.4.0",
10
- "@boopkit/cap-product-design": "0.4.0",
11
- "@boopkit/cap-project-mgmt": "0.4.0",
12
- "@boopkit/cap-services": "0.4.0",
13
- "@boopkit/cap-skills": "0.4.0",
14
- "@boopkit/cap-testing": "0.4.0",
15
- "@boopkit/cap-users": "0.4.1",
16
- "@boopkit/cap-web": "0.4.1",
10
+ "@boopkit/cap-product-design": "0.6.3",
11
+ "@boopkit/cap-project-mgmt": "0.4.3",
12
+ "@boopkit/cap-services": "0.4.2",
13
+ "@boopkit/cap-skills": "0.5.1",
14
+ "@boopkit/cap-testing": "0.5.1",
15
+ "@boopkit/cap-users": "0.4.3",
16
+ "@boopkit/cap-ux": "0.2.1",
17
+ "@boopkit/cap-web": "0.5.1",
17
18
  "@boopkit/logger": "0.4.0"
18
19
  }
package/dist/cli.js CHANGED
@@ -44,6 +44,7 @@ const add_1 = require("./commands/add");
44
44
  const adopt_1 = require("./commands/adopt");
45
45
  const update_1 = require("./commands/update");
46
46
  const loop_1 = require("./commands/loop");
47
+ const loop_merge_1 = require("./commands/loop-merge");
47
48
  const pkgJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
48
49
  const program = new commander_1.Command();
49
50
  program
@@ -101,23 +102,43 @@ program
101
102
  .action(adopt_1.runAdopt);
102
103
  program
103
104
  .command('loop')
104
- .description('Continuously process ready beads issues via Claude Code sessions')
105
- .option('--prefix <prefix>', 'Issue ID prefix to filter by')
106
- .option('--work <path>', 'Spec file for planning phase')
107
- .option('--flow <path>', 'Workflow file for planning phase')
108
- .option('--run', 'Actually execute (dry-run by default)')
109
- .option('--max <n>', 'Stop after N issues')
110
- .option('--budget <amount>', 'Budget cap per issue in USD (default: 5.00)')
111
- .option('--resume-limit <n>', 'Max resume attempts per issue (default: 3)')
112
- .option('--poll', 'Keep polling when no ready issues found')
113
- .option('--poll-interval <seconds>', 'Seconds between polls (default: 60)')
114
- .option('--model <model>', 'Claude model to use (default: claude-opus-4-6)')
115
- .option('--per-issue-branch', 'Create a separate branch per issue')
116
- .option('--no-branch', 'Skip branch creation entirely')
117
- .option('--features', 'Include feature-type issues (excluded by default)')
118
- .option('--no-skip-perms', 'Do not skip permission prompts')
119
- .option('--bare', 'Force API key auth (--bare mode); skips OAuth/keychain, uses ANTHROPIC_API_KEY strictly')
120
- .option('--json', 'Output summary as JSON')
121
- .addHelpText('after', '\nBy default runs in dry-run mode. Add --run to execute.')
122
- .action(loop_1.runLoop);
105
+ .summary('Drive Claude Code sessions to build work autonomously')
106
+ .description('Drive Claude Code sessions to build work autonomously, in one of three modes:\n' +
107
+ ' spec-driven --work <spec> --flow <flow> plan a feature tree from a spec, then build every task\n' +
108
+ ' issue-driven --prefix <issue-id> process ready beads issues in scope: ID starts with the prefix, or any parent-chain ancestor ID does\n' +
109
+ ' merge --merge [branch] integrate completed feature worktrees into main')
110
+ // — Mode selection (pick exactly one mode) —
111
+ .option('--work <path>', 'spec-driven: spec/work file to plan from (requires --flow)')
112
+ .option('--flow <path>', 'spec-driven: workflow file or skill dir that drives planning (requires --work)')
113
+ .option('--prefix <prefix>', 'issue-driven: scope of issues to process — in scope if the issue ID starts with this prefix OR any ancestor (parent chain) ID does, so issues re-parented under a matching epic/feature are included even with unrelated IDs. Pass a full issue ID; a truncated one over-matches (boop-4 also matches boop-45j)')
114
+ .option('--merge [branch]', 'merge: integrate completed feature worktrees into main (optional single branch skips readiness)')
115
+ // — Mode-specific options —
116
+ .option('--features', 'issue-driven only: also process leaf feature-type issues (excluded by default; always on in spec-driven mode). Feature roots that own child tasks are never claimed directly — they are containers, not work.')
117
+ .option('--watch', 'merge only: poll for ready branches and merge them as they land')
118
+ // — Shared execution options —
119
+ .option('--run', 'actually execute (dry-run by default)')
120
+ .option('--max <n>', 'stop after N issues')
121
+ .option('--budget <amount>', `budget cap per issue in USD (default: ${loop_1.DEFAULT_BUDGET_USD})`)
122
+ .option('--model <model>', 'Claude model to use, applied to every spawned session and nested loop (falls back to $ANTHROPIC_MODEL, then claude-opus-4-8). Sub-agents keep their own declared model unless they opt into model: inherit.')
123
+ .option('--poll', 'keep polling when no ready issues found')
124
+ .option('--poll-interval <seconds>', 'seconds between polls (default: 60)')
125
+ .option('--resume-limit <n>', 'max resume attempts per issue (default: 3)')
126
+ .option('--per-issue-branch', 'create a separate branch per issue')
127
+ .option('--no-branch', 'skip branch/worktree creation; run in place on the current branch')
128
+ .option('--no-skip-perms', 'do not skip permission prompts')
129
+ .option('--bare', 'force API key auth; skip OAuth/keychain, use ANTHROPIC_API_KEY strictly')
130
+ .option('--json', 'output summary as JSON')
131
+ .addHelpText('after', [
132
+ '',
133
+ 'Examples:',
134
+ ' boop loop --work specs/feature.spec.md --flow skills/my-flow/SKILL.md --run',
135
+ ' boop loop --prefix boop-abc --run --features',
136
+ ' boop loop --merge --run --watch',
137
+ '',
138
+ 'Notes:',
139
+ ' • Dry-run by default; add --run to execute.',
140
+ ' • --work and --flow must be used together; --features and --watch only apply to their own mode.',
141
+ ' • Merge mode rebases ready work/<id> branches onto main, runs tests, ff-merges, and cleans up worktrees.',
142
+ ].join('\n'))
143
+ .action((options) => (options.merge ? (0, loop_merge_1.runMerge)(options) : (0, loop_1.runLoop)(options)));
123
144
  program.parse(process.argv);
@@ -0,0 +1,83 @@
1
+ import { LoopOptions, WorktreeMode } from './loop';
2
+ /**
3
+ * Slice 2 — `boop loop --merge`.
4
+ *
5
+ * Sequential integration of completed feature worktrees back into main. No
6
+ * individual loop merges its own branch; this is the dedicated integrator.
7
+ *
8
+ * For each ready branch (sequential, failure-isolated):
9
+ * record orig sha → rebase work/<id> onto main → npm test → ff-merge into main
10
+ * → remove worktree + branch.
11
+ *
12
+ * Safety contract: main is NEVER left dirty. A rebase conflict aborts the rebase;
13
+ * a post-rebase test failure resets the branch to its original sha; either way we
14
+ * file a beads issue and skip to the next branch. Only `package.json` dependency
15
+ * additions are auto-resolved (the one documented known-safe pattern); every other
16
+ * conflict punts to a human via a beads issue.
17
+ */
18
+ export interface WorktreeMeta {
19
+ version: number;
20
+ mode: WorktreeMode;
21
+ scope: string;
22
+ branch: string;
23
+ worktreePath: string;
24
+ }
25
+ export interface MergeCandidate {
26
+ branch: string;
27
+ worktreePath: string;
28
+ scope: string;
29
+ mode: WorktreeMode;
30
+ ready: boolean;
31
+ }
32
+ interface ScopeIssue {
33
+ id: string;
34
+ parent?: string;
35
+ status?: string;
36
+ }
37
+ export interface MergeDeps {
38
+ projectDir?: string;
39
+ execSyncFn?: (cmd: string, opts?: {
40
+ cwd?: string;
41
+ stdio?: unknown;
42
+ }) => string;
43
+ existsSyncFn?: (p: string) => boolean;
44
+ readFileFn?: (p: string) => string;
45
+ /** Returns beads issues at the given status (`bd list --status=<s> --json`). */
46
+ bdListFn?: (status: 'open' | 'closed') => ScopeIssue[];
47
+ /** Parent-id lookup for ancestors not present in the listed set. */
48
+ getParentFn?: (id: string) => string | null;
49
+ /** File a beads issue on merge failure. Returns the created issue id (or null). */
50
+ createIssueFn?: (title: string, description: string) => string | null;
51
+ /** Best-effort sleep between watch polls. */
52
+ sleepFn?: (ms: number) => Promise<void>;
53
+ /** Dolt server-mode guard (defaults to the real `assertDoltServerMode`). */
54
+ assertServerModeFn?: (projectDir: string) => void;
55
+ }
56
+ /**
57
+ * Pick the higher of two version specifiers for the same dependency key. Ties and
58
+ * unparseable specifiers prefer `ours` (the integration/main side) for stability.
59
+ */
60
+ export declare function pickHigherVersion(ours: string, theirs: string): string;
61
+ /**
62
+ * Union-merge two package.json sides that conflicted during a rebase. Dependency
63
+ * maps are unioned (same-key version conflict → higher semver). Every other
64
+ * top-level key must already agree between the two sides; if any non-dependency
65
+ * key differs, the conflict is NOT known-safe and this throws so the caller punts
66
+ * to a human. Returns the merged JSON text (2-space indent, trailing newline).
67
+ */
68
+ export declare function mergePackageJsonContents(oursText: string, theirsText: string): string;
69
+ /**
70
+ * A worktree is ready to merge when every beads issue in its scope is closed.
71
+ * That means: at least one closed in-scope issue exists AND zero open in-scope
72
+ * issues remain. `bd ready` is insufficient (it only returns *unblocked* issues),
73
+ * so we list by status and filter with the same scope rule the loop uses.
74
+ */
75
+ export declare function isScopeComplete(scope: string, deps: MergeDeps): boolean;
76
+ /**
77
+ * Enumerate registered git worktrees, read each `.boop-worktree.json`, and decide
78
+ * which are ready to merge. Worktrees without metadata (e.g. unrelated worktrees)
79
+ * are ignored.
80
+ */
81
+ export declare function findMergeCandidates(deps: MergeDeps): MergeCandidate[];
82
+ export declare function runMerge(options: LoopOptions, deps?: MergeDeps): Promise<void>;
83
+ export {};