codebyplan 1.13.27 → 1.13.29
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/cli.js +1 -1
- package/package.json +1 -1
- package/templates/agents/cbp-improve-round.md +1 -1
- package/templates/agents/cbp-task-check.md +12 -8
- package/templates/hooks/README.md +21 -2
- package/templates/hooks/cbp-context-window-notify.sh +43 -0
- package/templates/hooks/cbp-mcp-round-sync.sh +9 -0
- package/templates/hooks/cbp-test-hooks.sh +119 -0
- package/templates/hooks/hooks.json +10 -0
- package/templates/settings.project.base.json +3 -2
- package/templates/skills/cbp-build-cc-mode/SKILL.md +4 -3
- package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +3 -2
- package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +1 -1
- package/templates/skills/cbp-merge-main/SKILL.md +1 -1
- package/templates/skills/cbp-round-complete/SKILL.md +164 -0
- package/templates/skills/cbp-round-end/SKILL.md +16 -14
- package/templates/skills/cbp-round-end/reference/findings-presentation.md +7 -17
- package/templates/skills/cbp-round-execute/SKILL.md +4 -0
- package/templates/skills/cbp-round-input/SKILL.md +6 -6
- package/templates/skills/cbp-round-start/SKILL.md +12 -15
- package/templates/skills/cbp-round-update/SKILL.md +31 -143
- package/templates/skills/cbp-standalone-task-check/SKILL.md +2 -2
- package/templates/skills/cbp-standalone-task-complete/SKILL.md +4 -3
- package/templates/skills/cbp-standalone-task-testing/SKILL.md +4 -4
- package/templates/skills/cbp-task-check/SKILL.md +3 -3
- package/templates/skills/cbp-task-complete/SKILL.md +7 -6
- package/templates/skills/cbp-task-testing/SKILL.md +3 -5
- package/templates/skills/cbp-todo/SKILL.md +1 -1
package/dist/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -279,6 +279,6 @@ Return findings sorted by severity (critical first). If no findings, return `sta
|
|
|
279
279
|
## Integration
|
|
280
280
|
|
|
281
281
|
- **Spawned by**: `/cbp-round-end` (Step 6)
|
|
282
|
-
- **Returns to**: `/cbp-round-end` which
|
|
282
|
+
- **Returns to**: `/cbp-round-end` which auto-applies in-scope findings inline and routes out-of-scope findings to `/cbp-round-update`
|
|
283
283
|
- **Does NOT**: Apply any changes
|
|
284
284
|
- **Reads**: Changed files, task requirements, round context
|
|
@@ -9,7 +9,7 @@ effort: xhigh
|
|
|
9
9
|
|
|
10
10
|
# Task Check Agent
|
|
11
11
|
|
|
12
|
-
AI-driven production readiness review with user satisfaction discussion.
|
|
12
|
+
AI-driven production readiness review with user satisfaction discussion. This is the **cross-round double-check** layer: per-round QA (build/lint/types per app, the `console.log`/debug scan, the OWASP/secret grep, API auth-enforcement curls, `pnpm audit`) already ran inside each round's `testing-qa-agent` — this agent does NOT re-run it. Its unique value is holistic: verifying all task requirements are met, checkpoint goals are aligned, the aggregated work is shippable, and — for tasks that span many rounds where scope can shift as new ideas/problems surface — detecting scope drift that should update the checkpoint or task rather than re-running per-round checks.
|
|
13
13
|
|
|
14
14
|
**Numeric-claim verification (Proposal P6)**: when round summaries assert numeric facts (file counts, package counts, percentage changes, line counts, version numbers), verify each via direct count: `find ... | wc -l`, `grep -c`, `wc -l <file>`. Do NOT accept narrative numbers without a verification command. Mismatches between asserted and actual counts indicate documentation drift; flag as a finding requiring a fix.
|
|
15
15
|
|
|
@@ -95,14 +95,16 @@ Check `task.files_changed`:
|
|
|
95
95
|
- List unapproved files
|
|
96
96
|
- Determine if unapproved files block completion
|
|
97
97
|
|
|
98
|
-
### Phase 6: Code Review
|
|
98
|
+
### Phase 6: Code Review (holistic spot-check)
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- No
|
|
103
|
-
- No
|
|
104
|
-
- Error handling present where needed
|
|
105
|
-
- Consistent with existing codebase patterns
|
|
100
|
+
Per-round QA already ran the line-level checks — the `console.log`/debug scan (round `testing-qa-agent` Phase 3.5), the OWASP secret/injection grep (Phase 5), the API auth-enforcement curl (Phase 3.55), and `pnpm audit` (Phase 3.7). Do NOT re-run them here. Phase 6 is a light holistic spot-check across the aggregated diff for what a single round cannot see:
|
|
101
|
+
|
|
102
|
+
- No obvious bugs or regressions that emerge only when all rounds' changes are read together
|
|
103
|
+
- No cross-round integration gaps (a field/contract introduced in one round that a later round broke)
|
|
104
|
+
- Error handling present where needed at the feature boundary
|
|
105
|
+
- Consistent with existing codebase patterns across the full task diff
|
|
106
|
+
|
|
107
|
+
If the aggregated diff surfaces an obvious issue per-round QA missed, flag it as a finding — but the per-round scans are authoritative for line-level concerns.
|
|
106
108
|
|
|
107
109
|
### Phase 7: Shippable Feature Gate
|
|
108
110
|
|
|
@@ -125,6 +127,8 @@ Update `round_outcome_analysis` with findings.
|
|
|
125
127
|
|
|
126
128
|
### Phase 9: User Satisfaction Discussion
|
|
127
129
|
|
|
130
|
+
For tasks that ran many rounds, scope drift accumulates quietly — each round may have absorbed a new idea or problem without the checkpoint/task requirements being updated. The satisfaction discussion is where that drift surfaces; treat the scope-divergence scan below as a first-class output, not an afterthought.
|
|
131
|
+
|
|
128
132
|
Present findings to user via AskUserQuestion:
|
|
129
133
|
|
|
130
134
|
```
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `codebyplan` npm package ships a small, portable set of Claude Code hooks. They run in your project, use only generic primitives (`git rev-parse`, `${CLAUDE_PROJECT_DIR}`, `${CLAUDE_PLUGIN_ROOT}`), and degrade gracefully (exit 0) when their preconditions aren't met.
|
|
4
4
|
|
|
5
|
-
Hook registration lives in [`hooks/hooks.json`](./hooks.json) —
|
|
5
|
+
Hook registration lives in [`hooks/hooks.json`](./hooks.json) — PreToolUse, PostToolUse, and UserPromptSubmit events are wired. (`Notification`, `SessionStart`, `SessionEnd`, `Stop`, and `SubagentStop` are also schema-permitted but unused here.)
|
|
6
6
|
|
|
7
7
|
**`cbp-statusline.sh` is auto-wired via `settings.project.base.json`.** The `statusLine` block is shipped inside `templates/settings.project.base.json` and merged into the consumer's `.claude/settings.json` automatically by `codebyplan claude install` (and on every `codebyplan claude update`). No manual copy-paste is required.
|
|
8
8
|
|
|
@@ -224,13 +224,32 @@ After a `complete_round` MCP call succeeds, reconciles the round's `files_change
|
|
|
224
224
|
|
|
225
225
|
---
|
|
226
226
|
|
|
227
|
+
### `cbp-context-window-notify.sh` — UserPromptSubmit
|
|
228
|
+
|
|
229
|
+
Injects a one-time notice into Claude's context when the session's total token usage
|
|
230
|
+
(input + cache-creation + cache-read tokens from the last assistant message) crosses
|
|
231
|
+
`CBP_CONTEXT_WARN_TOKENS` (default: 200000). Reads the JSONL transcript directly — not the
|
|
232
|
+
statusline payload — so the model itself, not just the status bar, is aware of a large window.
|
|
233
|
+
|
|
234
|
+
**Blocks vs warns**: never blocks — exits 0 on every path. Advisory only.
|
|
235
|
+
|
|
236
|
+
**Skips when**: `transcript_path` or `session_id` is absent from stdin, the transcript file does
|
|
237
|
+
not exist, or usage cannot be parsed (degrades to 0, below threshold).
|
|
238
|
+
|
|
239
|
+
**Re-arms**: the latch `${TMPDIR:-/tmp}/cbp-ctxwin-<session_id>.latched` is removed when usage
|
|
240
|
+
drops below threshold (e.g. after `/compact` or `/clear`), so the notice re-fires on the next crossing.
|
|
241
|
+
|
|
242
|
+
**Opt out**: set `CBP_CONTEXT_WARN_TOKENS` very high, or remove the `UserPromptSubmit` entry from settings.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
227
246
|
## Supporting (not registered)
|
|
228
247
|
|
|
229
248
|
### `test-hooks.sh` — invoked by `auto-test-hooks.sh`
|
|
230
249
|
|
|
231
250
|
Test suite for the plugin's 9 registered hooks. Runs two passes:
|
|
232
251
|
|
|
233
|
-
1. **Header check** — every registered hook (`lint-format-on-edit`, `test-coverage-gate`, `pre-commit-quality-gate`, `maestro-yaml-validate`, `auto-test-hooks`, `mcp-migration-guard`, `validate-git-stash-deny`, `cbp-mcp-round-sync`) carries the required `# Hook:` and `# Purpose:` header comments. `statusline` uses its own `# Claude Code Status Line` marker.
|
|
252
|
+
1. **Header check** — every registered hook (`lint-format-on-edit`, `test-coverage-gate`, `pre-commit-quality-gate`, `maestro-yaml-validate`, `auto-test-hooks`, `mcp-migration-guard`, `validate-git-stash-deny`, `cbp-mcp-round-sync`, `cbp-context-window-notify`) carries the required `# Hook:` and `# Purpose:` header comments. `statusline` uses its own `# Claude Code Status Line` marker.
|
|
234
253
|
2. **Functional smoke tests** — each hook is invoked with synthetic stdin matching its fast-path / graceful-degrade input; all must exit 0.
|
|
235
254
|
|
|
236
255
|
Not in `hooks.json` — invoked indirectly via `auto-test-hooks.sh` on hook edits, or directly via `bash ${CLAUDE_PLUGIN_ROOT}/hooks/test-hooks.sh`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# @scope: org-shared
|
|
3
|
+
# Hook: UserPromptSubmit
|
|
4
|
+
# Purpose: Emit a one-time notice into Claude's context when the session's total
|
|
5
|
+
# context-window usage crosses CBP_CONTEXT_WARN_TOKENS (default 200000).
|
|
6
|
+
# Reads the last assistant message.usage from the JSONL transcript
|
|
7
|
+
# (input + cache_creation + cache_read) — independent of the statusline,
|
|
8
|
+
# so the model itself, not just the status bar, knows the window is large.
|
|
9
|
+
# Latches per session so the notice fires once; re-arms after /clear or
|
|
10
|
+
# /compact drops usage below the threshold. Always exits 0 — never blocks.
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
INPUT=$(cat)
|
|
15
|
+
|
|
16
|
+
TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/null)
|
|
17
|
+
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // ""' 2>/dev/null)
|
|
18
|
+
|
|
19
|
+
[ -z "$TRANSCRIPT" ] && exit 0
|
|
20
|
+
[ -z "$SESSION_ID" ] && exit 0
|
|
21
|
+
[ ! -f "$TRANSCRIPT" ] && exit 0
|
|
22
|
+
|
|
23
|
+
THRESHOLD="${CBP_CONTEXT_WARN_TOKENS:-200000}"
|
|
24
|
+
LATCH="${TMPDIR:-/tmp}/cbp-ctxwin-${SESSION_ID}.latched"
|
|
25
|
+
|
|
26
|
+
TOTAL=$(tail -n 400 "$TRANSCRIPT" \
|
|
27
|
+
| jq -rR 'fromjson? | select(.message.usage != null)
|
|
28
|
+
| (.message.usage
|
|
29
|
+
| ((.input_tokens // 0) + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)))' \
|
|
30
|
+
2>/dev/null | tail -1) || TOTAL=0
|
|
31
|
+
|
|
32
|
+
TOTAL="${TOTAL:-0}"
|
|
33
|
+
|
|
34
|
+
if [ "$TOTAL" -ge "$THRESHOLD" ] 2>/dev/null; then
|
|
35
|
+
[ -f "$LATCH" ] && exit 0
|
|
36
|
+
touch "$LATCH"
|
|
37
|
+
jq -n --argjson tokens "$TOTAL" --argjson threshold "$THRESHOLD" \
|
|
38
|
+
'{hookSpecificOutput:{hookEventName:"UserPromptSubmit",additionalContext:("Context-window notice: total token usage has reached \($tokens) (threshold \($threshold)). The window is large — consider /compact or /clear, and be deliberate about large new reads.")}}'
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
rm -f "$LATCH" 2>/dev/null || true
|
|
43
|
+
exit 0
|
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
# staging-status flip, and web-UI flag sync to the codebyplan CLI.
|
|
6
6
|
# Replaces the inline jq merge + curl PATCH with a single CLI call.
|
|
7
7
|
#
|
|
8
|
+
# Trigger context (CHK-197): complete_round is now called by /cbp-round-complete
|
|
9
|
+
# (the permission-gated finalizer), which already runs `sync-approvals` once
|
|
10
|
+
# BEFORE completing the round. This hook firing afterward is the expected
|
|
11
|
+
# post-complete safety net — it catches approval drift between that pre-complete
|
|
12
|
+
# sync and the approval_locked write; it is NOT a duplicate run to remove.
|
|
13
|
+
# NOTE: this hook matches complete_round only; complete_standalone_round is NOT
|
|
14
|
+
# covered, so standalone rounds rely solely on /cbp-round-complete's pre-complete
|
|
15
|
+
# sync (pre-existing coverage gap, documented here intentionally — not fixed).
|
|
16
|
+
#
|
|
8
17
|
# Delegates to: npx codebyplan round sync-approvals
|
|
9
18
|
# - Git-diff drift merge (in/not-in DB vs git)
|
|
10
19
|
# - Staging-status → user_approved flip
|
|
@@ -255,6 +255,125 @@ fi
|
|
|
255
255
|
|
|
256
256
|
echo ""
|
|
257
257
|
|
|
258
|
+
# ===== HOOK SMOKE TESTS — cbp-context-window-notify =====
|
|
259
|
+
echo "## Hook Smoke Tests — cbp-context-window-notify"
|
|
260
|
+
|
|
261
|
+
HOOK="$HOOKS_DIR/cbp-context-window-notify.sh"
|
|
262
|
+
FIXTURES_CTX="$HOOKS_DIR/__test-fixtures__/cbp-context-window-notify"
|
|
263
|
+
|
|
264
|
+
if [ ! -f "$HOOK" ]; then
|
|
265
|
+
test_result "cbp-context-window-notify.sh present" "passed" "missing"
|
|
266
|
+
else
|
|
267
|
+
|
|
268
|
+
# Case 1: over-threshold → exit 0 AND stdout has .hookSpecificOutput.additionalContext
|
|
269
|
+
ISO=$(mktemp -d)
|
|
270
|
+
STDIN=$(jq -n --arg t "$FIXTURES_CTX/over-threshold.jsonl" --arg s "sid-over-$$" \
|
|
271
|
+
'{transcript_path:$t,session_id:$s}')
|
|
272
|
+
OUTPUT=$(echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" 2>/dev/null)
|
|
273
|
+
EXIT_CODE=$?
|
|
274
|
+
if [ "$EXIT_CODE" = "0" ] \
|
|
275
|
+
&& echo "$OUTPUT" | jq -e '.hookSpecificOutput.additionalContext' >/dev/null 2>&1; then
|
|
276
|
+
test_result "cbp-context-window-notify.sh over-threshold exits 0 + emits additionalContext JSON" "passed" "passed"
|
|
277
|
+
else
|
|
278
|
+
test_result "cbp-context-window-notify.sh over-threshold exits 0 + emits additionalContext JSON" "passed" "failed (exit=$EXIT_CODE output=$(echo "$OUTPUT" | head -c 80))"
|
|
279
|
+
fi
|
|
280
|
+
rm -rf "$ISO"
|
|
281
|
+
|
|
282
|
+
# Case 2: under-threshold → exit 0 AND empty stdout
|
|
283
|
+
ISO=$(mktemp -d)
|
|
284
|
+
STDIN=$(jq -n --arg t "$FIXTURES_CTX/under-threshold.jsonl" --arg s "sid-under-$$" \
|
|
285
|
+
'{transcript_path:$t,session_id:$s}')
|
|
286
|
+
OUTPUT=$(echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" 2>/dev/null)
|
|
287
|
+
EXIT_CODE=$?
|
|
288
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
289
|
+
test_result "cbp-context-window-notify.sh under-threshold exits 0 + empty stdout" "passed" "passed"
|
|
290
|
+
else
|
|
291
|
+
test_result "cbp-context-window-notify.sh under-threshold exits 0 + empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
292
|
+
fi
|
|
293
|
+
rm -rf "$ISO"
|
|
294
|
+
|
|
295
|
+
# Case 3: latch — fire once (over), second identical call (same session_id, same TMPDIR) → empty stdout
|
|
296
|
+
ISO=$(mktemp -d)
|
|
297
|
+
SID="sid-latch-$$"
|
|
298
|
+
STDIN=$(jq -n --arg t "$FIXTURES_CTX/over-threshold.jsonl" --arg s "$SID" \
|
|
299
|
+
'{transcript_path:$t,session_id:$s}')
|
|
300
|
+
echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" >/dev/null 2>&1
|
|
301
|
+
OUTPUT=$(echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" 2>/dev/null)
|
|
302
|
+
EXIT_CODE=$?
|
|
303
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
304
|
+
test_result "cbp-context-window-notify.sh latch suppresses second over-threshold call" "passed" "passed"
|
|
305
|
+
else
|
|
306
|
+
test_result "cbp-context-window-notify.sh latch suppresses second over-threshold call" "passed" "failed (exit=$EXIT_CODE)"
|
|
307
|
+
fi
|
|
308
|
+
rm -rf "$ISO"
|
|
309
|
+
|
|
310
|
+
# Case 4: re-arm — fire over (creates latch), then under → latch file removed
|
|
311
|
+
ISO=$(mktemp -d)
|
|
312
|
+
SID="sid-rearm-$$"
|
|
313
|
+
STDIN_OVER=$(jq -n --arg t "$FIXTURES_CTX/over-threshold.jsonl" --arg s "$SID" \
|
|
314
|
+
'{transcript_path:$t,session_id:$s}')
|
|
315
|
+
STDIN_UNDER=$(jq -n --arg t "$FIXTURES_CTX/under-threshold.jsonl" --arg s "$SID" \
|
|
316
|
+
'{transcript_path:$t,session_id:$s}')
|
|
317
|
+
echo "$STDIN_OVER" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" >/dev/null 2>&1
|
|
318
|
+
echo "$STDIN_UNDER" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" >/dev/null 2>&1
|
|
319
|
+
LATCH_FILE="$ISO/cbp-ctxwin-${SID}.latched"
|
|
320
|
+
if [ ! -f "$LATCH_FILE" ]; then
|
|
321
|
+
test_result "cbp-context-window-notify.sh re-arm removes latch on under-threshold" "passed" "passed"
|
|
322
|
+
else
|
|
323
|
+
test_result "cbp-context-window-notify.sh re-arm removes latch on under-threshold" "passed" "failed (latch still present)"
|
|
324
|
+
fi
|
|
325
|
+
rm -rf "$ISO"
|
|
326
|
+
|
|
327
|
+
# Case 5: cache-expired → exit 0 AND emits additionalContext JSON
|
|
328
|
+
ISO=$(mktemp -d)
|
|
329
|
+
STDIN=$(jq -n --arg t "$FIXTURES_CTX/cache-expired.jsonl" --arg s "sid-cache-$$" \
|
|
330
|
+
'{transcript_path:$t,session_id:$s}')
|
|
331
|
+
OUTPUT=$(echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" 2>/dev/null)
|
|
332
|
+
EXIT_CODE=$?
|
|
333
|
+
if [ "$EXIT_CODE" = "0" ] \
|
|
334
|
+
&& echo "$OUTPUT" | jq -e '.hookSpecificOutput.additionalContext' >/dev/null 2>&1; then
|
|
335
|
+
test_result "cbp-context-window-notify.sh cache-expired exits 0 + emits additionalContext JSON" "passed" "passed"
|
|
336
|
+
else
|
|
337
|
+
test_result "cbp-context-window-notify.sh cache-expired exits 0 + emits additionalContext JSON" "passed" "failed (exit=$EXIT_CODE)"
|
|
338
|
+
fi
|
|
339
|
+
rm -rf "$ISO"
|
|
340
|
+
|
|
341
|
+
# Case 6: graceful-degrade — empty stdin → exit 0
|
|
342
|
+
ISO=$(mktemp -d)
|
|
343
|
+
EXIT_CODE=$(echo '' | TMPDIR="$ISO" bash "$HOOK" >/dev/null 2>&1; echo $?)
|
|
344
|
+
if [ "$EXIT_CODE" = "0" ]; then
|
|
345
|
+
test_result "cbp-context-window-notify.sh graceful-degrade empty stdin exits 0" "passed" "passed"
|
|
346
|
+
else
|
|
347
|
+
test_result "cbp-context-window-notify.sh graceful-degrade empty stdin exits 0" "passed" "failed (exit=$EXIT_CODE)"
|
|
348
|
+
fi
|
|
349
|
+
rm -rf "$ISO"
|
|
350
|
+
|
|
351
|
+
# Case 7: malformed-line tolerance — a malformed/partial transcript line must NOT
|
|
352
|
+
# abort the hook (D3 "always exit 0"); the valid over-threshold line is still parsed
|
|
353
|
+
# (jq -rR 'fromjson?') and the notice still fires. The fixture lives only under
|
|
354
|
+
# .claude/hooks/__test-fixtures__; guard on its presence so this case stays
|
|
355
|
+
# byte-identical with the templates copy (which ships no __test-fixtures__ tree).
|
|
356
|
+
if [ -f "$FIXTURES_CTX/malformed.jsonl" ]; then
|
|
357
|
+
ISO=$(mktemp -d)
|
|
358
|
+
STDIN=$(jq -n --arg t "$FIXTURES_CTX/malformed.jsonl" --arg s "sid-malformed-$$" \
|
|
359
|
+
'{transcript_path:$t,session_id:$s}')
|
|
360
|
+
OUTPUT=$(echo "$STDIN" | TMPDIR="$ISO" CBP_CONTEXT_WARN_TOKENS=200000 bash "$HOOK" 2>/dev/null)
|
|
361
|
+
EXIT_CODE=$?
|
|
362
|
+
if [ "$EXIT_CODE" = "0" ] \
|
|
363
|
+
&& echo "$OUTPUT" | jq -e '.hookSpecificOutput.additionalContext' >/dev/null 2>&1; then
|
|
364
|
+
test_result "cbp-context-window-notify.sh malformed-line tolerance exits 0 + emits additionalContext JSON" "passed" "passed"
|
|
365
|
+
else
|
|
366
|
+
test_result "cbp-context-window-notify.sh malformed-line tolerance exits 0 + emits additionalContext JSON" "passed" "failed (exit=$EXIT_CODE output=$(echo "$OUTPUT" | head -c 80))"
|
|
367
|
+
fi
|
|
368
|
+
rm -rf "$ISO"
|
|
369
|
+
else
|
|
370
|
+
test_result "cbp-context-window-notify.sh malformed-line tolerance (fixture absent — templates runtime)" "passed" "passed"
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
echo ""
|
|
376
|
+
|
|
258
377
|
# ===== SUMMARY =====
|
|
259
378
|
echo "=== TEST SUMMARY ==="
|
|
260
379
|
echo -e "Passed: ${GREEN}$PASSED${NC}"
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"Skill(cbp-checkpoint-create)",
|
|
56
56
|
"Skill(cbp-checkpoint-check)",
|
|
57
57
|
"Skill(cbp-checkpoint-complete)",
|
|
58
|
-
"Skill(cbp-round-
|
|
58
|
+
"Skill(cbp-round-complete)",
|
|
59
|
+
"Skill(cbp-round-execute)",
|
|
59
60
|
"Skill(cbp-session-end)",
|
|
60
61
|
"Skill(cbp-task-complete)",
|
|
61
62
|
"Skill(cbp-standalone-task-create)",
|
|
@@ -114,9 +115,9 @@
|
|
|
114
115
|
"Skill(cbp-refresh-infra)",
|
|
115
116
|
"Skill(cbp-round-check)",
|
|
116
117
|
"Skill(cbp-round-end)",
|
|
117
|
-
"Skill(cbp-round-execute)",
|
|
118
118
|
"Skill(cbp-round-input)",
|
|
119
119
|
"Skill(cbp-round-start)",
|
|
120
|
+
"Skill(cbp-round-update)",
|
|
120
121
|
"Skill(cbp-session-start)",
|
|
121
122
|
"Skill(cbp-setup-e2e)",
|
|
122
123
|
"Skill(cbp-setup-eslint)",
|
|
@@ -31,19 +31,20 @@ Fifteen of the 16 authoring agents take the default (`cbp-cc-executor`, `cbp-dat
|
|
|
31
31
|
|
|
32
32
|
| skill | model | effort | reason |
|
|
33
33
|
| ----------------- | ------ | ------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
34
|
-
| cbp-round-end | sonnet | high | Spawns cbp-improve-round agent;
|
|
34
|
+
| cbp-round-end | sonnet | high | Spawns cbp-improve-round agent; auto-applies in-scope findings + routes out-of-scope to round-update — lighter than xhigh suffices |
|
|
35
35
|
| cbp-task-check | sonnet | high | Thin orchestrator over spawned cbp-task-check agent; inline-fallback path keeps Opus for safety |
|
|
36
36
|
| cbp-checkpoint-update | sonnet | high | Status updates + context patches mostly; lighter than xhigh |
|
|
37
37
|
| cbp-ship-main | sonnet | high | Production-impacting PR creation; keep Opus reasoning but drop effort |
|
|
38
38
|
| cbp-merge-main | sonnet | high | Long-lived-branch integration merge — surgical conflict resolution, no authoring |
|
|
39
39
|
|
|
40
|
-
### Haiku-low skills (
|
|
40
|
+
### Haiku-low skills (10)
|
|
41
41
|
|
|
42
42
|
`model: haiku` + `effort: low`. Pure mechanical / dispatch / templated work.
|
|
43
43
|
|
|
44
44
|
| skill | model | effort | reason |
|
|
45
45
|
| ---------------------- | ----- | ------ | ---------------------------------------------------------------------------------------- |
|
|
46
|
-
| cbp-round-update | haiku | low | Pure mechanical:
|
|
46
|
+
| cbp-round-update | haiku | low | Pure mechanical: triage round state (claude_approved/findings/hard_fail), route to round-complete or round-input |
|
|
47
|
+
| cbp-round-complete | haiku | low | Pure mechanical: sync-approvals git-add reconcile, complete round, route per unapproved count |
|
|
47
48
|
| cbp-round-check | haiku | low | Run build/lint/types commands, parse output, update QA |
|
|
48
49
|
| cbp-todo | haiku | low | Dispatch: single MCP call + route to next command |
|
|
49
50
|
| cbp-checkpoint-complete | haiku | low | Pure finalization — mark completed, write summary; judgment happened in checkpoint-check |
|
|
@@ -22,7 +22,7 @@ Precedence is `deny > ask > allow`; arrays union across scopes (managed/user/pro
|
|
|
22
22
|
|
|
23
23
|
### `allow` — the autonomous workflow surface
|
|
24
24
|
|
|
25
|
-
- **Non-lifecycle, non-shipment `/cbp-*` skills** — authoring (`cbp-build-cc-*`), frontend (`cbp-frontend-*`), git (`cbp-git-*`, `cbp-merge-main`, `cbp-refresh-infra`), round work (`cbp-round-check`/`-end`/`-
|
|
25
|
+
- **Non-lifecycle, non-shipment `/cbp-*` skills** — authoring (`cbp-build-cc-*`), frontend (`cbp-frontend-*`), git (`cbp-git-*`, `cbp-merge-main`, `cbp-refresh-infra`), round work (`cbp-round-check`/`-end`/`-input`/`-start`/`-update` — `cbp-round-update` is autonomous triage that only reads round state and routes to `cbp-round-complete` or `cbp-round-input`, so it runs without a prompt), setup/configure (`cbp-setup-*`, `cbp-ship-configure`, `cbp-supabase-*`), task prep (`cbp-task-check`/`-create`/`-start`/`-testing`, `cbp-standalone-task-check`/`-testing`), planning (`cbp-checkpoint-plan`/`-update`), plus `cbp-session-start` and `cbp-todo`. Invoking a skill is the intended mode of operation; the gated side effects happen inside via the Bash/MCP tools the skill calls, which carry their own tiering. The lifecycle/state-transition and plan-approval skills are the exception — they live in `ask` (next section).
|
|
26
26
|
- **All `mcp__codebyplan__*` reads** (`get_*`, `list_*`, `search_*`, `health_check`, `lookup_symbol`, `resolve_library_id`, `get_chunk`).
|
|
27
27
|
- **Routine workflow-write MCP tools** the pipeline calls many times per task: create/update/complete checkpoint, task, and round; session log + session-state writes; `create_worktree`, `add_library`, `flag_stale_chunk`, `update_server_config`, `update_eslint_repo_config`, `update_task_template`. Gating these with `ask` would make the autonomous workflow unusable.
|
|
28
28
|
- **Read/safe CLI commands** (both `codebyplan X` and `npx codebyplan X`): `whoami`, `resolve-worktree`, `statusline`, `ports`, `tech-stack`, `eslint`, `round`, `help`, `--version`.
|
|
@@ -30,7 +30,8 @@ Precedence is `deny > ask > allow`; arrays union across scopes (managed/user/pro
|
|
|
30
30
|
### `ask` — the deliberate confirm-gate
|
|
31
31
|
|
|
32
32
|
- **Production-shipment skills**: `cbp-ship`, `cbp-ship-main`, `cbp-checkpoint-end` — these promote/deploy to production, so they prompt even in an otherwise auto-allowed setup.
|
|
33
|
-
- **Lifecycle / state-transition skills**: `cbp-checkpoint-start`, `cbp-checkpoint-create`, `cbp-checkpoint-check`, `cbp-checkpoint-complete`, `cbp-round-
|
|
33
|
+
- **Lifecycle / state-transition skills**: `cbp-checkpoint-start`, `cbp-checkpoint-create`, `cbp-checkpoint-check`, `cbp-checkpoint-complete`, `cbp-round-complete`, `cbp-session-end`, `cbp-task-complete`, `cbp-standalone-task-create`, `cbp-standalone-task-start`, `cbp-standalone-task-complete` — these open or close checkpoints, tasks, rounds, and sessions (advancing workflow state in the database), so they stop for explicit confirmation rather than running autonomously. `cbp-round-complete` is the permission-gated round finalizer (reconciles the user's `git add`s, completes the round, routes onward); its `ask` prompt replaces the in-skill confirmation that used to live in `cbp-round-update` — which is now an autonomous, `allow`-tier triage step.
|
|
34
|
+
- **Plan-approval gate**: `cbp-round-execute` — the round plan is approved by confirming this `ask` prompt rather than via an in-skill AskUserQuestion. `cbp-round-start` runs its planning Q&A, then hands off to `cbp-round-execute`; the permission prompt is the user's go/no-go on the plan.
|
|
34
35
|
- **Destructive / admin MCP tools**: `delete_session_log`, `delete_worktree`, `create_repo`, `release_assignment`. (The launch and member-admin tools were dropped from the MCP surface in CHK-180 — those concerns are web-app only now.)
|
|
35
36
|
- **Mutating / external / clobber-risk CLI commands** (both prefixes): `setup`, `login`, `logout`, `upgrade-auth`, `config` (can overwrite committed `.codebyplan/` files), `branch` (rewrites branch config), `ship`, `claude` (`install`/`update`/`uninstall` overwrite `.claude/`).
|
|
36
37
|
|
|
@@ -88,7 +88,7 @@ A skill should do one thing in the pipeline. If a skill both plans AND executes,
|
|
|
88
88
|
If the skill is part of a chain, show it:
|
|
89
89
|
|
|
90
90
|
```
|
|
91
|
-
/cbp-round-start (planning) →
|
|
91
|
+
/cbp-round-start (planning) → /cbp-round-execute (ask-tier permission = plan approval)
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
### Approval Gates
|
|
@@ -42,7 +42,7 @@ Triggered by `/cbp-task-start` (Step 3.6, optional stale-check), `/cbp-task-comp
|
|
|
42
42
|
- **Cancel** — abort the skill.
|
|
43
43
|
- `unstaged_dirty=false AND staged_present=true` → print one informational line and proceed to Step 1:
|
|
44
44
|
`Staged changes detected — proceeding with merge.`
|
|
45
|
-
(Pre-staged files will be included in the merge commit at Step 2 — this is intentional; the caller already approved them via /cbp-round-
|
|
45
|
+
(Pre-staged files will be included in the merge commit at Step 2 — this is intentional; the caller already approved them via /cbp-round-complete.)
|
|
46
46
|
- `unstaged_dirty=false AND staged_present=false` → proceed silently to Step 1.
|
|
47
47
|
- Either `git diff` command exits with code ≥ 2 (git hard error — not-a-repo, detached HEAD with no commits, index lock, corrupt object store): surface the raw error output and STOP. Do NOT proceed to Step 1.
|
|
48
48
|
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-round-complete
|
|
4
|
+
description: Reconcile user git-add approvals, complete the round, and route to the next step
|
|
5
|
+
argument-hint: [chk-task-round | task-round]
|
|
6
|
+
triggers: [cbp-task-check, cbp-standalone-task-check, cbp-round-input]
|
|
7
|
+
effort: low
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Kind Detection
|
|
11
|
+
|
|
12
|
+
Inspect the resolved identifier from argument parsing to determine the task kind:
|
|
13
|
+
|
|
14
|
+
| Identifier shape | KIND |
|
|
15
|
+
|-----------------|------|
|
|
16
|
+
| `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
|
|
17
|
+
| `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
|
|
18
|
+
| _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
|
|
19
|
+
|
|
20
|
+
Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
|
|
21
|
+
|
|
22
|
+
| Operation | `checkpoint` KIND | `standalone` KIND |
|
|
23
|
+
|-----------|------------------|-------------------|
|
|
24
|
+
| Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
|
|
25
|
+
| Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
|
|
26
|
+
| Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
|
|
27
|
+
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?, caller_worktree_id)` ⚠️ `caller_worktree_id` is REQUIRED for standalone |
|
|
28
|
+
|
|
29
|
+
# Round Complete Command
|
|
30
|
+
|
|
31
|
+
The **permission-gated finalizer** for a round that `/cbp-round-update` triaged as clean. It reconciles which files the **user** approved via `git add`, completes the round, and routes to the next step.
|
|
32
|
+
|
|
33
|
+
This skill is gated by an `ask`-tier `Skill(cbp-round-complete)` permission rule in `settings.json`. **The permission prompt IS the user confirmation** — there is NO AskUserQuestion inside this skill. If the user declines the permission, the skill does not run: nothing is synced, no round is completed, and the user can stage files and re-invoke (directly or by re-running `/cbp-round-update`) when ready.
|
|
34
|
+
|
|
35
|
+
## HARD GATE — Every Step Must Execute
|
|
36
|
+
|
|
37
|
+
Step 2 (sync-approvals CLI) MUST exit 0. If it fails, do NOT proceed to Step 3. Before completing the round, verify:
|
|
38
|
+
|
|
39
|
+
- [ ] `codebyplan round sync-approvals` exited 0
|
|
40
|
+
|
|
41
|
+
If this is false: DO NOT proceed to Step 3.
|
|
42
|
+
|
|
43
|
+
## Instructions
|
|
44
|
+
|
|
45
|
+
### Step 1: Parse `$ARGUMENTS`
|
|
46
|
+
|
|
47
|
+
Parse the argument using the canonical chk-task-round notation (see `cbp-round-start` Step 0 "CHK / TASK / ROUND Identifier Notation Vocabulary"):
|
|
48
|
+
|
|
49
|
+
| Shape | Regex | Resolves to |
|
|
50
|
+
|-------|-------|-------------|
|
|
51
|
+
| `{chk}-{task}-{round}` (e.g. `108-1-2`) | `^[0-9]+-[0-9]+-[0-9]+$` | Checkpoint-bound: CHK-{chk} TASK-{task} ROUND-{round} |
|
|
52
|
+
| `{task}-{round}` (e.g. `45-2`) | `^[0-9]+-[0-9]+$` | Standalone: standalone TASK-{task} ROUND-{round} |
|
|
53
|
+
| _(empty)_ | — | Use Kind Detection to find active task and latest round |
|
|
54
|
+
|
|
55
|
+
Anything else is malformed — surface this error and stop:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
round-complete: invalid argument `{value}`. Expected:
|
|
59
|
+
108-1-2 → CHK-108 TASK-1 ROUND-2 (checkpoint-bound)
|
|
60
|
+
45-2 → standalone TASK-45 ROUND-2
|
|
61
|
+
(empty) → active task and latest round
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Note that `108-1` is **valid** here — it resolves to standalone TASK-108 ROUND-1 per the 2-segment task-round form. To target a checkpoint-bound round, use the 3-segment form `108-1-2`.
|
|
65
|
+
|
|
66
|
+
### Step 1.5: Get Current Task and Round
|
|
67
|
+
|
|
68
|
+
Given the parse from Step 1:
|
|
69
|
+
|
|
70
|
+
| Parse | Resolution path |
|
|
71
|
+
|-------|-----------------|
|
|
72
|
+
| `{chk}-{task}-{round}` | MCP `get_checkpoints(repo_id)` → filter `number === {chk}`. MCP `get_tasks(checkpoint_id)` → filter `number === {task}`. MCP `get_rounds(task_id)` → filter `number === {round}`. |
|
|
73
|
+
| `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. |
|
|
74
|
+
| _(empty)_ | Use Kind Detection: checkpoint KIND → MCP `get_current_task(repo_id)` + `get_rounds(task_id)`; standalone KIND → MCP `get_current_standalone_task(repo_id)` + `get_standalone_rounds(standalone_task_id)`. |
|
|
75
|
+
|
|
76
|
+
If no task found: `No active task. Nothing to complete.`
|
|
77
|
+
|
|
78
|
+
### Step 2: Sync git diff + approvals via CLI
|
|
79
|
+
|
|
80
|
+
Reconcile which files the user has approved by staging them. Run:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
npx codebyplan round sync-approvals --round-id <round_id> --task-id <task_id>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The CLI auto-resolves the caller worktree id with the following precedence:
|
|
87
|
+
1. `--caller-worktree-id <uuid>` override (if passed — skips all resolution)
|
|
88
|
+
2. Per-device branch-keyed cache (`.codebyplan/worktree.local.json`)
|
|
89
|
+
3. In-process tuple API call: `POST /worktrees/resolve` using `(device_id, repo_path, branch)`
|
|
90
|
+
|
|
91
|
+
On the write path (non `--dry-run`), if the worktree id cannot be resolved the CLI **hard-fails with exit 1** and prints an actionable message. To pre-populate the cache:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
npx codebyplan resolve-worktree --cache
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If this worktree is not yet registered, run `npx codebyplan setup` first, then re-run `/cbp-round-complete`.
|
|
98
|
+
|
|
99
|
+
The CLI parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task (forwarding `caller_worktree_id` on both writes so the server honors the feat-worktree lock). A **cleanly staged** file (`git add`-ed, no further unstaged changes) becomes `user_approved: true`.
|
|
100
|
+
|
|
101
|
+
Read the stdout JSON: `{ added, stale_marked, reactivated, total_files }`.
|
|
102
|
+
|
|
103
|
+
If the command exits non-zero, surface the stderr and STOP. Do NOT proceed to Step 3.
|
|
104
|
+
|
|
105
|
+
This is the **single** explicit reconcile owned by this skill. (The `cbp-mcp-round-sync.sh` PostToolUse hook fires again right after Step 3's `complete_round` — see the note below — but that is the existing post-complete safety net, not a duplicate run to schedule here.)
|
|
106
|
+
|
|
107
|
+
### Step 3: Complete the Round
|
|
108
|
+
|
|
109
|
+
Calculate duration from the round's `started_at` to now in minutes.
|
|
110
|
+
|
|
111
|
+
- **checkpoint KIND**: MCP `complete_round(round_id, duration_minutes)`.
|
|
112
|
+
- **standalone KIND**: MCP `complete_standalone_round(standalone_round_id, duration_minutes, caller_worktree_id)`. ⚠️ `caller_worktree_id` is REQUIRED — resolve via `CALLER_WT=$(npx codebyplan resolve-worktree 2>/dev/null)`. If `CALLER_WT` is empty, surface this warning and ask the user to confirm before proceeding:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
Warning: could not resolve caller_worktree_id (npx codebyplan resolve-worktree returned empty).
|
|
116
|
+
The complete_standalone_round call may be rejected by the pre-guard. Proceed anyway? (yes / no)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If the user confirms yes, proceed with `caller_worktree_id: ""`. If no, stop.
|
|
120
|
+
|
|
121
|
+
`complete_round` / `complete_standalone_round` sets the round `completed`, locks all `file_changes` for the round (`approval_locked: true`), and returns `unapproved_files[]` + `unapproved_count`. Hold those for routing.
|
|
122
|
+
|
|
123
|
+
> **PostToolUse hook note**: completing the round fires the `cbp-mcp-round-sync.sh` PostToolUse hook (matcher `mcp__codebyplan__complete_round`), which runs `sync-approvals` once more as a post-complete safety net for any approval drift between Step 2 and the lock. This is **expected** and is not double-processing — Step 2 is the pre-complete reconcile that makes `unapproved_count` accurate for routing; the hook is the existing catch-up. Note the hook matches `complete_round` only — `complete_standalone_round` is **not** covered by it (a pre-existing gap), so standalone rounds rely solely on this skill's Step 2 reconcile.
|
|
124
|
+
|
|
125
|
+
### Step 4: Route
|
|
126
|
+
|
|
127
|
+
**4a — Count files** — Display: `"Round N complete — Files: X total, Y approved, Z pending"`.
|
|
128
|
+
|
|
129
|
+
**4b — Route on `unapproved_count`** (from Step 3's `complete_round` response):
|
|
130
|
+
|
|
131
|
+
- **`unapproved_count === 0`** (every file user-approved): the user has signed off on the whole round.
|
|
132
|
+
- checkpoint KIND → auto-trigger `/cbp-task-check`.
|
|
133
|
+
- standalone KIND → auto-trigger `/cbp-standalone-task-check`.
|
|
134
|
+
- **`unapproved_count > 0`** (user withheld approval on some files): the unstaged files are the signal that more work is wanted on them. Auto-trigger `/cbp-round-input` — its Step 2 deep analysis reads exactly those `user_approved === false` files and formulates the next round's requirements. This route is **independent of how many files are staged**; round-input is reachable even when zero files were staged.
|
|
135
|
+
|
|
136
|
+
- **Degenerate auto-loop guard**: if the just-completed round had `round.context.auto_loop_mode === true` AND it was a clean exit (no `improve_round_findings[]`, no hard-fail — which is why `/cbp-round-update` triaged it to round-complete in the first place), do NOT auto-trigger `/cbp-round-input`. Its auto-loop path transcribes the prior round's findings verbatim, and a clean round has none — auto-triggering would spin on an empty input. Instead surface the clean-exit note below and STOP; the user stages the pending files and re-invokes (or runs `/cbp-round-input` manually). Persist `round.context.round_complete.degenerate_auto_loop_exit = true`.
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
## Round N Complete — Auto-loop finished clean
|
|
140
|
+
|
|
141
|
+
**Files**: X total, Y approved, Z pending
|
|
142
|
+
|
|
143
|
+
Pending files passed all checks; they are just not staged. Stage them
|
|
144
|
+
(`git add <path>`) to finish the task, or run /cbp-round-input to start
|
|
145
|
+
another round.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Persist a breadcrumb on the round via `update_round` / `update_standalone_round` per KIND: `round.context.round_complete = { staged_count, unstaged_count, route, decided_at }`.
|
|
149
|
+
|
|
150
|
+
## Key Rules
|
|
151
|
+
|
|
152
|
+
- **Permission prompt = confirmation** — gated by `ask`-tier `Skill(cbp-round-complete)`. NEVER add an AskUserQuestion to confirm running; the harness prompt is the gate. A declined permission is a clean no-op.
|
|
153
|
+
- **Step 2 (CLI) must exit 0** — if it fails, STOP before `complete_round`. The merge semantics are enforced by the CLI.
|
|
154
|
+
- **NEVER ask the user to git add files** — Step 2 only reads staging status. **NEVER stage files** — Claude does not touch the git staging area; the user's `git add` is the approval signal.
|
|
155
|
+
- **standalone KIND Step 3**: `caller_worktree_id` is REQUIRED for `complete_standalone_round` — always resolve and pass it.
|
|
156
|
+
- **Auto-triggered by `/cbp-round-update`** (clean triage), or run manually by the user.
|
|
157
|
+
|
|
158
|
+
## Integration
|
|
159
|
+
|
|
160
|
+
- **Gates**: `ask`-tier `Skill(cbp-round-complete)` permission prompt — the harness confirms before the skill runs; a decline makes NO writes. There is no in-skill AskUserQuestion.
|
|
161
|
+
- **Triggered by**: `/cbp-round-update` (auto, clean triage), or user manually
|
|
162
|
+
- **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND); delegates git+approval sync to `npx codebyplan round sync-approvals`
|
|
163
|
+
- **Writes**: MCP `complete_round` / `complete_standalone_round` (per KIND); `update_round` / `update_standalone_round` (`round_complete` breadcrumb); round+task `files_changed` written by the CLI
|
|
164
|
+
- **Triggers**: `/cbp-task-check` (checkpoint KIND, all files approved), `/cbp-standalone-task-check` (standalone KIND, all files approved), `/cbp-round-input` (some files unapproved — fires independent of staging count)
|