codebyplan 1.13.52 → 1.13.54
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 +3226 -897
- package/package.json +1 -1
- package/templates/agents/cbp-database-agent.md +1 -1
- package/templates/agents/cbp-e2e-maestro.md +1 -1
- package/templates/agents/cbp-e2e-playwright.md +24 -16
- package/templates/agents/cbp-e2e-tauri.md +1 -1
- package/templates/agents/cbp-e2e-vscode.md +1 -1
- package/templates/agents/cbp-e2e-xcuitest.md +1 -1
- package/templates/agents/cbp-improve-claude.md +2 -2
- package/templates/agents/{cbp-round-executor.md → cbp-round-builder.md} +23 -23
- package/templates/agents/{cbp-task-planner.md → cbp-round-planner.md} +26 -25
- package/templates/agents/cbp-security-agent.md +10 -2
- package/templates/agents/cbp-stripe-agent.md +2 -2
- package/templates/agents/cbp-testing-qa-agent.md +34 -20
- package/templates/agents/cbp-verify-reviewer.md +236 -0
- package/templates/context/architecture-map.md +4 -4
- package/templates/context/mcp-docs.md +57 -11
- package/templates/context/testing/e2e.md +9 -9
- package/templates/github-workflows/ci.yml +104 -0
- package/templates/github-workflows/publish.yml +8 -27
- package/templates/github-workflows/release-desktop.yml +215 -0
- package/templates/hooks/cbp-skill-context-guard.sh +1 -1
- package/templates/hooks/cbp-test-hooks.sh +9 -9
- package/templates/hooks/validate-structure-lengths.sh +1 -1
- package/templates/hooks/validate-structure-patterns.sh +1 -1
- package/templates/rules/README.md +1 -2
- package/templates/rules/agent-claim-verification.md +1 -1
- package/templates/rules/context-file-loading.md +10 -10
- package/templates/rules/development-workflow.md +73 -0
- package/templates/rules/e2e-mandatory.md +8 -8
- package/templates/rules/execution-proof.md +70 -0
- package/templates/rules/model-invocation-convention.md +2 -2
- package/templates/rules/parallel-waves.md +11 -11
- package/templates/rules/spawn-failure-is-gate-failure.md +76 -0
- package/templates/rules/task-routing-recommendation.md +1 -1
- package/templates/rules/todo-backend.md +3 -3
- package/templates/rules/two-tier-ci.md +63 -0
- package/templates/settings.project.base.json +15 -11
- package/templates/skills/cbp-build-cc-mode/SKILL.md +1 -1
- package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +7 -7
- package/templates/skills/cbp-build-cc-skill/SKILL.md +1 -1
- package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +2 -2
- package/templates/skills/cbp-build-cc-skill/reference/fork-eligibility.md +11 -14
- package/templates/skills/cbp-checkpoint-check/SKILL.md +11 -3
- package/templates/skills/cbp-checkpoint-create/SKILL.md +16 -1
- package/templates/skills/cbp-checkpoint-end/SKILL.md +5 -1
- package/templates/skills/cbp-checkpoint-update/SKILL.md +3 -3
- package/templates/skills/cbp-clear-continue/SKILL.md +2 -2
- package/templates/skills/cbp-clear-prep/SKILL.md +3 -3
- package/templates/skills/{cbp-task-complete → cbp-finalize}/SKILL.md +25 -29
- package/templates/skills/{cbp-task-complete → cbp-finalize}/reference/checkpoint-done-branching.md +1 -1
- package/templates/skills/{cbp-task-complete → cbp-finalize}/reference/next-step-heuristic.md +1 -1
- package/templates/skills/cbp-frontend-design/SKILL.md +1 -1
- package/templates/skills/cbp-frontend-ui/SKILL.md +7 -7
- package/templates/skills/cbp-git-commit/SKILL.md +3 -3
- package/templates/skills/cbp-merge-main/SKILL.md +4 -4
- package/templates/skills/{cbp-round-execute → cbp-round-build}/SKILL.md +93 -75
- package/templates/skills/cbp-round-complete/SKILL.md +15 -14
- package/templates/skills/cbp-round-plan/SKILL.md +344 -0
- package/templates/skills/cbp-session-end/SKILL.md +1 -1
- package/templates/skills/cbp-setup-cd/SKILL.md +291 -0
- package/templates/skills/cbp-setup-cd/reference/github-actions-cd.md +231 -0
- package/templates/skills/cbp-setup-ci/SKILL.md +175 -0
- package/templates/skills/cbp-setup-ci/reference/github-actions.md +100 -0
- package/templates/skills/cbp-ship/SKILL.md +21 -0
- package/templates/skills/cbp-ship-main/SKILL.md +3 -2
- package/templates/skills/cbp-standalone-task-check/SKILL.md +10 -9
- package/templates/skills/cbp-standalone-task-complete/SKILL.md +12 -13
- package/templates/skills/cbp-standalone-task-create/SKILL.md +16 -9
- package/templates/skills/cbp-standalone-task-start/SKILL.md +9 -5
- package/templates/skills/cbp-standalone-task-testing/SKILL.md +16 -7
- package/templates/skills/cbp-task-create/SKILL.md +6 -7
- package/templates/skills/cbp-task-start/SKILL.md +8 -8
- package/templates/skills/cbp-todo/SKILL.md +6 -8
- package/templates/skills/cbp-verify/SKILL.md +146 -0
- package/templates/skills/cbp-verify/reference/deterministic-gates.md +114 -0
- package/templates/skills/{cbp-round-end → cbp-verify}/reference/findings-presentation.md +16 -12
- package/templates/skills/cbp-verify/reference/round-scope.md +62 -0
- package/templates/skills/cbp-verify/reference/task-scope.md +71 -0
- package/templates/agents/cbp-improve-round.md +0 -283
- package/templates/agents/cbp-task-check.md +0 -217
- package/templates/skills/cbp-round-check/SKILL.md +0 -132
- package/templates/skills/cbp-round-end/SKILL.md +0 -173
- package/templates/skills/cbp-round-end/reference/inline-fallback.md +0 -35
- package/templates/skills/cbp-round-execute/reference/inline-fallback.md +0 -55
- package/templates/skills/cbp-round-input/SKILL.md +0 -197
- package/templates/skills/cbp-round-start/SKILL.md +0 -261
- package/templates/skills/cbp-round-update/SKILL.md +0 -120
- package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +0 -53
- package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +0 -31
- package/templates/skills/cbp-task-check/SKILL.md +0 -172
- package/templates/skills/cbp-task-testing/SKILL.md +0 -277
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cbp-round-plan
|
|
3
|
+
description: Plan a round — round-1 planning AND round-2+ deep-analysis of unapproved work, then spawn cbp-round-planner and auto-trigger /cbp-round-build
|
|
4
|
+
triggers: [cbp-round-build]
|
|
5
|
+
argument-hint: [chk-task-round | task-round | requirements-text] # e.g. `108-1-2`, `45-2`, or free-text
|
|
6
|
+
effort: xhigh
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Kind Detection
|
|
10
|
+
|
|
11
|
+
Inspect the resolved identifier from argument parsing to determine the task kind:
|
|
12
|
+
|
|
13
|
+
| Identifier shape | KIND |
|
|
14
|
+
|-----------------|------|
|
|
15
|
+
| `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
|
|
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`. |
|
|
18
|
+
|
|
19
|
+
Set `KIND` for the rest of this skill. Read/write sources vary by KIND:
|
|
20
|
+
|
|
21
|
+
| Operation | `checkpoint` KIND | `standalone` KIND |
|
|
22
|
+
|-----------|------------------|-------------------|
|
|
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
|
+
| Add round | `codebyplan round add` (break-glass: `add_round`) | `add_standalone_round(standalone_task_id, ...)` |
|
|
26
|
+
| Update round | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
|
|
27
|
+
| Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?, caller_worktree_id)` ⚠️ `caller_worktree_id` is REQUIRED for standalone |
|
|
28
|
+
| Update task | `codebyplan task update` (break-glass: `update_task`) | `update_standalone_task(standalone_task_id, ...)` |
|
|
29
|
+
|
|
30
|
+
> **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope and will be addressed in a later task.
|
|
31
|
+
|
|
32
|
+
# Round Plan Command
|
|
33
|
+
|
|
34
|
+
The single **planning entry** for the round cycle. It plans BOTH the first round (from `task.requirements`) AND every follow-up round (deep analysis of the prior round's unapproved work, verify gate/proof failures, and reviewer findings — the round-input deep-analysis role is now folded in here). It analyzes context, spawns `cbp-round-planner` for the plan, then auto-triggers `/cbp-round-build` — the `ask`-tier permission prompt on that skill IS the user's plan approval. NO execution or testing here — those belong to `/cbp-round-build` and `/cbp-verify`.
|
|
35
|
+
|
|
36
|
+
## Planner Spawn Failure Is A Gate Failure
|
|
37
|
+
|
|
38
|
+
If the `cbp-round-planner` agent spawn fails (`API Error: Extra usage required`, monthly Agent
|
|
39
|
+
usage cap, provider 5xx, rate limit, context overflow at spawn, the agent dying before emitting
|
|
40
|
+
its output contract), that is a **HARD GATE FAILURE** per `rules/spawn-failure-is-gate-failure.md`.
|
|
41
|
+
The orchestrator does **NOT** walk the planner's phases inline and self-certify a plan — doing so
|
|
42
|
+
re-introduces the exact fresh-context blind spot the planner exists to remove. STOP and surface the
|
|
43
|
+
retry directive verbatim:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
## Plan blocked — planner could not spawn
|
|
47
|
+
|
|
48
|
+
The round planner (cbp-round-planner) failed to spawn: <class> — <verbatim error>.
|
|
49
|
+
This is a hard gate failure, not a plan. Retry when capacity returns:
|
|
50
|
+
Next: /cbp-round-plan
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Record `round.context.planner_findings.spawn_failure = { class, error_message, decided_at }` so the
|
|
54
|
+
retry is auditable. Do NOT continue to Step 8/9; no plan means no execution.
|
|
55
|
+
|
|
56
|
+
## Pipeline
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
/cbp-round-plan (planning) → /cbp-round-build (ask-tier permission = plan approval)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Auto-loop mode**: when `auto_loop_mode === true` carries forward from the prior round, the Step 6
|
|
63
|
+
Q&A and the Step 4b mode prompt are skipped, and Step 8's `/cbp-round-build` permission is
|
|
64
|
+
auto-approved. See `cbp-verify` reference `round-scope.md` Phase 5 (the auto-loop decision that
|
|
65
|
+
carries `auto_loop_mode` forward) for the contract.
|
|
66
|
+
|
|
67
|
+
## Instructions
|
|
68
|
+
|
|
69
|
+
### Step 0: Parse `$ARGUMENTS` shape
|
|
70
|
+
|
|
71
|
+
Disambiguate the argument up front. Three input shapes:
|
|
72
|
+
|
|
73
|
+
### CHK / TASK / ROUND Identifier Notation Vocabulary
|
|
74
|
+
|
|
75
|
+
| Shape | Regex | Meaning |
|
|
76
|
+
|-------|-------|---------|
|
|
77
|
+
| `{chk}-{task}-{round}` (e.g. `108-1-2`) | `^[0-9]+-[0-9]+-[0-9]+$` | **Identifier**: targets round {round} of CHK-{chk} TASK-{task}. Sets `target_checkpoint`, `target_task`, `target_round`. |
|
|
78
|
+
| `{task}-{round}` (e.g. `45-2`) | `^[0-9]+-[0-9]+$` | **Identifier**: targets round {round} of standalone TASK-{task}. Sets `target_task`, `target_round` (no checkpoint). |
|
|
79
|
+
| Non-empty, non-identifier-shaped | — | **Free-text round requirements** (the follow-up-round requirements path). |
|
|
80
|
+
| _(empty)_ | — | No identifier, no requirements text — derive task/round from Kind Detection above. |
|
|
81
|
+
|
|
82
|
+
Malformed identifier shapes (`108-`, `-1-2`, `108--1`, `abc-1`) — surface this error and stop, mirroring `/cbp-task-start`'s error vocabulary:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
round-plan: invalid argument `{value}`. Expected:
|
|
86
|
+
108-1-2 → round 2 of CHK-108 TASK-1
|
|
87
|
+
45-2 → round 2 of standalone TASK-45
|
|
88
|
+
(free-text) → round requirements (follow-up round)
|
|
89
|
+
(empty) → derive from active task/round state
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Worked examples
|
|
93
|
+
|
|
94
|
+
- `round-plan 108-1-2` → resolve CHK-108 TASK-1, target round 2
|
|
95
|
+
- `round-plan 45-2` → resolve standalone TASK-45, target round 2
|
|
96
|
+
- `round-plan 108-1` → **standalone TASK-108 round 1** (NOT CHK-108 TASK-1). The 2-segment form means `{task}-{round}`; checkpoint-bound round-targeting requires all three numbers (`108-1-2`). If you got here trying to target CHK-108 TASK-1, you want `108-1-2` (specifying a round number) or `/cbp-task-start 108-1` (specifying just a task).
|
|
97
|
+
- `round-plan "Implement OAuth flow per CHK-X plan"` → free-text path; current-task/round derivation from state
|
|
98
|
+
- `round-plan` (empty) → derive from Kind Detection; round 1 uses `task.requirements`
|
|
99
|
+
- `round-plan 108-` → error: malformed identifier
|
|
100
|
+
- `round-plan -1-2` → error: malformed identifier
|
|
101
|
+
- `round-plan abc-1` → error: malformed identifier
|
|
102
|
+
|
|
103
|
+
> **Mental-model warning**: `task-start` and `round-plan` interpret the SAME `108-1` argument differently. `task-start 108-1` → CHK-108 TASK-1 (checkpoint-bound task). `round-plan 108-1` → standalone TASK-108 round 1 (because round-plan needs three numbers for a checkpoint-bound round). When in doubt, write all three: `round-plan 108-1-2`.
|
|
104
|
+
|
|
105
|
+
### Step 1: Get Current Task
|
|
106
|
+
|
|
107
|
+
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.
|
|
108
|
+
|
|
109
|
+
Otherwise: use Kind Detection to determine KIND, then:
|
|
110
|
+
- **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).
|
|
111
|
+
- **standalone KIND**: MCP `get_current_standalone_task(repo_id)` — standalone tools are NOT migrated; standalone KIND still uses MCP until a later task.
|
|
112
|
+
|
|
113
|
+
If no in-progress task and Step 0 produced no identifier, show error: `No active task. Run /cbp-task-start first.`
|
|
114
|
+
|
|
115
|
+
### Step 2: Determine Round Number
|
|
116
|
+
|
|
117
|
+
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).
|
|
118
|
+
|
|
119
|
+
Otherwise:
|
|
120
|
+
- **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.
|
|
121
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
|
|
122
|
+
|
|
123
|
+
Count existing rounds; next is N+1. **Round 1** → run the Step 3 first-round path. **Round 2+** → run the Step 3D deep-analysis path (the folded-in round-input deep-analysis role) before creating the round.
|
|
124
|
+
|
|
125
|
+
### Step 3: Gather Round Requirements
|
|
126
|
+
|
|
127
|
+
**If Step 0 parsed an identifier**: this skill was invoked to resume/start a specific round. Requirements come from existing round data (when the round exists) or task.requirements (for new round 1) — `$ARGUMENTS` is the identifier itself, NOT requirements text.
|
|
128
|
+
|
|
129
|
+
**Else (free-text path), if round number is 1:**
|
|
130
|
+
|
|
131
|
+
- Use `task.requirements` as the primary requirements
|
|
132
|
+
- If `$ARGUMENTS` provided (free-text), merge as additional context
|
|
133
|
+
|
|
134
|
+
**Else (round number > 1):** requirements come from the Step 3D Deep Analysis below — the prior round's unapproved work, verify gate/proof failures, and reviewer findings. Free-text `$ARGUMENTS` (if provided) is merged in as additional direction.
|
|
135
|
+
|
|
136
|
+
### Step 3D: Deep Analysis (round 2+ only — MANDATORY)
|
|
137
|
+
|
|
138
|
+
Follow-up rounds get the SAME depth as round 1. This is the deep-analysis role that round-input
|
|
139
|
+
formerly owned; it now runs inline here for every round after the first.
|
|
140
|
+
|
|
141
|
+
**3D-a:** Load task (already loaded in Step 1) — confirm `files_changed`, `requirements`, `context`, `qa` are present.
|
|
142
|
+
|
|
143
|
+
**3D-b:** Load all rounds:
|
|
144
|
+
- **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/*.json` (local-first; break-glass: MCP `get_rounds(task_id)`). Get previous round context + verify outcome.
|
|
145
|
+
- **standalone KIND** — MCP `get_standalone_rounds(standalone_task_id)`.
|
|
146
|
+
|
|
147
|
+
**3D-c:** Identify unapproved files from `task.files_changed` where `user_approved === false`.
|
|
148
|
+
|
|
149
|
+
**3D-d:** Read the content of each unapproved file (Read tool, max 5 files, first 100 lines each).
|
|
150
|
+
|
|
151
|
+
**3D-e:** Cross-reference with task requirements — for each requirement, is it met or missed?
|
|
152
|
+
|
|
153
|
+
**3D-f:** Extract verify findings from the latest round context. `/cbp-verify` writes its outcome
|
|
154
|
+
into the round/task context (`verify_manifest`, gate `new_failures[]`, execution-proof gaps, and any
|
|
155
|
+
blocking `cbp-verify-reviewer` findings it could not auto-apply inline because they reference files
|
|
156
|
+
outside the prior round's `files_changed[]`). Include those out-of-scope findings as high-priority
|
|
157
|
+
requirements; deterministic gate failures and proof gaps come first (they block shipping).
|
|
158
|
+
|
|
159
|
+
**3D-g:** Identify root causes — not "file X is wrong" but "requirement Y was not met because Z".
|
|
160
|
+
|
|
161
|
+
**3D-h:** Present the analysis to the user:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
## Follow-up Round Analysis
|
|
165
|
+
|
|
166
|
+
### Unapproved Files ([N])
|
|
167
|
+
| File | Action | Issue |
|
|
168
|
+
|------|--------|-------|
|
|
169
|
+
| path | modified | [what's wrong based on reading the file] |
|
|
170
|
+
|
|
171
|
+
### Requirements Coverage
|
|
172
|
+
| Requirement | Status | Gap |
|
|
173
|
+
|-------------|--------|-----|
|
|
174
|
+
| [req] | met/missed | [what's missing] |
|
|
175
|
+
|
|
176
|
+
### Verify Findings (from /cbp-verify on the previous round)
|
|
177
|
+
| # | Source | File | Issue |
|
|
178
|
+
|---|--------|------|-------|
|
|
179
|
+
| [gate failure / proof gap / reviewer finding the previous verify could not auto-apply] |
|
|
180
|
+
|
|
181
|
+
### Root Causes
|
|
182
|
+
1. [root cause with explanation]
|
|
183
|
+
2. [root cause with explanation]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Step 4: Create Round in DB
|
|
187
|
+
|
|
188
|
+
**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.
|
|
189
|
+
|
|
190
|
+
**standalone KIND**: MCP `add_standalone_round(standalone_task_id, ...)` — standalone still uses MCP.
|
|
191
|
+
|
|
192
|
+
Fields to supply:
|
|
193
|
+
- `task_id` (checkpoint) / `standalone_task_id` (standalone): current task ID
|
|
194
|
+
- `number`: next round number
|
|
195
|
+
- `status`: "in_progress"
|
|
196
|
+
- `started_at`: now (ISO format)
|
|
197
|
+
- `triggered_by`: `"user"` | `"claude"` | `"auto_loop"` — `auto_loop` when `auto_loop_mode === true` carries forward; `claude` when auto-triggered by a verify failure; `user` otherwise
|
|
198
|
+
- `requirements`: round requirements from Step 3 / 3D
|
|
199
|
+
- `context`: when `auto_loop_mode === true`, persist `auto_loop_mode: true`, `auto_loop_index: N`, `auto_loop_cap: C` into `round.context`
|
|
200
|
+
|
|
201
|
+
### Step 4b: Choose Mode (round 2+ only)
|
|
202
|
+
|
|
203
|
+
**If `round.context.auto_loop_mode === true` on the prior round**: skip the AskUserQuestion below. Auto-pick "Start round with these findings" using the Step 3D analysis directly. Set the next round's `auto_loop_mode = true`, carry `auto_loop_index` and `auto_loop_cap` forward.
|
|
204
|
+
|
|
205
|
+
**Else (manual mode)**, ask user via AskUserQuestion:
|
|
206
|
+
|
|
207
|
+
- **Start round with these findings** — use the Step 3D analysis as requirements
|
|
208
|
+
- **Discuss first** — open conversation about the analysis
|
|
209
|
+
- **Adjust** — user provides their own requirements
|
|
210
|
+
|
|
211
|
+
If "Discuss first": enter open discussion; when direction is clear, continue. If "Adjust": merge the user's requirements with the analysis context.
|
|
212
|
+
|
|
213
|
+
**Under `auto_loop_mode`**: requirements come VERBATIM from the prior round's reviewer findings and verify gate/proof failures, treated as a flat list. Test/gate failures are listed first (they block shipping); reviewer findings follow. Both sets are included unchanged — do not re-summarise or re-prioritise either.
|
|
214
|
+
|
|
215
|
+
### Step 5: Load Context from DB
|
|
216
|
+
|
|
217
|
+
Load from checkpoint and task:
|
|
218
|
+
- Checkpoint context (decisions, dependencies, constraints, goal)
|
|
219
|
+
- Task context and requirements
|
|
220
|
+
- Resources from checkpoint and task (documentation links, API docs, guides)
|
|
221
|
+
- Previous round results (files_changed, verify outcomes)
|
|
222
|
+
- For round 2+: load the latest completed round's `context.verify_manifest` and `context.executor_output`:
|
|
223
|
+
- **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.
|
|
224
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
|
|
225
|
+
- Identify unapproved files from task.files_changed (where user_approved === false)
|
|
226
|
+
|
|
227
|
+
### Step 6: First Round Analysis (Round 1 only)
|
|
228
|
+
|
|
229
|
+
For the first round only:
|
|
230
|
+
|
|
231
|
+
1. Analyze the task context and requirements thoroughly
|
|
232
|
+
2. Identify any ambiguities or gaps
|
|
233
|
+
3. If questions are needed, ask user via AskUserQuestion (max 4 per batch)
|
|
234
|
+
4. If task context changes from Q&A answers:
|
|
235
|
+
- **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.
|
|
236
|
+
- **standalone KIND**: MCP `update_standalone_task(standalone_task_id, context: {...})` — standalone still uses MCP.
|
|
237
|
+
- Save Q&A decisions as `context.decisions[]`
|
|
238
|
+
|
|
239
|
+
Skip this step for round 2+ (context already established via the Step 3D deep analysis).
|
|
240
|
+
|
|
241
|
+
**If `auto_loop_mode === true`, skip Q&A regardless of round number** — the auto-loop already has authoritative requirements from the prior round's findings.
|
|
242
|
+
|
|
243
|
+
### Step 7: Spawn Round Planner Agent
|
|
244
|
+
|
|
245
|
+
Spawn `cbp-round-planner` agent with:
|
|
246
|
+
```yaml
|
|
247
|
+
input:
|
|
248
|
+
task_number: N
|
|
249
|
+
round_number: N
|
|
250
|
+
requirements: task.requirements
|
|
251
|
+
round_requirements: [round-specific input from Step 3 / 3D]
|
|
252
|
+
checkpoint: {id, title, goal, context}
|
|
253
|
+
task: {id, title, requirements, context}
|
|
254
|
+
previous_rounds: {count, files_pending, files_changed, verify_manifest, unapproved_files}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Round 2+ context**: the planner receives the previous round's verify outcome and the list of unapproved files (from Step 3D).
|
|
258
|
+
|
|
259
|
+
**Priority**: if `round_requirements` is set (round 2+), the planner focuses on those specific goals while respecting `task.requirements` as context.
|
|
260
|
+
|
|
261
|
+
Wait for planner output. **If the spawn fails, STOP per "Planner Spawn Failure Is A Gate Failure" above** — do not self-certify a plan inline.
|
|
262
|
+
|
|
263
|
+
### Step 8: Present Plan
|
|
264
|
+
|
|
265
|
+
Present the plan to user:
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
## Round [N] Plan
|
|
269
|
+
|
|
270
|
+
**Goal**: [goal]
|
|
271
|
+
|
|
272
|
+
### Steps:
|
|
273
|
+
1. [step]
|
|
274
|
+
2. [step]
|
|
275
|
+
...
|
|
276
|
+
|
|
277
|
+
### Files to modify:
|
|
278
|
+
| File | Action | Purpose |
|
|
279
|
+
|------|--------|---------|
|
|
280
|
+
| ... | ... | ... |
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Wave table** — when `approved_plan.waves[]` contains ≥2 entries, render a wave summary table BEFORE the files table:
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
### Execution Waves
|
|
287
|
+
| Wave | Agent type | Files | Depends on | Skill preloads |
|
|
288
|
+
|------|-----------|-------|-----------|----------------|
|
|
289
|
+
| web-ui | cbp-round-builder | 7 | — | cbp-frontend-design |
|
|
290
|
+
| backend-api | cbp-round-builder | 4 | — | — |
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Single-wave plans present the existing flat plan view (no wave table) — backward compatible.
|
|
294
|
+
|
|
295
|
+
**Plan approval is the `ask`-tier `Skill(cbp-round-build)` permission prompt** — there is NO approve/needs-changes/wrong AskUserQuestion here. After presenting the plan, proceed to Step 9, which auto-triggers `/cbp-round-build`; the harness then shows the `ask`-tier permission prompt, and confirming it IS the user's go-ahead on the plan.
|
|
296
|
+
|
|
297
|
+
**Denied-build handling** — if the user declines the `/cbp-round-build` permission, the plan does not run. Treat the decline as "the plan must change":
|
|
298
|
+
|
|
299
|
+
- **Minor changes**: collect the user's feedback, re-spawn `cbp-round-planner` with it as a constraint (re-run Step 7), present the revised plan, and re-trigger `/cbp-round-build`.
|
|
300
|
+
- **Wrong direction**: save the rejection reason to round context and re-run this skill's deep-analysis path (Step 3D) for new requirements.
|
|
301
|
+
|
|
302
|
+
**If `auto_loop_mode === true`**: the loop auto-approves — log `round.context.plan_approval = { mode: "auto_loop", auto_approved_at: <ISO> }`, surface a one-line note `"Auto-approved under auto_loop_mode (round N of cap C)"`, and proceed to Step 9 (the `/cbp-round-build` permission is auto-approved under the loop).
|
|
303
|
+
|
|
304
|
+
### Step 9: Auto-trigger Round Build
|
|
305
|
+
|
|
306
|
+
Save planner output to round context, then trigger `/cbp-round-build`. The `ask`-tier permission prompt on `/cbp-round-build` is the user's plan approval (see Step 8).
|
|
307
|
+
|
|
308
|
+
- **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.
|
|
309
|
+
- **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` — standalone still uses MCP.
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
Starting build phase...
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Fallback: Context Recovery
|
|
316
|
+
|
|
317
|
+
If this command is triggered **directly** (not via `/cbp-todo`) and no context is available in the session:
|
|
318
|
+
|
|
319
|
+
1. Read `.codebyplan/repo.json` for `repo_id`
|
|
320
|
+
2. Use Kind Detection to determine KIND, then:
|
|
321
|
+
- **checkpoint KIND**: Read local `.codebyplan/state/` files for checkpoint + task (break-glass: MCP `get_current_task`).
|
|
322
|
+
- **standalone KIND**: MCP `get_current_standalone_task`.
|
|
323
|
+
3. Load round history:
|
|
324
|
+
- **checkpoint KIND**: Read `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/*.json` (break-glass: MCP `get_rounds(task_id)`).
|
|
325
|
+
- **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)`.
|
|
326
|
+
4. Continue from Step 1 (round 2+ deep analysis at Step 3D handles all context loading)
|
|
327
|
+
|
|
328
|
+
## Key Rules
|
|
329
|
+
|
|
330
|
+
- **Planning ONLY** — no code execution, no testing
|
|
331
|
+
- Planner gets full context (checkpoint + task + previous rounds)
|
|
332
|
+
- Round 1 plans from `task.requirements`; round 2+ runs the MANDATORY Step 3D deep analysis (same depth as round 1 — no quick-fix behavior)
|
|
333
|
+
- Planner spawn failure is a HARD GATE FAILURE — STOP + retry directive, NEVER self-certify a plan inline (`rules/spawn-failure-is-gate-failure.md`)
|
|
334
|
+
- Claude NEVER git adds files in round commands
|
|
335
|
+
|
|
336
|
+
## Integration
|
|
337
|
+
|
|
338
|
+
- **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), file contents (Read tool, round 2+ deep analysis)
|
|
339
|
+
- **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` — standalone still uses MCP
|
|
340
|
+
- **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`
|
|
341
|
+
- **Writes (standalone KIND)**: MCP `add_standalone_round`, `update_standalone_round`, `update_standalone_task` — standalone still uses MCP
|
|
342
|
+
- **Spawns**: `cbp-round-planner` (spawn failure = hard gate failure → STOP)
|
|
343
|
+
- **Triggers**: `/cbp-round-build` (auto, on plan approval)
|
|
344
|
+
- **Triggered by**: `/cbp-task-start` (round 1), `/cbp-verify` (round 2+ fix round or more-work), `/cbp-todo` (after /clear), user manually
|
|
@@ -30,7 +30,7 @@ Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can
|
|
|
30
30
|
2. If `rows[0]` exists and its `command` is non-empty (active work in flight):
|
|
31
31
|
```yaml
|
|
32
32
|
handoff:
|
|
33
|
-
command: <rows[0].command> # e.g. "/cbp-
|
|
33
|
+
command: <rows[0].command> # e.g. "/cbp-verify"
|
|
34
34
|
instructions: <rows[0].instructions> # human-readable trigger reason
|
|
35
35
|
state: <rows[0].state> # workflow state label
|
|
36
36
|
context: # entity ids used by the Step 4.5 freshness probe
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-setup-cd
|
|
4
|
+
description: Detect configured CD surfaces, write/update .codebyplan/cd.json via `codebyplan cd init`, scaffold publish.yml and release-desktop.yml GitHub Actions workflows, and walk through environment/approval/OIDC setup. Interactive, idempotent.
|
|
5
|
+
argument-hint: "[--force]"
|
|
6
|
+
effort: xhigh
|
|
7
|
+
allowed-tools: Read, Write, Edit, Bash(cat *), Bash(jq *), Bash(test *), Bash(ls *), Bash(diff *), Bash(codebyplan cd *), Bash(npx codebyplan cd *), AskUserQuestion
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# CD Setup
|
|
11
|
+
|
|
12
|
+
Configure `.codebyplan/cd.json`, scaffold `.github/workflows/publish.yml` and
|
|
13
|
+
`.github/workflows/release-desktop.yml`, and record the credential env-var names needed
|
|
14
|
+
at deploy time. Invoke at any time. Already-configured surfaces are preserved unless
|
|
15
|
+
`--force` is passed.
|
|
16
|
+
|
|
17
|
+
Pass `--force` to re-detect all surfaces and overwrite existing workflow files.
|
|
18
|
+
|
|
19
|
+
## Arguments
|
|
20
|
+
|
|
21
|
+
Inspect `$ARGUMENTS` for `--force`. If present, set `force_mode = true`.
|
|
22
|
+
Absent: idempotent mode — existing surface keys in `.codebyplan/cd.json` are preserved;
|
|
23
|
+
workflow files are not overwritten unless `--force`.
|
|
24
|
+
|
|
25
|
+
## Step 1 — Detect configured surfaces + read current state
|
|
26
|
+
|
|
27
|
+
Read detection signals and existing config:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cat .codebyplan/shipment.json 2>/dev/null || echo '{}'
|
|
31
|
+
cat .codebyplan/cd.json 2>/dev/null || echo '{}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Surface detection signals** (derive from `shipment.json` + filesystem):
|
|
35
|
+
|
|
36
|
+
| Surface | Signal |
|
|
37
|
+
|---------|--------|
|
|
38
|
+
| `npm` | `packages/*/package.json` with `publishConfig.access` set |
|
|
39
|
+
| `tauri` | `apps/*/src-tauri/tauri.conf.json` present |
|
|
40
|
+
| `vscode` | `apps/*/package.json` with `contributes` block |
|
|
41
|
+
| `expo` | `apps/*/eas.json` present |
|
|
42
|
+
| `vercel` | `.vercel/project.json` or `vercel.json` in any app |
|
|
43
|
+
| `railway` | `apps/*/railway.toml` or `apps/*/Dockerfile` present |
|
|
44
|
+
|
|
45
|
+
**Idempotency**: a surface already in `.codebyplan/cd.json` is "configured". A newly
|
|
46
|
+
detected surface not yet in the file is "new". A surface in the file but no longer
|
|
47
|
+
detected is "stale".
|
|
48
|
+
|
|
49
|
+
Display a detection table:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Surface | Detected | Configured | Workflow file
|
|
53
|
+
--------- | -------- | ---------- | ----------------------------------------
|
|
54
|
+
npm | yes | yes | .github/workflows/publish.yml (present)
|
|
55
|
+
tauri | yes | yes | .github/workflows/release-desktop.yml (present)
|
|
56
|
+
vscode | no | no | —
|
|
57
|
+
expo | no | no | —
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Step 2 — Confirm surfaces to manage
|
|
61
|
+
|
|
62
|
+
AskUserQuestion (multi-select):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Detected CD surfaces:
|
|
66
|
+
<table from Step 1>
|
|
67
|
+
|
|
68
|
+
Which surfaces should be managed by cd.json?
|
|
69
|
+
Already-configured surfaces are pre-checked. Deselect to remove from cd.json.
|
|
70
|
+
|
|
71
|
+
Select all that apply:
|
|
72
|
+
A) npm — publish.yml (GitHub Actions + OIDC)
|
|
73
|
+
B) tauri — release-desktop.yml (cross-platform Tauri build + signing)
|
|
74
|
+
C) vscode — VS Code marketplace publish (undetected — add eas.json to enable)
|
|
75
|
+
D) expo — EAS build + store submit (undetected)
|
|
76
|
+
E) vercel — Vercel production deploy (managed by Vercel GitHub integration)
|
|
77
|
+
F) railway — Railway deploy hook (managed by Railway GitHub integration)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
In `--force` mode: re-ask even for already-configured surfaces.
|
|
81
|
+
Otherwise: surfaces already in `cd.json` are preserved without re-asking.
|
|
82
|
+
|
|
83
|
+
If an expected surface is MISSING from detection: add the detection signal (e.g.
|
|
84
|
+
`publishConfig.access` in package.json, or `src-tauri/tauri.conf.json`) and re-run.
|
|
85
|
+
To DROP a surface: deselect it here and re-run with `--force` to remove its key from
|
|
86
|
+
`cd.json`, or edit `.codebyplan/cd.json` directly.
|
|
87
|
+
|
|
88
|
+
## Step 3 — Collect credential env-var names (per surface)
|
|
89
|
+
|
|
90
|
+
For each confirmed surface, collect only the env-var NAMES (never the values). Skip if
|
|
91
|
+
`--force` is absent AND `credentials.env_var_names[]` is already non-empty in `cd.json`.
|
|
92
|
+
|
|
93
|
+
Per-surface default name sets (accept defaults or override):
|
|
94
|
+
|
|
95
|
+
| Surface | Default env-var names |
|
|
96
|
+
| ------- | --------------------- |
|
|
97
|
+
| `npm` (OIDC) | *(none — OIDC handles auth; record `[]`)* |
|
|
98
|
+
| `npm` (token) | `NPM_TOKEN` |
|
|
99
|
+
| `tauri` | `TAURI_SIGNING_PRIVATE_KEY`, `TAURI_SIGNING_PRIVATE_KEY_PASSWORD`, `APPLE_CERTIFICATE`, `APPLE_CERTIFICATE_PASSWORD`, `APPLE_SIGNING_IDENTITY`, `APPLE_API_ISSUER`, `APPLE_API_KEY`, `APPLE_API_KEY_CONTENT`, `WINDOWS_CERTIFICATE`, `WINDOWS_CERTIFICATE_PASSWORD` |
|
|
100
|
+
| `vscode` | `VSCE_PAT` |
|
|
101
|
+
| `expo` | `EXPO_TOKEN` |
|
|
102
|
+
|
|
103
|
+
Full var descriptions: [reference/github-actions-cd.md](reference/github-actions-cd.md) § Per-Surface Credential Var-Name Reference.
|
|
104
|
+
|
|
105
|
+
Record collected names into `credentials.env_var_names[]`. Never write secret values.
|
|
106
|
+
|
|
107
|
+
## Step 4 — Collect environment + approval config (per surface)
|
|
108
|
+
|
|
109
|
+
For each confirmed surface, ask about GitHub Environments and approval gates. Skip if
|
|
110
|
+
already configured in `cd.json` and `--force` is absent.
|
|
111
|
+
|
|
112
|
+
AskUserQuestion per surface:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
GitHub Environment config for [surface]:
|
|
116
|
+
|
|
117
|
+
1. Deploy environment name (leave blank for none — e.g. "production"):
|
|
118
|
+
Environment: ___
|
|
119
|
+
|
|
120
|
+
2. Require manual approval before deploy?
|
|
121
|
+
A) No — auto-deploy on push (recommended for npm OIDC / Tauri tag)
|
|
122
|
+
B) Yes — require a reviewer to approve the workflow run
|
|
123
|
+
|
|
124
|
+
3. OIDC auth (exchange GitHub OIDC token for deploy credential)?
|
|
125
|
+
A) Yes — recommended for npm (no long-lived token; requires Trusted Publisher config on npmjs.com)
|
|
126
|
+
B) No — use a long-lived token from repository secrets
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Record as `environment`, `approval_required`, and `oidc_auth` on the surface block.
|
|
130
|
+
|
|
131
|
+
## Step 5 — Write .codebyplan/cd.json
|
|
132
|
+
|
|
133
|
+
Run `codebyplan cd init` to write the config:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx codebyplan cd init [--force]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The CLI writes `cd.json` from the collected surface data. If the CLI is unavailable (not
|
|
140
|
+
yet on PATH), write the file directly via jq:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
jq -n \
|
|
144
|
+
--argjson surfaces "$SURFACES_JSON" \
|
|
145
|
+
--argjson workflow "$WORKFLOW_JSON" \
|
|
146
|
+
'{surfaces: $surfaces, workflow: $workflow}' \
|
|
147
|
+
> .codebyplan/cd.json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Confirm by reading back the result:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cat .codebyplan/cd.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Per-surface shape: `{ trigger, path_filter, approval_required, oidc_auth, version_gate,
|
|
157
|
+
credentials: { env_var_names[] } }`. Credentials are env-var NAMES only — never values.
|
|
158
|
+
Schema: `packages/codebyplan-package/src/lib/types.ts` (`CdConfig`).
|
|
159
|
+
|
|
160
|
+
## Step 6 — Scaffold workflow files (diff-guarded)
|
|
161
|
+
|
|
162
|
+
Preview each workflow before writing:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npx codebyplan cd scaffold-workflow --dry-run
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
For each workflow file that already exists, show a diff and ask before overwriting (unless
|
|
169
|
+
`--force` is set):
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
diff .github/workflows/publish.yml <(npx codebyplan cd scaffold-workflow --workflow publish --dry-run)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
AskUserQuestion (only when file exists and `--force` is absent):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
.github/workflows/publish.yml already exists.
|
|
179
|
+
Diff (existing → new):
|
|
180
|
+
<diff output>
|
|
181
|
+
|
|
182
|
+
Overwrite?
|
|
183
|
+
A) Yes — adopt the scaffolded workflow (recommended — picks up latest template)
|
|
184
|
+
B) No — keep existing workflow unchanged
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Then write:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npx codebyplan cd scaffold-workflow [--force]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
If the CLI errors (missing bin, not yet released), write from the canonical templates at
|
|
194
|
+
`packages/codebyplan-package/templates/github-workflows/`:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
cp packages/codebyplan-package/templates/github-workflows/publish.yml \
|
|
198
|
+
.github/workflows/publish.yml
|
|
199
|
+
cp packages/codebyplan-package/templates/github-workflows/release-desktop.yml \
|
|
200
|
+
.github/workflows/release-desktop.yml
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Only copy templates relevant to the confirmed surface set (npm → publish.yml;
|
|
204
|
+
tauri → release-desktop.yml).
|
|
205
|
+
|
|
206
|
+
After writing, update `cd.json` to record `workflow.workflows_scaffolded: true` and the
|
|
207
|
+
current timestamp:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
jq '.workflow.workflows_scaffolded = true | .workflow.scaffolded_at = "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"' \
|
|
211
|
+
.codebyplan/cd.json > .codebyplan/cd.json.tmp \
|
|
212
|
+
&& mv .codebyplan/cd.json.tmp .codebyplan/cd.json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Step 7 — OIDC Trusted Publishing verification (npm surface)
|
|
216
|
+
|
|
217
|
+
If the npm surface uses `oidc_auth: true`, walk the user through verifying the npmjs.com
|
|
218
|
+
Trusted Publisher registration:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
npm OIDC Trusted Publishing setup
|
|
222
|
+
|
|
223
|
+
Verify these settings on npmjs.com → package → Settings → Trusted Publishers:
|
|
224
|
+
|
|
225
|
+
Publisher type : GitHub Actions
|
|
226
|
+
Repository owner: <github-org>
|
|
227
|
+
Repository name : <repo-slug>
|
|
228
|
+
Workflow filename: publish.yml
|
|
229
|
+
Environment : (blank, unless you set a GitHub Environment above)
|
|
230
|
+
|
|
231
|
+
If the Trusted Publisher is NOT configured, publish.yml will fail with E401.
|
|
232
|
+
Configure it at: https://www.npmjs.com/package/<package-name>/access
|
|
233
|
+
|
|
234
|
+
Configured? (Y/n)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
If `n`: print the npmjs.com configuration URL and pause — the user must complete this
|
|
238
|
+
before the first publish will succeed. Record the gap in `cd.json` as
|
|
239
|
+
`workflow.npm_oidc_publisher_verified: false`.
|
|
240
|
+
|
|
241
|
+
On `Y`: record `workflow.npm_oidc_publisher_verified: true`.
|
|
242
|
+
|
|
243
|
+
Skip this step when `oidc_auth: false` for the npm surface.
|
|
244
|
+
|
|
245
|
+
## Step 8 — Verify and report
|
|
246
|
+
|
|
247
|
+
Re-read the config and confirm workflow files exist:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
cat .codebyplan/cd.json
|
|
251
|
+
test -f .github/workflows/publish.yml && echo "publish.yml present" || echo "publish.yml MISSING"
|
|
252
|
+
test -f .github/workflows/release-desktop.yml && echo "release-desktop.yml present" || echo "release-desktop.yml MISSING"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Emit a summary:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
CD Setup — Complete
|
|
259
|
+
|
|
260
|
+
Surface | trigger | path_filter | approval | oidc | version_gate | workflow
|
|
261
|
+
------- | ------------- | -------------------------------- | -------- | ----- | ------------ | --------
|
|
262
|
+
npm | push-to-main | packages/codebyplan-package/** | no | yes | yes | publish.yml (present)
|
|
263
|
+
tauri | push-to-main | apps/desktop/** | no | no | yes | release-desktop.yml (present)
|
|
264
|
+
|
|
265
|
+
cd.json: .codebyplan/cd.json (written)
|
|
266
|
+
|
|
267
|
+
Next:
|
|
268
|
+
1. Add the credential env vars to GitHub repository secrets (Settings → Secrets and variables → Actions).
|
|
269
|
+
2. For npm OIDC: verify the Trusted Publisher on npmjs.com (Step 7 above).
|
|
270
|
+
3. Push a version bump to main to verify the publish.yml gate fires.
|
|
271
|
+
4. See reference/github-actions-cd.md for workflow anatomy and troubleshooting.
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Key Rules
|
|
275
|
+
|
|
276
|
+
- Credentials are NEVER written to `cd.json` or this skill — var names only
|
|
277
|
+
- Idempotent — re-running without `--force` preserves existing surface keys and workflow
|
|
278
|
+
files; it never clobbers a customized workflow
|
|
279
|
+
- Diff-guarded — existing workflow files are shown as a diff before overwriting
|
|
280
|
+
- Repos without `cd.json` fall back to the existing surface-detection path in `/cbp-ship`
|
|
281
|
+
— this skill writes the config that informs `/cbp-ship` Step 3 variant selection
|
|
282
|
+
- This skill is org-shared; its template twin at
|
|
283
|
+
`packages/codebyplan-package/templates/skills/cbp-setup-cd/SKILL.md` must stay
|
|
284
|
+
byte-identical (GATE-6)
|
|
285
|
+
|
|
286
|
+
## Additional resources
|
|
287
|
+
|
|
288
|
+
- Workflow anatomy + OIDC + drift-guard: [reference/github-actions-cd.md](reference/github-actions-cd.md)
|
|
289
|
+
- CD config schema: `packages/codebyplan-package/src/lib/types.ts` (`CdConfig`)
|
|
290
|
+
- CD CLI commands: `packages/codebyplan-package/src/cli/cd.ts`
|
|
291
|
+
- Surface detection signals: `packages/codebyplan-package/src/lib/cd-init.ts` (`detectSurfaces`, `normaliseSurfaceKey`)
|