codebyplan 1.5.1 → 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.
- package/dist/cli.js +4462 -748
- package/package.json +5 -1
- package/templates/.gitkeep +0 -0
- package/templates/README.md +20 -0
- package/templates/agents/cbp-cc-executor.md +213 -0
- package/templates/agents/cbp-database-agent.md +229 -0
- package/templates/agents/cbp-improve-claude.md +245 -0
- package/templates/agents/cbp-improve-round.md +284 -0
- package/templates/agents/cbp-mechanical-edits.md +111 -0
- package/templates/agents/cbp-research.md +282 -0
- package/templates/agents/cbp-round-executor.md +604 -0
- package/templates/agents/cbp-security-agent.md +134 -0
- package/templates/agents/cbp-task-check.md +213 -0
- package/templates/agents/cbp-task-planner.md +582 -0
- package/templates/agents/cbp-test-e2e-agent.md +363 -0
- package/templates/agents/cbp-testing-qa-agent.md +400 -0
- package/templates/context/mcp-docs.md +139 -0
- package/templates/hooks/README.md +236 -0
- package/templates/hooks/cbp-auto-test-hooks.sh +44 -0
- package/templates/hooks/cbp-lint-format-on-edit.sh +159 -0
- package/templates/hooks/cbp-maestro-yaml-validate.sh +100 -0
- package/templates/hooks/cbp-mcp-migration-guard.sh +32 -0
- package/templates/hooks/cbp-mcp-round-sync.sh +79 -0
- package/templates/hooks/cbp-mcp-worktree-inject.sh +76 -0
- package/templates/hooks/cbp-notify.sh +68 -0
- package/templates/hooks/cbp-plugin-dispatch.sh +29 -0
- package/templates/hooks/cbp-pre-commit-quality-gate.sh +204 -0
- package/templates/hooks/cbp-statusline.sh +347 -0
- package/templates/hooks/cbp-subagent-statusline.sh +182 -0
- package/templates/hooks/cbp-test-coverage-gate.sh +144 -0
- package/templates/hooks/cbp-test-hooks.sh +320 -0
- package/templates/hooks/hooks.json +85 -0
- package/templates/hooks/validate-context-usage.sh +59 -0
- package/templates/hooks/validate-git-commit.sh +78 -0
- package/templates/hooks/validate-git-stash-deny.sh +32 -0
- package/templates/hooks/validate-structure-lengths.sh +57 -0
- package/templates/hooks/validate-structure-lib.sh +104 -0
- package/templates/hooks/validate-structure-patterns.sh +54 -0
- package/templates/hooks/validate-structure-scope.sh +33 -0
- package/templates/hooks/validate-structure-smoke.sh +95 -0
- package/templates/hooks/validate-structure-templates.sh +34 -0
- package/templates/hooks/validate-structure.sh +69 -0
- package/templates/rules/.gitkeep +0 -0
- package/templates/rules/README.md +47 -0
- package/templates/rules/context-file-loading.md +52 -0
- package/templates/rules/scope-vocabulary.md +64 -0
- package/templates/rules/todo-backend.md +109 -0
- package/templates/settings.project.base.json +55 -0
- package/templates/settings.user.base.json +25 -0
- package/templates/skills/cbp-build-cc-agent/SKILL.md +139 -0
- package/templates/skills/cbp-build-cc-agent/examples/read-only-reviewer.md +32 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-hooks.md +41 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-skills-preload.md +25 -0
- package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +153 -0
- package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +37 -0
- package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +18 -0
- package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +67 -0
- package/templates/skills/cbp-build-cc-agent/templates/agent.md +66 -0
- package/templates/skills/cbp-build-cc-claude-file/SKILL.md +178 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/minimal-project.md +33 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/monorepo-with-imports.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/imports.md +72 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/what-belongs.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/project-claude-md.md +48 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/user-claude-md.md +22 -0
- package/templates/skills/cbp-build-cc-memory/SKILL.md +201 -0
- package/templates/skills/cbp-build-cc-memory/examples/feedback-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/project-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/reference-memory.md +13 -0
- package/templates/skills/cbp-build-cc-memory/examples/user-memory.md +14 -0
- package/templates/skills/cbp-build-cc-memory/reference/memory-types.md +59 -0
- package/templates/skills/cbp-build-cc-memory/reference/when-to-save.md +62 -0
- package/templates/skills/cbp-build-cc-memory/templates/MEMORY-index.md +4 -0
- package/templates/skills/cbp-build-cc-memory/templates/memory-entry.md +15 -0
- package/templates/skills/cbp-build-cc-mode/SKILL.md +99 -0
- package/templates/skills/cbp-build-cc-rule/SKILL.md +176 -0
- package/templates/skills/cbp-build-cc-rule/examples/global-rule.md +19 -0
- package/templates/skills/cbp-build-cc-rule/examples/scoped-rule.md +41 -0
- package/templates/skills/cbp-build-cc-rule/reference/paths-patterns.md +48 -0
- package/templates/skills/cbp-build-cc-rule/templates/rule.md +32 -0
- package/templates/skills/cbp-build-cc-settings/SKILL.md +220 -0
- package/templates/skills/cbp-build-cc-settings/examples/hooks-config.json +64 -0
- package/templates/skills/cbp-build-cc-settings/examples/permissions-config.json +34 -0
- package/templates/skills/cbp-build-cc-settings/examples/sandbox-config.json +42 -0
- package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +104 -0
- package/templates/skills/cbp-build-cc-settings/reference/permission-rules.md +61 -0
- package/templates/skills/cbp-build-cc-settings/reference/scope-precedence.md +73 -0
- package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +166 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.json +23 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.local.json +10 -0
- package/templates/skills/cbp-build-cc-skill/SKILL.md +154 -0
- package/templates/skills/cbp-build-cc-skill/examples/dynamic-context.md +31 -0
- package/templates/skills/cbp-build-cc-skill/examples/fork-skill.md +22 -0
- package/templates/skills/cbp-build-cc-skill/examples/knowledge-skill.md +25 -0
- package/templates/skills/cbp-build-cc-skill/examples/task-skill.md +29 -0
- package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +157 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +35 -0
- package/templates/skills/cbp-build-cc-skill/reference/string-substitutions.md +60 -0
- package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +90 -0
- package/templates/skills/cbp-build-cc-skill/templates/skill.md +51 -0
- package/templates/skills/cbp-checkpoint-check/SKILL.md +156 -0
- package/templates/skills/cbp-checkpoint-complete/SKILL.md +109 -0
- package/templates/skills/cbp-checkpoint-create/SKILL.md +287 -0
- package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
- package/templates/skills/cbp-checkpoint-update/SKILL.md +115 -0
- package/templates/skills/cbp-frontend-a11y/SKILL.md +109 -0
- package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +130 -0
- package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +122 -0
- package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +154 -0
- package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +111 -0
- package/templates/skills/cbp-frontend-design/SKILL.md +145 -0
- package/templates/skills/cbp-frontend-design/reference/nextjs-scss.md +118 -0
- package/templates/skills/cbp-frontend-design/reference/rn-expo.md +101 -0
- package/templates/skills/cbp-frontend-design/reference/tauri-react.md +82 -0
- package/templates/skills/cbp-frontend-ui/SKILL.md +262 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-label-maps.md +42 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-layout-patterns.md +105 -0
- package/templates/skills/cbp-frontend-ui/reference/variant-defaults.md +149 -0
- package/templates/skills/cbp-frontend-ux/SKILL.md +181 -0
- package/templates/skills/cbp-git-branch-feat-create/SKILL.md +115 -0
- package/templates/skills/cbp-git-commit/SKILL.md +278 -0
- package/templates/skills/cbp-git-worktree-create/SKILL.md +226 -0
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +145 -0
- package/templates/skills/cbp-merge-main/SKILL.md +228 -0
- package/templates/skills/cbp-round-check/SKILL.md +104 -0
- package/templates/skills/cbp-round-end/SKILL.md +183 -0
- package/templates/skills/cbp-round-end/reference/findings-presentation.md +44 -0
- package/templates/skills/cbp-round-end/reference/inline-fallback.md +35 -0
- package/templates/skills/cbp-round-execute/SKILL.md +211 -0
- package/templates/skills/cbp-round-execute/reference/inline-fallback.md +59 -0
- package/templates/skills/cbp-round-input/SKILL.md +165 -0
- package/templates/skills/cbp-round-start/SKILL.md +222 -0
- package/templates/skills/cbp-round-update/SKILL.md +163 -0
- package/templates/skills/cbp-session-end/SKILL.md +187 -0
- package/templates/skills/cbp-session-start/SKILL.md +155 -0
- package/templates/skills/cbp-ship/SKILL.md +332 -0
- package/templates/skills/cbp-ship/reference/changesets-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/eas-cli-overview.md +60 -0
- package/templates/skills/cbp-ship/reference/gh-cli-overview.md +135 -0
- package/templates/skills/cbp-ship/reference/gh-cli-shipment-commands.md +283 -0
- package/templates/skills/cbp-ship/reference/npm-publish-monorepo.md +252 -0
- package/templates/skills/cbp-ship/reference/npm-publish-oidc-trusted.md +157 -0
- package/templates/skills/cbp-ship/reference/npm-publish-overview.md +171 -0
- package/templates/skills/cbp-ship/reference/preflight-checklist.md +88 -0
- package/templates/skills/cbp-ship/reference/railway-nestjs-deployment.md +169 -0
- package/templates/skills/cbp-ship/reference/railway-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/railway-troubleshooting.md +168 -0
- package/templates/skills/cbp-ship/reference/release-please-overview.md +99 -0
- package/templates/skills/cbp-ship/reference/surface-expo-eas.md +155 -0
- package/templates/skills/cbp-ship/reference/surface-npm.md +180 -0
- package/templates/skills/cbp-ship/reference/surface-railway.md +152 -0
- package/templates/skills/cbp-ship/reference/surface-supabase.md +178 -0
- package/templates/skills/cbp-ship/reference/surface-tauri.md +138 -0
- package/templates/skills/cbp-ship/reference/surface-vercel.md +124 -0
- package/templates/skills/cbp-ship/reference/surface-vscode-ext.md +144 -0
- package/templates/skills/cbp-ship/reference/surfaces.md +60 -0
- package/templates/skills/cbp-ship/reference/testflight-automation.md +215 -0
- package/templates/skills/cbp-ship/reference/testflight-internal-vs-external.md +69 -0
- package/templates/skills/cbp-ship/reference/testflight-overview.md +98 -0
- package/templates/skills/cbp-ship/reference/versioning.md +116 -0
- package/templates/skills/cbp-ship/scripts/detect-surfaces.sh +217 -0
- package/templates/skills/cbp-ship/scripts/verify-expo-eas.sh +35 -0
- package/templates/skills/cbp-ship/scripts/verify-npm.sh +21 -0
- package/templates/skills/cbp-ship/scripts/verify-railway.sh +41 -0
- package/templates/skills/cbp-ship/scripts/verify-supabase.sh +19 -0
- package/templates/skills/cbp-ship/scripts/verify-tauri.sh +24 -0
- package/templates/skills/cbp-ship/scripts/verify-vercel.sh +32 -0
- package/templates/skills/cbp-ship/scripts/verify-vscode-ext.sh +25 -0
- package/templates/skills/cbp-ship/templates/eas.json +66 -0
- package/templates/skills/cbp-ship/templates/railway.toml +15 -0
- package/templates/skills/cbp-ship/templates/release-please-config.json +17 -0
- package/templates/skills/cbp-ship/templates/vercel.json +19 -0
- package/templates/skills/cbp-ship/templates/vscodeignore +21 -0
- package/templates/skills/cbp-ship/templates/workflow-changesets.yml +41 -0
- package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +53 -0
- package/templates/skills/cbp-ship/templates/workflow-npm-publish.yml +36 -0
- package/templates/skills/cbp-ship/templates/workflow-release-please.yml +21 -0
- package/templates/skills/cbp-ship/templates/workflow-tauri-release.yml +69 -0
- package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +31 -0
- package/templates/skills/cbp-ship-configure/SKILL.md +296 -0
- package/templates/skills/cbp-ship-configure/reference/expo-mobile.md +204 -0
- package/templates/skills/cbp-ship-configure/reference/npm-package.md +165 -0
- package/templates/skills/cbp-ship-configure/reference/railway-backend.md +199 -0
- package/templates/skills/cbp-ship-configure/reference/supabase.md +200 -0
- package/templates/skills/cbp-ship-configure/reference/tauri-desktop.md +181 -0
- package/templates/skills/cbp-ship-configure/reference/vercel.md +117 -0
- package/templates/skills/cbp-ship-configure/reference/vscode-ext.md +155 -0
- package/templates/skills/cbp-ship-main/SKILL.md +65 -0
- package/templates/skills/cbp-supabase-branch-check/SKILL.md +337 -0
- package/templates/skills/cbp-supabase-branch-check/reference/dag-steps.md +29 -0
- package/templates/skills/cbp-supabase-migrate/SKILL.md +314 -0
- package/templates/skills/cbp-supabase-migrate/reference/advisor-triage.md +70 -0
- package/templates/skills/cbp-supabase-migrate/reference/cli-fallback.md +87 -0
- package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +58 -0
- package/templates/skills/cbp-supabase-setup/SKILL.md +239 -0
- package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +121 -0
- package/templates/skills/cbp-supabase-setup/reference/cli-fallback.md +109 -0
- package/templates/skills/cbp-task-check/SKILL.md +166 -0
- package/templates/skills/cbp-task-complete/SKILL.md +206 -0
- package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +48 -0
- package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +56 -0
- package/templates/skills/cbp-task-create/SKILL.md +167 -0
- package/templates/skills/cbp-task-start/SKILL.md +239 -0
- package/templates/skills/cbp-task-testing/SKILL.md +277 -0
- package/templates/skills/cbp-todo/SKILL.md +97 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Surface: expo-mobile
|
|
2
|
+
|
|
3
|
+
Build mobile apps via EAS and deliver via TestFlight (iOS) / Play Console internal testing (Android).
|
|
4
|
+
|
|
5
|
+
**Local development uses `npx expo start`, not this surface.** This file covers checkpoint-end shipment only.
|
|
6
|
+
|
|
7
|
+
## Detection
|
|
8
|
+
|
|
9
|
+
Signals:
|
|
10
|
+
|
|
11
|
+
- `app.json` or `app.config.{ts,js}` at repo root or `apps/mobile/`
|
|
12
|
+
- `expo` in `package.json` dependencies
|
|
13
|
+
- `eas.json` (configured) OR `app.json` with no `eas.json` (detected but not configured)
|
|
14
|
+
|
|
15
|
+
## Configured indicators
|
|
16
|
+
|
|
17
|
+
`configured: true` requires:
|
|
18
|
+
|
|
19
|
+
1. `eas.json` present with at least one build profile (`development`, `preview`, `production` are conventional)
|
|
20
|
+
2. `app.json` has `expo.slug`, `expo.name`, `expo.ios.bundleIdentifier`, `expo.android.package`
|
|
21
|
+
3. `eas-cli` installed (`npx eas --version` succeeds)
|
|
22
|
+
4. `eas whoami` returns a logged-in user
|
|
23
|
+
5. `.codebyplan/shipment.json` `.surfaces.expo-mobile` block present with `eas_project_id`
|
|
24
|
+
|
|
25
|
+
Reference: [eas-cli-overview.md](./eas-cli-overview.md) for EAS CLI commands. Library docs via DocsByPlan MCP (`resolve_library_id('expo')`).
|
|
26
|
+
|
|
27
|
+
## Variants
|
|
28
|
+
|
|
29
|
+
Mobile shipment is **always opt-in per checkpoint** — `/cbp-ship` asks the user which variant for THIS checkpoint:
|
|
30
|
+
|
|
31
|
+
| Variant | What it does | When to use |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `expo-go-only` | Marks "no shipment, dev via Expo Go only" — informational | Early development, no internal testers yet |
|
|
34
|
+
| `eas-internal` | EAS Build (preview profile) → submit to TestFlight internal group | Internal team review, fast iteration |
|
|
35
|
+
| `eas-external` | EAS Build (production profile) → TestFlight external (review-gated) | Public-facing beta, requires Apple review |
|
|
36
|
+
|
|
37
|
+
App Store production submission is **NOT yet supported** by this skill — manually via App Store Connect when ready.
|
|
38
|
+
|
|
39
|
+
## STEPS — eas-internal variant
|
|
40
|
+
|
|
41
|
+
1. **Confirm intent** (already done by orchestrator's variant prompt — skip if already confirmed)
|
|
42
|
+
|
|
43
|
+
2. **Auto-bump build numbers** (per `versioning.md`):
|
|
44
|
+
```bash
|
|
45
|
+
cd "$APP_PATH"
|
|
46
|
+
# iOS buildNumber and Android versionCode auto-incremented by EAS by default
|
|
47
|
+
# if eas.json has "autoIncrement": "buildNumber" / "versionCode" — verify:
|
|
48
|
+
jq -r '.build.preview.autoIncrement // "manual"' eas.json
|
|
49
|
+
```
|
|
50
|
+
If `manual`, prompt user to bump `app.json` `expo.ios.buildNumber` / `expo.android.versionCode` first.
|
|
51
|
+
|
|
52
|
+
3. **Run EAS Build (preview profile, both platforms)**:
|
|
53
|
+
```bash
|
|
54
|
+
cd "$APP_PATH"
|
|
55
|
+
eas build --profile preview --platform all --non-interactive --no-wait
|
|
56
|
+
```
|
|
57
|
+
Capture the build IDs from output:
|
|
58
|
+
```
|
|
59
|
+
iOS: https://expo.dev/.../builds/IOS_BUILD_ID
|
|
60
|
+
Android: https://expo.dev/.../builds/ANDROID_BUILD_ID
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
4. **Wait for builds to complete** (10–25 min typical):
|
|
64
|
+
```bash
|
|
65
|
+
eas build:wait --build-id "$IOS_BUILD_ID"
|
|
66
|
+
eas build:wait --build-id "$ANDROID_BUILD_ID"
|
|
67
|
+
```
|
|
68
|
+
On failure, surface the build URL and stop this surface.
|
|
69
|
+
|
|
70
|
+
5. **Submit iOS to TestFlight internal group**:
|
|
71
|
+
```bash
|
|
72
|
+
eas submit --platform ios --id "$IOS_BUILD_ID" --non-interactive
|
|
73
|
+
```
|
|
74
|
+
This uploads to App Store Connect. The build then enters Apple's processing queue (5–30 min).
|
|
75
|
+
|
|
76
|
+
6. **Submit Android to Play internal track**:
|
|
77
|
+
```bash
|
|
78
|
+
eas submit --platform android --id "$ANDROID_BUILD_ID" --non-interactive
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
7. **Wait for TestFlight processing** (iOS only — Android internal track is faster):
|
|
82
|
+
- The orchestrator waits up to 15 min, polling via App Store Connect API.
|
|
83
|
+
- On timeout: mark `verification_pending` (not failure) — Apple sometimes takes longer.
|
|
84
|
+
|
|
85
|
+
8. **Result**:
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"status": "verified",
|
|
89
|
+
"ios": { "build_id": "...", "testflight_group": "internal", "version": "1.4.0 (124)" },
|
|
90
|
+
"android": { "build_id": "...", "play_track": "internal", "version": "1.4.0 (124)" }
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## STEPS — eas-external variant
|
|
95
|
+
|
|
96
|
+
Same as `eas-internal` through Step 4. Then:
|
|
97
|
+
|
|
98
|
+
5. **Submit iOS to TestFlight external** — requires Apple Beta Review (1–2 days):
|
|
99
|
+
```bash
|
|
100
|
+
eas submit --platform ios --id "$IOS_BUILD_ID" --non-interactive
|
|
101
|
+
# In App Store Connect → TestFlight → External Group → add this build
|
|
102
|
+
# External submissions trigger Apple Beta Review automatically
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
6. **Submit Android to Play external testing track** (closed/open):
|
|
106
|
+
```bash
|
|
107
|
+
eas submit --platform android --id "$ANDROID_BUILD_ID" --non-interactive --track beta
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
7. **Surface a notice** — external review is async; the orchestrator marks `verification_async` and reports back the App Store Connect URL for the user to monitor.
|
|
111
|
+
|
|
112
|
+
## STEPS — expo-go-only variant
|
|
113
|
+
|
|
114
|
+
No actual shipment. Record in shipment context:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{ "status": "skipped_intentionally", "reason": "expo-go-only — local dev via npx expo start", "next_checkpoint_default": "ask-again" }
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Verification
|
|
121
|
+
|
|
122
|
+
`scripts/verify-expo-eas.sh`:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
BUILD_ID="$1"
|
|
126
|
+
PROFILE="$2" # internal | external
|
|
127
|
+
|
|
128
|
+
# Build status
|
|
129
|
+
STATUS=$(eas build:view "$BUILD_ID" --json | jq -r .status)
|
|
130
|
+
[ "$STATUS" = "FINISHED" ] || { echo "Build not finished: $STATUS"; exit 1; }
|
|
131
|
+
|
|
132
|
+
# Submission status (TestFlight processing)
|
|
133
|
+
SUBMISSION=$(eas submit:list --status finished --json | jq -r ".[] | select(.buildId == \"$BUILD_ID\") | .status" | head -1)
|
|
134
|
+
[ "$SUBMISSION" = "finished" ] && exit 0
|
|
135
|
+
|
|
136
|
+
echo "Submission status: $SUBMISSION (Apple processing async — verification pending)"
|
|
137
|
+
exit 2 # treat as verification_pending, not failure
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Common failures
|
|
141
|
+
|
|
142
|
+
| Symptom | Cause | Fix |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `eas build` errors with "Provisioning profile not found" | Apple credentials sync needed | `eas credentials` → Manage credentials → Apple Distribution Certificate |
|
|
145
|
+
| TestFlight build stuck in "Processing" >1hr | Apple infra; may also indicate ITMS-90xxx warning | Check App Store Connect → Activity for the build; resubmit if needed |
|
|
146
|
+
| `eas submit` errors "Invalid bundle" | `app.json` `bundleIdentifier` doesn't match App Store Connect record | Verify match in ASC; or create new ASC app record |
|
|
147
|
+
| Build fails with "EXC_BAD_ACCESS" on TestFlight | Native module crash; not detectable in dev client | Use `eas build --profile development` + Sentry to debug |
|
|
148
|
+
|
|
149
|
+
## Rollback
|
|
150
|
+
|
|
151
|
+
TestFlight builds can be revoked via App Store Connect → TestFlight → Build → Expire. EAS doesn't support this from CLI. Surface to user as a manual step.
|
|
152
|
+
|
|
153
|
+
## Configure-once setup
|
|
154
|
+
|
|
155
|
+
See `${CLAUDE_PLUGIN_ROOT}/skills/ship-configure/reference/expo-mobile.md` for first-time setup (Apple Developer enrollment, ASC API key, EAS project init, eas.json scaffold).
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Surface: npm-package
|
|
2
|
+
|
|
3
|
+
Publish a package to the npm registry.
|
|
4
|
+
|
|
5
|
+
## Detection
|
|
6
|
+
|
|
7
|
+
Signals (all must hold):
|
|
8
|
+
|
|
9
|
+
- `package.json` with `private: false` (or `private` absent — defaults to publishable)
|
|
10
|
+
- Package is NOT under `apps/*` (apps are not published)
|
|
11
|
+
- Either `publishConfig` is set, OR the package has explicit `name` + `version`
|
|
12
|
+
- Workspace internal-only packages (`packages/auth`, `packages/design-tokens`) are excluded by listing them in `.codebyplan/shipment.json` `disabled[]`
|
|
13
|
+
|
|
14
|
+
## Configured indicators
|
|
15
|
+
|
|
16
|
+
`configured: true` requires:
|
|
17
|
+
|
|
18
|
+
1. `package.json` has `name`, `version`, `main`/`exports`, `files` field
|
|
19
|
+
2. `npm whoami` succeeds (logged in to registry)
|
|
20
|
+
3. Package version on registry differs from local: `npm view <name>@<local-version>` returns 404 (or different SHA)
|
|
21
|
+
4. 2FA is enabled on the npm account (verified via `npm profile get tfa` returning `auth-and-writes`)
|
|
22
|
+
|
|
23
|
+
Reference: [npm-publish-overview.md](./npm-publish-overview.md), [npm-publish-oidc-trusted.md](./npm-publish-oidc-trusted.md), [npm-publish-monorepo.md](./npm-publish-monorepo.md).
|
|
24
|
+
|
|
25
|
+
## Variants
|
|
26
|
+
|
|
27
|
+
| Variant | When |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `publish` | Local version > registry version AND build passes |
|
|
30
|
+
| `publish-prerelease` | Version contains `-alpha`, `-beta`, `-rc` — uses `--tag` to avoid promoting to `latest` |
|
|
31
|
+
| `skip` | Version unchanged since last shipment |
|
|
32
|
+
|
|
33
|
+
## STEPS — publish variant
|
|
34
|
+
|
|
35
|
+
The npm registry requires 2FA OTP for every publish. **The orchestrator NEVER runs `npm publish` directly** — the user runs it because the OTP is theirs.
|
|
36
|
+
|
|
37
|
+
1. **Detect packages to publish**:
|
|
38
|
+
```bash
|
|
39
|
+
bash "${CLAUDE_SKILL_DIR}/scripts/detect-surfaces.sh" --filter=npm-package
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
2. **Per package, check version status**:
|
|
43
|
+
```bash
|
|
44
|
+
cd "$PKG_PATH"
|
|
45
|
+
PKG_NAME=$(jq -r .name package.json)
|
|
46
|
+
LOCAL_VERSION=$(jq -r .version package.json)
|
|
47
|
+
REMOTE_VERSION=$(npm view "$PKG_NAME@$LOCAL_VERSION" version 2>/dev/null || echo "")
|
|
48
|
+
|
|
49
|
+
if [ "$REMOTE_VERSION" = "$LOCAL_VERSION" ]; then
|
|
50
|
+
echo "Already published — skip"
|
|
51
|
+
else
|
|
52
|
+
echo "Publishable — local $LOCAL_VERSION, registry has $(npm view "$PKG_NAME" version)"
|
|
53
|
+
fi
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
3. **Build the package** (orchestrator-side; no OTP needed):
|
|
57
|
+
```bash
|
|
58
|
+
pnpm --filter "$PKG_NAME" build
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If `package.json` `scripts.build` is absent, skip but warn — likely intentional (no build needed) but uncommon.
|
|
62
|
+
|
|
63
|
+
4. **Pre-publish checks**:
|
|
64
|
+
```bash
|
|
65
|
+
cd "$PKG_PATH"
|
|
66
|
+
npm pack --dry-run # see what will go in the tarball
|
|
67
|
+
pnpm publint || true # lints package.json, prints warnings
|
|
68
|
+
pnpm attw --pack 2>/dev/null || true # arethetypeswrong — ESM/CJS sanity check
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If `npm pack --dry-run` shows missing entrypoints (`main`/`exports` files not in tarball), HALT — surface the error and the `files` field needs fixing.
|
|
72
|
+
|
|
73
|
+
5. **Display publish command for the user to run** (the OTP step):
|
|
74
|
+
```
|
|
75
|
+
## npm publish — manual step
|
|
76
|
+
|
|
77
|
+
Package: @scope/pkg-name @ 1.4.0
|
|
78
|
+
Directory: /path/to/pkg
|
|
79
|
+
|
|
80
|
+
Run in your terminal:
|
|
81
|
+
cd /path/to/pkg
|
|
82
|
+
npm publish
|
|
83
|
+
|
|
84
|
+
Enter your 2FA code when prompted. Reply 'done' when published, 'fail' if it errored.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
6. **Verify publication** (after user reports done):
|
|
88
|
+
```bash
|
|
89
|
+
npm view "$PKG_NAME@$LOCAL_VERSION" version 2>&1
|
|
90
|
+
```
|
|
91
|
+
If matches local version → success. Otherwise → ask user to retry.
|
|
92
|
+
|
|
93
|
+
7. **Result**:
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"status": "verified",
|
|
97
|
+
"package": "@scope/pkg-name",
|
|
98
|
+
"version": "1.4.0",
|
|
99
|
+
"registry_url": "https://www.npmjs.com/package/@scope/pkg-name/v/1.4.0",
|
|
100
|
+
"published_at": "2026-04-29T14:32:00Z"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## STEPS — publish-prerelease variant
|
|
105
|
+
|
|
106
|
+
Same as `publish` but step 5 includes the `--tag` flag:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm publish --tag next # for X.Y.Z-rc.N
|
|
110
|
+
npm publish --tag beta # for X.Y.Z-beta.N
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Prereleases must NOT promote to `latest`. The user-facing instruction must explicitly include `--tag`.
|
|
114
|
+
|
|
115
|
+
## Versioning automation
|
|
116
|
+
|
|
117
|
+
This surface respects three modes (set per-package in `.codebyplan/shipment.json` `surfaces.npm-package.{path}.versioning`):
|
|
118
|
+
|
|
119
|
+
| Mode | Behavior |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `manual` | User bumps `package.json` version manually before checkpoint shipment |
|
|
122
|
+
| `release-please` | A GH Actions workflow opens version-bump PRs based on conventional commits — checkpoint merges those PRs as part of normal flow; `/cbp-ship` then publishes the bumped version |
|
|
123
|
+
| `changesets` | User adds `.changeset/*.md` entries during development; release-please-style PR aggregates them |
|
|
124
|
+
|
|
125
|
+
See [versioning.md](versioning.md) for which mode to pick.
|
|
126
|
+
|
|
127
|
+
## OIDC trusted publishing (recommended for CI)
|
|
128
|
+
|
|
129
|
+
For repos that publish from GH Actions instead of local, use OIDC trusted publishing — no token needed, no leaked credentials:
|
|
130
|
+
|
|
131
|
+
1. Set up via npm web → Account → Trusted Publishing → add the GH workflow path
|
|
132
|
+
2. In workflow, request `id-token: write` permission and use `npm publish --provenance`
|
|
133
|
+
|
|
134
|
+
`/cbp-ship-configure` can scaffold the GH Actions workflow that uses this. See [npm-publish-oidc-trusted.md](./npm-publish-oidc-trusted.md) and [npm-publish-monorepo.md](./npm-publish-monorepo.md).
|
|
135
|
+
|
|
136
|
+
## Verification
|
|
137
|
+
|
|
138
|
+
`scripts/verify-npm.sh`:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
PKG="$1"
|
|
142
|
+
VERSION="$2"
|
|
143
|
+
|
|
144
|
+
# Registry shows the version
|
|
145
|
+
RESOLVED=$(npm view "$PKG@$VERSION" version 2>/dev/null)
|
|
146
|
+
[ "$RESOLVED" = "$VERSION" ] || { echo "Not published: $PKG@$VERSION"; exit 1; }
|
|
147
|
+
|
|
148
|
+
# Tarball has SRI hash (provenance bonus)
|
|
149
|
+
SRI=$(npm view "$PKG@$VERSION" dist.integrity 2>/dev/null)
|
|
150
|
+
[ -n "$SRI" ] || echo "WARN: no integrity hash"
|
|
151
|
+
|
|
152
|
+
# If --provenance was used, attestation exists
|
|
153
|
+
HAS_ATTESTATION=$(npm view "$PKG@$VERSION" --json | jq -r '.dist.attestations // empty')
|
|
154
|
+
[ -n "$HAS_ATTESTATION" ] && echo "Provenance: yes"
|
|
155
|
+
|
|
156
|
+
echo "OK"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Common failures
|
|
160
|
+
|
|
161
|
+
| Symptom | Cause | Fix |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| `npm publish` rejects with "You cannot publish over the previously published versions" | Local version already on registry | Bump version in `package.json` |
|
|
164
|
+
| 403 forbidden | Not a maintainer of the package | `npm owner add <user> <pkg>` from an existing maintainer |
|
|
165
|
+
| `EOTP` after correct OTP | Token expired or 2FA app de-synced | `npm logout && npm login` |
|
|
166
|
+
| Tarball missing files | `files` field too restrictive | Verify with `npm pack --dry-run` and adjust `files` |
|
|
167
|
+
| Types not picked up by consumers | `exports` field missing types | Add `"exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } }` |
|
|
168
|
+
|
|
169
|
+
## Rollback
|
|
170
|
+
|
|
171
|
+
`npm unpublish` is restricted (only within 72 hours; only if no dependents). Better path:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
npm deprecate "$PKG@$BAD_VERSION" "Use $PKG@$GOOD_VERSION instead"
|
|
175
|
+
# Then publish a patch version that fixes the issue
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Configure-once setup
|
|
179
|
+
|
|
180
|
+
See `${CLAUDE_PLUGIN_ROOT}/skills/ship-configure/reference/npm-package.md` for first-time setup (npm login, 2FA enrollment, OIDC trusted publishing setup, choosing versioning mode).
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Surface: railway-backend
|
|
2
|
+
|
|
3
|
+
Deploy a backend service (NestJS / Node / Bun / Python) to Railway.
|
|
4
|
+
|
|
5
|
+
Railway is the standard backend platform for the CBP family (per architectural decision 2026-04-29). Other Docker-friendly platforms (Fly, Render, Heroku) can be added as separate surfaces if needed — Railway is the default.
|
|
6
|
+
|
|
7
|
+
## Detection
|
|
8
|
+
|
|
9
|
+
Signals (any of):
|
|
10
|
+
|
|
11
|
+
- `railway.toml` or `railway.json` at app root
|
|
12
|
+
- `.railway/` directory at app root
|
|
13
|
+
- `Dockerfile` AND `package.json` with non-frontend deps (no `next`, no `react-native`) AND not under workspace `packages/`
|
|
14
|
+
|
|
15
|
+
## Configured indicators
|
|
16
|
+
|
|
17
|
+
`configured: true` requires:
|
|
18
|
+
|
|
19
|
+
1. `railway.toml` or `.railway/config.json` present with `project` ID
|
|
20
|
+
2. `railway` CLI installed (`railway --version` succeeds)
|
|
21
|
+
3. `railway whoami` returns a logged-in user
|
|
22
|
+
4. `.codebyplan/shipment.json` `.surfaces.railway-backend` block has `project_id` AND `service_id` AND `environment_id`
|
|
23
|
+
|
|
24
|
+
## Variants
|
|
25
|
+
|
|
26
|
+
| Variant | When |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `deploy` | Service code or Dockerfile changed since last shipment |
|
|
29
|
+
| `skip` | No backend changes |
|
|
30
|
+
|
|
31
|
+
Detection uses git diff: if any path under the service directory changed between the prior shipment SHA and the current ship SHA, mark `deploy`.
|
|
32
|
+
|
|
33
|
+
## STEPS — deploy variant
|
|
34
|
+
|
|
35
|
+
Railway has two deployment modes:
|
|
36
|
+
|
|
37
|
+
- **Auto-deploy on push** — preferred. Linked to a GH branch; pushes trigger deploys via webhook.
|
|
38
|
+
- **Manual `railway up`** — fallback when GH integration isn't desired.
|
|
39
|
+
|
|
40
|
+
Detection: `railway service --json | jq .repoConfig` — if non-null, it's auto-deploy. Otherwise manual.
|
|
41
|
+
|
|
42
|
+
### Auto-deploy mode
|
|
43
|
+
|
|
44
|
+
1. **Verify GH integration is healthy**:
|
|
45
|
+
```bash
|
|
46
|
+
railway service --json | jq -r .repoConfig.repoLink
|
|
47
|
+
# Should match the current repo
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. **Wait for the deploy webhook to fire** (up to 30s after PR merge):
|
|
51
|
+
```bash
|
|
52
|
+
timeout 60 bash -c "while ! railway logs --json 2>/dev/null | jq -e '.[0].timestamp > \"$(date -u -v-1M +%FT%T)\"'; do sleep 5; done"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
3. **Get the deployment ID**:
|
|
56
|
+
```bash
|
|
57
|
+
DEPLOY_ID=$(railway deployment list --json | jq -r '.[0].id')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. **Wait for deployment SUCCESS state**:
|
|
61
|
+
```bash
|
|
62
|
+
timeout 600 bash -c "while [ \"\$(railway deployment status \"$DEPLOY_ID\" --json | jq -r .status)\" != \"SUCCESS\" ]; do
|
|
63
|
+
STATUS=\$(railway deployment status \"$DEPLOY_ID\" --json | jq -r .status)
|
|
64
|
+
[ \"\$STATUS\" = \"FAILED\" ] && exit 1
|
|
65
|
+
sleep 10
|
|
66
|
+
done"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
5. **Capture URL**:
|
|
70
|
+
```bash
|
|
71
|
+
URL=$(railway domain --json | jq -r '.[0].domain' | head -1)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Manual deploy mode
|
|
75
|
+
|
|
76
|
+
1. **Confirm with user**:
|
|
77
|
+
```
|
|
78
|
+
Railway is configured for manual deploy. Run: railway up
|
|
79
|
+
This builds locally + uploads + deploys (5-10 min).
|
|
80
|
+
A) Run `railway up` — start the deploy
|
|
81
|
+
B) Skip — deploy manually later
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. **Run the deploy**:
|
|
85
|
+
```bash
|
|
86
|
+
cd "$APP_PATH"
|
|
87
|
+
railway up --detach
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. **Steps 3-5 same as auto-deploy mode**.
|
|
91
|
+
|
|
92
|
+
## Verification
|
|
93
|
+
|
|
94
|
+
`scripts/verify-railway.sh`:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
DEPLOY_ID="$1"
|
|
98
|
+
URL="$2"
|
|
99
|
+
|
|
100
|
+
# Deployment status
|
|
101
|
+
STATUS=$(railway deployment status "$DEPLOY_ID" --json | jq -r .status)
|
|
102
|
+
[ "$STATUS" = "SUCCESS" ] || { echo "Deploy not successful: $STATUS"; exit 1; }
|
|
103
|
+
|
|
104
|
+
# Health endpoint (if configured)
|
|
105
|
+
if [ -n "$URL" ]; then
|
|
106
|
+
HEALTH=$(curl -sI -m 10 "https://$URL/health" 2>/dev/null | head -1 | awk '{print $2}')
|
|
107
|
+
[ "$HEALTH" = "200" ] || echo "WARN: /health returned $HEALTH (may not be implemented)"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
echo "OK"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Common failures
|
|
114
|
+
|
|
115
|
+
| Symptom | Cause | Fix |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| Deploy fails at "Building" | Dockerfile build error | `railway logs --build` — usually missing system dep or wrong Node version |
|
|
118
|
+
| Deploy succeeds, app crashes on start | Missing env var | `railway variables` — compare to `.env.example` |
|
|
119
|
+
| Health endpoint times out | Service not listening on Railway's `$PORT` | Bind to `process.env.PORT` not hardcoded port |
|
|
120
|
+
| GH webhook not firing | Disconnect or branch filter mismatch | Railway dashboard → service → Settings → Source → reconnect |
|
|
121
|
+
| OOM during build | Large node_modules | Add `.dockerignore`; use multi-stage build |
|
|
122
|
+
|
|
123
|
+
## Rollback
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
railway redeploy <prior-deployment-id>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The orchestrator surfaces this when verification fails:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Railway deployment FAILED.
|
|
133
|
+
Options:
|
|
134
|
+
A) Retry — sometimes transient
|
|
135
|
+
B) Rollback to deployment <prior-id> (last successful)
|
|
136
|
+
C) Investigate logs — railway logs --build / --runtime
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Multi-service projects
|
|
140
|
+
|
|
141
|
+
A Railway project can have multiple services (e.g., `api`, `worker`, `cron`). Each shipment surface is per-service. The detection emits one entry per service:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{ "id": "railway-backend", "instance": "apps/backend", "service_id": "svc_abc", ... }
|
|
145
|
+
{ "id": "railway-backend", "instance": "apps/worker", "service_id": "svc_def", ... }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The orchestrator deploys each independently.
|
|
149
|
+
|
|
150
|
+
## Configure-once setup
|
|
151
|
+
|
|
152
|
+
See `${CLAUDE_PLUGIN_ROOT}/skills/ship-configure/reference/railway-backend.md` for first-time setup (railway login, project creation/link, env var sync, GH integration, custom domain, health endpoint config).
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Surface: supabase
|
|
2
|
+
|
|
3
|
+
Push pending database migrations to the linked Supabase project.
|
|
4
|
+
|
|
5
|
+
This is the most consequential shipment surface — schema mismatches break web/backend immediately. Migration push is **always interactive** with explicit user review of the diff before applying.
|
|
6
|
+
|
|
7
|
+
## Detection
|
|
8
|
+
|
|
9
|
+
Signals:
|
|
10
|
+
|
|
11
|
+
- `supabase/` directory with `config.toml`
|
|
12
|
+
- `supabase/migrations/*.sql` — count of files newer than `last_shipped_migration_version` in `.codebyplan/shipment.json` `.surfaces.supabase`
|
|
13
|
+
|
|
14
|
+
## Configured indicators
|
|
15
|
+
|
|
16
|
+
`configured: true` requires:
|
|
17
|
+
|
|
18
|
+
1. `supabase/config.toml` parseable with `project_id` field
|
|
19
|
+
2. `supabase` CLI installed (`supabase --version` succeeds)
|
|
20
|
+
3. `supabase projects list` succeeds (CLI authenticated)
|
|
21
|
+
4. `.codebyplan/shipment.json` `.surfaces.supabase` block has `project_ref`
|
|
22
|
+
|
|
23
|
+
Library docs via DocsByPlan MCP (`resolve_library_id('supabase')`).
|
|
24
|
+
|
|
25
|
+
## Variants
|
|
26
|
+
|
|
27
|
+
| Variant | When |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `push-migrations` | At least one migration file is newer than `last_shipped_migration_version` |
|
|
30
|
+
| `skip` | No new migrations |
|
|
31
|
+
|
|
32
|
+
## STEPS — push-migrations variant
|
|
33
|
+
|
|
34
|
+
This is **always interactive**. The orchestrator does NOT silently apply migrations even with confirmation up front, because the diff might surprise the user (auto-generated migrations sometimes include unintended changes).
|
|
35
|
+
|
|
36
|
+
1. **List pending migrations**:
|
|
37
|
+
```bash
|
|
38
|
+
PROJECT_REF=$(jq -r '.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
39
|
+
LAST_VERSION=$(jq -r '.surfaces.supabase.last_shipped_migration_version // ""' .codebyplan/shipment.json)
|
|
40
|
+
|
|
41
|
+
PENDING=$(ls supabase/migrations/*.sql | sort)
|
|
42
|
+
if [ -n "$LAST_VERSION" ]; then
|
|
43
|
+
PENDING=$(echo "$PENDING" | awk -v cutoff="$LAST_VERSION" '$0 > "supabase/migrations/" cutoff')
|
|
44
|
+
fi
|
|
45
|
+
echo "$PENDING"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. **Show user the migration list** + counts:
|
|
49
|
+
```
|
|
50
|
+
## Pending migrations (4)
|
|
51
|
+
|
|
52
|
+
- 0083_add_user_avatars.sql (12 lines)
|
|
53
|
+
- 0084_index_session_lookups.sql (4 lines)
|
|
54
|
+
- 0085_rls_share_links.sql (28 lines)
|
|
55
|
+
- 0086_view_active_users.sql (8 lines)
|
|
56
|
+
|
|
57
|
+
Press Enter to review each diff individually, or type 'all' to see them concatenated.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. **Walk through each migration** via AskUserQuestion (one per file):
|
|
61
|
+
```
|
|
62
|
+
### 0083_add_user_avatars.sql
|
|
63
|
+
|
|
64
|
+
```sql
|
|
65
|
+
ALTER TABLE users ADD COLUMN avatar_url text;
|
|
66
|
+
CREATE INDEX users_avatar_url_idx ON users(avatar_url) WHERE avatar_url IS NOT NULL;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Approve this migration?
|
|
70
|
+
A) Approve — include in push
|
|
71
|
+
B) Skip this one (manual review needed)
|
|
72
|
+
C) Abort — stop shipment, don't push anything
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The user reviews each file. If they pick C on any, halt — do NOT continue with subsequent surfaces.
|
|
76
|
+
|
|
77
|
+
4. **Generate diff against the live project** for safety:
|
|
78
|
+
```bash
|
|
79
|
+
supabase db diff --use-migra --schema public,auth
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This compares local migrations to remote state. If the diff shows things NOT in the migrations (drift on the remote), HALT and surface to the user — remote drift means someone applied changes via the dashboard, and we shouldn't blindly push.
|
|
83
|
+
|
|
84
|
+
5. **Push approved migrations**:
|
|
85
|
+
```bash
|
|
86
|
+
supabase db push --include-all
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If push fails partway (e.g., migration 0084 errors), Supabase rolls back to the last successful migration. Surface the failure:
|
|
90
|
+
```
|
|
91
|
+
Migration push FAILED at 0084_index_session_lookups.sql
|
|
92
|
+
Reason: <error from supabase>
|
|
93
|
+
|
|
94
|
+
The migrations applied successfully:
|
|
95
|
+
✓ 0083_add_user_avatars.sql
|
|
96
|
+
|
|
97
|
+
The remaining migrations (0085, 0086) were NOT applied.
|
|
98
|
+
|
|
99
|
+
Options:
|
|
100
|
+
A) Fix migration 0084 in code, re-run /cbp-ship
|
|
101
|
+
B) Skip 0084 and proceed with 0085+0086 (use --include-files)
|
|
102
|
+
C) Abort — schema is partially-shipped; revert the applied migration manually if needed
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
6. **Regenerate TypeScript types** (if the project uses generated types):
|
|
106
|
+
```bash
|
|
107
|
+
if [ -f "supabase/functions/_shared/db.types.ts" ] || [ -f "packages/supabase/types.ts" ]; then
|
|
108
|
+
supabase gen types typescript --project-id "$PROJECT_REF" > "$TYPES_PATH"
|
|
109
|
+
# If diff exists, surface to user — types changes may need to be committed
|
|
110
|
+
if ! git diff --quiet "$TYPES_PATH"; then
|
|
111
|
+
echo "Types regenerated — diff present. Commit before completing checkpoint."
|
|
112
|
+
fi
|
|
113
|
+
fi
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
7. **Update the last-shipped marker**:
|
|
117
|
+
```bash
|
|
118
|
+
LAST_APPLIED=$(echo "$PENDING" | tail -1 | xargs basename)
|
|
119
|
+
jq --arg v "$LAST_APPLIED" '.surfaces.supabase.last_shipped_migration_version = $v' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp
|
|
120
|
+
mv .codebyplan/shipment.json.tmp .codebyplan/shipment.json
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
8. **Result**:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "verified",
|
|
127
|
+
"migrations_applied": ["0083_...", "0084_...", "0085_...", "0086_..."],
|
|
128
|
+
"types_regenerated": true,
|
|
129
|
+
"project_ref": "abcdefgh"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Verification
|
|
134
|
+
|
|
135
|
+
`scripts/verify-supabase.sh`:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
PROJECT_REF="$1"
|
|
139
|
+
EXPECTED_LAST="$2"
|
|
140
|
+
|
|
141
|
+
# All listed migrations are recorded in supabase_migrations table
|
|
142
|
+
APPLIED=$(supabase migration list --remote --linked 2>/dev/null | grep -F "$EXPECTED_LAST" | wc -l)
|
|
143
|
+
[ "$APPLIED" -gt 0 ] || { echo "Migration $EXPECTED_LAST not found on remote"; exit 1; }
|
|
144
|
+
|
|
145
|
+
# No drift
|
|
146
|
+
DRIFT=$(supabase db diff --use-migra 2>/dev/null | grep -v "^--" | grep -c .)
|
|
147
|
+
[ "$DRIFT" -eq 0 ] || { echo "WARN: $DRIFT lines of drift between local migrations and remote"; }
|
|
148
|
+
|
|
149
|
+
echo "OK"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Common failures
|
|
153
|
+
|
|
154
|
+
| Symptom | Cause | Fix |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `db push` fails with permission error | Service role token missing scopes | `supabase login` again, ensure access token has full project access |
|
|
157
|
+
| Migration fails on `RAISE EXCEPTION` | Data assertion failure | Inspect data; usually means a NOT NULL constraint with existing NULLs |
|
|
158
|
+
| RLS policy fails to apply | References non-existent role | Migrations must be self-contained; check `supabase/seed.sql` for role creation |
|
|
159
|
+
| Drift detected | Someone applied changes via dashboard | Pull dashboard changes into a migration: `supabase db diff -f resolve_drift` |
|
|
160
|
+
| Types regen breaks compilation | New column not exposed via API | Add the table/column to `exposed_schemas` in `config.toml` |
|
|
161
|
+
|
|
162
|
+
## Rollback
|
|
163
|
+
|
|
164
|
+
There's no clean rollback for applied migrations. Two paths:
|
|
165
|
+
|
|
166
|
+
1. **Forward-only revert** — write a new migration that undoes the change, push it
|
|
167
|
+
2. **Point-in-time restore** — Supabase paid tier; via dashboard
|
|
168
|
+
|
|
169
|
+
The orchestrator surfaces #1 as the recommended path:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
Migration cannot be auto-rolled-back.
|
|
173
|
+
Recommended: write a new migration that reverses the schema change, then re-run /cbp-ship.
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Configure-once setup
|
|
177
|
+
|
|
178
|
+
See `${CLAUDE_PLUGIN_ROOT}/skills/ship-configure/reference/supabase.md` for first-time setup (supabase login, project link, types path config, optional auto-types-on-edit).
|