@boopkit/cli 0.4.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/dist/capability-catalog.json +7 -0
- package/dist/capability-versions.json +12 -11
- package/dist/cli.js +40 -19
- package/dist/commands/loop-merge.d.ts +83 -0
- package/dist/commands/loop-merge.js +436 -0
- package/dist/commands/loop.d.ts +142 -0
- package/dist/commands/loop.js +578 -55
- package/package.json +1 -1
package/dist/commands/loop.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface LoopOptions {
|
|
|
15
15
|
skipPerms?: boolean;
|
|
16
16
|
bare?: boolean;
|
|
17
17
|
json?: boolean;
|
|
18
|
+
merge?: boolean | string;
|
|
19
|
+
watch?: boolean;
|
|
18
20
|
}
|
|
19
21
|
interface ClaudeRunResult {
|
|
20
22
|
exitCode: number;
|
|
@@ -24,6 +26,79 @@ export interface PlanResult {
|
|
|
24
26
|
featureId: string | null;
|
|
25
27
|
costUsd: number | null;
|
|
26
28
|
}
|
|
29
|
+
export type WorktreeMode = 'work-flow' | 'prefix';
|
|
30
|
+
export interface WorktreeContext {
|
|
31
|
+
path: string;
|
|
32
|
+
branch: string;
|
|
33
|
+
scope: string;
|
|
34
|
+
mode: WorktreeMode;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Hard requirement: beads must run in Dolt server mode so concurrent worktrees
|
|
38
|
+
* share one issue DB over TCP. Reads `.beads/metadata.json` and throws an
|
|
39
|
+
* actionable error on embedded/missing — call before any `bd` work.
|
|
40
|
+
*/
|
|
41
|
+
export declare function assertDoltServerMode(projectDir: string, deps?: {
|
|
42
|
+
existsSyncFn?: (p: string) => boolean;
|
|
43
|
+
readFileFn?: (p: string, enc: string) => string;
|
|
44
|
+
}): void;
|
|
45
|
+
/**
|
|
46
|
+
* Discover the running shared Dolt server's port from `.beads/dolt-server.port`.
|
|
47
|
+
* Worktrees never start their own server — they reuse this one over TCP.
|
|
48
|
+
* Returns null when no port file is present (caller errors clearly). Liveness
|
|
49
|
+
* (pid still running) is best-effort and never blocks discovery.
|
|
50
|
+
*/
|
|
51
|
+
export declare function discoverDoltServer(projectDir: string, deps?: {
|
|
52
|
+
existsSyncFn?: (p: string) => boolean;
|
|
53
|
+
readFileFn?: (p: string, enc: string) => string;
|
|
54
|
+
isPidAliveFn?: (pid: number) => boolean;
|
|
55
|
+
}): {
|
|
56
|
+
port: number;
|
|
57
|
+
pid?: number;
|
|
58
|
+
alive?: boolean;
|
|
59
|
+
} | null;
|
|
60
|
+
/**
|
|
61
|
+
* Create (or reuse) the loop's own git worktree at `../boop-<scope>` on branch
|
|
62
|
+
* `work/<scope>`, then pre-warm `npm install --prefer-offline`. This is what
|
|
63
|
+
* makes N loops run concurrently without colliding — each gets its own tree and
|
|
64
|
+
* branch; main is never checked out.
|
|
65
|
+
*
|
|
66
|
+
* Collision (Decision #4): if a worktree already exists at the path on the same
|
|
67
|
+
* branch, reuse it (and skip install if node_modules is present); if the path is
|
|
68
|
+
* occupied by something else, throw a clear error rather than silently suffixing.
|
|
69
|
+
*/
|
|
70
|
+
export declare function createWorktree(scope: string, mode: WorktreeMode, projectDir: string, deps?: {
|
|
71
|
+
execSyncFn?: (cmd: string, opts: {
|
|
72
|
+
encoding: string;
|
|
73
|
+
cwd?: string;
|
|
74
|
+
stdio?: unknown;
|
|
75
|
+
}) => string;
|
|
76
|
+
existsSyncFn?: (p: string) => boolean;
|
|
77
|
+
copyFileFn?: (src: string, dest: string) => void;
|
|
78
|
+
readdirFn?: (p: string) => string[];
|
|
79
|
+
readFileFn?: (p: string) => string;
|
|
80
|
+
appendFileFn?: (p: string, data: string) => void;
|
|
81
|
+
}): WorktreeContext;
|
|
82
|
+
/**
|
|
83
|
+
* Write `.boop-worktree.json` into the worktree root. This is the contract
|
|
84
|
+
* Slice 2 (`boop loop --merge`) reads — `mode` drives its readiness query.
|
|
85
|
+
*/
|
|
86
|
+
export declare function writeWorktreeMetadata(ctx: WorktreeContext, meta: {
|
|
87
|
+
workPath?: string;
|
|
88
|
+
flowPath?: string;
|
|
89
|
+
boopVersion: string;
|
|
90
|
+
startTime: string;
|
|
91
|
+
operator?: string;
|
|
92
|
+
budget?: string;
|
|
93
|
+
model?: string;
|
|
94
|
+
}, deps?: {
|
|
95
|
+
writeFileFn?: (p: string, data: string) => void;
|
|
96
|
+
}): Record<string, unknown>;
|
|
97
|
+
interface ReadyIssue {
|
|
98
|
+
id: string;
|
|
99
|
+
issue_type: string;
|
|
100
|
+
parent?: string;
|
|
101
|
+
}
|
|
27
102
|
export declare function buildPlanningPrompt(workContent: string, flowContent: string, prefix?: string): string;
|
|
28
103
|
export type RunClaudeFn = (prompt: string, opts: {
|
|
29
104
|
budget: string;
|
|
@@ -32,6 +107,7 @@ export type RunClaudeFn = (prompt: string, opts: {
|
|
|
32
107
|
sessionId: string;
|
|
33
108
|
resume?: boolean;
|
|
34
109
|
bare?: boolean;
|
|
110
|
+
cwd?: string;
|
|
35
111
|
}, logFile: string, readableLogFile?: string) => Promise<ClaudeRunResult>;
|
|
36
112
|
export declare function planWork(opts: {
|
|
37
113
|
workPath: string;
|
|
@@ -55,9 +131,75 @@ export declare function findFallbackFeature(features: Array<{
|
|
|
55
131
|
export declare function extractFeatureId(text: string): string | null;
|
|
56
132
|
export declare function isUsageLimitText(text: string): boolean;
|
|
57
133
|
export declare function isStandaloneUsageLimitMessage(text: string): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Resolve the model for a loop run. Precedence: an explicit `--model` flag, then
|
|
136
|
+
* the `ANTHROPIC_MODEL` environment variable, then the built-in default. The env
|
|
137
|
+
* fallback is what lets a nested `boop loop` (spawned by a Claude session that
|
|
138
|
+
* the parent loop launched with ANTHROPIC_MODEL set) inherit the same model
|
|
139
|
+
* instead of silently dropping to the default. Keep the default (claude-opus-4-8)
|
|
140
|
+
* in sync with the `--model` help text in cli.ts.
|
|
141
|
+
*/
|
|
142
|
+
export declare function resolveModel(optionModel: string | undefined, env?: NodeJS.ProcessEnv): string;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the loop should resume an issue that a session left open. A `blocked`
|
|
145
|
+
* issue was deliberately halted by the prior session because it judged it could
|
|
146
|
+
* not safely proceed — resuming just spends budget re-halting and risks the
|
|
147
|
+
* resume prompt being read as authorization to work past the block. Stop and
|
|
148
|
+
* surface it for the operator instead. Any other open status is genuinely
|
|
149
|
+
* unfinished work and is fine to resume.
|
|
150
|
+
*/
|
|
151
|
+
export declare function shouldResumeUnclosedIssue(status: string | undefined): boolean;
|
|
58
152
|
export declare function isIssueInScope(issue: {
|
|
59
153
|
id: string;
|
|
60
154
|
parent?: string;
|
|
61
155
|
}, prefix: string, getParentById: (id: string) => string | null): boolean;
|
|
156
|
+
/**
|
|
157
|
+
* A workflow-owned feature root is a feature-type issue that owns child tasks
|
|
158
|
+
* (the workflow steps: understand → plan → … → closeout). Once those children
|
|
159
|
+
* close, `bd ready` surfaces the feature root itself — but it is a *container*,
|
|
160
|
+
* not directly claimable work. Claiming it lets a worker session absorb
|
|
161
|
+
* punch-list fixes or whole workflow steps (the boop-qna / wishfleet-O7 bug).
|
|
162
|
+
*
|
|
163
|
+
* `hasChildren` is only consulted for feature-type issues, so non-features never
|
|
164
|
+
* pay the cost of the children lookup.
|
|
165
|
+
*/
|
|
166
|
+
export declare function isClaimableReadyIssue(issue: {
|
|
167
|
+
id: string;
|
|
168
|
+
issue_type: string;
|
|
169
|
+
}, hasChildren: (id: string) => boolean): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Decide whether the loop should close a feature root itself, as a safety net,
|
|
172
|
+
* when its workflow chain has completed. The intended owner of this close is the
|
|
173
|
+
* closeout child task (see boop-feature-dev-workflow SKILL step 6), but if that
|
|
174
|
+
* task never closed the root — or no closeout task exists — the feature would be
|
|
175
|
+
* orphaned open forever once filtered from claimable work. Only close when the
|
|
176
|
+
* feature is still open and every child is closed.
|
|
177
|
+
*/
|
|
178
|
+
export declare function shouldCloseFeatureRoot(feature: {
|
|
179
|
+
status: string;
|
|
180
|
+
issue_type: string;
|
|
181
|
+
} | null, children: {
|
|
182
|
+
status: string;
|
|
183
|
+
}[]): boolean;
|
|
184
|
+
export declare function getMatchingReadyIssues(prefix: string, includeFeatures: boolean, deps?: {
|
|
185
|
+
execSyncFn?: (cmd: string, opts: {
|
|
186
|
+
encoding: string;
|
|
187
|
+
}) => string;
|
|
188
|
+
}): ReadyIssue[];
|
|
189
|
+
/**
|
|
190
|
+
* Default per-issue budget cap in USD. The planning phase and each task each get
|
|
191
|
+
* this cap. Single source of truth — imported by cli.ts for its --budget help
|
|
192
|
+
* text so the documented default and the runtime fallback can't drift.
|
|
193
|
+
*/
|
|
194
|
+
export declare const DEFAULT_BUDGET_USD = "25.00";
|
|
195
|
+
/**
|
|
196
|
+
* Sent when resuming a session that ended without closing its issue. The opener
|
|
197
|
+
* must NOT read as operator authorization (the old "Approved. Continue..." text
|
|
198
|
+
* could be taken as permission to work past a block): an agent that marked the
|
|
199
|
+
* issue `blocked` made a deliberate safety call, and the block stands. The loop
|
|
200
|
+
* also skips resuming a `blocked` issue entirely (see shouldResumeUnclosedIssue)
|
|
201
|
+
* — this clause is the belt-and-suspenders for a block raised mid-resume.
|
|
202
|
+
*/
|
|
203
|
+
export declare const RESUME_PROMPT = "The previous session ended without closing this issue. Reload the state and continue.\n\nIMPORTANT: If the previous session marked this issue blocked with a diagnostic, the block stands. Do not re-open it or work around it. Read the issue's notes and the previous session's commits, confirm the block is still appropriate, and stop without taking further action.\n\nOtherwise, complete the workflow:\n- Finish any remaining implementation\n- Run tests to verify\n- Commit changes referencing the issue ID\n- Close the issue with bd close\n- Push with: git pull --rebase && git push\n\nDo not pause for review of completed work. Complete everything now.";
|
|
62
204
|
export declare function runLoop(options: LoopOptions): Promise<void>;
|
|
63
205
|
export {};
|