Launch
Launch — one command to a running stack
Section titled “Launch — one command to a running stack”pnpm run bootstrap walks every step end to end: .env collection, Cloudflare
connection, build, deploy, and a printed checklist for what only the dashboard
can do (Access, Email Routing, Slack/Telegram/Discord app creation). Re-run it
any time — answers persist in .env (gitignored, mode 600).
What the script does
Section titled “What the script does”- Preflight — verifies a Docker daemon is reachable (container builds) and
connects Alchemy to Cloudflare (browser OAuth once, or set
CLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_IDin.env). - Collects config — dashboard Access emails, worker secrets
(
GITHUB_TOKEN,AI_GATEWAY_TOKEN, Slack/Telegram/Discord credentials), your paid-CLI subscription credentials (Claude, Codex, Cursor, Devin — blank keeps the lane dark), feature flags (SHIBA_*_SUBSCRIPTION,AGENT_HARNESS,AUTOMATIONS_ENABLED,MEMORY_ENABLED), and the agent mailbox address. - Builds and deploys —
pnpm buildthenalchemy deploy. Everything in.envis bound as a secret or var; anything missing there is removed from the Worker on the next deploy, so.envis the source of truth.
After deploy (printed by the script)
Section titled “After deploy (printed by the script)”- Cloudflare Access — until an Access app covers the hostname, every
/api/*answers 401access_not_configuredby design (fail closed). Create it at one.dash.cloudflare.com → Access → Applications onapp.tryshiba.dev(or your workers.dev host);ACCESS_EMAILS+WORKERS_SUBDOMAINin.envpick up the audience automatically on redeploy. - Custom domain — Workers → Settings → Domains → Add
(e.g.
app.tryshiba.dev); mirror the hostname into.envasWORKER_HOSTNAME. - Agent mailbox — Email Routing → Custom addresses → create
dev@tryshiba.dev(or yourAGENT_MAILBOX) → route to Workershiba-ai-coworker, then register it viaPOST /api/mailboxes. Unregistered recipients are rejected by design — register first. - Sandbox image — the deployed Worker pulls the pushed registry image.
On an arm64 machine:
docker buildx build --platform linux/amd64 -t registry.cloudflare.com/<account-id>/shiba-ai-coworker-sandbox-dogfood:boot --push apps/backend. (Thedeploy-worker.ymlworkflow can build it too.) - Chat channels — Slack via
slack-app-manifest.yaml; Telegram viasetWebhookto/api/telegram/webhookwithTELEGRAM_WEBHOOK_SECRET; Discord via the Interactions Endpoint at/api/discord/interactionswithDISCORD_PUBLIC_KEY. - Check —
https://<host>/api/setup/statusafter signing in.
When alchemy deploy can’t plan (narrow API token)
Section titled “When alchemy deploy can’t plan (narrow API token)”The Alchemy plan phase reads D1/Vectorize/KV/R2 state; a token scoped for
Workers only gets 401s. Either widen CLOUDFLARE_API_TOKEN or deploy the
proven wrangler path: node scripts/assemble-public.mjs → copy
apps/backend/wrangler.jsonc to a sibling config with containers[].image
swapped to the pushed registry ref → strip absolute-URL and /app*//dashboard*
rules from public/_redirects → npx wrangler deploy -c <sibling> → delete
the sibling. secrets() can’t be pushed by wrangler without .env values —
set them with npx wrangler secret put <NAME>.
Rollback
Section titled “Rollback”npx wrangler rollback -c apps/backend/wrangler.jsonc returns the Worker to
the previous version. Removing a key from .env and redeploying removes the
binding; leave subscription flags blank to take a lane dark.
