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,252 @@
1
+ # Monorepo Publishing — pnpm Workspaces
2
+
3
+ Publishing one or more packages from a pnpm workspace. Workspace layout, `pnpm publish` vs `npm publish`, per-package `publishConfig`, version-management tools (changesets vs release-please), public/private separation, pre-publish gates.
4
+
5
+ ## Workspace Layout
6
+
7
+ A typical pnpm monorepo with mixed published and internal packages:
8
+
9
+ ```
10
+ repo/
11
+ ├── pnpm-workspace.yaml
12
+ ├── package.json # private: true; root tooling only
13
+ ├── packages/
14
+ │ ├── published/
15
+ │ │ ├── cli/ # @codebyplan/cli — published
16
+ │ │ ├── design-tokens/
17
+ │ │ └── auth/
18
+ │ └── internal/
19
+ │ ├── eslint-config/ # @codebyplan/eslint-config — private
20
+ │ └── tsconfig/
21
+ └── apps/
22
+ ├── web/ # not published
23
+ └── backend/
24
+ ```
25
+
26
+ `pnpm-workspace.yaml`:
27
+
28
+ ```yaml
29
+ packages:
30
+ - "packages/*/*"
31
+ - "apps/*"
32
+ ```
33
+
34
+ `packages/published/*` vs `packages/internal/*` is **organisational**. What keeps internal packages off the registry is `"private": true` in their `package.json` — pnpm refuses to publish private packages and skips them silently in `pnpm -r publish`.
35
+
36
+ ## Root `package.json`
37
+
38
+ Always private at the root — never accidentally publish the workspace meta-package:
39
+
40
+ ```json
41
+ {
42
+ "name": "codebyplan-monorepo",
43
+ "private": true,
44
+ "scripts": {
45
+ "build": "turbo run build",
46
+ "test": "turbo run test",
47
+ "lint:packages": "turbo run lint:package",
48
+ "release": "changeset publish"
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## Per-Package `package.json`
54
+
55
+ A published workspace package needs `publishConfig`:
56
+
57
+ ```json
58
+ {
59
+ "name": "@codebyplan/cli",
60
+ "version": "1.4.2",
61
+ "type": "module",
62
+ "exports": {
63
+ ".": {
64
+ "types": "./dist/index.d.ts",
65
+ "default": "./dist/index.js"
66
+ },
67
+ "./package.json": "./package.json"
68
+ },
69
+ "bin": { "codebyplan": "./dist/cli.js" },
70
+ "files": ["dist", "README.md"],
71
+ "engines": { "node": ">=20" },
72
+ "publishConfig": {
73
+ "access": "public",
74
+ "provenance": true
75
+ },
76
+ "repository": {
77
+ "type": "git",
78
+ "url": "git+https://github.com/codebyplan/codebyplan.git",
79
+ "directory": "packages/published/cli"
80
+ }
81
+ }
82
+ ```
83
+
84
+ Notes:
85
+
86
+ - `repository.directory` tells the registry which subfolder this package lives in. Required for provenance attestations to validate.
87
+ - `publishConfig.access: "public"` is required for scoped packages (`@codebyplan/*`). Without it the first publish fails with `402 Payment Required`.
88
+ - `publishConfig.provenance: true` is the package.json equivalent of `--provenance` on the CLI.
89
+
90
+ An internal package just sets `"private": true`:
91
+
92
+ ```json
93
+ {
94
+ "name": "@codebyplan/eslint-config",
95
+ "version": "0.0.0",
96
+ "private": true,
97
+ "main": "./index.js"
98
+ }
99
+ ```
100
+
101
+ ## `pnpm publish` vs `npm publish`
102
+
103
+ | Capability | `pnpm publish` | `npm publish` |
104
+ |------------|----------------|----------------|
105
+ | Recursive (`-r`) — publish all changed packages | Yes | No |
106
+ | `--filter` to scope to a subset | Yes | No |
107
+ | Auto-includes workspace root `LICENSE` | Yes | No |
108
+ | Rewrites `workspace:*` deps to actual versions in tarball | Yes — automatic | No |
109
+ | `--no-git-checks` | Yes | No |
110
+ | OIDC trusted publishing | Yes (npm CLI underneath) | Yes |
111
+
112
+ For a pnpm monorepo, **always use `pnpm publish`** — `npm publish` will leak `workspace:*` protocol strings into the published tarball and consumers will get install errors.
113
+
114
+ `pnpm publish -r` only publishes packages whose `version` is not already on the registry — safe to run repeatedly.
115
+
116
+ ## Version Management — Changesets vs release-please
117
+
118
+ Two dominant tools. Both work with pnpm + GitHub Actions OIDC.
119
+
120
+ ### Changesets
121
+
122
+ Maintainer-friendly — every PR adds a `.changeset/*.md` file declaring intent:
123
+
124
+ ```
125
+ .changeset/funky-tigers-dance.md
126
+ ---
127
+ "@codebyplan/cli": minor
128
+ "@codebyplan/auth": patch
129
+ ---
130
+
131
+ Added --provenance flag to publish command. Auth payload now includes scope.
132
+ ```
133
+
134
+ Workflow:
135
+
136
+ 1. `pnpm changeset` while authoring a PR. Pick affected packages and bump types.
137
+ 2. PR merges to main. Changesets GitHub Action opens (or updates) a "Version Packages" PR that consumes pending changesets, bumps versions, regenerates CHANGELOGs.
138
+ 3. Merging the Version Packages PR triggers `pnpm changeset publish` → calls `pnpm publish -r` for every bumped package.
139
+
140
+ `.changeset/config.json` essentials:
141
+
142
+ ```json
143
+ {
144
+ "changelog": "@changesets/cli/changelog",
145
+ "commit": false,
146
+ "fixed": [],
147
+ "linked": [],
148
+ "access": "public",
149
+ "baseBranch": "main",
150
+ "updateInternalDependencies": "patch",
151
+ "ignore": ["@codebyplan/web", "@codebyplan/backend"]
152
+ }
153
+ ```
154
+
155
+ `ignore` excludes apps that are deployed but never published.
156
+
157
+ Strengths: explicit intent per change; supports linked/fixed package groups; rich CHANGELOG output. Weaknesses: every PR must remember to add a changeset (the bot enforces this).
158
+
159
+ ### release-please
160
+
161
+ Conventional-commit-driven — version is inferred from commit messages (`feat:` → minor, `fix:` → patch, `feat!:` or `BREAKING CHANGE:` → major):
162
+
163
+ 1. Developer writes conventional-commit messages.
164
+ 2. release-please GitHub Action watches main, opens a release PR per package summarising commits since the last tag.
165
+ 3. Merging the release PR creates a git tag, GitHub release, and triggers a separate publish workflow.
166
+
167
+ `release-please-config.json`:
168
+
169
+ ```json
170
+ {
171
+ "packages": {
172
+ "packages/published/cli": { "release-type": "node" },
173
+ "packages/published/auth": { "release-type": "node" }
174
+ },
175
+ "plugins": ["node-workspace"]
176
+ }
177
+ ```
178
+
179
+ The `node-workspace` plugin keeps `workspace:*` deps in sync across the bump.
180
+
181
+ Strengths: zero per-PR ceremony when commit hygiene is enforced. Weaknesses: monorepo config is more involved; granular bump control is harder.
182
+
183
+ ### Picking one
184
+
185
+ - Conventional commits enforced → release-please.
186
+ - Want explicit per-PR intent and rich CHANGELOGs → Changesets.
187
+ - OSS / mixed contributors → Changesets (the bot reminds people).
188
+
189
+ CodeByPlan uses Changesets for `packages/published/*`.
190
+
191
+ ## Pre-Publish Gates
192
+
193
+ Run these in CI before `pnpm publish -r`:
194
+
195
+ | # | Gate | Command |
196
+ |---|------|---------|
197
+ | 1 | Build | `pnpm -r --filter "./packages/published/*" build` |
198
+ | 2 | Test | `pnpm -r --filter "./packages/published/*" test` |
199
+ | 3 | publint | `pnpm -r --filter "./packages/published/*" exec publint` |
200
+ | 4 | attw | `pnpm -r --filter "./packages/published/*" exec attw --pack .` |
201
+ | 5 | Dry-run pack | `pnpm -r --filter "./packages/published/*" publish --dry-run` |
202
+
203
+ [publint](https://publint.dev) catches missing `exports`, broken `main` pointers, type-definition exclusion, ESM/CJS misalignment. [Are The Types Wrong](https://arethetypeswrong.github.io/) validates that the published tarball resolves correctly under both CJS and ESM consumers across conditional-export combinations.
204
+
205
+ The dry-run output lists every file that would be in the tarball plus total size. Compare against `files` in `package.json` — anything outside `files` means the glob is wrong (or `.npmignore` is interfering).
206
+
207
+ `pnpm publish -r` skips already-published versions automatically, but for clarity:
208
+
209
+ ```bash
210
+ pnpm -r --filter "./packages/published/*" exec sh -c \
211
+ 'npm view "$npm_package_name@$npm_package_version" version 2>/dev/null \
212
+ && echo "ALREADY PUBLISHED" && exit 1 || true'
213
+ ```
214
+
215
+ Wire gates 3-4 as a turbo task in each package's `package.json`:
216
+
217
+ ```json
218
+ {
219
+ "scripts": {
220
+ "lint:package": "publint && attw --pack ."
221
+ }
222
+ }
223
+ ```
224
+
225
+ Then in CI before publish: `pnpm turbo run lint:package`.
226
+
227
+ ## Public / Private Separation Recap
228
+
229
+ | Layer | Mechanism | Purpose |
230
+ |-------|-----------|---------|
231
+ | Folder convention | `packages/published/*` vs `packages/internal/*` | Human signal |
232
+ | `private: true` | `package.json` per internal package | Hard block — pnpm refuses to publish |
233
+ | Changesets `ignore` | `.changeset/config.json` | Keeps deployed apps off the version PR |
234
+ | Workspace dep protocol | `"@codebyplan/foo": "workspace:*"` | Internal deps stay internal; pnpm rewrites at publish time |
235
+
236
+ When an internal package is published by mistake:
237
+
238
+ 1. `npm unpublish @scope/pkg@x.y.z` within 72 hours, OR
239
+ 2. `npm deprecate @scope/pkg@"<= x.y.z" "Internal package — do not use"` after that.
240
+
241
+ Then add `"private": true` and ship.
242
+
243
+ ## Sources
244
+
245
+ - [pnpm — publish](https://pnpm.io/cli/publish)
246
+ - [pnpm — workspaces](https://pnpm.io/workspaces)
247
+ - [npm Docs — package.json](https://docs.npmjs.com/cli/v10/configuring-npm/package-json)
248
+ - [Changesets](https://github.com/changesets/changesets)
249
+ - [release-please](https://github.com/googleapis/release-please)
250
+ - [publint](https://publint.dev/)
251
+ - [Are The Types Wrong](https://arethetypeswrong.github.io/)
252
+ - [npm CLI source](https://github.com/npm/cli)
@@ -0,0 +1,157 @@
1
+ # npm OIDC Trusted Publishing
2
+
3
+ Modern publish flow: no NPM_TOKEN, no leak risk. npm trusts a short-lived OIDC token issued by your CI provider. Provenance attestations are generated automatically and recorded in a public transparency ledger (Sigstore).
4
+
5
+ This is the **default publish path for `/cbp-ship`** when the npm-package surface is in play — it's the publish path the orchestrator should reach for first.
6
+
7
+ ## How It Works
8
+
9
+ 1. CI job starts. The CI provider (GitHub Actions, GitLab CI, CircleCI) mints a short-lived OIDC ID token signed with its public key.
10
+ 2. `npm publish` reads the OIDC token from the runner and exchanges it with the npm registry for a one-shot publish credential.
11
+ 3. npm validates the OIDC token's claims — `repository`, `workflow`, `ref`, `aud` — against the trusted-publisher rule registered for the package.
12
+ 4. If the claims match, the publish is accepted. If not, the publish is rejected with `403`.
13
+ 5. (GitHub Actions / GitLab only) npm automatically generates a Sigstore provenance attestation linking the published tarball to the exact commit, workflow file, and runner image that built it. The attestation is logged to the [Rekor transparency ledger](https://search.sigstore.dev/).
14
+
15
+ The OIDC token's lifetime is measured in minutes; it is bound to the workflow run; it cannot be replayed. There is nothing for an attacker to exfiltrate from the runner that survives the job.
16
+
17
+ ## Supported Providers
18
+
19
+ | Provider | OIDC | Auto-provenance |
20
+ |----------|------|-----------------|
21
+ | GitHub Actions (GitHub-hosted runners) | Yes | Yes |
22
+ | GitLab CI/CD (GitLab.com shared runners) | Yes | Yes |
23
+ | CircleCI cloud | Yes | No (must pass `--provenance` manually with extra setup) |
24
+ | Self-hosted runners (any provider) | Not supported | Not supported |
25
+
26
+ Self-hosted runners cannot use trusted publishing today — the npm registry does not yet validate signing certificates from non-cloud OIDC issuers.
27
+
28
+ ## Setup — GitHub Actions
29
+
30
+ ### Step 1 — Register the trusted publisher on npmjs.com
31
+
32
+ 1. Sign in at https://www.npmjs.com.
33
+ 2. Navigate to your package: `npmjs.com/package/<your-pkg>`.
34
+ 3. Settings → **Trusted Publishers** → **Add publisher**.
35
+ 4. Select **GitHub Actions**, then fill in:
36
+ - **Organization or user**: e.g. `codebyplan`
37
+ - **Repository**: e.g. `codebyplan`
38
+ - **Workflow filename**: e.g. `release.yml` (just the filename, not the full path)
39
+ - **Environment** (optional): e.g. `production` — restricts to runs scoped to a GitHub Actions environment
40
+
41
+ If the package does not yet exist on the registry, you must publish it once with a classic token before you can register a trusted publisher (npm requires the package to exist to attach a trust rule).
42
+
43
+ ### Step 2 — Update the workflow
44
+
45
+ Add `id-token: write` to the job's permissions and use a recent npm CLI (≥9.5.0; npm 10+ is recommended).
46
+
47
+ ```yaml
48
+ name: Release
49
+
50
+ on:
51
+ push:
52
+ tags:
53
+ - "v*"
54
+
55
+ jobs:
56
+ publish:
57
+ runs-on: ubuntu-latest
58
+
59
+ permissions:
60
+ contents: read # checkout
61
+ id-token: write # OIDC — required for trusted publishing
62
+ attestations: write # required for provenance attestations
63
+
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+
67
+ - uses: actions/setup-node@v4
68
+ with:
69
+ node-version: "20"
70
+ registry-url: "https://registry.npmjs.org"
71
+
72
+ - uses: pnpm/action-setup@v4
73
+ with:
74
+ version: 10
75
+
76
+ - run: pnpm install --frozen-lockfile
77
+
78
+ - run: pnpm build
79
+
80
+ - run: pnpm test
81
+
82
+ - name: Verify publish (dry run)
83
+ run: pnpm publish --dry-run --access public
84
+
85
+ - name: Lint package shape
86
+ run: |
87
+ pnpm dlx publint
88
+ pnpm dlx @arethetypeswrong/cli --pack
89
+
90
+ - name: Publish to npm
91
+ run: pnpm publish --access public --provenance --no-git-checks
92
+ ```
93
+
94
+ Notes:
95
+
96
+ - **No `NODE_AUTH_TOKEN` env var.** That's the entire point — there is no token to leak. The `setup-node` action wires up `.npmrc` to the registry URL; OIDC handshake happens inside `npm publish`.
97
+ - `--provenance` is **automatic** on GitHub Actions OIDC publishes (npm enables it implicitly), but passing the flag is harmless and makes intent explicit. `publishConfig.provenance: true` in `package.json` is the third equivalent.
98
+ - `--no-git-checks` (pnpm-only) bypasses the "current branch must be the publish branch, working tree must be clean" check. Safe in CI where the runner has a fresh clone at a tag.
99
+
100
+ ## Provenance Attestations
101
+
102
+ A provenance attestation is a JSON document signed by Sigstore that describes:
103
+
104
+ - The source repository URL and the exact commit SHA that was built.
105
+ - The workflow file path and the run ID.
106
+ - The builder identity (e.g. `https://github.com/actions/runner`).
107
+ - The npm package name, version, and tarball SHA.
108
+
109
+ After publish, the npm registry shows a "Provenance" badge on the package page linking to the Sigstore record.
110
+
111
+ ### Verifying attestations as a consumer
112
+
113
+ ```bash
114
+ npm audit signatures
115
+ ```
116
+
117
+ This walks every dependency in the current project, checks the registry signature on each tarball, and validates any provenance attestations. A failure means either the package was tampered with after publish or its signing identity changed unexpectedly.
118
+
119
+ For a single package without installing it:
120
+
121
+ ```bash
122
+ npm view <pkg> --json | jq '.dist.attestations'
123
+ ```
124
+
125
+ Returns the URL of the attestation bundle on the registry; the bundle is a Sigstore-format JSON that can be verified with `cosign` or the `sigstore-js` library.
126
+
127
+ ## Comparison vs Classic NPM_TOKEN
128
+
129
+ | Aspect | Classic NPM_TOKEN | OIDC Trusted Publishing |
130
+ |--------|-------------------|--------------------------|
131
+ | Secret stored in CI | Yes — long-lived token | No |
132
+ | Rotation burden | Manual; forgotten tokens are common | None — every publish mints a fresh credential |
133
+ | Leak blast radius | Token works from anywhere until revoked | Credential expires in minutes; bound to one workflow run |
134
+ | Provenance | Manual `--provenance` + extra setup | Automatic on GitHub Actions / GitLab |
135
+ | Setup complexity | Generate token, paste into CI secrets | One-time npm web UI registration |
136
+ | Works on self-hosted runners | Yes | No (today) |
137
+ | Works locally | Yes | No (no OIDC issuer) |
138
+
139
+ Classic tokens still have a place: local release machines, self-hosted runners, providers npm doesn't trust yet. For everything else, OIDC is the default in 2026.
140
+
141
+ ## Failure Modes
142
+
143
+ | Symptom | Cause | Fix |
144
+ |---------|-------|-----|
145
+ | `403 Forbidden — OIDC publish requires id-token: write` | Workflow missing the permission | Add `permissions.id-token: write` to the job |
146
+ | `403 — trusted publisher mismatch` | Workflow filename, repo, or org doesn't match the rule | Re-check the trusted-publisher rule on npmjs.com matches `${{ github.repository }}` and `${{ github.workflow_ref }}` exactly |
147
+ | `Provenance generation failed: repository field mismatch` | `package.json` `repository.url` doesn't match the GitHub repo URL | Set `"repository": { "type": "git", "url": "git+https://github.com/<org>/<repo>.git" }` (case-sensitive) |
148
+ | Attestations missing on the registry page | Used CircleCI without manual provenance setup | Either accept (CircleCI limitation) or migrate to GitHub Actions / GitLab |
149
+ | `OIDC token unavailable` from a self-hosted runner | Trusted publishing not supported there | Fall back to a granular token, or move the publish job to a GitHub-hosted runner |
150
+
151
+ ## Sources
152
+
153
+ - [npm Docs — Trusted publishers](https://docs.npmjs.com/trusted-publishers)
154
+ - [npm Docs — Generating provenance statements](https://docs.npmjs.com/generating-provenance-statements)
155
+ - [npm Docs — npm audit signatures](https://docs.npmjs.com/cli/v10/commands/npm-audit)
156
+ - [Sigstore](https://www.sigstore.dev/) — signing infrastructure
157
+ - [npm CLI source](https://github.com/npm/cli)
@@ -0,0 +1,171 @@
1
+ # npm Publish — Overview
2
+
3
+ Reference for the `/cbp-ship` orchestrator's `npm-package` surface. Covers what `npm publish` does, registry types, 2FA tiers, package metadata that affects publish output, and `latest` dist-tag semantics.
4
+
5
+ ## What `npm publish` Does
6
+
7
+ `npm publish` packs the current package into a tarball and uploads it to a registry, registering the version under the package name. Once a version is published it is **immutable** — you cannot republish the same `name@version` (you can only `npm unpublish` within 72 hours, and only if no other public package depends on it).
8
+
9
+ Pack rules:
10
+
11
+ 1. CLI computes the file list from (in order): `files` field in `package.json`, `.npmignore`, `.gitignore`. Always-included: `package.json`, `README*`, `LICENSE*`, the file at `main`/`bin`/`exports`. Always-excluded: `node_modules`, `.git`, `.npmrc`, `package-lock.json`.
12
+ 2. CLI runs lifecycle scripts: `prepublishOnly` → `prepack` → tarball write → `postpack` → `publish` → `postpublish`.
13
+ 3. Tarball uploaded to registry with auth (token or OIDC); registry assigns the `latest` dist-tag unless `--tag <name>` overrides.
14
+
15
+ `npm publish --dry-run` runs all the above except the upload — use it to preview the file list and lifecycle execution.
16
+
17
+ ## Registry Types
18
+
19
+ | Registry | Purpose | URL |
20
+ |----------|---------|-----|
21
+ | Public registry | Default; what `npm install <pkg>` hits | `https://registry.npmjs.org` |
22
+ | GitHub Packages | npm packages scoped to a GitHub org | `https://npm.pkg.github.com` |
23
+ | Private registry | Verdaccio, Nexus, JFrog Artifactory, Bytesafe, Cloudsmith | self-hosted or vendor URL |
24
+
25
+ Registry selection comes from (highest precedence first):
26
+
27
+ 1. `publishConfig.registry` in `package.json`
28
+ 2. `--registry <url>` on the CLI
29
+ 3. `npm_config_registry` env var
30
+ 4. `registry=` line in `.npmrc` (project, then user, then global)
31
+ 5. Default — `https://registry.npmjs.org`
32
+
33
+ Scoped packages (`@scope/name`) can route by scope: `@cbp-registry=https://npm.pkg.github.com` in `.npmrc` sends only that scope to GH Packages.
34
+
35
+ ## 2FA Tiers
36
+
37
+ npm offers two 2FA modes (set with `npm profile enable-2fa <mode>`):
38
+
39
+ | Mode | Covers | Use case |
40
+ |------|--------|----------|
41
+ | `auth-only` | Login, profile changes | Convenience — publishes work with token alone |
42
+ | `auth-and-writes` | Login + every publish, `dist-tag`, `unpublish`, `access` change | Hardened — publish requires fresh OTP |
43
+
44
+ Publishing requires **one** of:
45
+
46
+ - 2FA enabled on the account (any mode), OR
47
+ - A **granular access token** with "bypass 2FA" enabled (legacy automation tokens are deprecated; granular is the modern equivalent).
48
+
49
+ For CI flows the modern recommendation is **OIDC trusted publishing** (no token at all) — see [npm-publish-oidc-trusted.md](./npm-publish-oidc-trusted.md). Granular tokens with bypass-2FA remain valid for non-CI release machines.
50
+
51
+ ## Package Metadata That Matters at Publish Time
52
+
53
+ ### `exports`
54
+
55
+ Modern entry-point map. Replaces `main` for resolvers that honour it (Node ≥12.20, all modern bundlers). Conditional exports let you ship CJS + ESM + types from one package:
56
+
57
+ ```json
58
+ {
59
+ "exports": {
60
+ ".": {
61
+ "types": "./dist/index.d.ts",
62
+ "import": "./dist/index.mjs",
63
+ "require": "./dist/index.cjs"
64
+ },
65
+ "./package.json": "./package.json"
66
+ }
67
+ }
68
+ ```
69
+
70
+ Always export `./package.json` — toolchains (`publint`, `attw`) and some bundlers expect it. If `exports` is set, `main` becomes a fallback only for legacy resolvers.
71
+
72
+ ### `files`
73
+
74
+ Allowlist of paths to include in the tarball. Prefer `files` over `.npmignore` — allowlists fail closed (forgetting to ignore a build artefact never leaks a secret):
75
+
76
+ ```json
77
+ {
78
+ "files": ["dist", "README.md", "LICENSE"]
79
+ }
80
+ ```
81
+
82
+ `package.json`, `README*`, `LICENSE*` are always included regardless. `test/`, `__tests__/`, `*.test.*` are excluded automatically.
83
+
84
+ ### `publishConfig`
85
+
86
+ Per-package override of registry config, applied only at publish time. Common keys:
87
+
88
+ ```json
89
+ {
90
+ "publishConfig": {
91
+ "access": "public",
92
+ "registry": "https://registry.npmjs.org",
93
+ "tag": "next",
94
+ "provenance": true
95
+ }
96
+ }
97
+ ```
98
+
99
+ - `access: "public"` is required when first publishing a scoped package (`@scope/name`); otherwise registry assumes private and rejects free-tier accounts.
100
+ - `tag: "next"` (or any non-`latest`) keeps the version off the default install pointer — useful for prereleases.
101
+ - `provenance: true` is the package.json equivalent of `--provenance` (see [npm-publish-oidc-trusted.md](./npm-publish-oidc-trusted.md)).
102
+
103
+ ### `engines`
104
+
105
+ Declares Node/npm version compatibility:
106
+
107
+ ```json
108
+ {
109
+ "engines": { "node": ">=20.0.0", "pnpm": ">=10.0.0" }
110
+ }
111
+ ```
112
+
113
+ By default `engines` is advisory (warns, does not fail). `engine-strict=true` in `.npmrc` makes it a hard error on install.
114
+
115
+ ### `bin`
116
+
117
+ Maps CLI command names to file paths. The published tarball will mark these executable; the install will create symlinks in `node_modules/.bin`:
118
+
119
+ ```json
120
+ {
121
+ "bin": { "codebyplan": "./dist/cli.js" }
122
+ }
123
+ ```
124
+
125
+ The target file must have a shebang (`#!/usr/bin/env node`).
126
+
127
+ ## `latest` Dist-Tag Semantics
128
+
129
+ When a user runs `npm install <pkg>` without a version specifier, npm resolves to whatever the `latest` dist-tag points at. Implications:
130
+
131
+ - The first publish of a package always becomes `latest`.
132
+ - Subsequent publishes become `latest` **unless** `--tag <name>` is passed (or `publishConfig.tag` is set to something other than `latest`).
133
+ - Publishing a hotfix to an older major (e.g. `1.5.3` after `2.0.0` is already `latest`) will overwrite `latest` to point back at `1.5.3` — almost always a mistake. Use `npm publish --tag legacy` for hotfixes on old majors, then `npm dist-tag add <pkg>@1.5.3 v1-legacy` to give consumers an explicit pointer.
134
+
135
+ Common dist-tag conventions:
136
+
137
+ | Tag | Convention |
138
+ |-----|-----------|
139
+ | `latest` | Default install target — stable releases only |
140
+ | `next` | Upcoming version (often release candidates) |
141
+ | `beta` / `alpha` | Prereleases — opt-in via `npm install pkg@beta` |
142
+ | `canary` / `nightly` | Auto-published from main branch |
143
+
144
+ Manage tags after publish:
145
+
146
+ ```bash
147
+ npm dist-tag ls <pkg> # list all tags
148
+ npm dist-tag add <pkg>@<ver> next # promote a version to a tag
149
+ npm dist-tag rm <pkg> beta # remove a tag (does not unpublish)
150
+ ```
151
+
152
+ Tags must not parse as valid semver ranges — `v1.4` is rejected, `v1-legacy` is fine.
153
+
154
+ ## Pre-Publish Checklist
155
+
156
+ For a clean publish via `/cbp-ship`:
157
+
158
+ 1. `npm whoami` (or OIDC trust verified) — confirm auth context.
159
+ 2. `npm publish --dry-run` — review the file list; nothing surprising.
160
+ 3. `npx publint` — lint package.json shape.
161
+ 4. `npx @arethetypeswrong/cli --pack` — verify type resolution across CJS/ESM.
162
+ 5. Version bump committed and tagged in git (release-please or changesets handles this).
163
+ 6. CI green on the commit being published.
164
+
165
+ ## Sources
166
+
167
+ - [npm Docs — package.json](https://docs.npmjs.com/cli/v10/configuring-npm/package-json)
168
+ - [npm Docs — npm publish](https://docs.npmjs.com/cli/v10/commands/npm-publish)
169
+ - [npm Docs — npm dist-tag](https://docs.npmjs.com/cli/v10/commands/npm-dist-tag)
170
+ - [npm Docs — Configuring 2FA](https://docs.npmjs.com/configuring-two-factor-authentication)
171
+ - [npm CLI source](https://github.com/npm/cli)
@@ -0,0 +1,88 @@
1
+ # Pre-flight Checklist
2
+
3
+ Run before invoking `/cbp-ship`. The orchestrator's Step 1 detection runs this implicitly; this file documents what it checks and what to do when a check fails.
4
+
5
+ ## Universal pre-flight (every shipment)
6
+
7
+ | # | Check | Why | If fails |
8
+ |---|---|---|---|
9
+ | 1 | `gh auth status` succeeds | gh CLI is needed for tag push, release verification | `gh auth login` |
10
+ | 2 | Working tree is clean (no uncommitted changes) | Shipping uncommitted code = ghosts | Commit or stash; do NOT proceed |
11
+ | 3 | Current branch matches expected post-promotion branch | Caller (`/cbp-checkpoint-end`) just merged into PRODUCTION | If wrong, `git checkout` correct branch |
12
+ | 4 | `.codebyplan/` files are parseable | All config reads from per-concern files | Fix JSON; or run `npx codebyplan config` |
13
+ | 5 | Active checkpoint exists in DB | Shipment is per-checkpoint | Run `/cbp-todo` to find/create checkpoint |
14
+ | 6 | `checkpoint.context.check_results` exists | Checkpoint check must pass before shipment | Run `/cbp-checkpoint-check` first |
15
+
16
+ ## Per-surface pre-flight
17
+
18
+ The detection script (`scripts/detect-surfaces.sh`) emits `configured: false` with a `reason` when a surface fails its pre-flight. Rather than duplicating those reasons here, see each surface's `## Configured indicators` section in its reference file.
19
+
20
+ Quick reference:
21
+
22
+ | Surface | Critical pre-flight check |
23
+ |---|---|
24
+ | `vercel-web` | `vercel whoami` succeeds AND `.vercel/project.json` exists |
25
+ | `expo-mobile` | `eas whoami` succeeds AND `eas.json` parseable AND credentials valid (`eas credentials` audit) |
26
+ | `tauri-desktop` | All 9 GH secrets present in repo (`gh secret list`) |
27
+ | `npm-package` | `npm whoami` succeeds AND 2FA enabled AND local version > registry version |
28
+ | `vscode-ext` | `vsce verify-pat <publisher>` succeeds |
29
+ | `railway-backend` | `railway whoami` succeeds AND service is linked AND env vars set |
30
+ | `supabase` | `supabase projects list` succeeds AND project ref matches |
31
+
32
+ ## Recommended pre-flight when adding a new surface
33
+
34
+ If you're configuring a surface for the first time (via `/cbp-ship-configure`), run these once:
35
+
36
+ 1. **For Vercel**:
37
+ - Verify build works locally: `pnpm build`
38
+ - Verify env vars are documented: `cat .env.example`
39
+ - Verify domain DNS is healthy if using custom domain
40
+
41
+ 2. **For Expo / mobile**:
42
+ - Verify Apple Developer account is enrolled (paid)
43
+ - Verify ASC API key is generated and `.p8` file is readable
44
+ - Verify EAS project is created: `eas project:info`
45
+ - Run a development build first: `eas build --profile development --platform ios`
46
+
47
+ 3. **For Tauri desktop**:
48
+ - Generate signing key: `npx tauri signer generate -w ~/.tauri/{app}.key`
49
+ - Export Apple Developer ID cert as `.p12`
50
+ - Upload all 9 GH secrets per architecture doc
51
+ - Test the workflow on a non-production tag first (e.g., `v0.0.0-test`)
52
+
53
+ 4. **For npm package**:
54
+ - Verify `package.json` has `name`, `version`, `description`, `keywords`, `repository`, `license`, `author`
55
+ - Run `npm pack --dry-run` and verify the tarball contains the right files
56
+ - Run `pnpm publint` to catch metadata issues
57
+ - Run `pnpm attw --pack` to verify TS types resolve correctly
58
+
59
+ 5. **For VS Code extension**:
60
+ - Create a publisher account at https://aka.ms/vscode-create-publisher
61
+ - Generate PAT with "Marketplace → Manage" scope
62
+ - Run `vsce verify-pat <publisher>` — succeeds = good
63
+ - Verify `package.json` has `displayName`, `description`, `categories`, `icon` (≥128×128 PNG)
64
+
65
+ 6. **For Railway**:
66
+ - Create project: `railway init`
67
+ - Link service: `railway link`
68
+ - Add env vars: `railway variables set KEY=VALUE`
69
+ - Configure health endpoint in service code (`/health` returning 200)
70
+ - Test deploy: `railway up`
71
+
72
+ 7. **For Supabase**:
73
+ - Verify migrations directory is initialized: `ls supabase/migrations/`
74
+ - Link project: `supabase link --project-ref <ref>`
75
+ - Generate baseline migration if existing schema: `supabase db dump > supabase/migrations/0000_baseline.sql`
76
+ - Verify types path: `supabase gen types typescript --project-id <ref> > types.ts`
77
+
78
+ ## When pre-flight fails mid-shipment
79
+
80
+ If `/cbp-ship` is mid-shipment and a per-surface pre-flight fails:
81
+
82
+ 1. Mark that surface failed
83
+ 2. Continue with remaining surfaces (don't halt the whole shipment unless `supabase` failed)
84
+ 3. Surface the failure in the final report
85
+ 4. Suggest the user run `/cbp-ship-configure --surface=<id>` to fix
86
+ 5. After fix, re-run `/cbp-ship` — it picks up where it left off (verified surfaces are skipped)
87
+
88
+ The shipment record (`checkpoint.context.shipment`) tracks per-surface status, so partial re-runs are safe.