本文へ移動
cccskills
無料GitHub で公開

deploy

Deploy a crouton app to Cloudflare Workers STAGING (auto-provisioning) — the DEFAULT deploy, staging only, never production. Handles the staging bootstrap (auto-creates D1+KV, syncs ids, migrates), wiring CI, routine staging deploys, and Pages→Workers migration. For production use the separate /deploy-production skill. Use when deploying any app in apps/.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md12.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Deploy Skill — Cloudflare Workers

Deploys a crouton app to Cloudflare Workers (static assets) — the crouton deploy standard (#108). Wrangler auto-provisions the app's D1 + KV on the first deploy, so there's no manual resource/project creation, no id-juggling.

🟦 STAGING ONLY — this skill never deploys to production. "Deploy" defaults to staging here. Shipping to production is a deliberate, human-initiated action handled by the separate /deploy-production skill. Never deploy production as part of routine work.

Not Cloudflare Pages. We do NOT use wrangler pages …, pages_build_output_dir, or the Pages "strip env" step anymore. If you find those, the app is on the old Pages path — see Migrating a Pages app → Workers below.

Environment & domain convention (#133)

Two environments, two domains — kept on separate registrable domains so a staging session can never authenticate against production (cookie isolation):

Envwrangler envWorkerDomain
productiontop-level<app><app>.friendlyinter.net
stagingenv.staging<app>-staging<app>.pmcp.dev (public)

The deploy-env is named staging (not preview): scripts are cf:staging / db:migrate:staging, deploys use --env staging. (The general crouton CLI stays domain-agnostic via --domain <zone>; the friendlyinter.net/pmcp.dev split is this monorepo's convention, applied per app at its production cutover — #136 for triage.)

Usage

/deploy              # Deploy current app to STAGING (auto-detected from cwd)
/deploy velo         # Deploy a specific app to STAGING
# production → use the separate /deploy-production skill

Rules

  1. STAGING ONLY. This skill deploys to staging, never production (that's the separate /deploy-production skill). Always confirm the target app first.
  2. Workers, not Pages — NITRO_PRESET=cloudflare_module, output in .output/, deploy with wrangler deploy (never wrangler pages deploy).
  3. NEVER manually create D1/KV — they auto-provision from the id-less wrangler.jsonc on first deploy. After provisioning, run sync:ids and commit the written-back ids (remote d1 migrations apply needs them — workers-sdk#13632).
  4. NEVER skip nuxt prepare before build in CI — rolldown tsconfig bug. (Locally, the cf:* scripts assume node_modules/.nuxt are prepared from pnpm install.)
  5. hub: { db: 'sqlite' } — never hub: { database: true }.
  6. postinstall must be guarded — nuxt prepare 2>/dev/null || true, never bare (a bare prepare aborts the whole-monorepo install and fails every app's deploy).

How the pipeline works (one source of truth)

The deploy logic lives in the app's package.json scripts — the same commands you run locally and that CI runs. Don't reinvent them step-by-step:

  • cf:deploy (production — run only via the /deploy-production skill): build → wrangler deploy (auto-provision) → sync:ids → d1 migrations apply --remote
  • cf:staging (isolated staging env): build → inject-wrangler-env → wrangler deploy --env staging → sync:ids → inject-wrangler-env → d1 migrations apply --env staging --remote
  • sync:ids — queries wrangler, writes provisioned ids back into wrangler.jsonc
  • db:migrate / db:migrate:prod / db:migrate:staging — D1 migrations (local / remote / staging-remote)

A freshly scaffolded app (crouton init) already ships all of this: wrangler.jsonc (id-less), scripts/sync-wrangler-ids.mjs, scripts/inject-wrangler-env.mjs, drizzle.config.ts, the chained scripts, the CF stubs + nitro aliases, and the guarded postinstall.

Workflow

Step 1: Detect app

  • arg → apps/{arg}/; else if cwd is inside an app → that app; else ask.
  • Verify it has wrangler.jsonc + package.json.

Step 2: Pre-flight (run in parallel)

Confirm the app is Workers-ready:

  1. wrangler.jsonc present, Workers-style (has compatibility_flags: ["nodejs_compat"], d1_databases/kv_namespaces; no pages_build_output_dir).
  2. Scripts scripts/sync-wrangler-ids.mjs + scripts/inject-wrangler-env.mjs exist.
  3. drizzle.config.ts exists (so db:generate works).
  4. Package scripts — cf:deploy is the Workers chain; postinstall is guarded.
  5. CF stubs — server/utils/_cf-stubs/ exists; nuxt.config.ts has nitro.alias for passkey/webauthn/papaparse stubs and pins no preset.
  6. Auth — CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN available in the environment (see Credentials).

If anything is missing and the app is on the old Pages setup → Migrating a Pages app → Workers. If it's just missing files, copy them from apps/velo (the reference) or re-run the scaffolder.

Step 3: First (bootstrap) staging deploy

The id-less bindings auto-provision here. Confirm with the user, then deploy the isolated staging environment (its own auto-provisioned D1+KV):

cd apps/{app}
pnpm cf:staging     # provisions + deploys the *-staging worker, migrates --env staging

Then commit the written-back ids (bootstrap → committed):

git add apps/{app}/wrangler.jsonc && git commit -m "chore({app}): commit provisioned staging D1/KV ids"

The production bootstrap (cf:deploy, prod D1+KV, <app>.friendlyinter.net) is a deliberate, separate step — see the /deploy-production skill. This skill stops at staging.

If you're an agent without Cloudflare egress (sandbox), you can't run these — verify what's verifiable (config, pnpm sync:ids --dry-run logic) and have the user run the CF-gated steps, pasting output (the #109/#113/#114 loop).

Step 4: Wire CI (opt in via deploy.config.json)

There is one generic workflow for all apps — .github/workflows/deploy-apps.yml (#481/#638; the old per-app deploy-<app>.yml callers are retired — don't create one). An app opts in by adding a deploy.config.json next to its package.json. Model on apps/velo/deploy.config.json. Set: stagingUrl, productionUrl, layerPackages, and watchPaths (the app + its extended crouton* packages + lockfile). The workflow's detect job matches changed files against watchPaths and fans out one reusable deploy-app.yml call per affected app. Merge to main/open a PR → isolated staging with the URL commented on the PR; manual dispatch (app + environment inputs) → production (#347). The fan-out uses secrets: inherit.

Ensure repo-level secrets CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN exist (Settings → Secrets and variables → Actions).

Step 4.5: App (Worker) secrets

The app's own secrets (BETTER_AUTH_SECRET/BETTER_AUTH_URL, NUXT_*, etc.) live on the Worker, NOT in wrangler.jsonc. Worker secrets persist across deploys, so this is a one-time bootstrap per worker (prod + staging), not a per-deploy step.

Two ways:

  • Manual (one-time): npx wrangler secret bulk secrets.json (prod) / … --env staging (staging). BETTER_AUTH_URL/BASE_URL must be the production domain (not localhost). Pages secrets do NOT carry over — re-provide the values.
  • Automatic (CI): store the whole bundle as a repository-level Actions secret WORKER_SECRETS_JSON (a JSON object of { "NAME": "value", … }). It MUST be repo-level, NOT an Environment secret — the deploy job is reached via secrets: inherit from caller jobs that declare no environment:, so an Environment-scoped secret resolves EMPTY with no error and the Worker deploys without secrets (#1094). The reusable deploy-app.yml runs wrangler secret bulk from it on every deploy (--env staging for non-prod). Omit it to manage secrets manually. If the app depends on the bundle, set "secrets": { "required": true } in its deploy.config.json — an empty resolution then FAILS the deploy instead of silently skipping. Automation can't invent values — they must live in that secret once.

Step 5: Routine deploys (staging)

  • CI (preferred): merge to main (or open a PR) → the caller runs the staging pipeline (#347).
  • Local: pnpm cf:staging from the app dir.
  • Production is never routine — ship it deliberately via the /deploy-production skill.

Auto-seeded review login on staging previews (#608)

Every staging deploy auto-seeds a throwaway, loginable test account on the preview's isolated D1 so a reviewer can open the URL and be inside the app in one step — no register → create-team wall. deploy-app.yml runs scripts/seed-review-login.mjs against the deployed Worker (the app's own /api/auth/sign-up/email + a team via organization/create when the app doesn't auto-make one), then prints a 🔑 Test login block in the PR's staging comment. Creds are deterministic per preview (so redeploys reprint the same working login, no user pile-up) and the step is best-effort (never fails the deploy). Optional repo secret REVIEW_SEED_SECRET salts the password; production seeds nothing.

Migrating a Pages app → Workers

For an app still on the Pages setup (wrangler.toml, pages_build_output_dir, wrangler pages deploy):

  1. wrangler.toml → wrangler.jsonc in the Workers shape (see apps/velo): drop pages_build_output_dir; keep name/compatibility_*; d1_databases (reuse the existing prod database_id), kv_namespaces; add an env.staging block with a separate {app}-staging-db + KV (id-less to auto-provision, or existing staging ids).
  2. Add scripts/sync-wrangler-ids.mjs, scripts/inject-wrangler-env.mjs, drizzle.config.ts (copy from apps/velo).
  3. package.json — replace the Pages cf:* scripts with the Workers chain (NITRO_PRESET=cloudflare_module, sync:ids, db:migrate:staging); keep the guarded postinstall.
  4. nuxt.config.ts — remove nitro.preset: 'cloudflare-pages' (keep the nitro.alias stubs).
  5. CI — replace deploy-{app}.yml (+ any -preview.yml) with the thin caller from Step 4; delete the Pages strip-env step (not needed on Workers).
  6. Deploy + commit ids as in Step 3.

Credentials

The job/shell needs CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN.

  • CLOUDFLARE_ACCOUNT_ID — dashboard → Workers & Pages → Account ID (also the hex in the dashboard URL). Not secret.

  • CLOUDFLARE_API_TOKEN — My Profile → API Tokens → Create Custom Token. For Workers + auto-provisioning the token needs (Account-scoped):

    • Workers Scripts: Edit
    • D1: Edit
    • Workers KV Storage: Edit
    • (Workers R2 Storage: Edit if the app uses blob)

    Cloudflare shows a token's value only once, and GitHub never reveals a saved secret — so mint a fresh dedicated token rather than reusing one.

Note: this differs from the old Pages token (which used Cloudflare Pages: Edit). A Pages-only token will fail to auto-provision D1/KV.

Troubleshooting

Couldn't find a D1 DB … missing database_id (on migrate)

The first deploy provisioned the DB but the id isn't in wrangler.jsonc yet. Run pnpm sync:ids (after a deploy) and commit the result. cf:deploy/cf:staging do this automatically.

Configuration file does not support "env" / redirected config rejects env

Wrangler 4.64+ rejects env in a redirected config. scripts/inject-wrangler-env.mjs (run by cf:staging) re-injects env into .output/server/wrangler.json and removes the redirect so --env staging deploys read it directly. No manual strip step.

papaparse RollupError / passkey/tsyringe errors

Add the CF stubs + nitro.alias (see scaffolder output / apps/velo).

KV namespace not found by sync:ids

It matches the auto-provisioned title <worker-name>-<binding> (e.g. {app}-KV, {app}-staging-KV). The script logs the available titles if no match — adjust only if your account names them differently.

Build OOM

Set NODE_OPTIONS='--max-old-space-size=8192' (CI sets this).

Deploy Learnings Location

Per-app deploy gotchas: docs/projects/{app}/{app}-deploy.md. Append new fixes there. Reference implementation for everything above: apps/velo.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

a11y

無料

Accessibility review for Vue surfaces — the code-cleaning analog of /code-review and /simplify, pointed at WCAG/ARIA. Reviews just your diff (or a package/file), rates findings by severity, and either comments inline on the PR (--comment) or applies the safe fixes for you (--fix). Steers the depth-aware `a11y` subagent. Use when asked to "check accessibility", "a11y this", "audit ARIA/keyboard", or run /a11y.

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

ask-human

無料

Emit a blocking question the owner can read in ~10 seconds and answer in one reply — the scannable, recommendation-first handoff every agent posts when it hits a fork it can't own. Leads with the one decision + a recommendation, carries the 🤖 provenance header, doubles as the

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

audit

無料

Audit packages for documentation completeness, detect drift between code and docs, and maintain documentation quality across the monorepo. Use when checking package docs, running audits, or reviewing documentation health.

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

Author a placeable layout block that looks right at ANY pane size. The one hard rule — size to the PANE with container queries (@container), never the viewport — plus list/form playbooks and the sizing contract (minWidth etc.) the viability metric reads. Use when adding/converting a croutonLayoutBlocks block, or when a block overflows/breaks in a narrow pane.

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

When a bug or regression is reported, the FIRST step — before fixing — is to research how and when it was introduced (git archaeology), then record that finding on the tracking issue/PR. Use the moment a bug, error, broken build, or "this used to work" is reported, before writing a fix. Produces a first-bad-commit (or "not a code regression") note you paste onto the issue.

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

commit

無料

Smart, granular git commits following monorepo conventions. Analyzes changes, filters to session-relevant files, groups by intent, and uses conventional commit format. Use when committing code changes.

日本語の概要は準備中です。原文の説明を表示しています。

FriendlyInternet/nuxt-crouton102026年10月6日 更新

FriendlyInternet のスキルをすべて見る

このスキルの問題を報告する