/ccc-deploy — Actual Deploy Workflow
CC Commander · /ccc-deploy · Detect target → deploy → verify → announce
Use this when the user is ready to push a build live. This is distinct from /ccc-ship and /ccc-deploy-check: /ccc-ship handles pre-flight and release tagging, /ccc-deploy-check is a readiness gate, and /ccc-deploy runs the real deploy.
Response Shape
Always return these sections:
- Brand header:
**CC Commander** · /ccc-deploy · Actual deployment
- Detection summary:
Read the repository root and report detected deploy targets from:
package.jsonscripts:deploy,deploy:prod,deploy:production,pages:deploy,wrangler:deploy,vercel:deploy,fly:deploy,publish,releasefly.toml→ Fly.iovercel.jsonor avercelpackage/script → Vercelwrangler.toml,wrangler.json, orwrangler.jsonc→ Cloudflare.github/workflows/deploy.yml,.github/workflows/deploy.yaml,.github/workflows/pages.yml, or.github/workflows/pages.yaml→ GitHub Pages or workflow deploypackage.jsonpublishConfig,bin, orfilesplus aprepublishOnlyscript → npm package publish candidate
Use parallel Bash reads where possible and keep failures non-fatal:
test -f package.json && node -e "const p=require('./package.json'); console.log(JSON.stringify({scripts:p.scripts||{}, publishConfig:p.publishConfig||null, bin:p.bin||null, files:p.files||null}, null, 2))"
test -f fly.toml && echo fly.toml
test -f vercel.json && echo vercel.json
test -f wrangler.toml && echo wrangler.toml
find .github/workflows -maxdepth 1 -type f \( -name 'deploy.yml' -o -name 'deploy.yaml' -o -name 'pages.yml' -o -name 'pages.yaml' \) 2>/dev/null
- Platform picker —
AskUserQuestion
Build the options from the detection summary, put detected targets first, and enable autocomplete for the user to override. If exactly one strong target is detected, mark that label with ⭐. Never show more than four options in a single AskUserQuestion; use the second picker below for lower-confidence targets.
question: "Where should I deploy?"
header: "CC Commander Deploy"
multiSelect: false
autocomplete: true
options:
- label: "Vercel production"
value: "vercel"
description: "Detected from vercel.json or Vercel scripts. Runs vercel deploy --prod."
preview: "Deploys the current branch to Vercel production and verifies the returned URL."
- label: "Fly.io"
value: "fly"
description: "Detected from fly.toml. Runs fly deploy."
preview: "Streams deploy logs, checks release status, then verifies the app URL."
- label: "Cloudflare"
value: "cloudflare"
description: "Detected from wrangler config or Cloudflare deploy scripts."
preview: "Runs wrangler or npm Cloudflare deploy command, then verifies the Worker or Pages URL."
- label: "More deployment targets"
value: "more-targets"
description: "GitHub Pages, npm publish, or custom package deploy scripts."
preview: "Opens one more picker with less common deploy targets."
If the user chooses "More deployment targets", ask:
question: "Which deploy target?"
header: "CC Commander Deploy"
multiSelect: false
autocomplete: true
options:
- label: "GitHub Pages"
value: "github-pages"
description: "Detected from GitHub Pages workflow files."
preview: "Dispatches or watches the deploy workflow and verifies the Pages URL."
- label: "npm publish"
value: "npm"
description: "Detected from package publish metadata."
preview: "Publishes the package after package metadata and auth checks."
- label: "Custom npm deploy script"
value: "npm-script"
description: "Detected from package.json deploy scripts."
preview: "Runs the chosen npm deploy script and verifies the configured health URL."
- label: "Back"
value: "back"
description: "Return to the primary deploy target picker."
preview: "Choose Vercel, Fly.io, or Cloudflare instead."
If no target is detected, show the same picker without a star and include a short note: "No deploy target was obvious from the repo; pick the platform to use."
Deployment Runners
Before any deploy command:
- Confirm the git branch with
git rev-parse --abbrev-ref HEAD. - Show dirty state from
git status --short. - If dirty state is non-empty, warn clearly and ask the user whether to continue before deploying.
- Prefer package manager scripts when they are explicit production deploy scripts. Otherwise use the platform command below.
- Never fabricate secrets. If a command needs credentials, state the missing credential and stop.
Vercel
Use when selected or detected via vercel.json, Vercel scripts, or Vercel dependency.
Run:
vercel deploy --prod
Watch:
vercel inspect <deployment-url>
vercel logs <deployment-url>
Verify health:
- Parse the deploy URL from command output.
- Fetch the deploy URL with
WebFetch. - If the repo defines
HEALTHCHECK_URL,NEXT_PUBLIC_SITE_URL,SITE_URL, orAPP_URLin safe local config examples, verify that URL too. - PASS requires an HTTP success response and no obvious platform error page text.
Fly.io
Use when selected or detected via fly.toml.
Run:
fly deploy
Watch:
fly status
fly releases --limit 3
fly logs --no-tail
Verify health:
- Derive the app name from
fly.tomlorfly status. - Fetch
https://<app-name>.fly.devwithWebFetchwhen no explicit health URL exists. - If secrets are managed through 1Password, tell the user to rerun through
op run -- fly deployinstead of printing secret values.
Cloudflare
Use when selected or detected via wrangler.toml, wrangler.json, wrangler.jsonc, or Cloudflare scripts.
Prefer an explicit script if present:
npm run deploy
npm run deploy:prod
npm run wrangler:deploy
Otherwise run:
wrangler deploy
For Pages projects, run:
wrangler pages deploy <build-output-dir>
Watch:
wrangler deployments list
wrangler tail
Verify health:
- Fetch the Worker or Pages URL emitted by Wrangler with
WebFetch. - If the Cloudflare project is better served by the dedicated Cloudflare deployment workflow, hand off to
cloudflare-deployand preserve the selected target context.
GitHub Pages
Use when selected or detected via .github/workflows/deploy.yml, .github/workflows/deploy.yaml, .github/workflows/pages.yml, or .github/workflows/pages.yaml.
Run:
gh workflow run deploy.yml
If the workflow file is named differently, use that exact filename. If the workflow is triggered by push only, push the already committed release branch and then watch it.
Watch:
gh run list --workflow <workflow-file> --limit 5
gh run watch <run-id>
gh run view <run-id> --log-failed
Verify health:
- Derive the Pages URL from repository metadata when possible.
- Otherwise ask for the URL and fetch it with
WebFetch.
npm Publish
Use when selected or detected from publish metadata. This is a release deploy, not a web deploy.
Run checks first:
npm whoami
npm pack --dry-run
npm publish --access public
Watch:
npm view <package-name> version
npm view <package-name> dist-tags --json
Verify:
- Confirm the published version matches
package.json. - Fetch the npm package page with
WebFetchif the package is public.
Custom npm Deploy Script
Use the exact script selected from package.json.
Run:
npm run <deploy-script>
Watch and verify using any URL printed by the script, SITE_URL, APP_URL, or a user-provided health URL.
Post-Deploy Comms
After a verified deploy, emit a concise post-deploy message the user can send:
Deploy complete: <project> to <platform>
- Version or commit: <sha-or-version>
- URL: <deploy-url>
- Health check: PASS at <timestamp>
- Rollback: /ccc-rollback
If Discord or Slack is configured through /ccc-connect, offer to post the comms there. Do not invent channel names; use configured connector context or ask the user.
Post-Deploy Recommended Services
After successful deploy, suggest complementary services based on deploy platform:
For Vercel deploys:
- 🔔 Upstash — Add Redis cache, job queues, or rate limiting.
- 📊 PostHog — Product analytics and feature flags.
For Fly.io deploys:
For Cloudflare deploys:
- 🔗 Cloudflare R2 — Object storage for large files.
- ⚡ Upstash — Redis + Kafka serverless.
Failure Mode
When a deploy command, log watch, or health check fails:
- Surface the exact failing command and the relevant error lines.
- State whether the deploy likely failed before release, released but unhealthy, or could not be verified.
- Preserve the deploy URL, run id, release id, and commit sha if available.
- Suggest
/ccc-rollbackfor released-but-bad deploys. - Do not keep retrying indefinitely. One retry is acceptable only for transient network or platform status errors.
Anti-Patterns
- Do not run
/ccc-ship; this skill is the actual deploy step. - Do not skip health verification.
- Do not claim success from a zero exit code alone.
- Do not print secrets or
.envvalues. - Do not post Slack or Discord comms without user confirmation.
⚙️ Fable contract: plan before build · verifier ≠ worker · prove before alarm · loops need gates · leave durable state —
rules/fable-method.md