codebyplan 1.11.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +602 -345
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/agents/cbp-cc-executor.md +1 -1
- package/templates/agents/cbp-e2e-maestro.md +202 -0
- package/templates/agents/cbp-e2e-playwright.md +229 -0
- package/templates/agents/cbp-e2e-tauri.md +184 -0
- package/templates/agents/cbp-e2e-vscode.md +203 -0
- package/templates/agents/cbp-e2e-xcuitest.md +224 -0
- package/templates/agents/cbp-improve-claude.md +1 -1
- package/templates/agents/cbp-round-executor.md +11 -11
- package/templates/agents/cbp-task-check.md +1 -1
- package/templates/agents/cbp-task-planner.md +2 -0
- package/templates/agents/cbp-testing-qa-agent.md +9 -9
- package/templates/context/testing/e2e.md +303 -0
- package/templates/hooks/cbp-statusline.mjs +44 -0
- package/templates/hooks/cbp-statusline.py +24 -2
- package/templates/hooks/cbp-statusline.sh +22 -2
- package/templates/hooks/validate-structure-lengths.sh +2 -0
- package/templates/hooks/validate-structure-smoke.sh +2 -1
- package/templates/hooks/validate-structure-templates.sh +1 -0
- package/templates/rules/README.md +8 -1
- package/templates/rules/context-file-loading.md +4 -1
- package/templates/rules/e2e-mandatory.md +70 -0
- package/templates/rules/supabase-branch-lifecycle.md +99 -0
- package/templates/settings.project.base.json +1 -2
- package/templates/skills/cbp-build-cc-agent/SKILL.md +16 -14
- package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +4 -4
- package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +8 -6
- package/templates/skills/cbp-build-cc-mode/SKILL.md +4 -4
- package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +1 -2
- package/templates/skills/cbp-checkpoint-check/SKILL.md +12 -8
- package/templates/skills/cbp-checkpoint-create/SKILL.md +2 -0
- package/templates/skills/cbp-checkpoint-end/SKILL.md +27 -5
- package/templates/skills/cbp-checkpoint-plan/SKILL.md +2 -2
- package/templates/skills/cbp-checkpoint-plan/reference/e2e-discovery-probe.md +5 -5
- package/templates/skills/cbp-e2e-setup/SKILL.md +254 -0
- package/templates/skills/cbp-e2e-setup/reference/maestro.md +200 -0
- package/templates/skills/cbp-e2e-setup/reference/playwright.md +212 -0
- package/templates/skills/cbp-e2e-setup/reference/tauri.md +147 -0
- package/templates/skills/cbp-e2e-setup/reference/vscode.md +154 -0
- package/templates/skills/cbp-e2e-setup/reference/xcuitest.md +185 -0
- package/templates/skills/cbp-frontend-ui/SKILL.md +6 -6
- package/templates/skills/cbp-frontend-ux/SKILL.md +1 -1
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +17 -1
- package/templates/skills/cbp-round-execute/SKILL.md +30 -17
- package/templates/skills/cbp-session-start/SKILL.md +27 -2
- package/templates/skills/cbp-ship-main/SKILL.md +13 -0
- package/templates/skills/cbp-supabase-branch-check/SKILL.md +12 -5
- package/templates/skills/cbp-supabase-migrate/SKILL.md +139 -9
- package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +1 -1
- package/templates/skills/cbp-supabase-setup/SKILL.md +13 -7
- package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +2 -2
- package/templates/skills/cbp-task-check/SKILL.md +2 -2
- package/templates/skills/cbp-task-start/SKILL.md +2 -0
- package/templates/agents/cbp-test-e2e-agent.md +0 -363
|
@@ -56,7 +56,7 @@ Execute the survey instructions inline using Read/Grep/Bash. Save to `round.cont
|
|
|
56
56
|
For each entry, route per `rules/file-routing.md`:
|
|
57
57
|
|
|
58
58
|
- `.claude/skills/{name}/SKILL.md` → `cbp-build-cc-skill` via Skill tool
|
|
59
|
-
- `.claude/agents/{name}/AGENT.md` → `cbp-build-cc-agent` via Skill tool
|
|
59
|
+
- `.claude/agents/{name}.md` (or `{name}/AGENT.md` folder form) → `cbp-build-cc-agent` via Skill tool
|
|
60
60
|
- `.claude/rules/{name}.md` → `cbp-build-cc-rule` via Skill tool
|
|
61
61
|
- `.claude/CLAUDE.md` → `cbp-build-cc-claude-file` via Skill tool (or direct Edit)
|
|
62
62
|
- `.claude/settings*.json` → `cbp-build-cc-settings` via Skill tool
|
|
@@ -145,28 +145,40 @@ Read `task.context.testing_profile` (already loaded in Step 2).
|
|
|
145
145
|
|
|
146
146
|
On pass, synthesise `testing_qa_output` inline per the procedure in `reference/inline-fallback.md` "Validation fallback" section (output shape defined in `agents/cbp-testing-qa-agent.md` Output Contract) and persist to `round.context.testing_qa_output` at Step 7.
|
|
147
147
|
|
|
148
|
-
**All other profiles**: spawn `cbp-testing-qa-agent`
|
|
148
|
+
**All other profiles**: spawn `cbp-testing-qa-agent` against the wave's `files[]` (or full executor output in single-wave mode), and dispatch e2e specialists **config-driven** in parallel — all Agent calls in the same message:
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
1. **Short-circuit hints** (applied *before* reading `e2e.json`, emit no `e2e_eligible_skipped` signal): if `testing_profile === 'backend'` OR `round.context.round_type === 'survey'`, dispatch `cbp-testing-qa-agent` alone and skip e2e entirely. (The `claude_only` branch above already skips all agent spawns.)
|
|
151
|
+
2. Read `.codebyplan/e2e.json`. If the file is absent or `frameworks` is missing/empty, no framework is eligible — skip e2e entirely (no `e2e_eligible_skipped` signal) and run `cbp-testing-qa-agent` alone.
|
|
152
|
+
3. For each entry in `frameworks` where `enabled === true` AND `auto_run === true`: if `platforms[]` does not include the current CI target (e.g. an iOS-only config on a Linux runner with no simulator), skip the framework — a recorded valid platform skip per `rules/e2e-mandatory.md`, NOT added to `e2e_eligible[]`. Otherwise mark it **eligible** when its `app` source path intersects this wave's `files_changed` (repo root for single-app repos). Record the eligible framework names as `round.context.e2e_eligible[]`.
|
|
153
|
+
4. For every eligible framework, spawn the matching `cbp-e2e-*` specialist (per the `context/testing/e2e.md` dispatch routing table) IN PARALLEL with `cbp-testing-qa-agent` and with each other. Inject `framework`, `app`, `platforms`, and `credential_vars` from `e2e.json` — the config is authoritative; agents do not auto-detect.
|
|
154
|
+
5. `has_ui_work` and `testing_profile` are **hints only** beyond the short-circuit above — they never suppress an eligible framework. Pure `.claude/`-only and docs-only rounds match no configured `app` path and are therefore not eligible.
|
|
151
155
|
|
|
152
|
-
|
|
156
|
+
This realises the opt-out contract in `rules/e2e-mandatory.md`: an eligible framework whose specialist does not run — without a recorded valid skip reason — is an `e2e_eligible_skipped` hard-fail at Step 6.
|
|
157
|
+
|
|
158
|
+
Input contracts: `cbp-testing-qa-agent` receives `executor_output`, `testing_profile`, `has_ui_work` (see `agents/cbp-testing-qa-agent.md` Input Contract). The `cbp-e2e-*` specialist receives `repo_id`, `round_number`, `files_changed`, `prior_round_files_changed` (full task aggregate when round_number ≥ 2), `whole_checkpoint_mode: false`, `framework`, `app`, `platforms`, `credential_vars`, `test_strategy`, `pages_affected`, `has_auth`, `dev_server_port` (see `context/testing/e2e.md` Input Contract for the full shape). `test_strategy` is injected here in per-round mode; `/cbp-checkpoint-check` Step 5b omits it (the specialist self-resolves from `e2e.json` + DB in `whole_checkpoint_mode`).
|
|
159
|
+
|
|
160
|
+
**Independence**: neither agent reads the other's output. Baseline-regression findings surface as a BLOCKING gate at `/cbp-round-end` Step 7 (an explicit accept-or-fix user decision; baselines are NEVER auto-accepted). Per-wave spawns MAY run in parallel with the next wave's executor when dependency order allows. The `cbp-e2e-*` specialists are parallel siblings of `cbp-testing-qa-agent` — they do not share state.
|
|
153
161
|
|
|
154
162
|
### Step 5b: Post-E2E Screenshot Review (cbp-frontend-ui Phase 6.5)
|
|
155
163
|
|
|
156
|
-
|
|
164
|
+
Aggregate screenshots across ALL specialists that ran: `screenshots = Object.values(round.context.e2e_outputs ?? {}).flatMap(o => o.screenshots ?? [])`. When the aggregated list is non-empty, invoke the `cbp-frontend-ui` skill with `phase: 'screenshot_review'` (input: `files_changed`, `e2e_screenshots: <aggregated screenshots>`, `context: { checkpoint_goal, round_requirements }`). Under this phase the skill runs only Phase 6.5 (Rendered-Output Visual Review) + 7 + 8 — Phases 1-6 (style) already ran inline at executor Step 3.8 with `phase: 'style_only'`.
|
|
157
165
|
|
|
158
166
|
Persist findings to `round.context.frontend_ui_review` (merge with Step 3.8's style-only output if present). Baseline-regression findings surface as a BLOCKING gate at `/cbp-round-end` Step 7 (an explicit accept-or-fix user decision; baselines are NEVER auto-accepted); rendered_visual critical findings are surfaced in the Step 7 findings presentation. Neither auto-fails the round. cbp-testing-qa-agent does NOT read these findings (full independence per Step 5).
|
|
159
167
|
|
|
160
|
-
**Skip** when `round.context.
|
|
168
|
+
**Skip** when `round.context.e2e_outputs` is absent/empty, the aggregated `screenshots` list is empty, or `testing_profile === 'claude_only'`.
|
|
161
169
|
|
|
162
170
|
### Step 6: Hard-Fail Routing
|
|
163
171
|
|
|
164
|
-
Per-wave hard-fail signal
|
|
172
|
+
Per-wave hard-fail signal — true when ANY hold:
|
|
173
|
+
|
|
174
|
+
- `testing_qa_output.totals.hard_fail === true`.
|
|
175
|
+
- For any framework `f` in `round.context.e2e_outputs`: `e2e_outputs[f].status === 'failed'` OR `e2e_outputs[f].test_results?.failed > 0`.
|
|
176
|
+
- **`e2e_eligible_skipped`**: any framework in `round.context.e2e_eligible[]` for which no specialist output exists in `round.context.e2e_outputs` AND no valid skip reason is recorded (per the `rules/e2e-mandatory.md` valid-skip list). A silently-skipped eligible framework is a hard-fail.
|
|
165
177
|
|
|
166
178
|
**All waves hard_fail: false** → proceed to Step 7. **Any wave hard_fail: true**:
|
|
167
179
|
|
|
168
|
-
- **Simple fixes** (type errors, lint, missing imports, test assertion fixes, e2e `real`-category with clear code-side root cause, no prior re-trigger this round) → save failure details to round context; retrigger the failing wave's executor; re-run testing-qa AND
|
|
169
|
-
- **Structural OR already re-triggered once OR e2e preflight aborts
|
|
180
|
+
- **Simple fixes** (type errors, lint, missing imports, test assertion fixes, e2e `real`-category with clear code-side root cause, no prior re-trigger this round) → save failure details to round context; retrigger the failing wave's executor; re-run testing-qa AND the eligible `cbp-e2e-*` specialists for that wave.
|
|
181
|
+
- **Structural OR already re-triggered once OR e2e preflight aborts OR `e2e_eligible_skipped`** → save failure context via MCP `update_round`; auto-trigger `/cbp-round-input`. STOP.
|
|
170
182
|
|
|
171
183
|
## Inline execution fallback
|
|
172
184
|
|
|
@@ -180,9 +192,9 @@ When `cbp-testing-qa-agent` spawn fails OR the resolved `testing_profile` is `cl
|
|
|
180
192
|
|
|
181
193
|
Update round context via MCP `update_round`:
|
|
182
194
|
|
|
183
|
-
- `context`: { ...existing, executor_output, testing_qa_output,
|
|
195
|
+
- `context`: { ...existing, executor_output, testing_qa_output, e2e_eligible, e2e_outputs, frontend_ui_review }
|
|
184
196
|
|
|
185
|
-
`
|
|
197
|
+
`e2e_outputs` (a framework-keyed map of specialist outputs, e.g. `{ playwright: {...}, maestro: {...} }`) and `frontend_ui_review` are present only when the gates above admitted them (≥1 eligible framework ran AND Step 5b ran). `e2e_eligible[]` records which frameworks were eligible this round and drives the Step 6 `e2e_eligible_skipped` check.
|
|
186
198
|
|
|
187
199
|
### Step 8: Auto-trigger Round End
|
|
188
200
|
|
|
@@ -195,17 +207,18 @@ Trigger `/cbp-round-end`.
|
|
|
195
207
|
## Key Rules
|
|
196
208
|
|
|
197
209
|
- **Code + test writing + inline validation** — planning lives in `round-start`, summary in `round-end`
|
|
198
|
-
- Per-wave `cbp-testing-qa-agent` AND `cbp-
|
|
199
|
-
- `testing_profile` from `task.context` governs which checks run — read it once in Step 2; pass to every testing-qa +
|
|
200
|
-
- `claude_only` profile skips all agent spawns (testing-qa AND
|
|
201
|
-
-
|
|
210
|
+
- Per-wave `cbp-testing-qa-agent` AND the `cbp-e2e-*` specialist run in parallel (both against the same wave's `files[]`); they may also run in parallel with the NEXT wave's executor when dependency order allows
|
|
211
|
+
- `testing_profile` from `task.context` governs which checks run — read it once in Step 2; pass to every testing-qa + e2e specialist spawn
|
|
212
|
+
- `claude_only` profile skips all agent spawns (testing-qa AND `cbp-e2e-*`); runs hook syntax and skill structure checks inline
|
|
213
|
+
- E2E dispatch is **config-driven and opt-out** (`.codebyplan/e2e.json`), not gated on `has_ui_work`/`testing_profile` — an eligible framework that silently does not run is an `e2e_eligible_skipped` hard-fail (`rules/e2e-mandatory.md`)
|
|
214
|
+
- Step 5b (cbp-frontend-ui Phase 6.5) runs only when e2e produced screenshots — gated on the aggregated `e2e_outputs[*].screenshots[]` being non-empty
|
|
202
215
|
- Claude NEVER git adds files in round commands
|
|
203
216
|
|
|
204
217
|
## Integration
|
|
205
218
|
|
|
206
219
|
- **Reads**: MCP `get_current_task`, `get_rounds`
|
|
207
|
-
- **Writes**: MCP `update_round` (context with executor_output + testing_qa_output +
|
|
208
|
-
- **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of cbp-
|
|
220
|
+
- **Writes**: MCP `update_round` (context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + frontend_ui_review)
|
|
221
|
+
- **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of the `cbp-e2e-*` specialists), the `cbp-e2e-*` specialists (config-driven dispatch per `context/testing/e2e.md`, one per eligible framework in `.codebyplan/e2e.json`), `cbp-database-agent` (if DB work), `cbp-security-agent` (if security review needed)
|
|
209
222
|
- **Skill invocations**: `cbp-frontend-ui` at Step 5b with `phase: 'screenshot_review'` (post-e2e)
|
|
210
223
|
- **Triggers**: `/cbp-round-end` (auto)
|
|
211
224
|
- **Triggered by**: `/cbp-round-start` (auto, after plan approval)
|
|
@@ -12,7 +12,7 @@ Activate the session, open a fresh session log, and surface the previous log's p
|
|
|
12
12
|
|
|
13
13
|
## Instructions
|
|
14
14
|
|
|
15
|
-
Run Steps 0 through 5.8 silently (no intermediate output) — except Step 1.4 may surface a one-line fast-forward note or warning, and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 2 → 3 → 4 → 4.5 → 5 → 5.7 → 5.8 → 6 → 7.) Produce ONE output block at Step 6, then auto-trigger or stop per Step 7.
|
|
15
|
+
Run Steps 0 through 5.8 silently (no intermediate output) — except Step 1.4 may surface a one-line fast-forward note or warning, Step 1.5 may surface a one-line infra-drift nudge, and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 1.5 → 2 → 3 → 4 → 4.5 → 5 → 5.7 → 5.8 → 6 → 7.) Produce ONE output block at Step 6, then auto-trigger or stop per Step 7.
|
|
16
16
|
|
|
17
17
|
### Step 0: MCP Health Check
|
|
18
18
|
|
|
@@ -77,6 +77,31 @@ CURRENT="$(git rev-parse --abbrev-ref HEAD)"
|
|
|
77
77
|
|
|
78
78
|
Never rebase, reset, force-push, or stash. A non-fast-forwardable home branch is a signal to reconcile manually, not to overwrite.
|
|
79
79
|
|
|
80
|
+
### Step 1.5: Infra Drift Check
|
|
81
|
+
|
|
82
|
+
Surface — never block — when this worktree's CBP tooling has fallen behind. Runs after Step 1.4 and may add one line to the Step 6 output. Two mutually-exclusive concepts, keyed on repo type (`$PRODUCTION` is the branch resolved in Step 1.4):
|
|
83
|
+
|
|
84
|
+
- **Monorepo (concept A)** — both `packages/codebyplan-package/templates/` and `scripts/infra-drift.mjs` exist. Step 1.4 skips the fetch on a feat branch, so refresh `origin/$PRODUCTION` best-effort first, then run the reporter:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git fetch origin "$PRODUCTION" 2>/dev/null || true
|
|
88
|
+
node scripts/infra-drift.mjs 2>/dev/null || true
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The script self-guards (feat branch + behind > 0) and emits at most one `⚠ .claude/ infra is N behind — run /cbp-refresh-infra` line. Hold any output for Step 6.
|
|
92
|
+
|
|
93
|
+
- **Consumer (concept B)** — no `templates/`, but an install manifest exists (`.claude/.cbp.manifest.json`, falling back to `.cbp-claude.manifest.json` then `.codebyplan-claude.manifest.json`). Compare its `version` to the latest published `codebyplan`, offline-safe:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
LATEST="$(npm view codebyplan version 2>/dev/null)"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When `$LATEST` is non-empty and newer than the manifest `version`, hold one line for Step 6: `⚠ codebyplan {installed} → {LATEST} — run npx codebyplan@latest claude update`. Any failure (offline, npm absent) → silent.
|
|
100
|
+
|
|
101
|
+
- **Neither** → skip silently.
|
|
102
|
+
|
|
103
|
+
Concept B never fires in the monorepo — the `templates/` guard routes the source repo to concept A only (its manifest `version` is intentionally stale). Fully non-blocking; every failure path falls through with no output.
|
|
104
|
+
|
|
80
105
|
### Step 2: Check Dev Server
|
|
81
106
|
|
|
82
107
|
**Skip if `server_type` is `"none"`.**
|
|
@@ -198,7 +223,7 @@ Three-branch gate using `owned_count` and `total_count` from Step 5.8:
|
|
|
198
223
|
|
|
199
224
|
- **Triggered by**: user invocation, `/clear` recovery
|
|
200
225
|
- **Resolves**: `npx codebyplan resolve-worktree --json` (worktree id + distress signal; non-tuple-miss distress is non-blocking at session-start)
|
|
201
|
-
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `get_session_logs` (worktree-filtered, limit 1 — single call shared by Step 4 and Step 4.5), MCP `health_check`, MCP `get_current_task`, MCP `get_rounds`, MCP `get_checkpoints` (two calls: `{ repo_id, status: 'active' }` for the Step 5.8 ownership partition; `{ repo_id }` unfiltered for the Step 4.5 freshness probe, which may resolve a non-active checkpoint), MCP `get_tasks` / `get_rounds` for the Step 4.5 freshness probe
|
|
226
|
+
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `get_session_logs` (worktree-filtered, limit 1 — single call shared by Step 4 and Step 4.5), MCP `health_check`, MCP `get_current_task`, MCP `get_rounds`, MCP `get_checkpoints` (two calls: `{ repo_id, status: 'active' }` for the Step 5.8 ownership partition; `{ repo_id }` unfiltered for the Step 4.5 freshness probe, which may resolve a non-active checkpoint), MCP `get_tasks` / `get_rounds` for the Step 4.5 freshness probe; `scripts/infra-drift.mjs` + a best-effort `git fetch` (Step 1.5 monorepo drift) or the install manifest + `npm view codebyplan version` (Step 1.5 consumer drift)
|
|
202
227
|
- **Writes**: MCP `create_session_log` (new, possibly empty), MCP `update_session_state` (activate)
|
|
203
228
|
- **Spawns**: none
|
|
204
229
|
- **Triggers**: `/cbp-git-commit` (conditional, on user approval), `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)
|
|
@@ -52,6 +52,19 @@ Pass `--dry-run` through if the skill was invoked with a dry-run arg.
|
|
|
52
52
|
|
|
53
53
|
Parse JSON from Step 3. Report `pr_url`, `merge_commit`, `branch_deleted`. If `checks_failed: true`, surface `checks_failure_reason` and stop.
|
|
54
54
|
|
|
55
|
+
If `branch_deleted === true`, run a conditional Supabase preview-branch teardown for the feat branch that was just merged:
|
|
56
|
+
|
|
57
|
+
> Lifecycle contract: see [[supabase-branch-lifecycle]].
|
|
58
|
+
|
|
59
|
+
- Read `FEAT_BRANCH` from the `feat_branch` field in the Step 3 JSON output — NOT from `git branch --show-current`. By the time Step 4 runs, `codebyplan ship` has already checked out the base branch (unless `--keep-feat` was passed), so the live branch is the base, not the feat branch.
|
|
60
|
+
- Call `mcp__supabase__list_branches` with `project_id: rrvtrumtkhrsbhcyrwvf`.
|
|
61
|
+
- Scan the returned list for an entry whose `name` exactly equals `$FEAT_BRANCH`.
|
|
62
|
+
- If found: call `mcp__supabase__delete_branch` with its `branch_id`. Report the Supabase delete outcome alongside `pr_url` / `merge_commit` / `branch_deleted`.
|
|
63
|
+
- 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.
|
|
64
|
+
- 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.
|
|
65
|
+
- Never delete the parent project `rrvtrumtkhrsbhcyrwvf` itself or any persistent/production branch.
|
|
66
|
+
- This coordinates safely with `/cbp-checkpoint-end` — the existence-checked delete makes any second attempt a harmless no-op.
|
|
67
|
+
|
|
55
68
|
## Key Rules
|
|
56
69
|
|
|
57
70
|
- **Read branch names from config** — never hardcode "main"
|
|
@@ -62,10 +62,10 @@ Infer `TARGET` when absent:
|
|
|
62
62
|
|
|
63
63
|
## Step 1 — Read DB Paths Config
|
|
64
64
|
|
|
65
|
-
Read `.codebyplan.json` to obtain the configured DB path globs:
|
|
65
|
+
Read `.codebyplan/shipment.json` to obtain the configured DB path globs:
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
DB_PATHS=$(jq -r '.shipment.surfaces.supabase.db_paths[]? // empty' .codebyplan.json 2>/dev/null)
|
|
68
|
+
DB_PATHS=$(jq -r '.shipment.surfaces.supabase.db_paths[]? // empty' .codebyplan/shipment.json 2>/dev/null)
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
If `DB_PATHS` is empty, fall back to defaults:
|
|
@@ -80,11 +80,11 @@ Store each pattern as a separate entry for matching in Step 2.
|
|
|
80
80
|
|
|
81
81
|
## Step 2 — Detect DB-Path Changes
|
|
82
82
|
|
|
83
|
-
Resolve the BASE branch from `TARGET`. Read `.codebyplan.json`:
|
|
83
|
+
Resolve the BASE branch from `TARGET`. Read `.codebyplan/git.json`:
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
|
-
INTEGRATION=$(jq -r '.branch_config.integration // "development"' .codebyplan.json)
|
|
87
|
-
PRODUCTION=$(jq -r '.branch_config.production // "main"' .codebyplan.json)
|
|
86
|
+
INTEGRATION=$(jq -r '.branch_config.integration // "development"' .codebyplan/git.json)
|
|
87
|
+
PRODUCTION=$(jq -r '.branch_config.production // "main"' .codebyplan/git.json)
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
Set `BASE`:
|
|
@@ -156,6 +156,13 @@ Store as `PROJECT_REF`.
|
|
|
156
156
|
|
|
157
157
|
## Step 4 — Handle Missing project_ref
|
|
158
158
|
|
|
159
|
+
> **Note — Hybrid branch creation**: The preview branch may pre-exist as a CBP-created
|
|
160
|
+
> branch (named identically to the git branch, provisioned lazily by `cbp-supabase-migrate`
|
|
161
|
+
> on first DB change) rather than being auto-created by the GitHub integration on PR open.
|
|
162
|
+
> The by-name resolution in Step 3 works identically for both creation paths because both
|
|
163
|
+
> name the branch verbatim after the git branch. See [[supabase-branch-lifecycle]] for the
|
|
164
|
+
> full lifecycle contract.
|
|
165
|
+
|
|
159
166
|
If `PROJECT_REF` is empty after Step 3:
|
|
160
167
|
|
|
161
168
|
- `MODE=pre_pr_create`:
|
|
@@ -3,7 +3,7 @@ scope: org-shared
|
|
|
3
3
|
name: cbp-supabase-migrate
|
|
4
4
|
description: Scaffold or adopt a Supabase migration for the current PR branch, apply to the branch's preview DB, run advisor checks, regenerate TypeScript types. Includes a fresh-branch dry-run pre-flight that uses one persistent dry-run ephemeral branch per feature branch.
|
|
5
5
|
argument-hint: "[--new <name> | <path-to-sql>]"
|
|
6
|
-
allowed-tools: Read, Edit, Write, Bash(git *), Bash(supabase *), Bash(jq *), Bash(date *), Bash(which *), Bash(cp *), Bash(mv *), Bash(test *), Bash(ls *), mcp__supabase__apply_migration, mcp__supabase__list_migrations, mcp__supabase__get_advisors, mcp__supabase__generate_typescript_types, mcp__supabase__reset_branch, mcp__supabase__list_branches
|
|
6
|
+
allowed-tools: Read, Edit, Write, Bash(git *), Bash(supabase *), Bash(jq *), Bash(date *), Bash(which *), Bash(cp *), Bash(mv *), Bash(test *), Bash(ls *), mcp__supabase__apply_migration, mcp__supabase__list_migrations, mcp__supabase__get_advisors, mcp__supabase__generate_typescript_types, mcp__supabase__reset_branch, mcp__supabase__list_branches, mcp__supabase__create_branch, mcp__supabase__get_cost, mcp__supabase__confirm_cost, mcp__codebyplan__update_checkpoint, mcp__codebyplan__update_task
|
|
7
7
|
model: sonnet
|
|
8
8
|
effort: xhigh
|
|
9
9
|
---
|
|
@@ -61,11 +61,139 @@ Parse the output for:
|
|
|
61
61
|
- `POSTGRES_URL_NON_POOLING` — direct connection string for the preview DB
|
|
62
62
|
- `project_ref` — the Supabase project ref for this branch's environment
|
|
63
63
|
|
|
64
|
-
Capture both values. The `project_ref` is used
|
|
64
|
+
Capture both values. The `project_ref` is used from Step 3 onward; Step 2.3 may replace it with a `PREVIEW_PROJECT_REF` when it lazily provisions the branch. (Step 5.5 resolves its own separate dry-run branch `project_ref` — see [reference/preflight-dry-run.md](reference/preflight-dry-run.md).)
|
|
65
|
+
|
|
66
|
+
## Step 2.3 — Ensure Supabase Branch Exists
|
|
67
|
+
|
|
68
|
+
Couples the Supabase preview branch lifecycle to the git branch: when this skill runs on a
|
|
69
|
+
feat branch that touches the database, a Supabase branch named **exactly** the current git
|
|
70
|
+
branch is guaranteed to exist before any migration is applied. Naming it identically to the
|
|
71
|
+
git branch is the linchpin that lets the GitHub branching integration reconcile to the same
|
|
72
|
+
branch (no duplicate).
|
|
73
|
+
|
|
74
|
+
> Lifecycle contract: see [[supabase-branch-lifecycle]].
|
|
75
|
+
|
|
76
|
+
This step runs **before** Step 2.5: it lazily provisions the branch so that an empty
|
|
77
|
+
`project_ref` from Step 2 gets filled in. Step 2.5 then fires only when `project_ref` is
|
|
78
|
+
**still** empty after this step (i.e. this step was skipped or creation was declined).
|
|
79
|
+
|
|
80
|
+
### Guard 1 — feat-branch only
|
|
81
|
+
|
|
82
|
+
Read branch config from `.codebyplan/git.json`:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
PRODUCTION=$(jq -r '.branch_config.production // "main"' .codebyplan/git.json)
|
|
86
|
+
PROTECTED=$(jq -r '.branch_config.protected[]? // empty' .codebyplan/git.json)
|
|
87
|
+
INTEGRATION=$(jq -r '.branch_config.integration // empty' .codebyplan/git.json)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If `$BRANCH` equals `$PRODUCTION` or appears in `$PROTECTED`, skip this entire step — never
|
|
91
|
+
provision a Supabase branch for the production/protected branch. On `$PRODUCTION` the
|
|
92
|
+
`project_ref` from Step 2 is the parent project itself; Step 3's main-project guard handles
|
|
93
|
+
that case. (A standalone task pinned to the production branch is covered by this same check,
|
|
94
|
+
since its `$BRANCH` equals `$PRODUCTION`.)
|
|
95
|
+
|
|
96
|
+
If `$INTEGRATION` is non-empty and `$BRANCH` equals `$INTEGRATION`, skip this step — the
|
|
97
|
+
integration branch uses a persistent Supabase branch provisioned by `cbp-supabase-setup`,
|
|
98
|
+
not a lazy ephemeral one. Do NOT default or write `$INTEGRATION` to any value; only read and
|
|
99
|
+
skip.
|
|
100
|
+
|
|
101
|
+
### Guard 2 — DB-path / migration intent
|
|
102
|
+
|
|
103
|
+
Reuse the db_paths detection so the step proceeds only when this invocation actually touches
|
|
104
|
+
the database. Read the globs (default `supabase/**`, `apps/backend/**`, `packages/**/db/**`):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
DB_PATHS=$(jq -r '.shipment.surfaces.supabase.db_paths[]? // empty' .codebyplan/shipment.json 2>/dev/null)
|
|
108
|
+
[ -z "$DB_PATHS" ] && DB_PATHS=$(printf '%s\n' 'supabase/**' 'apps/backend/**' 'packages/**/db/**')
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Proceed when **either**:
|
|
112
|
+
- the branch diff against `origin/$PRODUCTION` touches any `DB_PATHS` glob, **or**
|
|
113
|
+
- this invocation will create/adopt a migration — `$ARGUMENTS` is `--new <name>` or a `.sql`
|
|
114
|
+
path (the migration file may not exist on disk yet, so explicit migrate intent counts as a
|
|
115
|
+
DB change). The bare-picker case (Step 5 Case C) is treated as migrate intent.
|
|
116
|
+
|
|
117
|
+
If neither holds (no DB-path changes and no migrate intent), skip this step silently and let
|
|
118
|
+
Step 2.5 / the normal flow handle the empty `project_ref` — do not provision or prompt for
|
|
119
|
+
cost on a branch that touches no database paths.
|
|
120
|
+
|
|
121
|
+
### Already-provisioned reuse
|
|
122
|
+
|
|
123
|
+
If `project_ref` from Step 2 is already non-empty, the GitHub integration (or a prior run)
|
|
124
|
+
already provisioned the branch. Capture it as `PREVIEW_PROJECT_REF` and jump straight to
|
|
125
|
+
"Record connection" below — idempotent, no creation.
|
|
126
|
+
|
|
127
|
+
### Idempotency check (list before create)
|
|
128
|
+
|
|
129
|
+
Call `mcp__supabase__list_branches` with the parent `project_id` `rrvtrumtkhrsbhcyrwvf`. The
|
|
130
|
+
parent `project_id` for MCP calls is the same ref string stored in `.codebyplan/shipment.json`
|
|
131
|
+
`surfaces.supabase.project_ref` — Supabase uses that one ref as both the project identifier
|
|
132
|
+
and the branch target. Scan the returned list for an entry whose `name` exactly equals
|
|
133
|
+
`$BRANCH` (slashes included — `feat/CHK-144-...` is a valid Supabase branch name).
|
|
134
|
+
|
|
135
|
+
- **Match found**: capture its `project_ref` as `PREVIEW_PROJECT_REF`. Skip creation; proceed
|
|
136
|
+
to "Record connection". This is the idempotent reuse path (covers a branch the GitHub
|
|
137
|
+
integration auto-created between Step 2 and now).
|
|
138
|
+
- **No match**: proceed to "Cost confirmation and creation".
|
|
139
|
+
|
|
140
|
+
### Cost confirmation and creation
|
|
141
|
+
|
|
142
|
+
Cost confirmation is mandatory before creating a branch — never bypass it:
|
|
143
|
+
|
|
144
|
+
1. Call `mcp__supabase__get_cost` with `type: "branch"`. Display the returned estimate to the
|
|
145
|
+
user, capturing the returned `confirm_cost_id`.
|
|
146
|
+
2. Call `mcp__supabase__confirm_cost` with that `confirm_cost_id`.
|
|
147
|
+
3. On user cancellation or cost-confirm rejection: emit a warning and continue in
|
|
148
|
+
scaffold-only mode (jump to Step 5 write-only path; skip Steps 5.5 and 6). `project_ref`
|
|
149
|
+
stays empty.
|
|
150
|
+
|
|
151
|
+
After cost is confirmed, call `mcp__supabase__create_branch`:
|
|
152
|
+
- `project_id`: `rrvtrumtkhrsbhcyrwvf` (parent project ref)
|
|
153
|
+
- `name`: `$BRANCH` (verbatim — slashes included)
|
|
154
|
+
- `confirm_cost_id`: the same id from the `get_cost` response that was passed to `confirm_cost`
|
|
155
|
+
|
|
156
|
+
After the create call returns, poll `mcp__supabase__list_branches` every 10 s until an entry
|
|
157
|
+
with `name == $BRANCH` appears (up to 60 s / 6 polls). Capture its `project_ref` as
|
|
158
|
+
`PREVIEW_PROJECT_REF`. If polling times out:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
Supabase branch creation for <BRANCH> did not settle within 60 s.
|
|
162
|
+
Check the Supabase dashboard: Branches — then re-run /cbp-supabase-migrate.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Stop.
|
|
166
|
+
|
|
167
|
+
### Record connection
|
|
168
|
+
|
|
169
|
+
Record the branch so cleanup (see `cbp-checkpoint-end`, `cbp-git-worktree-remove`) and other
|
|
170
|
+
skills can discover it. Phrase any context payload as prose — the MCP edge rejects raw
|
|
171
|
+
uppercase database keywords (Cloudflare WAF).
|
|
172
|
+
|
|
173
|
+
1. **Checkpoint / task context** — call `mcp__codebyplan__update_checkpoint` (or
|
|
174
|
+
`mcp__codebyplan__update_task` for a standalone task) to add to `context.discoveries`:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{ "topic": "supabase_preview_branch", "finding": "branch <BRANCH> -> project_ref <PREVIEW_PROJECT_REF>" }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
2. **`.codebyplan/shipment.json`** — read-merge-write (the `preview_branches` array may not
|
|
181
|
+
exist yet — create it if absent; never clobber the rest of the file). Under
|
|
182
|
+
`surfaces.supabase.preview_branches`, first check for an existing entry whose `branch`
|
|
183
|
+
equals `$BRANCH`: if present, update its `project_ref` only if it differs (no duplicate
|
|
184
|
+
append); if absent, append:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{ "branch": "<BRANCH>", "project_ref": "<PREVIEW_PROJECT_REF>", "created_at": "<ISO timestamp>" }
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Set `project_ref = $PREVIEW_PROJECT_REF` so Steps 3 onward target this branch's project.
|
|
65
191
|
|
|
66
192
|
## Step 2.5 — Empty project_ref Handling
|
|
67
193
|
|
|
68
|
-
If `project_ref` is empty after Step 2
|
|
194
|
+
If `project_ref` is **still** empty after Step 2.3 (no branch was provisioned — e.g. no
|
|
195
|
+
DB-path changes / no migrate intent, or this is a protected branch, or cost confirmation was
|
|
196
|
+
declined), AskUserQuestion:
|
|
69
197
|
|
|
70
198
|
```
|
|
71
199
|
Could not resolve a Supabase project_ref for branch: <BRANCH>
|
|
@@ -88,12 +216,14 @@ On (C): stop silently.
|
|
|
88
216
|
|
|
89
217
|
## Step 3 — Main-Project Guard
|
|
90
218
|
|
|
91
|
-
If `project_ref` is empty
|
|
219
|
+
If `project_ref` is empty, skip Steps 3 and 4 entirely and jump directly to Step 5. (Normally
|
|
220
|
+
Step 2.3 has already populated `project_ref` for a feat branch, or scaffold-only mode was
|
|
221
|
+
chosen in Step 2.5; this remains a defensive guard for the scaffold-only path.)
|
|
92
222
|
|
|
93
|
-
Read `.codebyplan.json`:
|
|
223
|
+
Read `.codebyplan/shipment.json`:
|
|
94
224
|
|
|
95
225
|
```bash
|
|
96
|
-
MAIN_PROJECT_REF=$(jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan.json)
|
|
226
|
+
MAIN_PROJECT_REF=$(jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
97
227
|
```
|
|
98
228
|
|
|
99
229
|
`MAIN_PROJECT_REF` is consumed by Step 5.5's dry-run CLI calls (`branches create` and `branches get`) to pin those calls to the parent project rather than any linked preview branch.
|
|
@@ -274,16 +404,16 @@ severity level. Hard-block enforcement at ship time is owned by `cbp-supabase-br
|
|
|
274
404
|
|
|
275
405
|
## Step 8 — Regenerate TypeScript Types
|
|
276
406
|
|
|
277
|
-
Read the types output path from `.codebyplan.json`:
|
|
407
|
+
Read the types output path from `.codebyplan/shipment.json`:
|
|
278
408
|
|
|
279
409
|
```bash
|
|
280
|
-
jq -r '.shipment.surfaces.supabase.types_path' .codebyplan.json
|
|
410
|
+
jq -r '.shipment.surfaces.supabase.types_path' .codebyplan/shipment.json
|
|
281
411
|
```
|
|
282
412
|
|
|
283
413
|
If the field is missing or empty, AskUserQuestion:
|
|
284
414
|
|
|
285
415
|
```
|
|
286
|
-
types_path not found in .codebyplan.json under
|
|
416
|
+
types_path not found in .codebyplan/shipment.json under surfaces.supabase.types_path.
|
|
287
417
|
Enter the path where TypeScript types should be written (e.g., apps/web/src/lib/database.types.ts):
|
|
288
418
|
```
|
|
289
419
|
|
|
@@ -12,7 +12,7 @@ The dry-run uses ONE persistent branch per feature branch — created on first u
|
|
|
12
12
|
|
|
13
13
|
DRY_RUN_BRANCH="${BRANCH}-cbp-migrate-dryrun"
|
|
14
14
|
|
|
15
|
-
The CLI `branches` sub-commands act on the project the CLI is *linked* to — mid-development that is often a preview branch, not the parent project. Pin every `branches` call to the parent with `--project-ref "$MAIN_PROJECT_REF"`, where `MAIN_PROJECT_REF` is the parent `project_ref` SKILL.md Step 3 already resolves from `.codebyplan.json` (`.shipment.surfaces.supabase.project_ref`). `mcp__supabase__list_branches` and `reset_branch` need no such flag — the MCP server is already bound to the parent project.
|
|
15
|
+
The CLI `branches` sub-commands act on the project the CLI is *linked* to — mid-development that is often a preview branch, not the parent project. Pin every `branches` call to the parent with `--project-ref "$MAIN_PROJECT_REF"`, where `MAIN_PROJECT_REF` is the parent `project_ref` SKILL.md Step 3 already resolves from `.codebyplan/shipment.json` (`.shipment.surfaces.supabase.project_ref`). `mcp__supabase__list_branches` and `reset_branch` need no such flag — the MCP server is already bound to the parent project.
|
|
16
16
|
|
|
17
17
|
1. Call `mcp__supabase__list_branches`. Look for an entry whose name equals `DRY_RUN_BRANCH`. If found, capture its `id` field as `DRY_RUN_BRANCH_ID` — `reset_branch` and every status poll below act on the branch id, not the name.
|
|
18
18
|
2. **If absent** — run `supabase --experimental branches create "$DRY_RUN_BRANCH" --project-ref "$MAIN_PROJECT_REF" --yes`. The `--yes` flag is required: branch creation prompts for cost confirmation and the skill runs non-interactively, so the prompt would otherwise hang. The CLI create command is asynchronous and returns a human-readable message (not JSON with an `id`). After the CLI call, poll `mcp__supabase__list_branches` until an entry whose name equals `DRY_RUN_BRANCH` appears, then capture its `id` as `DRY_RUN_BRANCH_ID`. This poll both confirms the create succeeded and yields the id. Creation clones at `git_ref=main` and replays main's migration chain as a baseline — skip the reset in step 4 and go straight to step 5 (the initial provisioning already gave a main baseline).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
scope: org-shared
|
|
3
3
|
name: cbp-supabase-setup
|
|
4
|
-
description: Enable Supabase GitHub branching integration — GitHub app authorization, required-status-check enforcement on main + integration branch, persistent branch creation, and idempotency marker in .codebyplan.json.
|
|
4
|
+
description: Enable Supabase GitHub branching integration — GitHub app authorization, required-status-check enforcement on main + integration branch, persistent branch creation, and idempotency marker in .codebyplan/shipment.json.
|
|
5
5
|
argument-hint: "[--force]"
|
|
6
6
|
allowed-tools: Read, Edit, Bash(supabase *), Bash(jq *), Bash(mv *), Bash(date *), Bash(test *), Bash(which *)
|
|
7
7
|
effort: xhigh
|
|
@@ -41,13 +41,19 @@ first, then re-invoke /cbp-supabase-setup.
|
|
|
41
41
|
Read `supabase/config.toml` to extract the linked `project_id` (under `[api]` or the top-level
|
|
42
42
|
`project_id` field, depending on CLI version).
|
|
43
43
|
|
|
44
|
-
Read `.codebyplan.json`:
|
|
44
|
+
Read `.codebyplan/git.json` and `.codebyplan/shipment.json`:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
jq '.branch_config.integration // empty' .codebyplan.json
|
|
48
|
-
jq '.shipment.surfaces.supabase.branching_configured // empty' .codebyplan.json
|
|
47
|
+
jq '.branch_config.integration // empty' .codebyplan/git.json
|
|
48
|
+
jq '.shipment.surfaces.supabase.branching_configured // empty' .codebyplan/shipment.json
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
> **Note — Two distinct Supabase branching models**: This skill performs a ONE-TIME
|
|
52
|
+
> persistent setup of the GitHub branching integration (the OAuth link, required-status-check
|
|
53
|
+
> rules, and optional persistent integration branch). It is separate from the PER-FEATURE
|
|
54
|
+
> explicit Supabase branches that `cbp-supabase-migrate` creates lazily on first DB change
|
|
55
|
+
> for each feat branch. See [[supabase-branch-lifecycle]] for the per-feature lifecycle.
|
|
56
|
+
|
|
51
57
|
Track per-item done state:
|
|
52
58
|
- `github_app_installed` — true if `branching_configured.github_app_installed` is already true
|
|
53
59
|
- `required_check_enforced` — true if `branching_configured.required_check_enforced` is already true
|
|
@@ -82,7 +88,7 @@ Set `github_app_installed = true` in the idempotency tracker (persisted at Step
|
|
|
82
88
|
|
|
83
89
|
## Step 4 — GitHub repo: required status check (manual checklist)
|
|
84
90
|
|
|
85
|
-
Read `branch_config.integration` from `.codebyplan.json`. Determine branches to protect:
|
|
91
|
+
Read `branch_config.integration` from `.codebyplan/git.json`. Determine branches to protect:
|
|
86
92
|
|
|
87
93
|
- Always: `main`
|
|
88
94
|
- Also: `branch_config.integration` (when set and !== 'main')
|
|
@@ -193,7 +199,7 @@ sql_paths = ["./seed.sql"]
|
|
|
193
199
|
|
|
194
200
|
Reference: [reference/branching-setup.md § 4](reference/branching-setup.md)
|
|
195
201
|
|
|
196
|
-
## Step 7 — Write idempotency marker to `.codebyplan.json`
|
|
202
|
+
## Step 7 — Write idempotency marker to `.codebyplan/shipment.json`
|
|
197
203
|
|
|
198
204
|
Generate the ISO timestamp in the shell first (jq can't produce wall-clock time natively),
|
|
199
205
|
then merge the marker under `shipment.surfaces.supabase.branching_configured`:
|
|
@@ -204,7 +210,7 @@ jq --arg now "$NOW" '.shipment.surfaces.supabase.branching_configured = {
|
|
|
204
210
|
enabled_at: $now,
|
|
205
211
|
github_app_installed: true,
|
|
206
212
|
required_check_enforced: true
|
|
207
|
-
}' .codebyplan.json > .codebyplan.json.tmp && mv .codebyplan.json.tmp .codebyplan.json
|
|
213
|
+
}' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp && mv .codebyplan/shipment.json.tmp .codebyplan/shipment.json
|
|
208
214
|
```
|
|
209
215
|
|
|
210
216
|
The three sub-fields:
|
|
@@ -26,7 +26,7 @@ Verify: the integration tile now shows the connected repository name.
|
|
|
26
26
|
Protect both `main` AND the integration branch (e.g., `development`) so PRs cannot be merged
|
|
27
27
|
until the Supabase Preview environment passes.
|
|
28
28
|
|
|
29
|
-
For each branch (`main`, then the integration branch from `.codebyplan.json`
|
|
29
|
+
For each branch (`main`, then the integration branch from `.codebyplan/git.json`
|
|
30
30
|
`branch_config.integration`):
|
|
31
31
|
|
|
32
32
|
1. **GitHub → Repository → Settings → Branches → Add branch protection rule**.
|
|
@@ -94,7 +94,7 @@ migration push.
|
|
|
94
94
|
|
|
95
95
|
## 5. Idempotency Marker
|
|
96
96
|
|
|
97
|
-
After setup completes, `/cbp-supabase-setup` writes to `.codebyplan.json`:
|
|
97
|
+
After setup completes, `/cbp-supabase-setup` writes to `.codebyplan/shipment.json`:
|
|
98
98
|
|
|
99
99
|
```json
|
|
100
100
|
{
|
|
@@ -18,12 +18,12 @@ If the `cbp-task-check` agent spawn fails for any reason (`API Error: Extra usag
|
|
|
18
18
|
Procedure summary (pointer back to canonical):
|
|
19
19
|
|
|
20
20
|
1. Detect the failure class from the error string; record `round.context.task_check_findings.spawn_failure = { class, error_message, decided_at }`.
|
|
21
|
-
2. Walk the agent's documented Phase 1-10 checklist inline using `Read` / `Grep` / `Bash` / MCP `get_*` tools — the agent's
|
|
21
|
+
2. Walk the agent's documented Phase 1-10 checklist inline using `Read` / `Grep` / `Bash` / MCP `get_*` tools — the agent's definition file is the inline script.
|
|
22
22
|
3. Populate the agent's output contract (`verdict`, `route_recommendation`, `requirements_status`, `qa_status`, `code_review_findings`, `user_satisfaction`, `scope_divergence_detected`, etc.) with `mode: 'inline_fallback'` so analytics distinguishes.
|
|
23
23
|
4. Apply the pre-emptive-skip rule: when the same failure class fired in the previous skill of this session, skip the spawn attempt entirely and go straight to inline.
|
|
24
24
|
5. Continue the skill — do NOT abort. Inline-fallback is intended to keep the pipeline moving under sustained outages.
|
|
25
25
|
|
|
26
|
-
Inline-fallback is NOT a quality downgrade trapdoor — every Phase from the
|
|
26
|
+
Inline-fallback is NOT a quality downgrade trapdoor — every Phase from the agent definition MUST be walked, in order, with the same Read/Grep depth the agent would have used. Skipping phases under the banner of fallback is a separate failure mode that `cbp-improve-claude` flags as `inline_fallback_shortcutting`.
|
|
27
27
|
|
|
28
28
|
## When Used
|
|
29
29
|
|
|
@@ -115,6 +115,8 @@ fi
|
|
|
115
115
|
|
|
116
116
|
**If `git checkout` exits non-zero** (typically "would clobber" because a tracked file has unstaged changes that conflict with target's version): surface the raw git error verbatim, stop, do NOT attempt recovery. The user resolves and re-invokes. This is the only case where `/cbp-task-start` halts on branch state.
|
|
117
117
|
|
|
118
|
+
**Note — Supabase preview branch**: no Supabase branch is created at this point. Creation is lazy — it happens on the first DB change when `/cbp-supabase-migrate` runs on the feat branch, which provisions a Supabase branch named identically to the git branch. See `cbp-supabase-migrate` Step 2.3 for the creation protocol.
|
|
119
|
+
|
|
118
120
|
#### 3.4 — Persist + verify
|
|
119
121
|
|
|
120
122
|
After successful switch:
|