Quick notes for getting a local pea environment running.
- Bun (used for installs and scripts).
- A recent Node runtime for tooling that Bun delegates to.
bun installbun installalso runsprepare, which installs the Husky git hooks.
bun run devserves the full app athttp://localhost:3742— use this for manual testing (chat, auth, etc.).- Port 8788 is used by Playwright (
preview:e2e) so tests don’t clash with your dev server, and by standalone mock workers if you run Wrangler on them directly. It is not the same origin as normalbun run dev.
- Copy
.env.exampleto.envbefore starting any work, then update secrets as needed. - Local startup does not require creating Cloudflare D1 or KV resources. The
checked-in
wrangler.jsonckeeps only binding names (no baked-in remote IDs). bun run dev(starts mock API servers automatically and setsRESEND_API_BASE_URL,AI_MODE=mock, andAI_MOCK_BASE_URLto local mock Workers).- Add new mock API servers by following
docs/agents/mock-api-servers.md. - To opt into live remote inference locally, set
AI_MODE=remotebefore startingbun run dev. - When
AI_MODE=remote, setAI_GATEWAY_IDin.env; remote AI mode now requires requests to flow through a configured Cloudflare AI Gateway. - Local remote inference does not require
wrangler dev --remote; the normal dev server keeps local Durable Objects/D1 while routing Workers AI calls through Cloudflare using the configured account credentials. - If you only need the client bundle or worker, use:
bun run dev:clientbun run dev:worker
- Set
CLOUDFLARE_ENVto switch Wrangler environments (defaults toproduction). Playwright sets this totest.
- Git hooks mirror the current
kody/Epicflare setup:pre-commit:lint-stagedon staged files, thenbun run typecheckpre-push:bun run test:push
bun run validateruns format check, lint fix, build, typecheck, Playwright tests, and MCP E2E tests.bun run formatapplies formatting updates.bun run test:e2e:installto install Playwright browsers.bun run test:e2eto run Playwright specs.bun run test:mcpto run MCP server E2E tests.bun run test:pushruns the checks enforced bypre-push(test:e2eandtest:mcp).
- Update
docs/agentswhen behavior, workflows, architecture notes, or verification guidance change. - Treat docs updates as part of done work.
- Keep
AGENTS.mdconcise and index-like; put details in focused docs. - When failures repeat, promote lessons from docs into tests, lint rules, or scripts.
Use this script to ensure a known test login exists in any deployed environment:
- Local D1 (default):
bun run migrate:localbun tools/seed-test-data.ts --local
- Local D1 with custom persisted state:
bun tools/seed-test-data.ts --local --persist-to .wrangler/state/e2e
- Remote D1:
bun tools/seed-test-data.ts --remote --config <wrangler-config-path>- Add
--env <name>when the config uses environment-scoped bindings and the environment is not already set viaCLOUDFLARE_ENV.
- Default credentials:
- email:
kody@kcd.dev - password:
kodylovesyou
- email:
- Admin account (has admin privileges via
shared/admin.ts):bun tools/seed-test-data.ts --local --email me@kentcdodds.com --password iliketwix- email:
me@kentcdodds.com - password:
iliketwix
- Override credentials when needed:
bun tools/seed-test-data.ts --email <email> --password <password>
- When changing DB schema/model definitions or migrations, review
tools/seed-test-data.tsand update it so seeded data still matches the new model and remains useful for local and preview verification.
For a full local reset before seeding:
- Drop app tables:
bun ./wrangler-env.ts d1 execute APP_DB --local --command "PRAGMA foreign_keys=OFF; DROP TABLE IF EXISTS password_resets; DROP TABLE IF EXISTS mock_resend_messages; DROP TABLE IF EXISTS users; PRAGMA foreign_keys=ON;"
- Re-apply migrations:
bun run migrate:local
- Seed test account:
bun tools/seed-test-data.ts
For preview environments, we do a full resource reset:
- Delete preview resources:
bun tools/ci/preview-resources.ts cleanup --worker-name <preview-worker-name>
- Recreate preview resources and config:
bun tools/ci/preview-resources.ts ensure --worker-name <preview-worker-name> --out-config wrangler-preview.generated.json
- Re-apply remote migrations:
CLOUDFLARE_ENV=preview bun ./wrangler-env.ts d1 migrations apply APP_DB --remote --config wrangler-preview.generated.json
- Seed test account:
CLOUDFLARE_ENV=preview bun tools/seed-test-data.ts --remote --config wrangler-preview.generated.json
The GitHub Actions preview workflow creates per-preview Cloudflare resources so each PR preview is isolated:
- D1 database:
<preview-worker-name>-db - KV namespace (OAuth state):
<preview-worker-name>-oauth-kv
The workflow resolves or creates those resources, then writes their real IDs into a generated Wrangler config before running migrations and deploy.
When a PR is closed, the cleanup job deletes the preview Worker(s) and these resources as well.
Cloudflare Workers supports version preview_urls, but those preview URLs are
not currently available for Workers that use Durable Objects. The main app
Worker binds MCP_OBJECT, so app previews continue to use per-PR Worker names.
Mock Workers do not use Durable Objects, so their Wrangler configs opt into
preview_urls = true and the workflow includes mock version preview links when
Cloudflare returns them.
Production deploys also ensure required Cloudflare resources exist before migrations/deploy:
- D1 database: from
env.production.d1_databasesbindingAPP_DB - KV namespace:
OAUTH_KV(defaults to<worker-name>-oauthwhen creating)
Like preview deploys, production deploys inject the resolved D1/KV IDs into a generated Wrangler config at deploy time instead of relying on baked-in IDs in the checked-in template.
Both the preview and production deploy workflows run a post-deploy healthcheck
against <deploy-url>/health and fail the job if it does not return
{ ok: true, commitSha } with commitSha matching the commit SHA deployed by
that workflow.
Preview deploys also run bun tools/seed-test-data.ts after deploy to create or
verify the shared test account credentials listed above.
If you ever need to do the same operations manually, use:
bun tools/ci/preview-resources.ts ensure --worker-name <name> --out-config <path>bun tools/ci/preview-resources.ts cleanup --worker-name <name>bun tools/ci/production-resources.ts ensure --out-config <path>
Use the Remix package index for quick navigation:
docs/agents/remix/index.md