Skip to content

Local Development

SAM uses a Cloudflare-first development approach. Local development has significant limitations — no real OAuth, DNS, or VMs. For meaningful testing, deploy to staging.

  1. Make changes locally — edit code, run lint and typecheck
  2. Deploy to staging — via the “Deploy Staging” GitHub Actions workflow or pnpm deploy:staging
  3. Test on Cloudflare — real D1, KV, Workers, DNS
  4. Merge to main — in the canonical repository, successful main CI triggers production deployment; in self-host forks, run Deploy Production manually with the exact synced commit SHA when you want to update the instance

For quick iteration on API logic, you can use Wrangler’s local emulator:

Terminal window
pnpm dev

This starts:

  • API at http://localhost:8787 (Wrangler with Miniflare)
  • Web UI at http://localhost:5173 (Vite dev server)
FeatureLocalStaging
GitHub OAuthNo (callbacks won’t work)Yes
DNS/subdomainsNoYes
VM provisioningNoYes
D1/KV/R2Emulated (may differ)Real
Agent sessionsNoYes
Terminal window
node --version # v20.x or higher
pnpm --version # 9.x or higher

Go 1.26.6+ is needed if you’re working on the VM Agent (packages/vm-agent/) or CLI (packages/cli/).

Terminal window
pnpm install
Terminal window
pnpm tsx scripts/deploy/generate-keys.ts

This generates ENCRYPTION_KEY, JWT_PRIVATE_KEY, and JWT_PUBLIC_KEY for local use.

Create apps/api/.dev.vars with minimal configuration:

Terminal window
BASE_DOMAIN=localhost:8787
ENCRYPTION_KEY=<from generate-keys>
JWT_PRIVATE_KEY=<from generate-keys>
JWT_PUBLIC_KEY=<from generate-keys>
Terminal window
pnpm dev
Terminal window
pnpm build # Build all packages
pnpm test # Run tests
pnpm typecheck # Type check
pnpm lint # Lint
pnpm format # Format

Packages must be built in dependency order:

Terminal window
pnpm --filter @simple-agent-manager/shared build
pnpm --filter @simple-agent-manager/providers build
pnpm --filter @simple-agent-manager/api build

Or use pnpm build from the root — Turborepo handles ordering.

apps/
├── api/ # Cloudflare Worker API (Hono)
├── web/ # Control plane UI (React + Vite)
├── www/ # Marketing site + docs (Astro)
└── tail-worker/ # Log aggregation worker
packages/
├── shared/ # Shared types and utilities
├── providers/ # Cloud provider abstraction (Hetzner, Scaleway, GCP, Vultr, Infomaniak, DigitalOcean, UpCloud)
├── cloud-init/ # Cloud-init template generator
├── terminal/ # Shared terminal component (xterm.js)
├── ui/ # Design system components
└── vm-agent/ # Go VM agent (PTY, WebSocket, ACP)

For real testing, deploy to a staging environment:

Terminal window
# Via GitHub Actions (recommended)
# Trigger the "Deploy Staging" workflow
# Or via CLI
pnpm deploy:staging

Staging gives you the full Cloudflare stack: real D1, KV, Workers, DNS, and VM provisioning.