codebyplan 1.5.0 → 1.8.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.
Files changed (206) hide show
  1. package/README.md +48 -5
  2. package/dist/cli.js +4578 -2709
  3. package/package.json +5 -1
  4. package/templates/.gitkeep +0 -0
  5. package/templates/README.md +20 -0
  6. package/templates/agents/cbp-cc-executor.md +213 -0
  7. package/templates/agents/cbp-database-agent.md +229 -0
  8. package/templates/agents/cbp-improve-claude.md +245 -0
  9. package/templates/agents/cbp-improve-round.md +284 -0
  10. package/templates/agents/cbp-mechanical-edits.md +111 -0
  11. package/templates/agents/cbp-research.md +282 -0
  12. package/templates/agents/cbp-round-executor.md +604 -0
  13. package/templates/agents/cbp-security-agent.md +134 -0
  14. package/templates/agents/cbp-task-check.md +213 -0
  15. package/templates/agents/cbp-task-planner.md +582 -0
  16. package/templates/agents/cbp-test-e2e-agent.md +363 -0
  17. package/templates/agents/cbp-testing-qa-agent.md +400 -0
  18. package/templates/context/mcp-docs.md +139 -0
  19. package/templates/hooks/README.md +236 -0
  20. package/templates/hooks/cbp-auto-test-hooks.sh +44 -0
  21. package/templates/hooks/cbp-lint-format-on-edit.sh +159 -0
  22. package/templates/hooks/cbp-maestro-yaml-validate.sh +100 -0
  23. package/templates/hooks/cbp-mcp-migration-guard.sh +32 -0
  24. package/templates/hooks/cbp-mcp-round-sync.sh +79 -0
  25. package/templates/hooks/cbp-mcp-worktree-inject.sh +76 -0
  26. package/templates/hooks/cbp-notify.sh +68 -0
  27. package/templates/hooks/cbp-plugin-dispatch.sh +29 -0
  28. package/templates/hooks/cbp-pre-commit-quality-gate.sh +204 -0
  29. package/templates/hooks/cbp-statusline.sh +347 -0
  30. package/templates/hooks/cbp-subagent-statusline.sh +182 -0
  31. package/templates/hooks/cbp-test-coverage-gate.sh +144 -0
  32. package/templates/hooks/cbp-test-hooks.sh +320 -0
  33. package/templates/hooks/hooks.json +85 -0
  34. package/templates/hooks/validate-context-usage.sh +59 -0
  35. package/templates/hooks/validate-git-commit.sh +78 -0
  36. package/templates/hooks/validate-git-stash-deny.sh +32 -0
  37. package/templates/hooks/validate-structure-lengths.sh +57 -0
  38. package/templates/hooks/validate-structure-lib.sh +104 -0
  39. package/templates/hooks/validate-structure-patterns.sh +54 -0
  40. package/templates/hooks/validate-structure-scope.sh +33 -0
  41. package/templates/hooks/validate-structure-smoke.sh +95 -0
  42. package/templates/hooks/validate-structure-templates.sh +34 -0
  43. package/templates/hooks/validate-structure.sh +69 -0
  44. package/templates/rules/.gitkeep +0 -0
  45. package/templates/rules/README.md +47 -0
  46. package/templates/rules/context-file-loading.md +52 -0
  47. package/templates/rules/scope-vocabulary.md +64 -0
  48. package/templates/rules/todo-backend.md +109 -0
  49. package/templates/settings.project.base.json +55 -0
  50. package/templates/settings.user.base.json +25 -0
  51. package/templates/skills/cbp-build-cc-agent/SKILL.md +139 -0
  52. package/templates/skills/cbp-build-cc-agent/examples/read-only-reviewer.md +32 -0
  53. package/templates/skills/cbp-build-cc-agent/examples/with-hooks.md +41 -0
  54. package/templates/skills/cbp-build-cc-agent/examples/with-skills-preload.md +25 -0
  55. package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +153 -0
  56. package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +37 -0
  57. package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +18 -0
  58. package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +67 -0
  59. package/templates/skills/cbp-build-cc-agent/templates/agent.md +66 -0
  60. package/templates/skills/cbp-build-cc-claude-file/SKILL.md +178 -0
  61. package/templates/skills/cbp-build-cc-claude-file/examples/minimal-project.md +33 -0
  62. package/templates/skills/cbp-build-cc-claude-file/examples/monorepo-with-imports.md +39 -0
  63. package/templates/skills/cbp-build-cc-claude-file/reference/imports.md +72 -0
  64. package/templates/skills/cbp-build-cc-claude-file/reference/what-belongs.md +39 -0
  65. package/templates/skills/cbp-build-cc-claude-file/templates/project-claude-md.md +48 -0
  66. package/templates/skills/cbp-build-cc-claude-file/templates/user-claude-md.md +22 -0
  67. package/templates/skills/cbp-build-cc-memory/SKILL.md +201 -0
  68. package/templates/skills/cbp-build-cc-memory/examples/feedback-memory.md +11 -0
  69. package/templates/skills/cbp-build-cc-memory/examples/project-memory.md +11 -0
  70. package/templates/skills/cbp-build-cc-memory/examples/reference-memory.md +13 -0
  71. package/templates/skills/cbp-build-cc-memory/examples/user-memory.md +14 -0
  72. package/templates/skills/cbp-build-cc-memory/reference/memory-types.md +59 -0
  73. package/templates/skills/cbp-build-cc-memory/reference/when-to-save.md +62 -0
  74. package/templates/skills/cbp-build-cc-memory/templates/MEMORY-index.md +4 -0
  75. package/templates/skills/cbp-build-cc-memory/templates/memory-entry.md +15 -0
  76. package/templates/skills/cbp-build-cc-mode/SKILL.md +99 -0
  77. package/templates/skills/cbp-build-cc-rule/SKILL.md +176 -0
  78. package/templates/skills/cbp-build-cc-rule/examples/global-rule.md +19 -0
  79. package/templates/skills/cbp-build-cc-rule/examples/scoped-rule.md +41 -0
  80. package/templates/skills/cbp-build-cc-rule/reference/paths-patterns.md +48 -0
  81. package/templates/skills/cbp-build-cc-rule/templates/rule.md +32 -0
  82. package/templates/skills/cbp-build-cc-settings/SKILL.md +220 -0
  83. package/templates/skills/cbp-build-cc-settings/examples/hooks-config.json +64 -0
  84. package/templates/skills/cbp-build-cc-settings/examples/permissions-config.json +34 -0
  85. package/templates/skills/cbp-build-cc-settings/examples/sandbox-config.json +42 -0
  86. package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +104 -0
  87. package/templates/skills/cbp-build-cc-settings/reference/permission-rules.md +61 -0
  88. package/templates/skills/cbp-build-cc-settings/reference/scope-precedence.md +73 -0
  89. package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +166 -0
  90. package/templates/skills/cbp-build-cc-settings/templates/settings.json +23 -0
  91. package/templates/skills/cbp-build-cc-settings/templates/settings.local.json +10 -0
  92. package/templates/skills/cbp-build-cc-skill/SKILL.md +154 -0
  93. package/templates/skills/cbp-build-cc-skill/examples/dynamic-context.md +31 -0
  94. package/templates/skills/cbp-build-cc-skill/examples/fork-skill.md +22 -0
  95. package/templates/skills/cbp-build-cc-skill/examples/knowledge-skill.md +25 -0
  96. package/templates/skills/cbp-build-cc-skill/examples/task-skill.md +29 -0
  97. package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +157 -0
  98. package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +35 -0
  99. package/templates/skills/cbp-build-cc-skill/reference/string-substitutions.md +60 -0
  100. package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +90 -0
  101. package/templates/skills/cbp-build-cc-skill/templates/skill.md +51 -0
  102. package/templates/skills/cbp-checkpoint-check/SKILL.md +156 -0
  103. package/templates/skills/cbp-checkpoint-complete/SKILL.md +109 -0
  104. package/templates/skills/cbp-checkpoint-create/SKILL.md +287 -0
  105. package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
  106. package/templates/skills/cbp-checkpoint-update/SKILL.md +115 -0
  107. package/templates/skills/cbp-frontend-a11y/SKILL.md +109 -0
  108. package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +130 -0
  109. package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +122 -0
  110. package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +154 -0
  111. package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +111 -0
  112. package/templates/skills/cbp-frontend-design/SKILL.md +145 -0
  113. package/templates/skills/cbp-frontend-design/reference/nextjs-scss.md +118 -0
  114. package/templates/skills/cbp-frontend-design/reference/rn-expo.md +101 -0
  115. package/templates/skills/cbp-frontend-design/reference/tauri-react.md +82 -0
  116. package/templates/skills/cbp-frontend-ui/SKILL.md +262 -0
  117. package/templates/skills/cbp-frontend-ui/reference/ui-label-maps.md +42 -0
  118. package/templates/skills/cbp-frontend-ui/reference/ui-layout-patterns.md +105 -0
  119. package/templates/skills/cbp-frontend-ui/reference/variant-defaults.md +149 -0
  120. package/templates/skills/cbp-frontend-ux/SKILL.md +181 -0
  121. package/templates/skills/cbp-git-branch-feat-create/SKILL.md +115 -0
  122. package/templates/skills/cbp-git-commit/SKILL.md +278 -0
  123. package/templates/skills/cbp-git-worktree-create/SKILL.md +226 -0
  124. package/templates/skills/cbp-git-worktree-remove/SKILL.md +145 -0
  125. package/templates/skills/cbp-merge-main/SKILL.md +228 -0
  126. package/templates/skills/cbp-round-check/SKILL.md +104 -0
  127. package/templates/skills/cbp-round-end/SKILL.md +183 -0
  128. package/templates/skills/cbp-round-end/reference/findings-presentation.md +44 -0
  129. package/templates/skills/cbp-round-end/reference/inline-fallback.md +35 -0
  130. package/templates/skills/cbp-round-execute/SKILL.md +211 -0
  131. package/templates/skills/cbp-round-execute/reference/inline-fallback.md +59 -0
  132. package/templates/skills/cbp-round-input/SKILL.md +165 -0
  133. package/templates/skills/cbp-round-start/SKILL.md +222 -0
  134. package/templates/skills/cbp-round-update/SKILL.md +163 -0
  135. package/templates/skills/cbp-session-end/SKILL.md +187 -0
  136. package/templates/skills/cbp-session-start/SKILL.md +155 -0
  137. package/templates/skills/cbp-ship/SKILL.md +332 -0
  138. package/templates/skills/cbp-ship/reference/changesets-overview.md +120 -0
  139. package/templates/skills/cbp-ship/reference/eas-cli-overview.md +60 -0
  140. package/templates/skills/cbp-ship/reference/gh-cli-overview.md +135 -0
  141. package/templates/skills/cbp-ship/reference/gh-cli-shipment-commands.md +283 -0
  142. package/templates/skills/cbp-ship/reference/npm-publish-monorepo.md +252 -0
  143. package/templates/skills/cbp-ship/reference/npm-publish-oidc-trusted.md +157 -0
  144. package/templates/skills/cbp-ship/reference/npm-publish-overview.md +171 -0
  145. package/templates/skills/cbp-ship/reference/preflight-checklist.md +88 -0
  146. package/templates/skills/cbp-ship/reference/railway-nestjs-deployment.md +169 -0
  147. package/templates/skills/cbp-ship/reference/railway-overview.md +120 -0
  148. package/templates/skills/cbp-ship/reference/railway-troubleshooting.md +168 -0
  149. package/templates/skills/cbp-ship/reference/release-please-overview.md +99 -0
  150. package/templates/skills/cbp-ship/reference/surface-expo-eas.md +155 -0
  151. package/templates/skills/cbp-ship/reference/surface-npm.md +180 -0
  152. package/templates/skills/cbp-ship/reference/surface-railway.md +152 -0
  153. package/templates/skills/cbp-ship/reference/surface-supabase.md +178 -0
  154. package/templates/skills/cbp-ship/reference/surface-tauri.md +138 -0
  155. package/templates/skills/cbp-ship/reference/surface-vercel.md +124 -0
  156. package/templates/skills/cbp-ship/reference/surface-vscode-ext.md +144 -0
  157. package/templates/skills/cbp-ship/reference/surfaces.md +60 -0
  158. package/templates/skills/cbp-ship/reference/testflight-automation.md +215 -0
  159. package/templates/skills/cbp-ship/reference/testflight-internal-vs-external.md +69 -0
  160. package/templates/skills/cbp-ship/reference/testflight-overview.md +98 -0
  161. package/templates/skills/cbp-ship/reference/versioning.md +116 -0
  162. package/templates/skills/cbp-ship/scripts/detect-surfaces.sh +217 -0
  163. package/templates/skills/cbp-ship/scripts/verify-expo-eas.sh +35 -0
  164. package/templates/skills/cbp-ship/scripts/verify-npm.sh +21 -0
  165. package/templates/skills/cbp-ship/scripts/verify-railway.sh +41 -0
  166. package/templates/skills/cbp-ship/scripts/verify-supabase.sh +19 -0
  167. package/templates/skills/cbp-ship/scripts/verify-tauri.sh +24 -0
  168. package/templates/skills/cbp-ship/scripts/verify-vercel.sh +32 -0
  169. package/templates/skills/cbp-ship/scripts/verify-vscode-ext.sh +25 -0
  170. package/templates/skills/cbp-ship/templates/eas.json +66 -0
  171. package/templates/skills/cbp-ship/templates/railway.toml +15 -0
  172. package/templates/skills/cbp-ship/templates/release-please-config.json +17 -0
  173. package/templates/skills/cbp-ship/templates/vercel.json +19 -0
  174. package/templates/skills/cbp-ship/templates/vscodeignore +21 -0
  175. package/templates/skills/cbp-ship/templates/workflow-changesets.yml +41 -0
  176. package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +53 -0
  177. package/templates/skills/cbp-ship/templates/workflow-npm-publish.yml +36 -0
  178. package/templates/skills/cbp-ship/templates/workflow-release-please.yml +21 -0
  179. package/templates/skills/cbp-ship/templates/workflow-tauri-release.yml +69 -0
  180. package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +31 -0
  181. package/templates/skills/cbp-ship-configure/SKILL.md +296 -0
  182. package/templates/skills/cbp-ship-configure/reference/expo-mobile.md +204 -0
  183. package/templates/skills/cbp-ship-configure/reference/npm-package.md +165 -0
  184. package/templates/skills/cbp-ship-configure/reference/railway-backend.md +199 -0
  185. package/templates/skills/cbp-ship-configure/reference/supabase.md +200 -0
  186. package/templates/skills/cbp-ship-configure/reference/tauri-desktop.md +181 -0
  187. package/templates/skills/cbp-ship-configure/reference/vercel.md +117 -0
  188. package/templates/skills/cbp-ship-configure/reference/vscode-ext.md +155 -0
  189. package/templates/skills/cbp-ship-main/SKILL.md +65 -0
  190. package/templates/skills/cbp-supabase-branch-check/SKILL.md +337 -0
  191. package/templates/skills/cbp-supabase-branch-check/reference/dag-steps.md +29 -0
  192. package/templates/skills/cbp-supabase-migrate/SKILL.md +314 -0
  193. package/templates/skills/cbp-supabase-migrate/reference/advisor-triage.md +70 -0
  194. package/templates/skills/cbp-supabase-migrate/reference/cli-fallback.md +87 -0
  195. package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +58 -0
  196. package/templates/skills/cbp-supabase-setup/SKILL.md +239 -0
  197. package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +121 -0
  198. package/templates/skills/cbp-supabase-setup/reference/cli-fallback.md +109 -0
  199. package/templates/skills/cbp-task-check/SKILL.md +166 -0
  200. package/templates/skills/cbp-task-complete/SKILL.md +206 -0
  201. package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +48 -0
  202. package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +56 -0
  203. package/templates/skills/cbp-task-create/SKILL.md +167 -0
  204. package/templates/skills/cbp-task-start/SKILL.md +239 -0
  205. package/templates/skills/cbp-task-testing/SKILL.md +277 -0
  206. package/templates/skills/cbp-todo/SKILL.md +97 -0
