codebyplan 1.13.38 → 1.13.40
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 +25142 -425
- package/package.json +4 -2
- package/templates/agents/cbp-cc-executor.md +4 -4
- package/templates/agents/cbp-map-architecture.md +90 -0
- package/templates/agents/cbp-round-executor.md +2 -0
- package/templates/agents/cbp-task-check.md +2 -0
- package/templates/agents/cbp-task-planner.md +2 -0
- package/templates/context/architecture/arch-map-spec.md +204 -0
- package/templates/context/architecture-map.md +117 -0
- package/templates/hooks/README.md +14 -2
- package/templates/hooks/cbp-session-start-hook.sh +32 -0
- package/templates/hooks/cbp-test-coverage-gate.sh +20 -6
- package/templates/hooks/cbp-test-hooks.sh +72 -0
- package/templates/hooks/hooks.json +11 -0
- package/templates/hooks/validate-structure.sh +3 -2
- package/templates/rules/architecture-map.md +30 -0
- package/templates/rules/context-file-loading.md +3 -0
- package/templates/rules/supabase-branch-lifecycle.md +1 -1
- package/templates/settings.project.base.json +15 -1
- package/templates/skills/cbp-checkpoint-check/SKILL.md +10 -10
- package/templates/skills/cbp-checkpoint-complete/SKILL.md +7 -7
- package/templates/skills/cbp-checkpoint-create/SKILL.md +11 -9
- package/templates/skills/cbp-checkpoint-end/SKILL.md +4 -4
- package/templates/skills/cbp-checkpoint-plan/SKILL.md +10 -10
- package/templates/skills/cbp-checkpoint-start/SKILL.md +6 -6
- package/templates/skills/cbp-checkpoint-update/SKILL.md +9 -9
- package/templates/skills/cbp-git-commit/SKILL.md +8 -4
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +3 -2
- package/templates/skills/cbp-map-architecture/SKILL.md +170 -0
- package/templates/skills/cbp-merge-main/SKILL.md +2 -5
- package/templates/skills/cbp-refresh-arch-map/SKILL.md +191 -0
- package/templates/skills/cbp-round-check/SKILL.md +12 -8
- package/templates/skills/cbp-round-complete/SKILL.md +16 -10
- package/templates/skills/cbp-round-end/SKILL.md +9 -10
- package/templates/skills/cbp-round-execute/SKILL.md +7 -6
- package/templates/skills/cbp-round-input/SKILL.md +24 -12
- package/templates/skills/cbp-round-start/SKILL.md +36 -16
- package/templates/skills/cbp-round-update/SKILL.md +14 -10
- package/templates/skills/cbp-session-end/SKILL.md +22 -12
- package/templates/skills/cbp-session-start/SKILL.md +19 -15
- package/templates/skills/cbp-ship/SKILL.md +4 -4
- package/templates/skills/cbp-ship/reference/surface-supabase.md +3 -3
- package/templates/skills/cbp-ship-configure/SKILL.md +1 -1
- package/templates/skills/cbp-ship-configure/reference/railway-backend.md +2 -2
- package/templates/skills/cbp-ship-configure/reference/vercel.md +1 -1
- package/templates/skills/cbp-ship-main/SKILL.md +2 -2
- package/templates/skills/cbp-standalone-task-complete/SKILL.md +3 -2
- package/templates/skills/cbp-supabase-migrate/SKILL.md +6 -7
- package/templates/skills/cbp-task-check/SKILL.md +10 -10
- package/templates/skills/cbp-task-complete/SKILL.md +11 -9
- package/templates/skills/cbp-task-create/SKILL.md +7 -5
- package/templates/skills/cbp-task-start/SKILL.md +15 -17
- package/templates/skills/cbp-task-testing/SKILL.md +18 -18
- package/templates/skills/cbp-todo/SKILL.md +21 -21
|
@@ -14,14 +14,14 @@ Inspect the resolved identifier from argument parsing to determine the task kind
|
|
|
14
14
|
|-----------------|------|
|
|
15
15
|
| `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
|
|
16
16
|
| `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
|
|
17
|
-
| _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
|
|
17
|
+
| _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. (Kind-detection is MCP-unavoidable — no identifier yet means no local path to probe; subsequent operations are local-first per the rows below.) |
|
|
18
18
|
|
|
19
19
|
Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
|
|
20
20
|
|
|
21
21
|
| Operation | `checkpoint` KIND | `standalone` KIND |
|
|
22
22
|
|-----------|------------------|-------------------|
|
|
23
|
-
| Get task | `get_current_task
|
|
24
|
-
| Get rounds | `get_rounds
|
|
23
|
+
| Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
|
|
24
|
+
| Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
|
|
25
25
|
| Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
|
|
26
26
|
| Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
|
|
27
27
|
| Update task | `update_task(task_id, ...)` | `update_standalone_task(standalone_task_id, ...)` |
|
|
@@ -64,9 +64,13 @@ If the argument matches the numeric regex, resolve the target task/round from DB
|
|
|
64
64
|
|
|
65
65
|
### Step 2: Deep Analysis (MANDATORY — always runs)
|
|
66
66
|
|
|
67
|
-
**2a:** Load task
|
|
67
|
+
**2a:** Load task:
|
|
68
|
+
- **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task(repo_id)` when state dir is absent and sync fails. Get `files_changed`, `requirements`, `context`, `qa`.
|
|
69
|
+
- **standalone KIND** — MCP `get_current_standalone_task(repo_id)`. (Standalone KIND still uses MCP until a later task.)
|
|
68
70
|
|
|
69
|
-
**2b:** Load all rounds
|
|
71
|
+
**2b:** Load all rounds:
|
|
72
|
+
- **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/*.json` (local-first; break-glass: MCP `get_rounds(task_id)`). Get previous round context, testing-qa output.
|
|
73
|
+
- **standalone KIND** — MCP `get_standalone_rounds(standalone_task_id)`.
|
|
70
74
|
|
|
71
75
|
**2c:** Identify unapproved files from `task.files_changed` where `user_approved === false`
|
|
72
76
|
|
|
@@ -144,10 +148,12 @@ Based on the analysis + user input, create detailed requirements that:
|
|
|
144
148
|
|
|
145
149
|
If the new round requirements change the task direction:
|
|
146
150
|
|
|
147
|
-
1. Update task context
|
|
151
|
+
1. Update task context per KIND:
|
|
152
|
+
- **checkpoint KIND**: `codebyplan task update --id <task_id> --checkpoint-id <checkpoint_id> --context '<json>'` (CLI write-through: local state file + REST). Break-glass fallback: MCP `update_task(task_id, context: { ... })` when the CLI is unavailable.
|
|
153
|
+
- **standalone KIND**: MCP `update_standalone_task(standalone_task_id, context: { ... })`. (Standalone KIND still uses MCP until a later task.)
|
|
148
154
|
- Add new decisions to `context.decisions[]`
|
|
149
155
|
- Update `context.discoveries[]` if applicable
|
|
150
|
-
2. If checkpoint-level changes needed (checkpoint KIND only)
|
|
156
|
+
2. If checkpoint-level changes needed (checkpoint KIND only): `codebyplan checkpoint update --id <checkpoint_id> --context '<json>'` (CLI write-through). Break-glass fallback: MCP `update_checkpoint`.
|
|
151
157
|
|
|
152
158
|
### Step 7: Auto-trigger Round Start
|
|
153
159
|
|
|
@@ -166,14 +172,18 @@ Trigger `/cbp-round-start` with the round requirements as arguments.
|
|
|
166
172
|
If this command is triggered **directly** (not via `/cbp-todo`) and no context is available in the session:
|
|
167
173
|
|
|
168
174
|
1. Read `.codebyplan/repo.json` for `repo_id`
|
|
169
|
-
2. Use Kind Detection to determine KIND, then
|
|
170
|
-
|
|
175
|
+
2. Use Kind Detection to determine KIND, then:
|
|
176
|
+
- **checkpoint KIND**: Read local `.codebyplan/state/` files for checkpoint + task (break-glass: MCP `get_current_task`).
|
|
177
|
+
- **standalone KIND**: MCP `get_current_standalone_task`.
|
|
178
|
+
3. Load round history:
|
|
179
|
+
- **checkpoint KIND**: Read `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/*.json` (break-glass: MCP `get_rounds(task_id)`).
|
|
180
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)`.
|
|
171
181
|
4. Continue from Step 2 (deep analysis handles all context loading)
|
|
172
182
|
|
|
173
183
|
## Key Rules
|
|
174
184
|
|
|
175
185
|
- **Deep analysis is MANDATORY** — always runs, even if arguments provided (for context)
|
|
176
|
-
- **Analysis reads from
|
|
186
|
+
- **Analysis reads from local state first**, falling back to MCP only when state files are absent and sync fails
|
|
177
187
|
- **Follow-up rounds get same depth as round 1** — no quick-fix behavior
|
|
178
188
|
- **Never ask to git add** — user file approval (git staging) is reconciled by `/cbp-round-complete`
|
|
179
189
|
- **Update all context locations** — task, checkpoint, and round should all have consistent information
|
|
@@ -181,6 +191,8 @@ If this command is triggered **directly** (not via `/cbp-todo`) and no context i
|
|
|
181
191
|
## Integration
|
|
182
192
|
|
|
183
193
|
- **Triggered by**: `/cbp-round-update` (auto, not-clean triage), `/cbp-round-complete` (auto, files left unapproved after completing the round), `/cbp-round-execute` (auto, on hard-fail after retry exhausted), `/cbp-todo` (after /clear), user manually
|
|
184
|
-
- **Reads
|
|
185
|
-
- **
|
|
194
|
+
- **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/*.json` (local-first; break-glass: MCP `get_current_task` / `get_rounds`), file contents (Read tool)
|
|
195
|
+
- **Reads (standalone KIND)**: MCP `get_current_standalone_task` / `get_standalone_rounds` (standalone KIND still uses MCP until a later task)
|
|
196
|
+
- **Writes (checkpoint KIND)**: `codebyplan task update` (context), `codebyplan checkpoint update` (context, if needed). Break-glass: MCP `update_task` / `update_checkpoint`.
|
|
197
|
+
- **Writes (standalone KIND)**: MCP `update_standalone_task` / (checkpoint via MCP `update_checkpoint` if needed). (Standalone KIND still uses MCP until a later task.)
|
|
186
198
|
- **Triggers**: `/cbp-round-start` (auto)
|
|
@@ -17,16 +17,18 @@ Inspect the resolved identifier from argument parsing to determine the task kind
|
|
|
17
17
|
| `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
|
|
18
18
|
| _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
|
|
19
19
|
|
|
20
|
-
Set `KIND` for the rest of this skill.
|
|
20
|
+
Set `KIND` for the rest of this skill. Read/write sources vary by KIND:
|
|
21
21
|
|
|
22
22
|
| Operation | `checkpoint` KIND | `standalone` KIND |
|
|
23
23
|
|-----------|------------------|-------------------|
|
|
24
|
-
| Get task | `get_current_task
|
|
25
|
-
| Get rounds | `get_rounds
|
|
26
|
-
| Add round | `
|
|
27
|
-
| Update round | `
|
|
24
|
+
| Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
|
|
25
|
+
| Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
|
|
26
|
+
| Add round | `codebyplan round add` (break-glass: `add_round`) | `add_standalone_round(standalone_task_id, ...)` |
|
|
27
|
+
| Update round | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
|
|
28
28
|
| 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 |
|
|
29
|
-
| Update task | `
|
|
29
|
+
| Update task | `codebyplan task update` (break-glass: `update_task`) | `update_standalone_task(standalone_task_id, ...)` |
|
|
30
|
+
|
|
31
|
+
> **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope for this task and will be addressed in a later task.
|
|
30
32
|
|
|
31
33
|
# Round Start Command
|
|
32
34
|
|
|
@@ -94,17 +96,23 @@ round-start: invalid argument `{value}`. Expected:
|
|
|
94
96
|
|
|
95
97
|
### Step 1: Get Current Task
|
|
96
98
|
|
|
97
|
-
If Step 0 produced an identifier (`target_task` set): resolve directly per the identifier (bound or standalone) — use KIND-appropriate
|
|
99
|
+
If Step 0 produced an identifier (`target_task` set): resolve directly per the identifier (bound or standalone) — use KIND-appropriate sources per the Kind Detection table above.
|
|
98
100
|
|
|
99
|
-
Otherwise: use Kind Detection to determine KIND, then
|
|
101
|
+
Otherwise: use Kind Detection to determine KIND, then:
|
|
102
|
+
- **checkpoint KIND**: read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
|
|
103
|
+
- **standalone KIND**: MCP `get_current_standalone_task(repo_id)` — standalone tools are NOT migrated this task; standalone KIND still uses MCP until a later task.
|
|
100
104
|
|
|
101
105
|
If no in-progress task and Step 0 produced no identifier, show error: `No active task. Run /cbp-task-start first.`
|
|
102
106
|
|
|
103
107
|
### Step 2: Determine Round Number
|
|
104
108
|
|
|
105
|
-
If Step 0 produced `target_round`: use that as the round number directly (may target an existing round for resume, or N+1 for a new round — disambiguate by
|
|
109
|
+
If Step 0 produced `target_round`: use that as the round number directly (may target an existing round for resume, or N+1 for a new round — disambiguate by reading local round files or MCP per KIND below).
|
|
110
|
+
|
|
111
|
+
Otherwise:
|
|
112
|
+
- **checkpoint KIND**: list `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_rounds` when the state dir is absent and sync fails.
|
|
113
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
Count existing rounds; next is N+1.
|
|
108
116
|
|
|
109
117
|
### Step 3: Gather Round Requirements
|
|
110
118
|
|
|
@@ -122,7 +130,11 @@ Otherwise: use MCP `get_rounds` (checkpoint KIND) or `get_standalone_rounds` (st
|
|
|
122
130
|
|
|
123
131
|
### Step 4: Create Round in DB
|
|
124
132
|
|
|
125
|
-
|
|
133
|
+
**checkpoint KIND**: `codebyplan round add --task-id <uuid> --checkpoint-id <uuid> --number <N> --status in_progress --started-at <ISO> --triggered-by <user|claude|auto_loop> [--requirements <text>] [--context <json>]` (CLI write-through: writes local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` + REST). Break-glass fallback: MCP `add_round` when the CLI is unavailable.
|
|
134
|
+
|
|
135
|
+
**standalone KIND**: MCP `add_standalone_round(standalone_task_id, ...)` — standalone still uses MCP.
|
|
136
|
+
|
|
137
|
+
Fields to supply:
|
|
126
138
|
- `task_id` (checkpoint) / `standalone_task_id` (standalone): current task ID
|
|
127
139
|
- `number`: next round number
|
|
128
140
|
- `status`: "in_progress"
|
|
@@ -138,7 +150,9 @@ Load from checkpoint and task:
|
|
|
138
150
|
- Task context and requirements
|
|
139
151
|
- Resources from checkpoint and task (documentation links, API docs, guides)
|
|
140
152
|
- Previous round results (files_changed, QA results)
|
|
141
|
-
- For round 2+: load the latest completed round's `context.testing_qa_output` and `context.executor_output
|
|
153
|
+
- For round 2+: load the latest completed round's `context.testing_qa_output` and `context.executor_output`:
|
|
154
|
+
- **checkpoint KIND**: read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_rounds` when the state dir is absent and sync fails.
|
|
155
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
|
|
142
156
|
- Identify unapproved files from task.files_changed (where user_approved === false)
|
|
143
157
|
|
|
144
158
|
### Step 6: First Round Analysis (Round 1 only)
|
|
@@ -149,7 +163,8 @@ For the first round only:
|
|
|
149
163
|
2. Identify any ambiguities or gaps
|
|
150
164
|
3. If questions are needed, ask user via AskUserQuestion (max 4 per batch)
|
|
151
165
|
4. If task context changes from Q&A answers:
|
|
152
|
-
-
|
|
166
|
+
- **checkpoint KIND**: `codebyplan task update --id <task-id> --checkpoint-id <uuid> --context <json>` (CLI write-through: local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` + REST). Break-glass fallback: MCP `update_task` when the CLI is unavailable.
|
|
167
|
+
- **standalone KIND**: MCP `update_standalone_task(standalone_task_id, context: {...})` — standalone still uses MCP.
|
|
153
168
|
- Save Q&A decisions as `context.decisions[]`
|
|
154
169
|
|
|
155
170
|
Skip this step for round 2+ (context already established via `/cbp-round-input`).
|
|
@@ -219,7 +234,10 @@ Single-wave plans present the existing flat plan view (no wave table) — backwa
|
|
|
219
234
|
|
|
220
235
|
### Step 9: Auto-trigger Round Execute
|
|
221
236
|
|
|
222
|
-
Save planner output to round context
|
|
237
|
+
Save planner output to round context, then trigger `/cbp-round-execute`. The `ask`-tier permission prompt on `/cbp-round-execute` is the user's plan approval (see Step 8).
|
|
238
|
+
|
|
239
|
+
- **checkpoint KIND**: `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --context <json>` (CLI write-through: local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` + REST). Break-glass fallback: MCP `update_round` when the CLI is unavailable.
|
|
240
|
+
- **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` — standalone still uses MCP.
|
|
223
241
|
|
|
224
242
|
```
|
|
225
243
|
Starting execution phase...
|
|
@@ -235,8 +253,10 @@ Starting execution phase...
|
|
|
235
253
|
|
|
236
254
|
## Integration
|
|
237
255
|
|
|
238
|
-
- **Reads**:
|
|
239
|
-
- **
|
|
256
|
+
- **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_rounds` as break-glass)
|
|
257
|
+
- **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` — standalone still uses MCP
|
|
258
|
+
- **Writes (checkpoint KIND)**: `codebyplan round add` (Step 4), `codebyplan round update` (Step 9), `codebyplan task update` (Step 6 context only) — break-glass: MCP `add_round` / `update_round` / `update_task`
|
|
259
|
+
- **Writes (standalone KIND)**: MCP `add_standalone_round`, `update_standalone_round`, `update_standalone_task` — standalone still uses MCP
|
|
240
260
|
- **Spawns**: `cbp-task-planner`
|
|
241
261
|
- **Triggers**: `/cbp-round-execute` (auto, on plan approval)
|
|
242
262
|
- **Triggered by**: `/cbp-task-start` (round 1), `/cbp-round-input` (round 2+)
|
|
@@ -17,13 +17,15 @@ Inspect the resolved identifier from argument parsing to determine the task kind
|
|
|
17
17
|
| `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
|
|
18
18
|
| _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
|
|
19
19
|
|
|
20
|
-
Set `KIND` for the rest of this skill. round-update is **read + triage only** — it reads round state and routes; it never completes the round or writes file approvals.
|
|
20
|
+
Set `KIND` for the rest of this skill. round-update is **read + triage only** — it reads round state and routes; it never completes the round or writes file approvals. Read/write sources vary by KIND:
|
|
21
21
|
|
|
22
22
|
| Operation | `checkpoint` KIND | `standalone` KIND |
|
|
23
23
|
|-----------|------------------|-------------------|
|
|
24
|
-
| Get task | `get_current_task
|
|
25
|
-
| Get rounds | `get_rounds
|
|
26
|
-
| Update round (audit only) | `
|
|
24
|
+
| Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
|
|
25
|
+
| Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
|
|
26
|
+
| Update round (audit only) | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
|
|
27
|
+
|
|
28
|
+
> **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope for this task and will be addressed in a later task.
|
|
27
29
|
|
|
28
30
|
The completion + file-approval reconcile (`sync-approvals`, `complete_round` / `complete_standalone_round`) now lives in `/cbp-round-complete`.
|
|
29
31
|
|
|
@@ -72,9 +74,9 @@ Given the parse from Step 1:
|
|
|
72
74
|
|
|
73
75
|
| Parse | Resolution path |
|
|
74
76
|
|-------|-----------------|
|
|
75
|
-
| `{chk}-{task}-{round}` |
|
|
76
|
-
| `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. |
|
|
77
|
-
| _(empty)_ |
|
|
77
|
+
| `{chk}-{task}-{round}` | Read `.codebyplan/state/checkpoints/` to find the checkpoint where `number === {chk}` (local-first; `npx codebyplan sync` on miss; break-glass: MCP `get_checkpoints(repo_id)`). Read `checkpoints/<id>/tasks/<taskId>.json` to find task where `number === {task}` (break-glass: MCP `get_tasks`). Read `checkpoints/<id>/tasks/<id>/rounds/<roundId>.json` to find round where `number === {round}` (break-glass: MCP `get_rounds`). |
|
|
78
|
+
| `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. Standalone still uses MCP. |
|
|
79
|
+
| _(empty)_ | checkpoint KIND → read `.codebyplan/state/checkpoints/<id>/tasks/<id>.json` (local-first; sync on miss; break-glass: MCP `get_current_task` + `get_rounds`); standalone KIND → MCP `get_current_standalone_task(repo_id)` + `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP. |
|
|
78
80
|
|
|
79
81
|
If no task found: `No active task. Nothing to update.`
|
|
80
82
|
|
|
@@ -97,7 +99,7 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
|
|
|
97
99
|
|
|
98
100
|
- **Auto-loop** (`round.context.auto_loop_mode === true`): compute `next_index = (round.context.auto_loop_index ?? 0) + 1`.
|
|
99
101
|
- If `next_index > (round.context.auto_loop_cap ?? 5)`: surface the cap-exhausted prompt via AskUserQuestion (a genuine multi-option user decision — keep it). Options: extend cap, stop loop / drop into round-input, close task as-is. Persist `round.context.auto_loop_cap_exhausted = { user_choice, decided_at }` and route per choice.
|
|
100
|
-
- Otherwise: persist `round.context.auto_loop_decision = { spawned_next: true, next_index, decided_at }` on the current round
|
|
102
|
+
- Otherwise: persist `round.context.auto_loop_decision = { spawned_next: true, next_index, decided_at }` on the current round (audit trail) — **checkpoint KIND**: `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --context <json>` (break-glass: MCP `update_round`); **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` — standalone still uses MCP. Then auto-trigger `/cbp-round-input` with NO prompt. Pass `auto_loop_mode: true`, `auto_loop_index: next_index`, `auto_loop_cap: (prior cap ?? 5)` forward — round-start Step 4 persists them on the new round.
|
|
101
103
|
- **Manual round**: auto-trigger `/cbp-round-input` directly (no prompt).
|
|
102
104
|
|
|
103
105
|
## Key Rules
|
|
@@ -111,6 +113,8 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
|
|
|
111
113
|
## Integration
|
|
112
114
|
|
|
113
115
|
- **Triggered by**: `/cbp-round-end` (auto), or user manually
|
|
114
|
-
- **Reads
|
|
115
|
-
- **
|
|
116
|
+
- **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_checkpoints` / `get_tasks` / `get_rounds` as break-glass)
|
|
117
|
+
- **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` — standalone still uses MCP
|
|
118
|
+
- **Writes (checkpoint KIND)**: `codebyplan round update` — audit only (`auto_loop_decision` / `auto_loop_cap_exhausted`; break-glass: MCP `update_round`). No completion, no file-approval writes.
|
|
119
|
+
- **Writes (standalone KIND)**: MCP `update_standalone_round` — audit only — standalone still uses MCP
|
|
116
120
|
- **Triggers**: `/cbp-round-complete` (clean triage — `ask`-tier permission prompt is the user confirmation), `/cbp-round-input` (not-clean triage: outstanding findings, hard-fail, or unapproved Claude checks — fires independent of git staging; also the auto-loop dirty spawn), cap-exhausted prompt routes from Step 3b (any of the three options)
|
|
@@ -17,17 +17,17 @@ Always write a session log for this session — **even if empty**. `/cbp-session
|
|
|
17
17
|
|
|
18
18
|
1. Resolve the current session log:
|
|
19
19
|
- Preferred: use the log ID held in context from `/cbp-session-start`.
|
|
20
|
-
- Fallback: MCP `get_session_logs` (limit 1, most recent open log for this `repo_id`).
|
|
21
|
-
- If still none found (e.g. session-start was skipped), create one now with MCP `create_session_log
|
|
22
|
-
2. Pull facts from
|
|
23
|
-
- Rounds added/completed, tasks advanced/completed during this session
|
|
20
|
+
- Fallback: read `.codebyplan/state/session/current.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_session_logs` (limit 1, most recent open log for this `repo_id`) when the state dir is absent and sync fails.
|
|
21
|
+
- If still none found (e.g. session-start was skipped), create one now with `codebyplan session create-log` (break-glass: MCP `create_session_log`).
|
|
22
|
+
2. Pull facts from local state files rather than narrating from memory:
|
|
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
25
|
|
|
26
26
|
### Step 1.3: Capture Handoff Snapshot
|
|
27
27
|
|
|
28
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
29
|
|
|
30
|
-
1.
|
|
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
31
|
2. If `rows[0]` exists and its `command` is non-empty (active work in flight):
|
|
32
32
|
```yaml
|
|
33
33
|
handoff:
|
|
@@ -46,7 +46,7 @@ Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can
|
|
|
46
46
|
|
|
47
47
|
Continuing Step 1:
|
|
48
48
|
|
|
49
|
-
3.
|
|
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:
|
|
50
50
|
- `ended_at`: now (maps to the `closed_at` column per TASK-2 alias)
|
|
51
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
52
|
- `summary`: concise — may be empty if nothing happened
|
|
@@ -58,12 +58,12 @@ Same rule as `/cbp-session-start` Step 5.7 — only commit files that are **not*
|
|
|
58
58
|
|
|
59
59
|
1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
|
|
60
60
|
2. Resolve **task-related files** (leave these uncommitted):
|
|
61
|
-
- MCP `get_current_task(repo_id)`
|
|
62
|
-
- If active task exists:
|
|
61
|
+
- Read `.codebyplan/state/todos.json` (local-first; reuse result from Step 1.3 if already fetched) to identify the active task id. Break-glass fallback: MCP `get_current_task(repo_id)` when the state dir is absent and sync fails.
|
|
62
|
+
- If active task exists: read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/` directory and filter to rounds with status not in `completed` / `cancelled`. Break-glass fallback: MCP `get_rounds(task_id)`.
|
|
63
63
|
- Collect `files[]` from those rounds → `task_files` set
|
|
64
64
|
- If no active task exists, `task_files` is empty
|
|
65
65
|
3. `infra_files = changed_files − task_files`
|
|
66
|
-
4. Re-run `git status --porcelain` immediately before showing the commit-prompt (after Steps 1–1.3 have completed their
|
|
66
|
+
4. Re-run `git status --porcelain` immediately before showing the commit-prompt (after Steps 1–1.3 have completed their round-trips). Recompute `infra_files` from the fresh listing — eliminates the race where files appear in the index only after network round-trips complete.
|
|
67
67
|
5. If `infra_files` is empty → skip. Otherwise present once:
|
|
68
68
|
|
|
69
69
|
```
|
|
@@ -145,9 +145,19 @@ Non-blocking — session end proceeds regardless of outcome.
|
|
|
145
145
|
|
|
146
146
|
Non-blocking — if kill fails, warn and continue. Silent when no process found.
|
|
147
147
|
|
|
148
|
+
### Step 2.5: Stop Watch Daemon
|
|
149
|
+
|
|
150
|
+
Stop this worktree's Realtime watch daemon, non-blocking and non-fatal:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npx codebyplan watch stop 2>/dev/null || true
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This SIGTERMs the per-worktree pidfile daemon started by `cbp-session-start-hook.sh`. Silently ignored when no daemon is running for this worktree. 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.
|
|
157
|
+
|
|
148
158
|
### Step 3: Update Session State
|
|
149
159
|
|
|
150
|
-
|
|
160
|
+
Run `codebyplan session update-state --action deactivate` (CLI write-through: writes `.codebyplan/state/session/state.json` + REST). Break-glass fallback: MCP `update_session_state` with action `deactivate` when the CLI is unavailable. Note: the CLI validates `--action` — only `activate`/`deactivate` are accepted; a missing, valueless, or invalid value exits 1 with a usage message.
|
|
151
161
|
|
|
152
162
|
### Step 4: Output
|
|
153
163
|
|
|
@@ -160,8 +170,8 @@ You can close this window.
|
|
|
160
170
|
## Integration
|
|
161
171
|
|
|
162
172
|
- **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
|
|
163
|
-
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward)
|
|
164
|
-
- **Writes**: MCP `update_session_log`
|
|
173
|
+
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward); 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 handoff snapshot + Step 1.5 active-task lookup), `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/` (Step 1.5 task-file resolution); `npx codebyplan version-status` (Step 1.7 package-freshness gate)
|
|
174
|
+
- **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`), `codebyplan session create-log` (Step 1 fallback when no log exists; break-glass: MCP `create_session_log`), `codebyplan session update-state --action deactivate` (Step 3 — CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`)
|
|
165
175
|
- **Spawns**: none
|
|
166
176
|
- **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 `newer:true AND guarded:false` update path (committing changed `.claude/` and `.codebyplan/` paths).
|
|
167
177
|
- **Paired with**: `/cbp-session-start`
|
|
@@ -142,18 +142,22 @@ LSP_NUDGE=$(npx codebyplan lsp --check 2>/dev/null || true)
|
|
|
142
142
|
|
|
143
143
|
### Step 3: Update Session State
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
Run `codebyplan session update-state --action activate` (CLI write-through: writes `.codebyplan/state/session/state.json` + REST). This deactivates all other repos automatically. Break-glass fallback: MCP `update_session_state` with action `activate` when the CLI is unavailable. Note: the CLI validates `--action` — only `activate`/`deactivate` are accepted; a missing, valueless, or invalid value exits 1 with a usage message.
|
|
146
|
+
|
|
147
|
+
Note: Step 0 `health_check` stays MCP unconditionally — it tests MCP connectivity itself and must not be replaced.
|
|
146
148
|
|
|
147
149
|
### Step 4: Read Last Session Log
|
|
148
150
|
|
|
149
|
-
|
|
151
|
+
Read `.codebyplan/state/session/current.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_session_logs({ repo_id, worktree_id, limit: 1 })` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
|
|
152
|
+
|
|
153
|
+
Take the first row — same inclusive-worktree scope as Step 4.5 so the previous-session display and the handoff probe agree on which row is "most recent for this worktree".
|
|
150
154
|
|
|
151
155
|
- If a previous log exists, hold its title/summary/pending items for the Step 6 output so the user sees where they left off.
|
|
152
156
|
- If none exists (first session ever for this worktree), skip silently.
|
|
153
157
|
|
|
154
158
|
### Step 5: Create This Session's Log
|
|
155
159
|
|
|
156
|
-
|
|
160
|
+
Run `codebyplan session create-log --started-at <now> --repo-id <repo_id> --worktree-id <WORKTREE_ID>` (CLI write-through: writes `.codebyplan/state/session/current.json` + REST). Create it **even if empty** — this establishes the record for session-end to finalize. Break-glass fallback: MCP `create_session_log` when the CLI is unavailable.
|
|
157
161
|
|
|
158
162
|
Minimal seed content:
|
|
159
163
|
|
|
@@ -167,7 +171,7 @@ Hold the new log's ID in context so `/cbp-session-end` can update the same recor
|
|
|
167
171
|
|
|
168
172
|
Probe the most-recent closed session log for a structured handoff payload (the handoff freshness-gate contract is specified inline in this step) and auto-resume directly into the captured command when fresh. Additive — placed BEFORE the existing `/cbp-todo` auto-trigger; ALL failure paths fall through silently to Step 7.
|
|
169
173
|
|
|
170
|
-
1. Reuse the row held from Step 4 (
|
|
174
|
+
1. Reuse the row held from Step 4 (held from Step 4 in memory — do NOT re-read from disk here; at this point `session/current.json` still holds the previous session row, which Step 5 will overwrite).
|
|
171
175
|
2. **Defensive gates** (any failure → silent fall-through to Step 7):
|
|
172
176
|
- No row returned → fall through.
|
|
173
177
|
- Row missing `closed_at` (orphan / still-open session) → fall through.
|
|
@@ -175,12 +179,12 @@ Probe the most-recent closed session log for a structured handoff payload (the h
|
|
|
175
179
|
- `row.content` exists but parse throws or shape mismatch (`command` field absent OR is an empty string) → fall through.
|
|
176
180
|
3. **Freshness gate** — load the row as `handoff = row.content` (per CHK-111 Migration A column alias). Mark stale when ANY of:
|
|
177
181
|
- `(now - row.closed_at) > freshness_window_hours` (read from `.codebyplan/repo.json`, default 24 hours)
|
|
178
|
-
- Referenced entity in `handoff.context` has shifted. For each id present,
|
|
179
|
-
- `checkpoint_id` →
|
|
180
|
-
- `task_id` →
|
|
181
|
-
- `round_id` →
|
|
182
|
+
- Referenced entity in `handoff.context` has shifted. For each id present, read the matching local state file and check `updated_at`:
|
|
183
|
+
- `checkpoint_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>.json` (local-first; sync + MCP break-glass if missing)
|
|
184
|
+
- `task_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>.json` (local-first; sync + MCP break-glass if missing)
|
|
185
|
+
- `round_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/<round_id>.json` (local-first; sync + MCP break-glass if missing)
|
|
182
186
|
Then compare `entry.updated_at > handoff.captured_at` → stale on any inequality.
|
|
183
|
-
-
|
|
187
|
+
- Local file missing after sync attempt → stale (referenced entity gone or moved out of reach).
|
|
184
188
|
- `handoff.context.checkpoint_id` resolves to a checkpoint whose `worktree_id` is non-null AND (caller `WORKTREE_ID` is `null` OR differs from `checkpoint.worktree_id`) → stale (a fresh handoff for another worktree's work — or for assigned work this caller cannot confirm ownership of — must not auto-resume here). Mirrors the cbp-todo Step 1.5 ownership rule.
|
|
185
189
|
4. **On stale OR any defensive gate hit**: fall through silently to Step 7 (existing `/cbp-todo` trigger).
|
|
186
190
|
5. **On fresh hit**: trigger `handoff.command` directly with `handoff.context` / `handoff.state` in the trigger arguments. The downstream skill self-loads its full context — do NOT duplicate `/cbp-todo` Step 2's context-loading matrix here. Skip Step 5.7, Step 6 output, and Step 7.
|
|
@@ -191,12 +195,12 @@ Clean the working tree of leftover infra before the session begins. Only commit
|
|
|
191
195
|
|
|
192
196
|
1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
|
|
193
197
|
2. Resolve **task-related files** (leave these uncommitted):
|
|
194
|
-
- MCP `get_current_task(repo_id)`
|
|
195
|
-
- If active task exists:
|
|
198
|
+
- Read `.codebyplan/state/todos.json` (local-first) to identify the active task id. If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task(repo_id)` when the state dir is absent and sync fails.
|
|
199
|
+
- If active task exists: read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/` directory and filter to rounds with status not in `completed` / `cancelled`. Break-glass fallback: MCP `get_rounds(task_id)`.
|
|
196
200
|
- Collect `files[]` from those rounds → `task_files` set
|
|
197
201
|
- If no active task exists, `task_files` is empty
|
|
198
202
|
3. `infra_files = changed_files − task_files`
|
|
199
|
-
4. **Re-run `git status --porcelain` immediately before showing the commit-prompt** (after Steps 0–5 have completed all
|
|
203
|
+
4. **Re-run `git status --porcelain` immediately before showing the commit-prompt** (after Steps 0–5 have completed all their round-trips). Eliminates the race where prior-session staged files appear in the index only after network round-trips complete. Recompute `infra_files` from the fresh listing.
|
|
200
204
|
5. If `infra_files` is empty → skip. Otherwise present once:
|
|
201
205
|
|
|
202
206
|
```
|
|
@@ -213,7 +217,7 @@ Non-blocking — session start proceeds either way.
|
|
|
213
217
|
|
|
214
218
|
### Step 5.8: Resolve Ownership
|
|
215
219
|
|
|
216
|
-
Call MCP `get_checkpoints({ repo_id, status: 'active' })
|
|
220
|
+
Call MCP `get_checkpoints({ repo_id, status: 'active' })` (MCP only — deliberate: the active-filter query has no local-mirror equivalent). Partition results into:
|
|
217
221
|
|
|
218
222
|
- `owned[]` — entries where `checkpoint.worktree_id === WORKTREE_ID`, OR both are `null`
|
|
219
223
|
- `cross_worktree[]` — entries where `checkpoint.worktree_id` is non-null AND differs from `WORKTREE_ID` (includes the case where caller `WORKTREE_ID` is `null` but the target has a non-null `worktree_id`)
|
|
@@ -253,8 +257,8 @@ Three-branch gate using `owned_count` and `total_count` from Step 5.8:
|
|
|
253
257
|
|
|
254
258
|
- **Triggered by**: user invocation, `/clear` recovery
|
|
255
259
|
- **Resolves**: `npx codebyplan resolve-worktree --json` (worktree id + distress signal; non-tuple-miss distress is non-blocking at session-start)
|
|
256
|
-
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `
|
|
257
|
-
- **Writes**: MCP `create_session_log` (
|
|
260
|
+
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `health_check` (Step 0 hard gate — stays MCP unconditionally); local-first reads (with `npx codebyplan sync` + MCP break-glass): `.codebyplan/state/session/current.json` (Step 4 previous log + Step 4.5 handoff probe), `.codebyplan/state/checkpoints/<id>.json` / `tasks/<id>.json` / `rounds/<id>.json` (Step 4.5 freshness probe), `.codebyplan/state/todos.json` (Step 5.7 active-task lookup); MCP `get_checkpoints({ repo_id, status: 'active' })` (Step 5.8 ownership partition — MCP only, no local mirror for active-filter query); `scripts/infra-drift.mjs` + a best-effort `git fetch` (Step 1.5 monorepo drift); `npx codebyplan version-status` (Step 1.6 package-freshness gate); `npx codebyplan lsp --check` (Step 1.7 LSP binary nudge — reads `.codebyplan/lsp.json`, non-blocking). Reads at Step 3 and later do NOT fire on a Step 0 MCP hard-fail or the Step 1.6 update-and-halt path
|
|
261
|
+
- **Writes**: `codebyplan session create-log` (Step 5 — CLI write-through; break-glass: MCP `create_session_log`), `codebyplan session update-state --action activate` (Step 3 — CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`) — both SKIPPED on a Step 0 MCP hard-fail and on the Step 1.6 update-and-halt path
|
|
258
262
|
- **Spawns**: none
|
|
259
263
|
- **Triggers**: `/cbp-git-commit` (conditional, on user approval at Step 5.7 or the Step 1.6 update path), `handoff.command` (on fresh handoff hit at Step 4.5), `/cbp-todo` (auto fall-through when owned_count >= 1 or total_count === 0; STOPS with no trigger when total_count >= 1 AND owned_count === 0; NOT triggered on a Step 0 hard-fail or the Step 1.6 update-and-halt path)
|
|
260
264
|
- **Paired with**: `/cbp-session-end`
|
|
@@ -21,7 +21,7 @@ Step 1 of `/cbp-checkpoint-end` handles branch promotion to main via `/cbp-ship-
|
|
|
21
21
|
|
|
22
22
|
| Source | What's read |
|
|
23
23
|
| ----------------------------- | ----------------------------------------------------------------------------------------- |
|
|
24
|
-
| MCP `get_current_task`
|
|
24
|
+
| Local state `.codebyplan/state/checkpoints/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` break-glass | Active checkpoint (for context.shipment write-back) |
|
|
25
25
|
| `.codebyplan/git.json` + `.codebyplan/shipment.json` | `branch_config`, `shipment` section if present (per `ship-configure`) |
|
|
26
26
|
| Repo scan | Detect surfaces from filesystem (vercel.json, eas.json, package.json publishConfig, etc.) |
|
|
27
27
|
| `checkpoint.context.shipment` | Last shipment record (timestamp, surfaces, results) |
|
|
@@ -197,7 +197,7 @@ Verification timeouts are conservative (Vercel: 5min, EAS: 30min, TestFlight pro
|
|
|
197
197
|
|
|
198
198
|
### Step 7 — Persist shipment record
|
|
199
199
|
|
|
200
|
-
Write to `checkpoint.context.shipment` via MCP `update_checkpoint
|
|
200
|
+
Write to `checkpoint.context.shipment` via `codebyplan checkpoint update <id> --context '{"shipment": {...}}'` (CLI write-through); use MCP `update_checkpoint` as documented break-glass when the CLI is unavailable:
|
|
201
201
|
|
|
202
202
|
```json
|
|
203
203
|
{
|
|
@@ -326,7 +326,7 @@ When present, this overrides scan results. `ship-configure` writes here.
|
|
|
326
326
|
## Integration
|
|
327
327
|
|
|
328
328
|
- **Triggered by**: `/cbp-checkpoint-end` (auto, after branch promotion to main via `/cbp-ship-main`); user direct invocation for re-runs
|
|
329
|
-
- **Reads**: MCP `get_current_task
|
|
330
|
-
- **Writes**: MCP `update_checkpoint`
|
|
329
|
+
- **Reads**: Local state `.codebyplan/state/checkpoints/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` as documented break-glass when the state dir is absent and sync fails. Also reads `.codebyplan/git.json` + `.codebyplan/shipment.json` (`branch_config` + `shipment`), filesystem scan.
|
|
330
|
+
- **Writes**: `codebyplan checkpoint update <id> --context '...'` (CLI write-through) for context.shipment; MCP `update_checkpoint` break-glass.
|
|
331
331
|
- **Calls**: per-surface deploy via reference files (vercel CLI, eas CLI, supabase CLI, npm, vsce, railway CLI, gh release)
|
|
332
332
|
- **Triggers**: returns control to caller — does NOT auto-trigger `/cbp-checkpoint-complete` (that's the caller's job)
|
|
@@ -35,8 +35,8 @@ This is **always interactive**. The orchestrator does NOT silently apply migrati
|
|
|
35
35
|
|
|
36
36
|
1. **List pending migrations**:
|
|
37
37
|
```bash
|
|
38
|
-
PROJECT_REF=$(jq -r '.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
39
|
-
LAST_VERSION=$(jq -r '.surfaces.supabase.last_shipped_migration_version // ""' .codebyplan/shipment.json)
|
|
38
|
+
PROJECT_REF=$(jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
39
|
+
LAST_VERSION=$(jq -r '.shipment.surfaces.supabase.last_shipped_migration_version // ""' .codebyplan/shipment.json)
|
|
40
40
|
|
|
41
41
|
PENDING=$(ls supabase/migrations/*.sql | sort)
|
|
42
42
|
if [ -n "$LAST_VERSION" ]; then
|
|
@@ -116,7 +116,7 @@ This is **always interactive**. The orchestrator does NOT silently apply migrati
|
|
|
116
116
|
7. **Update the last-shipped marker**:
|
|
117
117
|
```bash
|
|
118
118
|
LAST_APPLIED=$(echo "$PENDING" | tail -1 | xargs basename)
|
|
119
|
-
jq --arg v "$LAST_APPLIED" '.surfaces.supabase.last_shipped_migration_version = $v' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp
|
|
119
|
+
jq --arg v "$LAST_APPLIED" '.shipment.surfaces.supabase.last_shipped_migration_version = $v' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp
|
|
120
120
|
mv .codebyplan/shipment.json.tmp .codebyplan/shipment.json
|
|
121
121
|
```
|
|
122
122
|
|
|
@@ -126,7 +126,7 @@ The skill's job is to verify these credentials EXIST and are valid; never to sto
|
|
|
126
126
|
Run the verification step from the surface reference. For Vercel, this is:
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
|
-
vercel inspect "$(jq -r '.surfaces."vercel-web".project_id' .codebyplan/shipment.json)" 2>&1 | head -20
|
|
129
|
+
vercel inspect "$(jq -r '.shipment.surfaces."vercel-web".project_id' .codebyplan/shipment.json)" 2>&1 | head -20
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
If verification passes, mark the surface as configured. If it fails, surface the error and offer to retry the failing step.
|
|
@@ -161,7 +161,7 @@ railway domain
|
|
|
161
161
|
Verify:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
PROJECT_ID=$(jq -r '.surfaces."railway-backend".project_id' .codebyplan/shipment.json)
|
|
164
|
+
PROJECT_ID=$(jq -r '.shipment.surfaces."railway-backend".project_id' .codebyplan/shipment.json)
|
|
165
165
|
railway status --json | jq
|
|
166
166
|
# Expect: project + service info matching saved IDs
|
|
167
167
|
```
|
|
@@ -171,7 +171,7 @@ Test deploy:
|
|
|
171
171
|
```bash
|
|
172
172
|
railway up --detach
|
|
173
173
|
# Wait, then verify URL responds
|
|
174
|
-
URL=$(jq -r '.surfaces."railway-backend".url' .codebyplan/shipment.json)
|
|
174
|
+
URL=$(jq -r '.shipment.surfaces."railway-backend".url' .codebyplan/shipment.json)
|
|
175
175
|
curl -sI "$URL/health" | head -1
|
|
176
176
|
```
|
|
177
177
|
|
|
@@ -98,7 +98,7 @@ Write `.codebyplan/shipment.json`:
|
|
|
98
98
|
Verify:
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
PROJECT_ID=$(jq -r '.surfaces."vercel-web".project_id' .codebyplan/shipment.json)
|
|
101
|
+
PROJECT_ID=$(jq -r '.shipment.surfaces."vercel-web".project_id' .codebyplan/shipment.json)
|
|
102
102
|
vercel inspect "$PROJECT_ID" --json | jq -r '.name, .latestDeployments[0].readyState'
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -13,7 +13,7 @@ Compose a PR body from checkpoint context, then delegate all git/gh mechanics to
|
|
|
13
13
|
|
|
14
14
|
### Step 1: Read Checkpoint Context
|
|
15
15
|
|
|
16
|
-
Use MCP `get_current_task`
|
|
16
|
+
Read local state `.codebyplan/state/checkpoints/<id>.json` to get the active checkpoint; on miss run `npx codebyplan sync` once and re-read. Use MCP `get_current_task` as documented break-glass when the state dir is absent and sync fails. Collect `checkpoint.title`, completed task titles (from `.codebyplan/state/checkpoints/<id>/tasks/*.json` filtered to `status === 'completed'`; MCP `get_tasks` break-glass), and key decisions from `checkpoint.context.decisions[]`.
|
|
17
17
|
|
|
18
18
|
### Step 2: Compose PR Body
|
|
19
19
|
|
|
@@ -98,4 +98,4 @@ If `branch_deleted === true`, run a conditional Supabase preview-branch teardown
|
|
|
98
98
|
|
|
99
99
|
- **Called by**: `/cbp-checkpoint-end`
|
|
100
100
|
- **Delegates to**: `codebyplan ship` CLI
|
|
101
|
-
- **Reads**: MCP `get_current_task
|
|
101
|
+
- **Reads**: Local state `.codebyplan/state/checkpoints/<id>.json` + `.../tasks/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` / `get_tasks` as documented break-glass when the state dir is absent and sync fails.
|
|
@@ -169,12 +169,13 @@ Parse the JSON output and store: `pr_url`, `merge_commit`, `branch_deleted`, `fe
|
|
|
169
169
|
When `branch_deleted === true` in the ship JSON:
|
|
170
170
|
|
|
171
171
|
- Read `FEAT_BRANCH` from the `feat_branch` field in the ship JSON — NOT from `git branch --show-current`. By the time Step 7.3 runs, `codebyplan ship` has already checked out the base branch, so the live branch is the base, not the feat branch.
|
|
172
|
-
-
|
|
172
|
+
- Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id`.
|
|
173
|
+
- Call `mcp__supabase__list_branches` with the resolved `project_id`.
|
|
173
174
|
- Scan the returned list for an entry whose `name` exactly equals `FEAT_BRANCH`.
|
|
174
175
|
- If found: call `mcp__supabase__delete_branch` with its `branch_id`. Report the outcome.
|
|
175
176
|
- If not found: no-op silently — the GitHub integration may have already removed the preview branch on PR close; not-found is success, NOT an error.
|
|
176
177
|
- If the `list_branches` call itself fails (network, auth, or non-success response): emit a non-blocking warning that the Supabase preview branch for `FEAT_BRANCH` may still exist and should be verified in the dashboard. Never treat an API failure as a not-found success.
|
|
177
|
-
- Never delete the
|
|
178
|
+
- Never delete the branch where `is_default` is true in the `list_branches` response (the production/parent project branch) or any other persistent/long-lived branch.
|
|
178
179
|
|
|
179
180
|
### Step 7.5: Complete Standalone Task
|
|
180
181
|
|