codebyplan 1.13.62 → 1.13.64
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 +1108 -2061
- package/package.json +1 -1
- package/templates/agents/cbp-e2e-playwright.md +10 -10
- package/templates/hooks/cbp-mcp-round-sync.sh +4 -15
- package/templates/hooks/cbp-skill-context-guard.sh +33 -13
- package/templates/hooks/cbp-test-hooks.sh +85 -0
- package/templates/hooks/hooks.json +0 -9
- package/templates/rules/architecture-map.md +6 -0
- package/templates/rules/cbp-operating-gotchas.md +13 -1
- package/templates/rules/e2e-mandatory.md +5 -0
- package/templates/rules/model-invocation-convention.md +1 -1
- package/templates/rules/scope-vocabulary.md +5 -0
- package/templates/rules/supabase-branch-lifecycle.md +2 -2
- package/templates/rules/task-routing-recommendation.md +1 -1
- package/templates/rules/todo-backend.md +11 -8
- package/templates/settings.project.base.json +9 -12
- package/templates/skills/cbp-build-cc-agent/SKILL.md +3 -0
- package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +31 -0
- package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +6 -0
- package/templates/skills/cbp-build-cc-agent/templates/agent.md +1 -0
- package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +11 -4
- package/templates/skills/cbp-build-cc-skill/SKILL.md +1 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +14 -0
- package/templates/skills/cbp-build-cc-skill/templates/skill.md +1 -0
- package/templates/skills/cbp-checkpoint-create/SKILL.md +12 -22
- package/templates/skills/cbp-checkpoint-end/SKILL.md +37 -0
- package/templates/skills/cbp-checkpoint-plan/SKILL.md +10 -8
- package/templates/skills/cbp-checkpoint-start/SKILL.md +27 -19
- package/templates/skills/cbp-checkpoint-update/SKILL.md +1 -1
- package/templates/skills/cbp-clear-prep/SKILL.md +1 -1
- package/templates/skills/cbp-finalize/SKILL.md +2 -2
- package/templates/skills/cbp-finalize/reference/checkpoint-done-branching.md +1 -1
- package/templates/skills/cbp-finalize/reference/next-step-heuristic.md +1 -1
- package/templates/skills/cbp-round-complete/SKILL.md +3 -24
- package/templates/skills/cbp-round-plan/SKILL.md +1 -1
- package/templates/skills/cbp-session-end/SKILL.md +40 -30
- package/templates/skills/cbp-session-start/SKILL.md +7 -7
- package/templates/skills/cbp-session-start/qa-regression.md +32 -25
- package/templates/skills/cbp-standalone-task-complete/SKILL.md +2 -5
- package/templates/skills/cbp-standalone-task-create/SKILL.md +5 -13
- package/templates/skills/cbp-standalone-task-start/SKILL.md +10 -10
- package/templates/skills/cbp-task-create/SKILL.md +1 -1
- package/templates/skills/cbp-task-start/SKILL.md +10 -10
- package/templates/skills/cbp-todo/SKILL.md +23 -38
- package/templates/skills/cbp-todo/qa-regression.md +21 -27
- package/templates/skills/cbp-verify/reference/round-scope.md +1 -2
- package/templates/hooks/cbp-mcp-caller-worktree-inject.sh +0 -78
|
@@ -97,6 +97,7 @@ Key fields by use case:
|
|
|
97
97
|
| Manual-only workflow | `disable-model-invocation: true` |
|
|
98
98
|
| Hide from `/` menu | `user-invocable: false` |
|
|
99
99
|
| Pre-approve tools | `allowed-tools: Bash(git add *) Bash(git commit *)` |
|
|
100
|
+
| Block specific tools | `disallowed-tools: Write, Edit` (denylist applied before `allowed-tools`; blocks those tools for the duration of the skill) |
|
|
100
101
|
| Accept arguments | `argument-hint: [file] [mode]`, optionally `arguments: [file mode]` for named `$file`/`$mode` |
|
|
101
102
|
| Set model + effort | `model: inherit` (the standard value — explicitly signals session-model inheritance) and `effort: xhigh` (default for plugin skills; lower tiers `high`/`medium`/`low` per [/cbp-build-cc-mode](../build-cc-mode/SKILL.md)). A non-`inherit` model pin forces a model the user didn't choose and can carry the session's 1M `[1m]` tier onto the skill (→ "usage credits required for 1M context"), so pin only as a deliberate, documented exception |
|
|
102
103
|
| Path-scoped auto-load | `paths: ["src/api/**/*.ts"]` |
|
|
@@ -12,6 +12,7 @@ Source: official Claude Code skills spec. All fields are optional; `description`
|
|
|
12
12
|
| `disable-model-invocation` | `true` → only user can invoke (via `/name`). Upstream skills that auto-trigger this skill MUST emit a `Next: /name` directive instead — model invocation is blocked by the runtime; see SKILL.md Step 4 "Convention: User-only / permission-gated finalizer" |
|
|
13
13
|
| `user-invocable` | `false` → hidden from `/` menu, Claude-only |
|
|
14
14
|
| `allowed-tools` | Pre-approve tools while the skill is active |
|
|
15
|
+
| `disallowed-tools` | Denylist tools blocked while the skill is active — complement to `allowed-tools`. Applied before `allowed-tools`; e.g. `disallowed-tools: Write, Edit` prevents those tools even if the session allows them |
|
|
15
16
|
| `model` | Model for this skill's turn. **CBP skills set `model: inherit`** (the standard value — explicitly signals session-model inheritance). A non-`inherit` pin (e.g. `sonnet`) forces that model and can carry the session's 1M `[1m]` context tier onto the skill, triggering "usage credits required for 1M context"; use only as a deliberate, documented exception — see [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) |
|
|
16
17
|
| `effort` | Override effort level (`low`/`medium`/`high`/`xhigh`/`max`). **Plugin skills authored in CBP MUST set this explicitly** (no commented-out placeholder); defaults to `xhigh`. See [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) for the matrix |
|
|
17
18
|
| `context` | `fork` → run in a subagent |
|
|
@@ -39,3 +40,16 @@ Total skill-description budget in context: 1% of the context window (fallback 8,
|
|
|
39
40
|
| `user-invocable: false` | No | Yes | Description in context; body loads on auto-invoke |
|
|
40
41
|
|
|
41
42
|
> **Upstream-directive rule**: a skill with `disable-model-invocation: true` cannot be invoked by another skill. Any upstream skill that auto-triggers it MUST emit a `Next: /skill-name` close-out directive and stop. See "Convention: User-only / permission-gated finalizer" in SKILL.md Step 4 for the full pattern and canonical example.
|
|
43
|
+
|
|
44
|
+
## `context: fork` + `agent:` interplay
|
|
45
|
+
|
|
46
|
+
`agent:` is **ignored by the runtime unless `context: fork` is also set**. When both are present, the skill body runs in the named agent's context (isolated subagent). Built-in agent types: `Explore`, `Plan`, `general-purpose`, or any custom agent name. Note that `Explore`/`Plan` subagents skip the project `CLAUDE.md` — they have no inherited session context. Use `general-purpose` (or a custom agent) when the forked skill needs CLAUDE.md to be in scope.
|
|
47
|
+
|
|
48
|
+
## CBP-only fields (not read by Claude Code)
|
|
49
|
+
|
|
50
|
+
Two fields in CBP `.claude/` structural files are **CBP framework metadata** — they are NOT part of the official Claude Code skills spec and are not read by the Claude Code runtime:
|
|
51
|
+
|
|
52
|
+
| Field | Purpose |
|
|
53
|
+
|-------|---------|
|
|
54
|
+
| `scope:` | Distribution class — `org-shared` \| `project-shared` \| `repo-only:<repo-name>`. Required only on user-created skills (no template twin). Package-managed skills are `org-shared` by default and need no marker. See [rules/scope-vocabulary.md](../../../../rules/scope-vocabulary.md) |
|
|
55
|
+
| `triggers:` | CBP pipeline routing documentation only — describes when the skill auto-fires in the CBP pipeline. Has no runtime effect; Claude Code does not read it |
|
|
@@ -8,6 +8,7 @@ description: What this skill does and when to use it. Front-load the key use cas
|
|
|
8
8
|
# disable-model-invocation: false # true = only user can invoke via /name
|
|
9
9
|
# user-invocable: true # false = only Claude can invoke (hidden from / menu)
|
|
10
10
|
# allowed-tools: Read, Grep, Glob, Bash(git status *)
|
|
11
|
+
# disallowed-tools: Write, Edit # tools blocked while the skill is active (complement to allowed-tools)
|
|
11
12
|
# model: # OMIT to inherit the session model (recommended). A pinned model can carry the session's 1M [1m] tier and require usage credits — pin only as a documented exception (see /cbp-build-cc-mode)
|
|
12
13
|
# review effort with /cbp-build-cc-mode if the default doesn't fit this skill's purpose
|
|
13
14
|
effort: xhigh
|
|
@@ -60,35 +60,25 @@ Skip when the description has zero domain matches OR the user already named a ta
|
|
|
60
60
|
|
|
61
61
|
Lightweight inference from the description — no deep analysis. **Title**: concise, ≤80 chars. **Goal**: ≤300 chars, a faithful restatement of intent (not a plan).
|
|
62
62
|
|
|
63
|
-
### Step 6:
|
|
64
|
-
|
|
65
|
-
Ask the user via AskUserQuestion whether to claim this checkpoint now:
|
|
66
|
-
|
|
67
|
-
- **Claim for me + this worktree** (default) — resolve `npx codebyplan resolve-worktree 2>/dev/null` and set it as the checkpoint `worktree_id` at create. The creator carries momentum straight through plan → start.
|
|
68
|
-
- **Leave it open** — create with `worktree_id` null so anyone free can claim it later via `/cbp-checkpoint-start`.
|
|
69
|
-
|
|
70
|
-
Record the choice; it drives both the create call (Step 7) and the plan→start routing in `/cbp-checkpoint-plan`.
|
|
71
|
-
|
|
72
|
-
### Step 7: Create Checkpoint Row
|
|
63
|
+
### Step 6: Create Checkpoint Row
|
|
73
64
|
|
|
74
65
|
`codebyplan checkpoint create` (CLI write-through: writes `.codebyplan/state/checkpoints/<id>.json` + REST). Pass flags:
|
|
75
66
|
- `--repo-id` (from `.codebyplan/repo.json`), `--title`, `--goal`, `--deadline`, `--status pending`
|
|
76
67
|
- `--ideas` JSON `[{ description: <raw user text> }]`
|
|
77
|
-
- `--worktree-id` the resolved worktree **only if the user chose "claim"**; omit when "leave open"
|
|
78
68
|
|
|
79
|
-
Do **not** pass `--number` — the database auto-assigns the next per-repo checkpoint number via a `BEFORE INSERT` trigger (advisory-locked `MAX(number)+1` scoped to `repo_id`). The DB-assigned number comes back on the created row (and is written into `.codebyplan/state/checkpoints/<id>.json`); read it for the branch slug (Step
|
|
69
|
+
Do **not** pass `--number` — the database auto-assigns the next per-repo checkpoint number via a `BEFORE INSERT` trigger (advisory-locked `MAX(number)+1` scoped to `repo_id`). The DB-assigned number comes back on the created row (and is written into `.codebyplan/state/checkpoints/<id>.json`); read it for the branch slug (Step 7) and the result display (Step 8).
|
|
80
70
|
|
|
81
71
|
Break-glass fallback: MCP `create_checkpoint` (also omit `number`) when the CLI is unavailable.
|
|
82
72
|
|
|
83
|
-
|
|
73
|
+
Assignment (`assigned_user_id`) is stamped server-side from the caller's JWT when the checkpoint is activated via `/cbp-checkpoint-start` — it is not set at create time. No `context`, `research`, `plan`, or tasks are written here.
|
|
84
74
|
|
|
85
|
-
### Step
|
|
75
|
+
### Step 7: Create + Switch to Feat Branch
|
|
86
76
|
|
|
87
|
-
`{NNN}` below is the DB-assigned checkpoint number read back from the Step
|
|
77
|
+
`{NNN}` below is the DB-assigned checkpoint number read back from the Step 6 `codebyplan checkpoint create` response.
|
|
88
78
|
|
|
89
79
|
Read `.codebyplan/git.json` `branch_config.production` (default `"main"`) as `BASE`. codebyplan repos are main-only — never create or branch from a `development`/integration branch.
|
|
90
80
|
|
|
91
|
-
**
|
|
81
|
+
**7.1 — Reuse the cloud-created branch when present.** When the repo is GitHub-connected, the CHK-207 `create-feat-branch` Edge Function fires on the Step 6 row INSERT, creates `feat/CHK-{NNN}-<slug>` on origin, and writes `branch_name` back to the checkpoint row. Creating a second, differently-slugged branch here orphans the cloud one — so re-read the row first:
|
|
92
82
|
|
|
93
83
|
```bash
|
|
94
84
|
sleep 5 # give the INSERT webhook a moment to write branch_name back
|
|
@@ -96,14 +86,14 @@ npx codebyplan sync 2>/dev/null || true
|
|
|
96
86
|
BRANCH=$(jq -r '.branch_name // empty' ".codebyplan/state/checkpoints/{checkpoint-id}.json" 2>/dev/null)
|
|
97
87
|
```
|
|
98
88
|
|
|
99
|
-
(Break-glass: MCP `get_checkpoints` and read the row's `branch_name`.) If `BRANCH` is non-empty, check out the existing remote branch and skip
|
|
89
|
+
(Break-glass: MCP `get_checkpoints` and read the row's `branch_name`.) If `BRANCH` is non-empty, check out the existing remote branch and skip 7.2 entirely — do NOT push (it already exists on origin) and do NOT persist `--branch-name` (the Edge Function already recorded it):
|
|
100
90
|
|
|
101
91
|
```bash
|
|
102
92
|
git fetch origin "$BRANCH"
|
|
103
93
|
git checkout -b "$BRANCH" --track "origin/$BRANCH"
|
|
104
94
|
```
|
|
105
95
|
|
|
106
|
-
**
|
|
96
|
+
**7.2 — Fallback: create the branch locally.** Only when `BRANCH` is empty (repo not GitHub-connected, or the webhook hasn't landed). Compute the slug deterministically:
|
|
107
97
|
|
|
108
98
|
```bash
|
|
109
99
|
SLUG=$(codebyplan slug "{checkpoint title}")
|
|
@@ -122,13 +112,13 @@ Persist the branch via `codebyplan checkpoint update --id <checkpoint-id> --bran
|
|
|
122
112
|
|
|
123
113
|
**Note — Supabase preview branch**: no Supabase branch is created here. Creation is lazy — it happens on the first DB change when `/cbp-supabase-migrate` runs on this feat branch, which provisions a Supabase branch named identically to the git branch. See `cbp-supabase-migrate` Step 2.3 for the creation protocol.
|
|
124
114
|
|
|
125
|
-
### Step
|
|
115
|
+
### Step 8: Show Result + Auto-Trigger Plan
|
|
126
116
|
|
|
127
117
|
```
|
|
128
118
|
## Checkpoint Created
|
|
129
119
|
|
|
130
120
|
**CHK-NNN**: [title] • **Deadline**: [date] • **Branch**: feat/CHK-NNN-slug
|
|
131
|
-
**
|
|
121
|
+
**Assignment**: stamped on activation via /cbp-checkpoint-start
|
|
132
122
|
**Worktree**: `npx codebyplan worktree add CHK-{NNN}`
|
|
133
123
|
|
|
134
124
|
Now planning CHK-NNN… handing off to /cbp-checkpoint-plan.
|
|
@@ -139,6 +129,6 @@ Auto-trigger `/cbp-checkpoint-plan {NNN}` in the same context. This skill create
|
|
|
139
129
|
## Integration
|
|
140
130
|
|
|
141
131
|
- **Runs inline**: mechanical setup only — no assessment, research, Q&A, plan, or tasks
|
|
142
|
-
- **Reads**: `.codebyplan/state/checkpoints/*.json` (local-first; `npx codebyplan sync` if stale; MCP `get_checkpoints` break-glass); `.codebyplan/repo.json`, `.codebyplan/git.json
|
|
143
|
-
- **Writes**: `codebyplan checkpoint create` (description-only ideas + deadline
|
|
132
|
+
- **Reads**: `.codebyplan/state/checkpoints/*.json` (local-first; `npx codebyplan sync` if stale; MCP `get_checkpoints` break-glass); `.codebyplan/repo.json`, `.codebyplan/git.json`
|
|
133
|
+
- **Writes**: `codebyplan checkpoint create` (description-only ideas + deadline), `codebyplan checkpoint update --branch-name` (break-glass: MCP `create_checkpoint` / `update_checkpoint`)
|
|
144
134
|
- **Triggers**: `/cbp-checkpoint-plan` (auto)
|
|
@@ -265,6 +265,41 @@ After the feat branch git delete, run the same conditional Supabase teardown for
|
|
|
265
265
|
- If not found: no-op silently — idempotent, not-found is success.
|
|
266
266
|
- If the `list_branches` call itself fails (network, auth, or a non-success response — distinct from a successful lookup that returns no match): emit a non-blocking warning that the Supabase preview branch for `$FEAT_BRANCH` may still exist and should be verified in the dashboard. Do not treat an API failure as a not-found success.
|
|
267
267
|
|
|
268
|
+
### Step 9.5: Physical Git-Worktree Cleanup
|
|
269
|
+
|
|
270
|
+
After the feat branch has been git-deleted (Step 9), check whether a git worktree is still
|
|
271
|
+
checked out to that now-deleted branch and clean it up if safe.
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
git worktree list --porcelain
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Scan the output for any `worktree` entry whose `branch` field matches `refs/heads/$FEAT_BRANCH`
|
|
278
|
+
(i.e. the feat branch just deleted in Step 9). For each matching worktree path:
|
|
279
|
+
|
|
280
|
+
**Case A — the current session is NOT inside that worktree path:**
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
codebyplan worktree remove <path>
|
|
284
|
+
git worktree prune
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Record the removed path in `WORKTREES_REMOVED[]`. If `codebyplan worktree remove` exits
|
|
288
|
+
non-zero, emit a non-blocking warning and continue — a failed removal does not halt shipment.
|
|
289
|
+
|
|
290
|
+
**Case B — the current session IS inside that worktree path (i.e. `$PWD` starts with
|
|
291
|
+
`<path>`):**
|
|
292
|
+
|
|
293
|
+
Do NOT self-remove. Surface a single directive (no A/B/C menu):
|
|
294
|
+
|
|
295
|
+
> "This session is inside the worktree at `<path>`. After switching to your main checkout,
|
|
296
|
+
> run `codebyplan worktree remove <path>` to clean it up."
|
|
297
|
+
|
|
298
|
+
Record the path in `WORKTREES_REMOVED[]` as `{ path, status: 'pending_manual_cleanup' }`.
|
|
299
|
+
|
|
300
|
+
If `git worktree list --porcelain` finds no worktree checked out to the deleted feat branch,
|
|
301
|
+
skip this step silently — `WORKTREES_REMOVED` stays empty.
|
|
302
|
+
|
|
268
303
|
### Step 10: Save Shipment Results and Summary
|
|
269
304
|
|
|
270
305
|
Update checkpoint context via `codebyplan checkpoint update <id> --context '{"shipment": {...}}'` (CLI write-through); use MCP `update_checkpoint` as documented break-glass when the CLI is unavailable. The `shipment` block contains both branch promotion AND runtime surface results (from `/cbp-ship` Step 7):
|
|
@@ -280,6 +315,7 @@ context.shipment: {
|
|
|
280
315
|
stale_branches_cleaned: [list of deleted git branches],
|
|
281
316
|
feat_branch_deleted: true/false,
|
|
282
317
|
supabase_branches_deleted: [list of Supabase preview branch names removed in Steps 8–9],
|
|
318
|
+
worktrees_removed: WORKTREES_REMOVED, // from Step 9.5 — paths removed or pending manual cleanup
|
|
283
319
|
e2e_images_uploaded: E2E_IMAGES_UPLOADED // from Step 7.5 — { count, stored_paths, skipped, error? } (CHK-171)
|
|
284
320
|
}
|
|
285
321
|
```
|
|
@@ -310,6 +346,7 @@ Present summary:
|
|
|
310
346
|
- Stale branches deleted: [N] ([list])
|
|
311
347
|
- Feat branch: [deleted/kept]
|
|
312
348
|
- Supabase preview branches deleted: [N] ([list from supabase_branches_deleted], or "none")
|
|
349
|
+
- Git worktrees cleaned: [N] ([paths from worktrees_removed], or "none")
|
|
313
350
|
|
|
314
351
|
### Before/After Branch State
|
|
315
352
|
- Before: [list of feat/* branches]
|
|
@@ -8,7 +8,7 @@ effort: xhigh
|
|
|
8
8
|
|
|
9
9
|
# Checkpoint Plan Command
|
|
10
10
|
|
|
11
|
-
Runs INLINE (no subagent) — all analysis and Q&A stay in the main session. This is the rigour stage that prevents half-baked plans: it discovers shortcomings, decides whether existing dependencies suffice or a new one is warranted, compares competing approaches, and only THEN creates tasks. It produces `plan.steps[]` + tasks but **never activates the checkpoint and never claims a user
|
|
11
|
+
Runs INLINE (no subagent) — all analysis and Q&A stay in the main session. This is the rigour stage that prevents half-baked plans: it discovers shortcomings, decides whether existing dependencies suffice or a new one is warranted, compares competing approaches, and only THEN creates tasks. It produces `plan.steps[]` + tasks but **never activates the checkpoint and never claims a user** — that is `/cbp-checkpoint-start`.
|
|
12
12
|
|
|
13
13
|
## Pipeline
|
|
14
14
|
|
|
@@ -37,7 +37,7 @@ Malformed (non-numeric, contains `-`): surface `checkpoint-plan: invalid argumen
|
|
|
37
37
|
2. Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`) — load existing tasks. This sets the mode:
|
|
38
38
|
- **fresh** — zero tasks: full plan + create all tasks.
|
|
39
39
|
- **additive re-plan** — tasks exist: gap-analyse against them; only ADD new tasks or refine requirements for gaps. NEVER delete or overwrite an in-flight task.
|
|
40
|
-
3. Note whether `
|
|
40
|
+
3. Note whether `assigned_user_id` is set (claimed at activation) — drives routing in Step 11.
|
|
41
41
|
|
|
42
42
|
### Step 2: Assess Ideas + Codebase
|
|
43
43
|
|
|
@@ -134,16 +134,18 @@ Final write of the complete `checkpoint.context` JSONB via `codebyplan checkpoin
|
|
|
134
134
|
...
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
This skill does **NOT** activate the checkpoint and does **NOT** claim a user
|
|
137
|
+
This skill does **NOT** activate the checkpoint and does **NOT** claim a user.
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
Resolve the current user: `npx codebyplan whoami --json` → `user_id`.
|
|
140
|
+
|
|
141
|
+
- **Open or yours** — `whoami` returns a `user_id` AND `assigned_user_id` is either null (unclaimed) or equals caller `user_id`: auto-trigger `/cbp-checkpoint-start` in the same context. `assigned_user_id` is stamped on activation, so a freshly-created checkpoint (null) is claimed by `/cbp-checkpoint-start` itself — the creator carries momentum into activation.
|
|
142
|
+
- **Owned by another, or no identity** — `assigned_user_id` is non-null and differs from caller `user_id`, or `whoami` returns no `user_id`: surface a single directive — `Next: /cbp-checkpoint-start` — so the owning session (or anyone free, if open) claims and starts it. Never auto-activate a checkpoint owned by a different user.
|
|
141
143
|
|
|
142
144
|
## Integration
|
|
143
145
|
|
|
144
|
-
- **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json`, `session/current.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`, `get_tasks`)
|
|
146
|
+
- **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json`, `session/current.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`, `get_tasks`); `npx codebyplan whoami --json`
|
|
145
147
|
- **Writes**: `codebyplan checkpoint update` (ideas assessment, context, plan, research), `codebyplan task create` (break-glass: MCP `update_checkpoint`, `create_task`)
|
|
146
148
|
- **Spawns**: `cbp-research` (level 2+ only), config-matched `cbp-e2e-*` specialist (opt-in discovery probe, `whole_checkpoint_mode` — see `context/testing/e2e.md` dispatch contract)
|
|
147
149
|
- **Triggered by**: `/cbp-checkpoint-create` (auto), or user directly
|
|
148
|
-
- **Triggers**: `/cbp-checkpoint-start` (auto when
|
|
149
|
-
- **Never**: activates the checkpoint or claims a user
|
|
150
|
+
- **Triggers**: `/cbp-checkpoint-start` (auto when open/unclaimed or assigned to the current user; directive when owned by another or no identity)
|
|
151
|
+
- **Never**: activates the checkpoint or claims a user — that is `/cbp-checkpoint-start`
|
|
@@ -8,7 +8,7 @@ effort: high
|
|
|
8
8
|
|
|
9
9
|
# Checkpoint Start Command
|
|
10
10
|
|
|
11
|
-
The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` produces tasks but deliberately leaves the checkpoint `pending` and
|
|
11
|
+
The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` produces tasks but deliberately leaves the checkpoint `pending` and unclaimed so it can sit in a team queue. This skill flips it to `active` — the server auto-stamps `assigned_user_id` from the caller's JWT on activation — and routes into the first task.
|
|
12
12
|
|
|
13
13
|
## Pipeline
|
|
14
14
|
|
|
@@ -20,7 +20,13 @@ The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` p
|
|
|
20
20
|
|
|
21
21
|
### Step 0: Parse `$ARGUMENTS`
|
|
22
22
|
|
|
23
|
-
Source `repo_id` from `.codebyplan/repo.json`. Resolve
|
|
23
|
+
Source `repo_id` from `.codebyplan/repo.json`. Resolve the current user once for the whole skill:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx codebyplan whoami --json # → {"user_id":"<uuid>","email":"…"} or null
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`USER_ID` = `user_id` from the result (may be null for anonymous/keychain-empty callers).
|
|
24
30
|
|
|
25
31
|
| Shape | Resolves to |
|
|
26
32
|
|-------|-------------|
|
|
@@ -31,55 +37,57 @@ Malformed (non-numeric, contains `-`): surface `checkpoint-start: invalid argume
|
|
|
31
37
|
|
|
32
38
|
### Step 1: Load Checkpoint + Tasks
|
|
33
39
|
|
|
34
|
-
Read `.codebyplan/state/checkpoints/<id>.json` for `status`, `
|
|
40
|
+
Read `.codebyplan/state/checkpoints/<id>.json` for `status`, `assigned_user_id`, `plan` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`).
|
|
35
41
|
|
|
36
42
|
### Step 2: Planned-Gate
|
|
37
43
|
|
|
38
44
|
A checkpoint must be planned before it can start.
|
|
39
45
|
|
|
40
|
-
- **No tasks AND empty `plan.steps[]`** → refuse: surface `CHK-NNN is not planned yet.` and auto-trigger `/cbp-checkpoint-plan {NNN}`. STOP. (An unplanned checkpoint is
|
|
46
|
+
- **No tasks AND empty `plan.steps[]`** → refuse: surface `CHK-NNN is not planned yet.` and auto-trigger `/cbp-checkpoint-plan {NNN}`. STOP. (An unplanned checkpoint is unassigned, so there is nothing to own yet — always kick off planning, matching `/cbp-todo` Rule A.)
|
|
41
47
|
- **Already `active`** → no activation needed; skip to Step 3 for a claim-check only, then Step 5.
|
|
42
48
|
- **`pending` with tasks** → proceed.
|
|
43
49
|
|
|
44
50
|
### Step 3: Claim Logic
|
|
45
51
|
|
|
46
|
-
Compare the checkpoint's `
|
|
52
|
+
Compare the checkpoint's `assigned_user_id` against `USER_ID`:
|
|
47
53
|
|
|
48
|
-
| Checkpoint `
|
|
49
|
-
|
|
50
|
-
| null (
|
|
51
|
-
| equals `
|
|
52
|
-
| a DIFFERENT
|
|
54
|
+
| Checkpoint `assigned_user_id` | Action |
|
|
55
|
+
|-------------------------------|--------|
|
|
56
|
+
| null (open — not yet claimed) | Proceed to Step 4 activation. The server will stamp `assigned_user_id = USER_ID` (from JWT) on `status=active`. If `USER_ID` is null (anonymous caller), warn the checkpoint will stay unclaimed and proceed. |
|
|
57
|
+
| equals `USER_ID` | Already yours — no-op. Proceed to Step 5. |
|
|
58
|
+
| a DIFFERENT user (non-null) | STOP. Surface: `CHK-NNN is assigned to user <assigned_user_id-email-or-uuid>; you are <USER_ID-email-or-uuid>. Ask the owner to release the assignment, or a maintainer can use the release_assignment tool, then re-run /cbp-checkpoint-start.` Do not activate. |
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
Never wrest a checkpoint from another user.
|
|
55
61
|
|
|
56
62
|
### Step 4: Activate
|
|
57
63
|
|
|
58
|
-
If the checkpoint is already `active` AND `
|
|
64
|
+
If the checkpoint is already `active` AND `assigned_user_id` already equals `USER_ID` (the Step 3 no-op row), skip this step entirely and proceed to Step 5 — nothing to write.
|
|
65
|
+
|
|
66
|
+
Otherwise set the checkpoint `active` via `codebyplan checkpoint update --id <checkpoint-id> --status active` (CLI write-through; break-glass: MCP `update_checkpoint`). The server auto-stamps `assigned_user_id = ctx.userId` (from the JWT) on activation — no client-side user param required. After the write, read the row back to confirm `assigned_user_id` is non-null.
|
|
59
67
|
|
|
60
|
-
|
|
68
|
+
If the checkpoint was already `active` but `assigned_user_id` is still null (edge case: prior activation without a valid JWT), re-read and surface a warning rather than silently proceeding.
|
|
61
69
|
|
|
62
70
|
### Step 5: Route
|
|
63
71
|
|
|
64
72
|
Follow the close-out routing convention — auto-trigger the next same-context step, never an A/B/C menu. `{first-pending-task}` is the lowest-numbered pending task from Step 1 (not necessarily TASK-1, since additive re-planning may have completed earlier ones):
|
|
65
73
|
|
|
66
|
-
- **Claimed by THIS session** (`
|
|
67
|
-
- **`
|
|
74
|
+
- **Claimed by THIS session** (`USER_ID` is non-null and now owns the checkpoint): auto-trigger `/cbp-task-start {chk}-{first-pending-task}` in the same context.
|
|
75
|
+
- **`USER_ID` null / anonymous**: surface a single directive — `Next: /cbp-task-start {chk}-{first-pending-task}` — and let the user proceed.
|
|
68
76
|
|
|
69
77
|
Show a one-line confirmation before routing:
|
|
70
78
|
|
|
71
79
|
```
|
|
72
80
|
## Checkpoint Started
|
|
73
81
|
|
|
74
|
-
**CHK-NNN**: [title] • **Status**: active • **Claimed by**: [
|
|
82
|
+
**CHK-NNN**: [title] • **Status**: active • **Claimed by**: [user email or "open"]
|
|
75
83
|
**Next task**: TASK-[N] — [title]
|
|
76
84
|
**Worktree**: `npx codebyplan worktree add CHK-{NNN}`
|
|
77
85
|
```
|
|
78
86
|
|
|
79
87
|
## Integration
|
|
80
88
|
|
|
81
|
-
- **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_checkpoints`, `get_tasks`); `npx codebyplan
|
|
82
|
-
- **Writes**: `codebyplan checkpoint update --status active
|
|
83
|
-
- **Triggered by**: `/cbp-checkpoint-plan` (auto when
|
|
89
|
+
- **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_checkpoints`, `get_tasks`); `npx codebyplan whoami --json`
|
|
90
|
+
- **Writes**: `codebyplan checkpoint update --status active` (CLI write-through; break-glass: MCP `update_checkpoint`; server auto-stamps `assigned_user_id` from JWT on activation)
|
|
91
|
+
- **Triggered by**: `/cbp-checkpoint-plan` (auto when open/unclaimed or assigned to the current user), `/cbp-todo` (planned-but-pending gate), or user directly
|
|
84
92
|
- **Triggers**: `/cbp-task-start` (auto when claimed), or `/cbp-checkpoint-plan` (when the checkpoint is unplanned)
|
|
85
93
|
- **Never**: plans or creates tasks — that is `/cbp-checkpoint-plan`
|
|
@@ -43,7 +43,7 @@ Given the parse from Step 0.5:
|
|
|
43
43
|
| Parse | Resolution path |
|
|
44
44
|
|-------|-----------------|
|
|
45
45
|
| `{chk}` | Scan `.codebyplan/state/checkpoints/*.json` for `number === {chk}` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). |
|
|
46
|
-
| _(empty)_ | Read `.codebyplan/state/session/current.json`
|
|
46
|
+
| _(empty)_ | Read `.codebyplan/state/session/current.json` to find the active checkpoint (fallback: MCP `get_current_task`). If no active checkpoint, scan local state for `pending` checkpoints (fallback: MCP `get_checkpoints` filtered by `pending`). |
|
|
47
47
|
|
|
48
48
|
### Step 1.5: Detect Entry Context (from `/cbp-finalize` expand path)
|
|
49
49
|
|
|
@@ -119,4 +119,4 @@ The user must run both commands manually.
|
|
|
119
119
|
- **Writes**: `.codebyplan/clear/handoff.md`
|
|
120
120
|
- **Next**: user runs `/clear`, then `/cbp-clear-continue`
|
|
121
121
|
- **Companion**: `.claude/skills/cbp-clear-continue/SKILL.md` reads `.codebyplan/clear/handoff.md`
|
|
122
|
-
- **Guard hook**: `.claude/hooks/cbp-skill-context-guard.sh` — fires when context
|
|
122
|
+
- **Guard hook**: `.claude/hooks/cbp-skill-context-guard.sh` — fires when context exceeds the model-aware threshold: `CBP_CONTEXT_WARN_TOKENS` (default 200000) for standard models; `CBP_CONTEXT_WARN_TOKENS_1M` (default 800000) for `[1m]`-context models. No model id found → standard tier (fail-conservative).
|
|
@@ -153,7 +153,7 @@ Show the completion summary:
|
|
|
153
153
|
**Warnings**: [any QA / file-approval warnings from Step 3, or "none"]
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
Then route. Same-context transitions (next task in this checkpoint) auto-trigger `cbp-task-start` via the Skill tool. Checkpoint-done (last task) also auto-triggers `cbp-checkpoint-check` via the Skill tool (`ask`-tier — the permission prompt is the human gate; the
|
|
156
|
+
Then route. Same-context transitions (next task in this checkpoint) auto-trigger `cbp-task-start` via the Skill tool. Checkpoint-done (last task) also auto-triggers `cbp-checkpoint-check` via the Skill tool (`ask`-tier — the permission prompt is the human gate; the model-aware context guard handles oversized contexts via the cbp-clear-prep flow — 200K standard, 800K on `[1m]` sessions). Only the no-task-anywhere session-end fallback surfaces as a single directive (`Next: Run /clear, then /cbp-session-end`) for the user to invoke.
|
|
157
157
|
|
|
158
158
|
#### 9a — Determine routing context
|
|
159
159
|
|
|
@@ -182,7 +182,7 @@ If no next task is found (no pending work anywhere in the repo), emit directive
|
|
|
182
182
|
The checkpoint has no remaining tasks. Invoke `cbp-checkpoint-check` via the Skill tool.
|
|
183
183
|
`cbp-checkpoint-check` is `ask`-tier — the harness permission prompt IS the human gate; the
|
|
184
184
|
user confirms (or declines) before checkpoint verification and ship begins. If the context
|
|
185
|
-
window is above the
|
|
185
|
+
window is above the model-aware threshold (200K standard, 800K for `[1m]` sessions) the `cbp-skill-context-guard.sh` hook will block it and
|
|
186
186
|
direct you to run `/cbp-clear-prep` first; otherwise checkpoint-check starts on confirmation.
|
|
187
187
|
|
|
188
188
|
## Integration
|
|
@@ -17,7 +17,7 @@ The skill detects "checkpoint done" at Step 9 by:
|
|
|
17
17
|
When all siblings are done, the skill invokes `cbp-checkpoint-check` via the Skill tool:
|
|
18
18
|
|
|
19
19
|
- `cbp-checkpoint-check` is `ask`-tier — the harness permission prompt IS the human gate. The user confirms (or declines) before checkpoint verification and the shipment chain begin.
|
|
20
|
-
- No `/clear` is emitted unconditionally. If the `cbp-skill-context-guard.sh` hook detects the context window is above the
|
|
20
|
+
- No `/clear` is emitted unconditionally. If the `cbp-skill-context-guard.sh` hook detects the context window is above the model-aware threshold (200K for standard models; 800K for `[1m]`-context models; env vars `CBP_CONTEXT_WARN_TOKENS` / `CBP_CONTEXT_WARN_TOKENS_1M`) it blocks the skill and directs you to run `/cbp-clear-prep` first (which writes a handoff; the user then runs `/clear`, then `/cbp-clear-continue` resumes); otherwise checkpoint-check starts immediately on confirmation.
|
|
21
21
|
|
|
22
22
|
There is no AskUserQuestion menu. Expanding the checkpoint with more tasks (`/cbp-checkpoint-update`) or wrapping up the session (`/cbp-session-end`) are no longer surfaced as inline alternatives — the deterministic next step on checkpoint-done is `cbp-checkpoint-check`. (The user can still invoke those other skills manually at any time; they are simply not part of the auto-flow.)
|
|
23
23
|
|
|
@@ -19,7 +19,7 @@ No AskUserQuestion, no `/clear`. The skill fires immediately.
|
|
|
19
19
|
|
|
20
20
|
Two sub-cases:
|
|
21
21
|
|
|
22
|
-
**Checkpoint done** (last task in the checkpoint complete): auto-trigger `cbp-checkpoint-check` via the Skill tool. `cbp-checkpoint-check` is `ask`-tier — the permission prompt is the human gate; the
|
|
22
|
+
**Checkpoint done** (last task in the checkpoint complete): auto-trigger `cbp-checkpoint-check` via the Skill tool. `cbp-checkpoint-check` is `ask`-tier — the permission prompt is the human gate; the model-aware context guard handles oversized contexts (via `cbp-clear-prep`) only when context is near the limit — 200K standard, 800K on `[1m]` sessions (env vars `CBP_CONTEXT_WARN_TOKENS` / `CBP_CONTEXT_WARN_TOKENS_1M`). No unconditional `/clear`. (See `checkpoint-done-branching.md`.)
|
|
23
23
|
|
|
24
24
|
**Session end** (no pending tasks anywhere): emit a single directive line at the end of skill output and stop:
|
|
25
25
|
|
|
@@ -25,7 +25,7 @@ Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
|
|
|
25
25
|
| Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
|
|
26
26
|
| Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
|
|
27
27
|
| Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
|
|
28
|
-
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes
|
|
28
|
+
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?)` |
|
|
29
29
|
|
|
30
30
|
# Round Complete Command
|
|
31
31
|
|
|
@@ -84,20 +84,7 @@ Reconcile which files the user has approved by staging them. Run:
|
|
|
84
84
|
npx codebyplan round sync-approvals --round-id <round_id> --task-id <task_id>
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
The CLI
|
|
88
|
-
1. `--caller-worktree-id <uuid>` override (if passed — skips all resolution)
|
|
89
|
-
2. Per-device branch-keyed cache (`.codebyplan/worktree.local.json`)
|
|
90
|
-
3. In-process tuple API call: `POST /worktrees/resolve` using `(device_id, repo_path, branch)`
|
|
91
|
-
|
|
92
|
-
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:
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
npx codebyplan resolve-worktree --cache
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
If this worktree is not yet registered, run `npx codebyplan setup` first, then re-run `/cbp-round-complete`.
|
|
99
|
-
|
|
100
|
-
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`.
|
|
87
|
+
The CLI parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task. A **cleanly staged** file (`git add`-ed, no further unstaged changes) becomes `user_approved: true`.
|
|
101
88
|
|
|
102
89
|
Read the stdout JSON: `{ added, stale_marked, reactivated, total_files }`.
|
|
103
90
|
|
|
@@ -110,14 +97,7 @@ This is the **single** explicit reconcile owned by this skill. (The `cbp-mcp-rou
|
|
|
110
97
|
Calculate duration from the round's `started_at` to now in minutes.
|
|
111
98
|
|
|
112
99
|
- **checkpoint KIND**: `codebyplan round complete --id <round_id> --task-id <task_id> --checkpoint-id <checkpoint_id>` (CLI write-through: local state file + REST). Break-glass fallback: MCP `complete_round(round_id, duration_minutes)` when the CLI is unavailable. Note: the CLI does not accept `duration_minutes`; the backend computes duration server-side.
|
|
113
|
-
- **standalone KIND**: MCP `complete_standalone_round(standalone_round_id, duration_minutes
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
Warning: could not resolve caller_worktree_id (npx codebyplan resolve-worktree returned empty).
|
|
117
|
-
The complete_standalone_round call may be rejected by the pre-guard. Proceed anyway? (yes / no)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
If the user confirms yes, proceed with `caller_worktree_id: ""`. If no, stop.
|
|
100
|
+
- **standalone KIND**: MCP `complete_standalone_round(standalone_round_id, duration_minutes)`. The server keys on the JWT user (`ctx.userId`) — no worktree param needed or accepted.
|
|
121
101
|
|
|
122
102
|
`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.
|
|
123
103
|
|
|
@@ -158,7 +138,6 @@ Payload: `round.context.round_complete = { staged_count, unstaged_count, route,
|
|
|
158
138
|
- **Permission prompt = confirmation** — gated by `ask`-tier `Skill(cbp-round-complete)`. Because the skill is `disable-model-invocation: true`, this gate applies to the user's **direct** `/cbp-round-complete` invocation. NEVER add an AskUserQuestion to confirm running; the harness prompt is the gate. A declined permission is a clean no-op.
|
|
159
139
|
- **Step 2 (CLI) must exit 0** — if it fails, STOP before `complete_round`. The merge semantics are enforced by the CLI.
|
|
160
140
|
- **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.
|
|
161
|
-
- **standalone KIND Step 3**: `caller_worktree_id` is REQUIRED for `complete_standalone_round` — always resolve and pass it.
|
|
162
141
|
|
|
163
142
|
## Integration
|
|
164
143
|
|
|
@@ -25,7 +25,7 @@ Set `KIND` for the rest of this skill. Read/write sources vary by KIND:
|
|
|
25
25
|
| Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
|
|
26
26
|
| Add round | `codebyplan round add` (break-glass: `add_round`) | `add_standalone_round(standalone_task_id, ...)` |
|
|
27
27
|
| Update round | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
|
|
28
|
-
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes
|
|
28
|
+
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?)` |
|
|
29
29
|
| Update task | `codebyplan task update` (break-glass: `update_task`) | `update_standalone_task(standalone_task_id, ...)` |
|
|
30
30
|
|
|
31
31
|
> **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope and will be addressed in a later task.
|
|
@@ -22,35 +22,46 @@ Always write a session log for this session — **even if empty**. `/cbp-session
|
|
|
22
22
|
2. Pull facts from local state files rather than narrating from memory:
|
|
23
23
|
- Rounds added/completed, tasks advanced/completed during this session (read from `.codebyplan/state/checkpoints/` subtree)
|
|
24
24
|
- Decisions, blockers, or discoveries recorded in checkpoint/task context
|
|
25
|
-
|
|
26
|
-
### Step 1.3: Capture Handoff Snapshot
|
|
27
|
-
|
|
28
|
-
Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can auto-resume. The handoff write-path + payload shape are specified inline here and in `/cbp-session-start` Step 4.5 (freshness gate).
|
|
29
|
-
|
|
30
|
-
1. Read `.codebyplan/state/todos.json` (local-first) and take the queue head `rows[0]` (rows are ordered by `sort_order`; `rows[0]` is the current next-action). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_todos({ repo_id, worktree_id })` when the state dir is absent and sync fails. The worker stamps `command`, `instructions`, `state`, and the entity ids `checkpoint_id` / `task_id` / `round_id` on every row.
|
|
31
|
-
2. If `rows[0]` exists and its `command` is non-empty (active work in flight):
|
|
32
|
-
```yaml
|
|
33
|
-
handoff:
|
|
34
|
-
command: <rows[0].command> # e.g. "/cbp-verify"
|
|
35
|
-
instructions: <rows[0].instructions> # human-readable trigger reason
|
|
36
|
-
state: <rows[0].state> # workflow state label
|
|
37
|
-
context: # entity ids used by the Step 4.5 freshness probe
|
|
38
|
-
checkpoint_id: <rows[0].checkpoint_id>
|
|
39
|
-
task_id: <rows[0].task_id>
|
|
40
|
-
round_id: <rows[0].round_id>
|
|
41
|
-
captured_at: <ISO now> # for entity-drift freshness comparison
|
|
42
|
-
captured_session_log_id: <current session log id>
|
|
43
|
-
```
|
|
44
|
-
3. If the queue is empty or `rows[0].command` is empty / idle: set `handoff = null` so the next session's probe falls through to `/cbp-todo`.
|
|
45
|
-
4. Hold `handoff` in context for Step 1's `update_session_log` call below — it ships in the same write as `ended_at` and `summary`.
|
|
46
|
-
|
|
47
|
-
Continuing Step 1:
|
|
48
|
-
|
|
49
|
-
3. Run `codebyplan session update-log --id <log-id> --ended-at <now> --summary <text> --pending <text> --handoff <json>` (CLI write-through: updates `.codebyplan/state/session/current.json` + REST). Break-glass fallback: MCP `update_session_log` when the CLI is unavailable. Fields:
|
|
25
|
+
3. Run `codebyplan session update-log --id <log-id> --ended-at <now> --summary <text> --pending <text> --git-branch <current-branch>` (CLI write-through: updates `.codebyplan/state/session/current.json` + REST). Break-glass fallback: MCP `update_session_log` when the CLI is unavailable. Fields:
|
|
50
26
|
- `ended_at`: now (maps to the `closed_at` column per TASK-2 alias)
|
|
51
|
-
- `handoff`: from Step 1.3 (jsonb or `null`; MCP write surface aliases to the `content` column transparently per CHK-111 Migration A — `handoff` wins over `content` when both are passed)
|
|
52
27
|
- `summary`: concise — may be empty if nothing happened
|
|
53
28
|
- `pending`: open items the next session should see first
|
|
29
|
+
- `git_branch`: the current git branch (informational; `git rev-parse --abbrev-ref HEAD`)
|
|
30
|
+
- **Do NOT pass `--handoff` / `handoff` field.** The DB handoff field is no longer written here. Omit entirely — never pass `handoff:null` (it clobbers summary/pending content).
|
|
31
|
+
|
|
32
|
+
### Step 1.3: Optional Handoff File (mid-work only)
|
|
33
|
+
|
|
34
|
+
When an active in-progress task or round exists, offer to write a handoff file so the next session can auto-resume. Skip entirely when not mid-work.
|
|
35
|
+
|
|
36
|
+
1. Read `.codebyplan/state/todos.json` (local-first) and check `rows[0]` (queue head, ordered by `sort_order`). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_todos({ repo_id })` when the state dir is absent and sync fails. The worker stamps `command`, `instructions`, `state`, and entity ids `checkpoint_id` / `task_id` / `round_id` on every row.
|
|
37
|
+
|
|
38
|
+
2. **If `rows[0]` exists and its `command` is non-empty** (active work in flight):
|
|
39
|
+
- Determine the handoff file path. The directory is keyed by the human-facing **number** (`<NNN>` checkpoint number / `<N>` standalone task number) — matching the committed `.codebyplan/checkpoint/<NNN>/` plan-artifact convention and the session-start resume probe (which globs by number). Resolve the number from local state (break-glass: MCP):
|
|
40
|
+
- Checkpoint work: read `.codebyplan/state/checkpoints/<rows[0].checkpoint_id>.json` → `number` (break-glass: MCP `get_checkpoints`). Path: `.codebyplan/checkpoint/<NNN>/handoff.md`.
|
|
41
|
+
- Standalone work: read the standalone task's `number` from local standalone state (break-glass: MCP `get_standalone_tasks`). Path: `.codebyplan/standalone/<N>/handoff.md`.
|
|
42
|
+
- Offer to write the file:
|
|
43
|
+
```
|
|
44
|
+
Write handoff file for next session?
|
|
45
|
+
<path>
|
|
46
|
+
|
|
47
|
+
Reply: yes | no
|
|
48
|
+
```
|
|
49
|
+
- On `yes`: write the file with this structure:
|
|
50
|
+
```markdown
|
|
51
|
+
---
|
|
52
|
+
command: <rows[0].command>
|
|
53
|
+
state: <rows[0].state>
|
|
54
|
+
captured_at: <ISO now>
|
|
55
|
+
checkpoint_id: <rows[0].checkpoint_id or null>
|
|
56
|
+
task_id: <rows[0].task_id or null>
|
|
57
|
+
round_id: <rows[0].round_id or null>
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
<rows[0].instructions — human-readable trigger reason>
|
|
61
|
+
```
|
|
62
|
+
- The file is committed with the session's final commit (Step 1.5) or the user can stage it manually.
|
|
63
|
+
|
|
64
|
+
3. **If the queue is empty or `rows[0].command` is empty/idle**: skip — no handoff file is written.
|
|
54
65
|
|
|
55
66
|
### Step 1.5: Commit Non-Task Files
|
|
56
67
|
|
|
@@ -117,7 +128,7 @@ Stop this worktree's Realtime watch daemon, non-blocking and non-fatal:
|
|
|
117
128
|
npx codebyplan watch stop 2>/dev/null || true
|
|
118
129
|
```
|
|
119
130
|
|
|
120
|
-
This SIGTERMs the per-worktree pidfile daemon started by `cbp-session-start-hook.sh`. Silently ignored when no daemon is running
|
|
131
|
+
This SIGTERMs the per-worktree pidfile daemon started by `cbp-session-start-hook.sh`. Silently ignored when no daemon is running. If there is no daemon to stop (e.g. session-start was skipped), `watch stop` itself exits 0 — the `|| true` guard is defense-in-depth only, so Step 3's session-state write never sees a failure from this step.
|
|
121
132
|
|
|
122
133
|
### Step 3: Update Session State
|
|
123
134
|
|
|
@@ -134,9 +145,8 @@ You can close this window.
|
|
|
134
145
|
## Integration
|
|
135
146
|
|
|
136
147
|
- **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
|
|
137
|
-
- **Reads**: `.codebyplan/repo.json`; local-first reads (with `npx codebyplan sync` + MCP break-glass): `.codebyplan/state/session/current.json` (Step 1 resolve log), `.codebyplan/state/todos.json` (Step 1.3
|
|
138
|
-
- **Writes**: `codebyplan session update-log --id <id> ...` (Step 1 finalize — CLI write-through to `.codebyplan/state/session/current.json`; break-glass: MCP `update_session_log
|
|
148
|
+
- **Reads**: `.codebyplan/repo.json`; local-first reads (with `npx codebyplan sync` + MCP break-glass): `.codebyplan/state/session/current.json` (Step 1 resolve log), `.codebyplan/state/todos.json` (Step 1.3 mid-work detection + Step 1.5 active-task lookup), `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/` (Step 1.5 task-file resolution); `codebyplan session freshness-gate` (Step 1.7 package-freshness gate, without --halt-on-update); `codebyplan session infra-files --json --task-files <csv>` (Step 1.5 infra-file set math)
|
|
149
|
+
- **Writes**: `codebyplan session update-log --id <id> --git-branch <branch> ...` (Step 1 finalize — CLI write-through to `.codebyplan/state/session/current.json`; break-glass: MCP `update_session_log`; handoff field never passed), `codebyplan session create-log` (Step 1 fallback when no log exists; break-glass: MCP `create_session_log`), optional handoff file at `.codebyplan/checkpoint/<NNN>/handoff.md` or `.codebyplan/standalone/<N>/handoff.md` (Step 1.3, mid-work only), `codebyplan session update-state --action deactivate` (Step 3 — CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`)
|
|
139
150
|
- **Spawns**: none
|
|
140
151
|
- **Triggers**: none at the skill-contract level. Step 1.5 may invoke `/cbp-git-commit` inline on user approval; Step 1.7 may invoke `/cbp-git-commit` on the `result === 'updated'` path (committing changed `.claude/` and `.codebyplan/` paths).
|
|
141
152
|
- **Paired with**: `/cbp-session-start`
|
|
142
|
-
- **Pairs with**: `/cbp-session-start` Step 4.5 (handoff payload shape + freshness-gate contract; specified inline — no separate rule file)
|