@@ -0,0 +1,187 @@
1
+ ---
2
+ scope: org-shared
3
+ name: cbp-session-end
4
+ description: End a development session
5
+ effort: xhigh
6
+ ---
7
+
8
+ # Session End Command
9
+
10
+ End the current session. Commits only non-task files — files tied to an unfinished task stay uncommitted so the user finishes them on their terms.
11
+
12
+ ## Instructions
13
+
14
+ ### Step 1: Finalize Session Log
15
+
16
+ Always write a session log for this session — **even if empty**. `/cbp-session-start` opens the log; session-end finalizes it.
17
+
18
+ 1. Resolve the current session log:
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 the DB rather than narrating from memory:
23
+ - Rounds added/completed, tasks advanced/completed during this session
24
+ - Decisions, blockers, or discoveries recorded in checkpoint/task context
25
+
26
+ ### Step 1.3: Capture Handoff Snapshot
27
+
28
+ Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can auto-resume. Per `.claude/rules/session-resume.md` write-path contract.
29
+
30
+ 1. Call MCP `get_next_action({ repo_id, worktree_id })`.
31
+ 2. If the returned `command` is non-empty (active work in flight):
32
+ ```yaml
33
+ handoff:
34
+ command: <result.command> # e.g. "/cbp-round-update"
35
+ instructions: <result.instructions> # human-readable trigger reason
36
+ state: <result.state> # workflow state label
37
+ context: <result.context> # entity ids (checkpoint_id / task_id / round_id) used by freshness probe
38
+ captured_at: <ISO now> # for entity-drift freshness comparison
39
+ captured_session_log_id: <current session log id>
40
+ ```
41
+ 3. If `command` is empty / idle / queue-empty: set `handoff = null` so the next session's probe falls through to `/cbp-todo`.
42
+ 4. Hold `handoff` in context for Step 1's `update_session_log` call below — it ships in the same write as `ended_at` and `summary`.
43
+
44
+ Continuing Step 1:
45
+
46
+ 3. Use MCP `update_session_log` to finalize:
47
+ - `ended_at`: now (maps to the `closed_at` column per TASK-2 alias)
48
+ - `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)
49
+ - `summary`: concise — may be empty if nothing happened
50
+ - `pending`: open items the next session should see first
51
+
52
+ ### Step 1.5: Commit Non-Task Files
53
+
54
+ Same rule as `/cbp-session-start` Step 5.7 — only commit files that are **not** part of an unfinished task.
55
+
56
+ 1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
57
+ 2. Resolve **task-related files** (leave these uncommitted):
58
+ - MCP `get_current_task(repo_id)` → active task
59
+ - If active task exists: MCP `get_rounds(task_id)`, filter to rounds with status not in `completed` / `cancelled`
60
+ - Collect `files[]` from those rounds → `task_files` set
61
+ - If no active task exists, `task_files` is empty
62
+ 3. `infra_files = changed_files − task_files`
63
+ 4. If `infra_files` is empty → skip. Otherwise present once:
64
+
65
+ ```
66
+ Commit these non-task files before ending session?
67
+ [list of infra_files]
68
+
69
+ Reply: yes | no | select
70
+ ```
71
+
72
+ 5. On `yes`: `git add` the listed files, then trigger `/cbp-git-commit`.
73
+ On `no`: skip. On `select`: ask which subset.
74
+
75
+ Non-blocking — session end proceeds either way.
76
+
77
+ ### Step 1.7: Auto-Update CodeByPlan Assets
78
+
79
+ Run the latest published CLIs to pull any asset or config changes. Sub-block A runs first, then Sub-block B. A failure in A does **not** skip B — each sub-block has its own retry-and-warn lane.
80
+
81
+ **a) `codebyplan claude` (asset subcommand group)**
82
+
83
+ Run the latest published CLI's asset-update verb to pull any skill / agent / hook changes:
84
+
85
+ ```
86
+ npx codebyplan@latest claude update
87
+ ```
88
+
89
+ Always run — do not skip, even when the current repo is the canonical-owner monorepo source.
90
+
91
+ The command may pause for interactive prompts when:
92
+
93
+ - a tracked file has been hand-edited locally (overwrite / skip / diff)
94
+ - a new file is being shipped for the first time (opt-in / skip)
95
+ - a file has been removed from the package (remove / keep)
96
+
97
+ Respond to each prompt in the terminal as it appears. The commit prompt below runs only after all per-file prompts are resolved.
98
+
99
+ Failure handling:
100
+
101
+ - On non-zero exit: wait ~5 s, retry once.
102
+ - If retry also fails: print a warning and continue — this step is non-blocking.
103
+
104
+ After the command exits (success):
105
+
106
+ 1. Run `git status --porcelain -- .claude/` to detect any file changes.
107
+ 2. If non-empty, present once (same pattern as Step 1.5):
108
+
109
+ ```
110
+ .claude/ was updated. Commit these changes?
111
+ [list of changed paths under .claude/]
112
+
113
+ Reply: yes | no | select
114
+ ```
115
+
116
+ On `yes`: `git add` the listed paths only (not the whole `.claude/` directory), then trigger `/cbp-git-commit`.
117
+ On `no`: skip. On `select`: ask which subset.
118
+
119
+ 3. Print the final stdout line from the update command as a one-line session summary (e.g. `codebyplan claude update: 47 files tracked.`). Silent when the command produces no stdout.
120
+
121
+ Non-blocking — session end proceeds regardless of outcome.
122
+
123
+ **b) `codebyplan` (project CLI)**
124
+
125
+ Fetch the latest published version of the project CLI. The `codebyplan` CLI has no `update` verb (subcommands are `setup`, `sync`, `eslint`); the freshness idiom is to invoke a fast read-only flag with `@latest` so npx fetches and caches the newest published version:
126
+
127
+ ```
128
+ npx codebyplan@latest --version
129
+ ```
130
+
131
+ Do **not** run `sync`, `setup`, or any other state-changing subcommand — this step updates the cached binary only.
132
+
133
+ Failure handling:
134
+
135
+ - On non-zero exit: wait ~5 s, retry once.
136
+ - If retry also fails: print a warning and continue — this step is non-blocking.
137
+
138
+ After the command exits (success):
139
+
140
+ 1. Run `git status --porcelain -- .codebyplan/` to detect any file changes.
141
+ 2. If non-empty, present once (same pattern as Step 1.5):
142
+
143
+ ```
144
+ .codebyplan/ was updated. Commit these changes?
145
+ [list of changed paths under .codebyplan/]
146
+
147
+ Reply: yes | no | select
148
+ ```
149
+
150
+ On `yes`: `git add` the listed paths only, then trigger `/cbp-git-commit`.
151
+ On `no`: skip. On `select`: ask which subset.
152
+
153
+ 3. Print the command's stdout (the version line) as a one-line session summary (e.g. `codebyplan 1.4.2`). Silent when the command produces no stdout.
154
+
155
+ Non-blocking — session end proceeds regardless of outcome.
156
+
157
+ ### Step 2: Auto-Stop Servers
158
+
159
+ **Skip if `server_type` is `"none"`.**
160
+
161
+ 1. Get `server_port` from `.codebyplan/server.json` context
162
+ 2. Check for running process: `lsof -ti:{PORT} 2>/dev/null`
163
+ 3. If process found, kill: `lsof -ti:{PORT} | xargs kill -9 2>/dev/null || true`
164
+
165
+ Non-blocking — if kill fails, warn and continue. Silent when no process found.
166
+
167
+ ### Step 3: Update Session State
168
+
169
+ Use MCP `update_session_state` with action `deactivate`.
170
+
171
+ ### Step 4: Output
172
+
173
+ ```
174
+ Session ended. Log finalized.
175
+
176
+ You can close this window.
177
+ ```
178
+
179
+ ## Integration
180
+
181
+ - **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
182
+ - **Reads**: `.codebyplan/repo.json`, MCP `get_session_logs` (resolve current log), MCP `get_current_task`, MCP `get_rounds`, MCP `get_next_action` (Step 1.3 handoff snapshot)
183
+ - **Writes**: MCP `update_session_log` (with `ended_at` + `handoff` per TASK-2 alias surface; or `create_session_log` fallback), MCP `update_session_state` (deactivate)
184
+ - **Spawns**: none
185
+ - **Triggers**: none at the skill-contract level. Steps 1.5 and 1.7 may invoke `/cbp-git-commit` inline on user approval.
186
+ - **Paired with**: `/cbp-session-start`
187
+ - **Pairs with**: `.claude/rules/session-resume.md` (handoff payload shape + write-path contract)
@@ -0,0 +1,155 @@
1
+ ---
2
+ scope: org-shared
3
+ name: cbp-session-start
4
+ description: Start a development session
5
+ triggers: [cbp-todo]
6
+ effort: low
7
+ ---
8
+
9
+ # Session Start Command
10
+
11
+ Activate the session, open a fresh session log, and surface the previous log's pending items so the user can pick up where they left off.
12
+
13
+ ## Instructions
14
+
15
+ Do Steps 0–5 and Step 4.5 silently (no intermediate output). Step 5.7 may surface an approval gate. Produce ONE output block at Step 6, then auto-trigger `/cbp-todo`.
16
+
17
+ ### Step 0: MCP Health Check
18
+
19
+ Call MCP `health_check` tool.
20
+
21
+ - **If succeeds**: Continue silently
22
+ - **If fails**: Show warning:
23
+
24
+ ```
25
+ ⚠ MCP connection failed. Check:
26
+ 1. Network connectivity
27
+ 2. API key validity (CODEBYPLAN_API_KEY env var)
28
+ 3. codebyplan.com availability
29
+
30
+ Session continues but MCP-dependent features will be unavailable.
31
+ ```
32
+
33
+ Continue to Step 1 (non-blocking).
34
+
35
+ ### Step 1: Load Config
36
+
37
+ Read per-concern config files from the project root. Single load point for the session:
38
+
39
+ - `repo_id` (UUID) — from `.codebyplan/repo.json`, required for all MCP operations
40
+ - `server_port`, `server_type`, `auto_push_enabled` — from `.codebyplan/server.json`
41
+ - `git_branch` — from `.codebyplan/git.json`
42
+
43
+ Resolve `worktree_id` at runtime (CHK-108: never read from `.codebyplan/repo.json`):
44
+
45
+ ```bash
46
+ WORKTREE_ID=$(npx codebyplan resolve-worktree 2>/dev/null)
47
+ ```
48
+
49
+ Pass `WORKTREE_ID` to MCP tools that support it. Empty output means the (device, path, branch) tuple is unregistered — see fallback note below.
50
+
51
+ **If `worktree_id` resolves to empty** (the (device, path, branch) tuple does not match any registered worktree row): the session continues, but downstream MCP calls treat this caller as untagged — every hard-lock pre-guard sees a NULL `caller_worktree_id` and may reject mutations on assigned rows. Surface a one-line note in the Step 6 output instructing the user to run `npx codebyplan setup` from this directory to register the worktree.
52
+
53
+ ### Step 2: Check Dev Server
54
+
55
+ **Skip if `server_type` is `"none"`.**
56
+
57
+ 1. Get `server_port` from `.codebyplan/server.json`
58
+ 2. Check if running: `lsof -ti:{PORT} 2>/dev/null`
59
+ 3. If running, verify health: `curl -s -o /dev/null -w "%{http_code}" http://localhost:{PORT}/ --max-time 2`
60
+ 4. If NOT running, note in output that user should start via desktop app
61
+
62
+ ### Step 3: Update Session State
63
+
64
+ Use MCP `update_session_state` with action `activate`. This deactivates all other repos automatically.
65
+
66
+ ### Step 4: Read Last Session Log
67
+
68
+ Call MCP `get_session_logs({ repo_id, worktree_id, limit: 1 })` — same inclusive-worktree call shape used by Step 4.5 below so the previous-session display and the handoff probe agree on which row is "most recent for this worktree". Take the first (and only) row.
69
+
70
+ - If a previous log exists, hold its title/summary/pending items for the Step 6 output so the user sees where they left off.
71
+ - If none exists (first session ever for this worktree), skip silently.
72
+
73
+ ### Step 5: Create This Session's Log
74
+
75
+ Use MCP `create_session_log` to open a new session log for the current session. Create it **even if empty** — this establishes the record for session-end to finalize.
76
+
77
+ Minimal seed content:
78
+
79
+ - `started_at`: now
80
+ - `repo_id` from config; `worktree_id` from `WORKTREE_ID` resolved in Step 1
81
+ - `summary`: empty (session-end fills this in)
82
+
83
+ Hold the new log's ID in context so `/cbp-session-end` can update the same record.
84
+
85
+ ### Step 4.5: Handoff Auto-Resume Probe
86
+
87
+ Probe the most-recent closed session log for a structured handoff payload (per `.claude/rules/session-resume.md`) 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.
88
+
89
+ 1. Reuse the row held from Step 4 (same `get_session_logs({ repo_id, worktree_id, limit: 1 })` call shape — no extra MCP round-trip).
90
+ 2. **Defensive gates** (any failure → silent fall-through to Step 7):
91
+ - No row returned → fall through.
92
+ - Row missing `closed_at` (orphan / still-open session) → fall through.
93
+ - `row.content` is `null` → no handoff captured at end-of-session → fall through.
94
+ - `row.content` exists but parse throws or shape mismatch (`command` field absent OR is an empty string) → fall through.
95
+ 3. **Freshness gate** — load the row as `handoff = row.content` (per CHK-111 Migration A column alias). Mark stale when ANY of:
96
+ - `(now - row.closed_at) > freshness_window_hours` (read from `.codebyplan/repo.json`, default 24 hours)
97
+ - Referenced entity in `handoff.context` has shifted. For each id present, run the matching MCP read and find the row whose `id` matches:
98
+ - `checkpoint_id` → `get_checkpoints({ repo_id })` → find entry where `entry.id === handoff.context.checkpoint_id`
99
+ - `task_id` → `get_tasks({ checkpoint_id })` if `handoff.context.checkpoint_id` is present, else `get_tasks({ repo_id, standalone: true })` → find entry where `entry.id === handoff.context.task_id`
100
+ - `round_id` → `get_rounds({ task_id: handoff.context.task_id })` → find entry where `entry.id === handoff.context.round_id`
101
+ Then compare `entry.updated_at > handoff.captured_at` → stale on any inequality.
102
+ - Entity lookup fails OR the matching `id` is not present in the returned array → stale (referenced entity gone or moved out of reach).
103
+ 4. **On stale OR any defensive gate hit**: fall through silently to Step 7 (existing `/cbp-todo` trigger).
104
+ 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.
105
+
106
+ ### Step 5.7: Commit Non-Task Files
107
+
108
+ Clean the working tree of leftover infra before the session begins. Only commit files that are **not** part of an unfinished task.
109
+
110
+ 1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
111
+ 2. Resolve **task-related files** (leave these uncommitted):
112
+ - MCP `get_current_task(repo_id)` → active task
113
+ - If active task exists: MCP `get_rounds(task_id)`, filter to rounds with status not in `completed` / `cancelled`
114
+ - Collect `files[]` from those rounds → `task_files` set
115
+ - If no active task exists, `task_files` is empty
116
+ 3. `infra_files = changed_files − task_files`
117
+ 4. **Re-run `git status --porcelain` immediately before showing the commit-prompt** (after Steps 0–5 have completed all MCP round-trips). Eliminates the race where prior-session staged files appear in the index only after MCP init's network round-trips complete. Recompute `infra_files` from the fresh listing.
118
+ 5. If `infra_files` is empty → skip. Otherwise present once:
119
+
120
+ ```
121
+ Commit these non-task files before starting session?
122
+ [list of infra_files]
123
+
124
+ Reply: yes | no | select
125
+ ```
126
+
127
+ 6. On `yes`: `git add` the listed files, then trigger `/cbp-git-commit` (it handles conventional message + commit).
128
+ On `no`: skip. On `select`: ask which subset.
129
+
130
+ Non-blocking — session start proceeds either way.
131
+
132
+ ### Step 6: Output
133
+
134
+ ```
135
+ Session active | Worktree: [worktree_id or "main"]
136
+
137
+ Previous session: [title or "none"]
138
+ Pending: [pending items from previous log, or "—"]
139
+
140
+ [⚠ Dev server not running — start via desktop app — only if applicable]
141
+ ```
142
+
143
+ ### Step 7: Auto-trigger Todo
144
+
145
+ Trigger `/cbp-todo` to determine what to work on.
146
+
147
+ ## Integration
148
+
149
+ - **Triggered by**: user invocation, `/clear` recovery
150
+ - **Reads**: `.codebyplan/repo.json`, 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` / `get_tasks` / `get_rounds` for freshness probe (Step 4.5)
151
+ - **Writes**: MCP `create_session_log` (new, possibly empty), MCP `update_session_state` (activate)
152
+ - **Spawns**: none
153
+ - **Triggers**: `/cbp-git-commit` (conditional, on user approval), `handoff.command` (on fresh handoff hit at Step 4.5), `/cbp-todo` (auto fall-through)
154
+ - **Paired with**: `/cbp-session-end`
155
+ - **Pairs with**: `.claude/rules/session-resume.md` (handoff payload shape + freshness gate contract)
@@ -0,0 +1,332 @@
1
+ ---
2
+ scope: org-shared
3
+ name: cbp-ship
4
+ description: Orchestrate runtime deployment for a checkpoint — Vercel web, EAS mobile (Expo Go dev build / TestFlight preview), Tauri desktop, npm package publish, VS Code extension, Railway backend, Supabase migrations. Detects configured surfaces, walks the user through what to deploy, executes per-surface deploy steps, verifies each landed.
5
+ effort: xhigh
6
+ ---
7
+
8
+ # Ship Command
9
+
10
+ Single orchestrator for deploying a checkpoint to every runtime it has — web (Vercel), mobile (EAS / TestFlight), desktop (Tauri), npm packages, VS Code extension, backend (Railway), database migrations (Supabase).
11
+
12
+ Step 1 of `/cbp-checkpoint-end` handles branch promotion to main via `/cbp-ship-main` (which runs `codebyplan ship`). Runtime deployment happens here, after the branch is already merged.
13
+
14
+ ## When to Use
15
+
16
+ - Auto-called by `/cbp-checkpoint-end` after branch promotion to main completes
17
+ - User-invokable directly when re-running shipment after a fix (e.g., "Vercel deploy failed, fix the env var, re-run `/cbp-ship`")
18
+ - NOT for mid-checkpoint dev iteration — local development uses `npx expo start` / `pnpm dev` etc., not this skill
19
+
20
+ ## Inputs
21
+
22
+ | Source | What's read |
23
+ | ----------------------------- | ----------------------------------------------------------------------------------------- |
24
+ | MCP `get_current_task` | Active checkpoint (for context.shipment write-back) |
25
+ | `.codebyplan/git.json` + `.codebyplan/shipment.json` | `branch_config`, `shipment` section if present (per `ship-configure`) |
26
+ | Repo scan | Detect surfaces from filesystem (vercel.json, eas.json, package.json publishConfig, etc.) |
27
+ | `checkpoint.context.shipment` | Last shipment record (timestamp, surfaces, results) |
28
+
29
+ ## Instructions
30
+
31
+ ### Step 1 — Detect applicable surfaces
32
+
33
+ Run the detection script:
34
+
35
+ ```bash
36
+ bash "${CLAUDE_SKILL_DIR}/scripts/detect-surfaces.sh"
37
+ ```
38
+
39
+ It emits JSON of the form:
40
+
41
+ ```json
42
+ {
43
+ "surfaces": [
44
+ {
45
+ "id": "vercel-web",
46
+ "app_path": "apps/web",
47
+ "configured": true,
48
+ "reason": "vercel.json + .vercel/project.json present"
49
+ },
50
+ {
51
+ "id": "expo-mobile",
52
+ "app_path": "apps/mobile",
53
+ "configured": false,
54
+ "reason": "app.json present but eas.json missing"
55
+ },
56
+ {
57
+ "id": "tauri-desktop",
58
+ "app_path": "apps/desktop",
59
+ "configured": true,
60
+ "reason": "src-tauri/ + .github/workflows/release-desktop.yml present"
61
+ },
62
+ {
63
+ "id": "npm-package",
64
+ "app_path": "packages/codebyplan-package",
65
+ "configured": true,
66
+ "reason": "publishConfig.access set"
67
+ },
68
+ {
69
+ "id": "vscode-ext",
70
+ "app_path": "apps/vscode",
71
+ "configured": false,
72
+ "reason": "package.json contributes block missing publisher"
73
+ },
74
+ {
75
+ "id": "railway-backend",
76
+ "app_path": "apps/backend",
77
+ "configured": false,
78
+ "reason": "Dockerfile missing + railway.toml absent"
79
+ },
80
+ {
81
+ "id": "supabase",
82
+ "migrations_pending": 4,
83
+ "configured": true,
84
+ "reason": "supabase/migrations/ has 4 entries newer than last shipment"
85
+ }
86
+ ]
87
+ }
88
+ ```
89
+
90
+ Each surface is one of: `configured: true` (ready to ship), `configured: false` (detected but missing setup), or absent from the array (not detected at all — e.g., a repo with no mobile app).
91
+
92
+ Surface catalog reference: [reference/surfaces.md](reference/surfaces.md).
93
+
94
+ ### Step 2 — Handle gaps for early-stage repos
95
+
96
+ For each surface with `configured: false`, present the gap to the user:
97
+
98
+ ```
99
+ [surface-id] detected at [app_path] but not configured for shipment.
100
+ Reason: [reason]
101
+
102
+ Options:
103
+ A) Configure now via /cbp-ship-configure --surface=[id]
104
+ B) Skip this surface for this checkpoint
105
+ C) Mark "not shipping yet" — record in .codebyplan/shipment.json `disabled[]` (no future prompts)
106
+ ```
107
+
108
+ Use AskUserQuestion. Skip is the safe default for first-stage repos — a Next.js app that's never been Vercel-linked shouldn't block checkpoint shipment. Choice C writes `{"disabled":["vercel-web"]}` to `.codebyplan/shipment.json` so subsequent checkpoints don't re-ask.
109
+
110
+ If ALL detected surfaces are unconfigured AND the user picks Skip/Mark for all, exit with `## No deployable surfaces configured. Branch promotion already completed; runtime deploy skipped.` Do NOT treat this as failure.
111
+
112
+ ### Step 3 — Build the shipment plan
113
+
114
+ For each surface with `configured: true`, determine the deploy variant:
115
+
116
+ | Surface | Variants |
117
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
118
+ | `vercel-web` | `production` (when shipping to PRODUCTION branch — Vercel auto-deploys), `preview` (Vercel auto-creates per-PR), `manual` (force redeploy via `vercel --prod`) |
119
+ | `expo-mobile` | `expo-go` (dev build via `npx expo start`, no shipment — informational only), `eas-internal` (EAS build + TestFlight internal group), `eas-external` (TestFlight external — review-gated, opt-in only) |
120
+ | `tauri-desktop` | `tag-and-release` (push `v*.*.*` tag, GH Actions builds + signs) — variant matters only when version bumped this checkpoint |
121
+ | `npm-package` | `publish` (only when `package.json` version bumped or release-please PR merged this checkpoint) |
122
+ | `vscode-ext` | `vsce-publish` (only when version bumped) |
123
+ | `railway-backend` | `deploy` (Railway redeploys on integration push if linked; manual `railway up` otherwise) |
124
+ | `supabase` | `push-migrations` (only when pending count > 0) — interactive, walks user through diff/review/push |
125
+
126
+ For mobile: ask the user via AskUserQuestion which variant for THIS checkpoint:
127
+
128
+ ```
129
+ Mobile shipment for this checkpoint:
130
+ A) Skip — local dev only this checkpoint
131
+ B) EAS build + TestFlight internal (preview to internal testers)
132
+ C) EAS build + TestFlight external (review-gated, public-facing beta)
133
+ ```
134
+
135
+ For all other surfaces, default to the variant that matches the branch the checkpoint just shipped to (`production` for main, `preview` for staging/integration). Don't ask unless the inferred variant is ambiguous (e.g., mobile, or version-gated surfaces where no version bump happened).
136
+
137
+ ### Step 4 — Confirm the shipment plan
138
+
139
+ Present the plan in one block, ask for confirmation:
140
+
141
+ ```
142
+ ## Shipment Plan — Checkpoint CHK-NNN [title]
143
+
144
+ Will deploy:
145
+ - vercel-web (apps/web) → production (auto-deploy on main merge)
146
+ - expo-mobile (apps/mobile) → eas-internal (TestFlight internal group)
147
+ - supabase → push 4 pending migrations (interactive review)
148
+
149
+ Will skip:
150
+ - tauri-desktop → no version bump this checkpoint
151
+ - npm-package → no version bump this checkpoint
152
+ - vscode-ext → not configured (run /cbp-ship-configure when ready)
153
+
154
+ Confirm shipment? [yes / change / abort]
155
+ ```
156
+
157
+ Use AskUserQuestion. On `change`, re-enter Step 3 with prior answers as defaults. On `abort`, write `checkpoint.context.shipment.aborted_at` and stop — caller (`/cbp-checkpoint-end`) treats abort as "do not call `/cbp-checkpoint-complete`."
158
+
159
+ ### Step 5 — Execute per-surface deploys
160
+
161
+ For each confirmed surface, load the surface reference file and execute its deploy procedure:
162
+
163
+ | Surface | Reference |
164
+ | ----------------- | ------------------------------------------------------------------ |
165
+ | `vercel-web` | [reference/surface-vercel.md](reference/surface-vercel.md) |
166
+ | `expo-mobile` | [reference/surface-expo-eas.md](reference/surface-expo-eas.md) |
167
+ | `tauri-desktop` | [reference/surface-tauri.md](reference/surface-tauri.md) |
168
+ | `npm-package` | [reference/surface-npm.md](reference/surface-npm.md) |
169
+ | `vscode-ext` | [reference/surface-vscode-ext.md](reference/surface-vscode-ext.md) |
170
+ | `railway-backend` | [reference/surface-railway.md](reference/surface-railway.md) |
171
+ | `supabase` | [reference/surface-supabase.md](reference/surface-supabase.md) |
172
+
173
+ Each reference file has a `## STEPS` section the orchestrator follows literally. When a step needs user input (npm OTP, TestFlight credentials, Supabase migration approval), use AskUserQuestion inline — do NOT batch user input upfront, because a user may need to abort after seeing one surface's prompt.
174
+
175
+ Run surfaces sequentially in the order: `supabase` → `vercel-web` → `railway-backend` → `expo-mobile` → `tauri-desktop` → `vscode-ext` → `npm-package`. Database migrations first (web/backend depend on schema). Mobile/desktop/extension/npm later (independent tails).
176
+
177
+ If a surface fails:
178
+
179
+ - Capture the error in `shipment_results[surface_id]`
180
+ - Continue with subsequent surfaces (don't block the whole shipment on one failure)
181
+ - Surface the failure in the final report with a clear remediation hint
182
+
183
+ EXCEPTION: `supabase` migration push failure halts the rest. Schema mismatch downstream is worse than partial shipment.
184
+
185
+ ### Step 6 — Verify each surface landed
186
+
187
+ After each surface deploys, run its verification:
188
+
189
+ ```bash
190
+ bash "${CLAUDE_SKILL_DIR}/scripts/verify-vercel.sh" "$VERCEL_DEPLOYMENT_ID"
191
+ bash "${CLAUDE_SKILL_DIR}/scripts/verify-expo-eas.sh" "$EAS_BUILD_ID"
192
+ bash "${CLAUDE_SKILL_DIR}/scripts/verify-railway.sh" "$RAILWAY_PROJECT_ID"
193
+ bash "${CLAUDE_SKILL_DIR}/scripts/verify-supabase.sh" "$MIGRATION_VERSION"
194
+ ```
195
+
196
+ Verification timeouts are conservative (Vercel: 5min, EAS: 30min, TestFlight processing: 15min). On timeout, mark `verification_pending` (not failure) — the deploy may still complete async.
197
+
198
+ ### Step 7 — Persist shipment record
199
+
200
+ Write to `checkpoint.context.shipment` via MCP `update_checkpoint`:
201
+
202
+ ```json
203
+ {
204
+ "shipment": {
205
+ "timestamp": "2026-04-29T14:32:00Z",
206
+ "surfaces": [
207
+ {
208
+ "id": "vercel-web",
209
+ "variant": "production",
210
+ "status": "verified",
211
+ "url": "https://codebyplan.com",
212
+ "deployment_id": "dpl_xyz"
213
+ },
214
+ {
215
+ "id": "expo-mobile",
216
+ "variant": "eas-internal",
217
+ "status": "verified",
218
+ "build_id": "abc123",
219
+ "testflight_group": "internal"
220
+ },
221
+ {
222
+ "id": "supabase",
223
+ "variant": "push-migrations",
224
+ "status": "verified",
225
+ "migrations_applied": [
226
+ "0083_add_x",
227
+ "0084_index_y",
228
+ "0085_rls_z",
229
+ "0086_view_w"
230
+ ]
231
+ }
232
+ ],
233
+ "skipped": [
234
+ { "id": "tauri-desktop", "reason": "no version bump" },
235
+ { "id": "vscode-ext", "reason": "not configured" }
236
+ ],
237
+ "aborted_at": null
238
+ }
239
+ }
240
+ ```
241
+
242
+ ### Step 8 — Report
243
+
244
+ ```
245
+ ## Shipment Complete — CHK-NNN
246
+
247
+ | Surface | Variant | Status | URL/ID |
248
+ |---|---|---|---|
249
+ | vercel-web | production | ✓ verified | https://codebyplan.com (dpl_xyz) |
250
+ | expo-mobile | eas-internal | ✓ verified | TestFlight build #42 |
251
+ | supabase | push-migrations | ✓ verified | 4 migrations applied |
252
+ | tauri-desktop | — | ⊘ skipped | no version bump |
253
+ | vscode-ext | — | ⊘ skipped | not configured |
254
+
255
+ All shipments succeeded. Returning control to /cbp-checkpoint-end.
256
+ ```
257
+
258
+ If any surface failed, the report leads with the failures and offers re-run paths:
259
+
260
+ ```
261
+ ## Shipment Partial — CHK-NNN
262
+
263
+ ✓ vercel-web (production) → https://codebyplan.com
264
+ ✗ expo-mobile (eas-internal) → BUILD FAILED: missing APPLE_TEAM_ID
265
+ Fix: /cbp-ship-configure --surface=expo-mobile, then re-run /cbp-ship
266
+ ⊘ tauri-desktop → skipped (no version bump)
267
+
268
+ Checkpoint shipment is incomplete. /cbp-checkpoint-end will hold; resolve and re-run.
269
+ ```
270
+
271
+ ## Shipment Manifest in `.codebyplan/shipment.json` (optional)
272
+
273
+ Repos can override default detection by adding entries to `.codebyplan/shipment.json`:
274
+
275
+ ```json
276
+ {
277
+ "disabled": ["vscode-ext"],
278
+ "surfaces": {
279
+ "vercel-web": { "project_id": "prj_abc", "team_id": "team_xyz" },
280
+ "railway-backend": {
281
+ "project_id": "rl_123",
282
+ "service_id": "svc_456",
283
+ "platform": "railway"
284
+ },
285
+ "expo-mobile": {
286
+ "eas_project_id": "ea_789",
287
+ "default_testflight_group": "internal"
288
+ },
289
+ "supabase": { "project_ref": "abcdefgh", "skip_seed": true }
290
+ }
291
+ }
292
+ ```
293
+
294
+ When present, this overrides scan results. `ship-configure` writes here.
295
+
296
+ ## Key Rules
297
+
298
+ - **Branch promotion happens BEFORE this skill** — `/cbp-checkpoint-end` calls `/cbp-ship-main` first (which runs `codebyplan ship`); this skill handles runtime deployment only, never branch promotion
299
+ - **Sequential, not parallel** — surfaces deploy in defined order; supabase first
300
+ - **One verification per surface** — never claim shipment without running the verify script
301
+ - **AskUserQuestion inline, not batched** — user can abort mid-shipment
302
+ - **Skip ≠ fail** — unconfigured surfaces are normal for early-stage repos; never block on them
303
+ - **No mid-checkpoint invocation for dev builds** — local dev uses `npx expo start` / `pnpm dev`; this skill is end-of-checkpoint only
304
+ - **Credentials never live in `.claude/`** — Apple keys, npm tokens, supabase access tokens stay in CLI session / keychain / GH secrets; this skill checks they're reachable, never stores them
305
+ - **Read all platform names from config** — never hardcode "production"/"main"/"development"
306
+
307
+ ## Error Recovery
308
+
309
+ | Failure | Action |
310
+ | ----------------------------- | --------------------------------------------------------------------------- |
311
+ | Vercel deploy timeout | Mark `verification_pending`, continue — Vercel async-deploys |
312
+ | EAS build failed (credential) | Stop mobile surface, surface error, continue other surfaces |
313
+ | Supabase migration error | HALT shipment — schema mismatch is worse than partial deploy |
314
+ | npm publish 2FA reject | Stop npm surface, ask user to re-run with fresh OTP |
315
+ | Railway deploy failed | Continue, mark failed — backend can be re-deployed independently |
316
+ | All surfaces failed | Write `shipment.aborted_at`, return failure to `/cbp-checkpoint-end` |
317
+
318
+ ## Additional resources
319
+
320
+ - Surface catalog: [reference/surfaces.md](reference/surfaces.md)
321
+ - Versioning rules: [reference/versioning.md](reference/versioning.md)
322
+ - Pre-flight checklist: [reference/preflight-checklist.md](reference/preflight-checklist.md)
323
+ - Configure setup: `/cbp-ship-configure`
324
+ - Detection script: [scripts/detect-surfaces.sh](scripts/detect-surfaces.sh)
325
+
326
+ ## Integration
327
+
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`, `.codebyplan/git.json` + `.codebyplan/shipment.json` (`branch_config` + `shipment`), filesystem scan
330
+ - **Writes**: MCP `update_checkpoint` (context.shipment)
331
+ - **Calls**: per-surface deploy via reference files (vercel CLI, eas CLI, supabase CLI, npm, vsce, railway CLI, gh release)
332
+ - **Triggers**: returns control to caller — does NOT auto-trigger `/cbp-checkpoint-complete` (that's the caller's job)