codebyplan 1.5.1 → 1.9.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 +116 -0
- package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
- package/templates/skills/cbp-checkpoint-plan/SKILL.md +137 -0
- package/templates/skills/cbp-checkpoint-plan/reference/alternative-comparison-template.md +54 -0
- package/templates/skills/cbp-checkpoint-plan/reference/dep-decision-rubric.md +50 -0
- package/templates/skills/cbp-checkpoint-plan/reference/e2e-discovery-probe.md +57 -0
- package/templates/skills/cbp-checkpoint-plan/reference/gap-analysis-playbook.md +47 -0
- package/templates/skills/cbp-checkpoint-start/SKILL.md +84 -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 +111 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Railway — Troubleshooting
|
|
2
|
+
|
|
3
|
+
Failure modes the `/cbp-ship` orchestrator and human operators have hit on Railway, with the actual fix. Ordered roughly by frequency.
|
|
4
|
+
|
|
5
|
+
For platform-level concept reference see [railway-overview.md](./railway-overview.md). For the canonical NestJS deployment shape see [railway-nestjs-deployment.md](./railway-nestjs-deployment.md).
|
|
6
|
+
|
|
7
|
+
## 1. Healthcheck Timeout — Service Marked CRASHED
|
|
8
|
+
|
|
9
|
+
**Symptom:** Build succeeds, deploy log shows `Starting Healthcheck` and then `Healthcheck failed!` after the configured timeout. New deployment never goes live; old one keeps serving.
|
|
10
|
+
|
|
11
|
+
**Causes (in order of likelihood):**
|
|
12
|
+
|
|
13
|
+
1. **App listening on `localhost`/`127.0.0.1` instead of `0.0.0.0`** — Railway's proxy is on a different interface and can't reach you.
|
|
14
|
+
2. **Hardcoded port** — app listens on `3000` but Railway assigned `PORT=8080`.
|
|
15
|
+
3. **Healthcheck path wrong** — configured `/health`, app exposes `/api/health`. Railway sees 404 → fail.
|
|
16
|
+
4. **Healthcheck depends on Supabase / external service that's down** — transient outage cascades into a broken deploy.
|
|
17
|
+
5. **Slow boot** — NestJS module init (e.g. running migrations on boot) takes longer than the healthcheck timeout (default 100s).
|
|
18
|
+
|
|
19
|
+
**Fix:**
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Bind to 0.0.0.0, read $PORT
|
|
23
|
+
await app.listen(parseInt(process.env.PORT ?? '3000', 10), '0.0.0.0');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Verify with: `railway logs` immediately after deploy — look for `Listening on 0.0.0.0:<port>` line.
|
|
27
|
+
|
|
28
|
+
For slow boot, raise the healthcheck timeout in `Settings → Deploy → Healthcheck Timeout` (max 300s). Better: defer migrations out of boot path.
|
|
29
|
+
|
|
30
|
+
For dependency-tainted healthcheck, see the "keep healthchecks cheap" guidance in [railway-nestjs-deployment.md](./railway-nestjs-deployment.md).
|
|
31
|
+
|
|
32
|
+
## 2. Build OOM — `Killed` or Exit Code 137
|
|
33
|
+
|
|
34
|
+
**Symptom:** Build log ends with `Killed` or `exit code 137` during `pnpm install` or `turbo build`. No useful stack.
|
|
35
|
+
|
|
36
|
+
**Cause:** Railway's default build runner has a memory cap (~8 GB on Hobby). Heavy monorepo builds — particularly with `next build` in the same image, or when sharp/prisma engines compile from source — exceed it.
|
|
37
|
+
|
|
38
|
+
**Fix:**
|
|
39
|
+
|
|
40
|
+
1. Slim the build context. Add a `.dockerignore`:
|
|
41
|
+
```
|
|
42
|
+
**/node_modules
|
|
43
|
+
**/.next
|
|
44
|
+
**/dist
|
|
45
|
+
**/.turbo
|
|
46
|
+
**/coverage
|
|
47
|
+
**/.git
|
|
48
|
+
```
|
|
49
|
+
2. Use multi-stage with `pnpm --filter=<pkg> deploy --prod /out` so the runtime image only carries one app's deps.
|
|
50
|
+
3. Avoid `pnpm install --recursive` — let `pnpm install` (workspace-aware) do it once.
|
|
51
|
+
4. If still OOMing on Hobby: upgrade to Pro (larger build runner) or move heavy compile steps to a CI step that publishes a prebuilt artefact.
|
|
52
|
+
|
|
53
|
+
## 3. $PORT Binding Errors
|
|
54
|
+
|
|
55
|
+
**Symptom:** `Error: listen EADDRINUSE` or `Error: Cannot find module 'PORT'` or app binds to literally the string `"$PORT"`.
|
|
56
|
+
|
|
57
|
+
**Causes:**
|
|
58
|
+
|
|
59
|
+
| Symptom | Cause |
|
|
60
|
+
|---------|-------|
|
|
61
|
+
| `listen EADDRINUSE: ::1:8080` | Two processes in the container both binding the same port (e.g. `tini` start script forking twice) |
|
|
62
|
+
| Listens on string `"$PORT"` | Shell-form CMD without shell expansion: `CMD node main.js --port=$PORT` won't expand. Use `CMD ["sh", "-c", "node main.js --port=$PORT"]` or read from env in code (preferred) |
|
|
63
|
+
| `parseInt(undefined)` → NaN | App didn't fall back; ensure `process.env.PORT ?? '3000'` |
|
|
64
|
+
|
|
65
|
+
## 4. GitHub Webhook Desync — "I Pushed and Nothing Happened"
|
|
66
|
+
|
|
67
|
+
**Symptom:** `git push` to the configured deploy branch lands on GitHub. No new deployment appears in Railway.
|
|
68
|
+
|
|
69
|
+
**Diagnosis:**
|
|
70
|
+
|
|
71
|
+
1. GitHub repo → `Settings → Webhooks` → find Railway's webhook → `Recent Deliveries` tab.
|
|
72
|
+
2. Look at the latest delivery for your push. If it's `200 OK`, problem is on Railway's side. If it's red (4xx/5xx) or missing, problem is on GitHub's side.
|
|
73
|
+
|
|
74
|
+
**Fixes:**
|
|
75
|
+
|
|
76
|
+
- **Webhook delivery missing** — your push didn't match the configured branch filter. Check `Settings → Source` on the Railway service.
|
|
77
|
+
- **Webhook 401/403** — Railway's GitHub App was uninstalled or its permissions were revoked. Reinstall: Railway dashboard → service → `Settings → Source → Reconnect`.
|
|
78
|
+
- **Webhook 200 but no Railway deploy** — webhook reached Railway but was filtered out. Check that the branch matches and that the commit doesn't only touch ignored paths (Railway has an optional path filter).
|
|
79
|
+
- **Last resort:** `Settings → Deploy → Trigger Deploy` manually.
|
|
80
|
+
|
|
81
|
+
## 5. Env Var Typo / Missing Var
|
|
82
|
+
|
|
83
|
+
**Symptom:** App boots, then crashes with `SUPABASE_URL is undefined` or similar. Deployment marked CRASHED.
|
|
84
|
+
|
|
85
|
+
**Diagnosis:**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
railway variables # list all vars in current service
|
|
89
|
+
railway run -- printenv | grep SUPABASE
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Common gotchas:**
|
|
93
|
+
|
|
94
|
+
- Trailing newline or whitespace on a pasted value. Use the dashboard "raw editor" for multi-line values.
|
|
95
|
+
- Variable defined on the wrong environment (you set it on `staging` but deployed `production`).
|
|
96
|
+
- Reference variable broken: `${{ Postgres.DATABASE_URL }}` evaluates to empty string if the `Postgres` service was renamed.
|
|
97
|
+
- `NODE_ENV=development` accidentally inherited — check it's `production` everywhere.
|
|
98
|
+
|
|
99
|
+
**Fix:** Set the var, then redeploy. New env vars do NOT auto-restart the service — you must trigger a redeploy via dashboard or `railway redeploy`.
|
|
100
|
+
|
|
101
|
+
## 6. Deploy Stuck in BUILDING
|
|
102
|
+
|
|
103
|
+
**Symptom:** Deploy has been in `BUILDING` state for 15+ minutes with no log output, or logs frozen mid-build.
|
|
104
|
+
|
|
105
|
+
**Causes:**
|
|
106
|
+
|
|
107
|
+
1. Railway build runner is in a degraded region — check https://status.railway.com.
|
|
108
|
+
2. Network stall pulling base image or pnpm packages.
|
|
109
|
+
3. Cache mount corruption — rare, but happens when a build is killed mid-write.
|
|
110
|
+
|
|
111
|
+
**Fixes:**
|
|
112
|
+
|
|
113
|
+
1. Cancel the deployment from the dashboard (deployment row → kebab menu → Cancel).
|
|
114
|
+
2. Trigger a fresh deploy.
|
|
115
|
+
3. If second deploy stalls in the same place: clear build cache via `Settings → Danger → Clear build cache`, then redeploy.
|
|
116
|
+
4. If still stuck after cache clear: status page check, then support ticket. Do NOT keep retrying — you're burning build minutes.
|
|
117
|
+
|
|
118
|
+
## 7. Healthcheck Timeout Misconfiguration
|
|
119
|
+
|
|
120
|
+
**Symptom:** Healthcheck path returns 200 quickly when curled directly, but Railway still marks it failed.
|
|
121
|
+
|
|
122
|
+
**Diagnosis steps:**
|
|
123
|
+
|
|
124
|
+
1. `railway run -- curl -v http://localhost:$PORT/health` — does it work from inside the container?
|
|
125
|
+
2. If yes: Railway proxy timeout is too tight. Default is 100s for the *initial* healthcheck window. Bump to 300s if app boot is genuinely slow.
|
|
126
|
+
3. Healthcheck path field accepts a path only — not a full URL. `/health` correct, `http://localhost:3000/health` wrong.
|
|
127
|
+
4. HTTPS-only middleware (e.g. `helmet` with `hsts` redirect) can 301 the healthcheck. Whitelist the `/health` path from any redirect middleware.
|
|
128
|
+
|
|
129
|
+
## 8. Logs Inspection — What to Run
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
railway logs # tail current service logs (live)
|
|
133
|
+
railway logs --deployment <id> # logs for a specific past deployment
|
|
134
|
+
railway logs --build # build logs (vs runtime logs)
|
|
135
|
+
railway status # current service deployment + state
|
|
136
|
+
railway whoami # confirm you're logged in as the right account
|
|
137
|
+
railway environment # which env is linked
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For programmatic access (CI, `/cbp-ship` polling), use the GraphQL API at `https://backboard.railway.com/graphql/v2` with `Authorization: Bearer $RAILWAY_TOKEN`. The `deployments` and `deploymentLogs` queries are the relevant ones — see the API explorer linked from https://docs.railway.com.
|
|
141
|
+
|
|
142
|
+
## 9. Private Networking Not Resolving
|
|
143
|
+
|
|
144
|
+
**Symptom:** `api` service can't reach `worker.railway.internal` — `getaddrinfo ENOTFOUND` or connection refused.
|
|
145
|
+
|
|
146
|
+
**Causes:**
|
|
147
|
+
|
|
148
|
+
1. Service name has changed; the internal hostname follows the *current* service name (lowercase, no spaces).
|
|
149
|
+
2. Calling code uses IPv4 socket but Railway internal mesh is IPv6-only. Node 18+ defaults are fine; if you've forced `family: 4` somewhere, drop it.
|
|
150
|
+
3. Both services must be in the same project AND environment. Cross-environment internal DNS is not a thing.
|
|
151
|
+
|
|
152
|
+
## 10. Rollback
|
|
153
|
+
|
|
154
|
+
**Symptom:** Last deploy broke production; need to revert in <60 seconds.
|
|
155
|
+
|
|
156
|
+
**Fix:**
|
|
157
|
+
|
|
158
|
+
1. Dashboard → service → deployments list → find the last good deployment → kebab → `Redeploy`.
|
|
159
|
+
2. Or CLI: `railway redeploy --deployment <id>`.
|
|
160
|
+
|
|
161
|
+
This re-runs the *same image* — no rebuild — so it lands in seconds. After rollback, fix the offending commit on GitHub; the next push will deploy normally.
|
|
162
|
+
|
|
163
|
+
## Sources
|
|
164
|
+
|
|
165
|
+
- https://docs.railway.com — primary reference
|
|
166
|
+
- https://railway.com/changelog — when behaviour changes here, update this file
|
|
167
|
+
- https://status.railway.com — platform status, check first when something is "weird"
|
|
168
|
+
- https://station.railway.com — community Q&A; useful for edge cases not in docs
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# release-please — Overview
|
|
2
|
+
|
|
3
|
+
`release-please` is a Google-maintained tool that automates semver releases by parsing Conventional Commits. It runs as a GitHub Action (`googleapis/release-please-action`), watches commits to a configured branch, opens a "Release PR" that bumps `package.json` version + updates `CHANGELOG.md`, and (when the Release PR merges) cuts a GH Release tag. Used by the `npm-package` surface in `/cbp-ship` for opt-in versioning automation, and optionally for `tauri-desktop`.
|
|
4
|
+
|
|
5
|
+
Upstream: https://github.com/googleapis/release-please
|
|
6
|
+
|
|
7
|
+
## How `/cbp-ship` uses it
|
|
8
|
+
|
|
9
|
+
The `npm-package` surface ([surface-npm.md](./surface-npm.md)) offers `release-please` as one of three versioning modes (manual, release-please, changesets). When a repo opts in via `/cbp-ship-configure`:
|
|
10
|
+
|
|
11
|
+
1. Configure scaffolds `.github/workflows/release-please.yml` from `templates/workflow-release-please.yml`
|
|
12
|
+
2. Devs commit using Conventional Commits (`feat:`, `fix:`, etc.)
|
|
13
|
+
3. release-please opens a Release PR on the watched branch (configured in .github/workflows/release-please.yml; typically `main`)
|
|
14
|
+
4. Maintainer reviews + merges the Release PR
|
|
15
|
+
5. release-please tags the release; `/cbp-ship` then publishes the bumped version to npm
|
|
16
|
+
|
|
17
|
+
The release-please-managed CHANGELOG.md is the source of truth for release notes.
|
|
18
|
+
|
|
19
|
+
## Commit message → version bump mapping
|
|
20
|
+
|
|
21
|
+
| Prefix | Action |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `feat:` | Minor bump in next release-please PR |
|
|
24
|
+
| `fix:` | Patch bump |
|
|
25
|
+
| `feat!:` / `fix!:` / `BREAKING CHANGE:` footer | Major bump |
|
|
26
|
+
| `chore:`, `docs:`, `refactor:`, `test:`, `style:`, `perf:`, `ci:` | No bump |
|
|
27
|
+
|
|
28
|
+
Reference: [versioning.md](./versioning.md) for the full rules including changesets and manual modes.
|
|
29
|
+
|
|
30
|
+
## Config shape
|
|
31
|
+
|
|
32
|
+
`release-please-config.json` (single-package):
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
37
|
+
"release-type": "node",
|
|
38
|
+
"include-component-in-tag": false,
|
|
39
|
+
"bump-minor-pre-major": true,
|
|
40
|
+
"bump-patch-for-minor-pre-major": false,
|
|
41
|
+
"draft": false,
|
|
42
|
+
"prerelease": false,
|
|
43
|
+
"packages": {
|
|
44
|
+
".": {
|
|
45
|
+
"package-name": "<your-package-name>",
|
|
46
|
+
"changelog-path": "CHANGELOG.md",
|
|
47
|
+
"release-type": "node"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`.release-please-manifest.json` tracks current versions:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{ ".": "1.4.2" }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For monorepos, list each package in `packages` and use the `node-workspace` plugin to keep `workspace:*` deps in sync after bumps.
|
|
60
|
+
|
|
61
|
+
## Release-types
|
|
62
|
+
|
|
63
|
+
| release-type | Use for |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `node` | npm packages — bumps `package.json`, generates CHANGELOG |
|
|
66
|
+
| `python` | Python packages — bumps `pyproject.toml` / `setup.py` |
|
|
67
|
+
| `rust` | Cargo crates — bumps `Cargo.toml` |
|
|
68
|
+
| `go` | Go modules — tags only (no manifest file to bump) |
|
|
69
|
+
| `simple` | Tag + CHANGELOG only — for repos with no language manifest |
|
|
70
|
+
| `terraform-module` | Terraform modules |
|
|
71
|
+
|
|
72
|
+
CBP defaults: `node` for `npm-package` surface, `simple` if applied to `tauri-desktop` (Tauri version lives in `tauri.conf.json` which release-please can update via `extra-files`).
|
|
73
|
+
|
|
74
|
+
## Tokens + permissions
|
|
75
|
+
|
|
76
|
+
The default `secrets.GITHUB_TOKEN` is sufficient for most use cases. A PAT is required when:
|
|
77
|
+
|
|
78
|
+
- Release commits should re-trigger CI (default `GITHUB_TOKEN` doesn't trigger downstream workflows — this is a GH security feature)
|
|
79
|
+
- Cross-repo releases (rare for CBP)
|
|
80
|
+
- Repo has branch protections that exclude bots
|
|
81
|
+
|
|
82
|
+
Workflow permissions:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
permissions:
|
|
86
|
+
contents: write # to create tags + commit CHANGELOG
|
|
87
|
+
pull-requests: write # to open the Release PR
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Comparison vs Changesets
|
|
91
|
+
|
|
92
|
+
See [npm-publish-monorepo.md](./npm-publish-monorepo.md) "Changesets vs release-please" for the full decision matrix. Short version: release-please assumes Conventional Commits are enforced; changesets adds a per-PR ceremony but gives explicit per-PR intent.
|
|
93
|
+
|
|
94
|
+
## Pairs With
|
|
95
|
+
|
|
96
|
+
- [surface-npm.md](./surface-npm.md) — npm publish surface that consumes the bumped version
|
|
97
|
+
- [versioning.md](./versioning.md) — when to pick release-please vs changesets vs manual
|
|
98
|
+
- [npm-publish-monorepo.md](./npm-publish-monorepo.md) — release-please monorepo configuration with the `node-workspace` plugin
|
|
99
|
+
- `templates/release-please-config.json`, `templates/workflow-release-please.yml` — scaffolds the configure skill drops into the repo
|
|
@@ -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).
|