Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions .env.development.local.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
# MAILGUN_API_KEY=key-...
# MAILGUN_DOMAIN=app.kilocode.ai
# NEVERBOUNCE_API_KEY=...
# @url cloud-agent-next
CLOUD_AGENT_API_URL=http://localhost:8794

# Stripe integration
STRIPE_WEBHOOK_SECRET="...extract this from: stripe listen --forward-to http://localhost:3000/api/stripe/webhook"
# @url cloud-agent-next
CLOUD_AGENT_NEXT_API_URL=http://localhost:8794

# DEV_SAVE_PROXY_STREAMS=true
# @url cloudflare-code-review-infra
CODE_REVIEW_WORKER_URL=http://localhost:8789

# Cloud Agent API (local dev)
CLOUD_AGENT_API_URL=http://localhost:8788
# Cloudflare webhook agent ingest (local dev)
WEBHOOK_AGENT_URL=http://0.0.0.0:8793
# @url cloudflare-auto-fix-infra
AUTO_FIX_URL=http://localhost:8792

# @url cloudflare-auto-triage-infra
AUTO_TRIAGE_URL=http://localhost:8791

# @url cloudflare-app-builder
APP_BUILDER_URL=http://localhost:8790

# @url kiloclaw
KILOCLAW_API_URL=http://localhost:8795

# @url cloudflare-session-ingest
SESSION_INGEST_WORKER_URL=http://localhost:8800

# @url cloudflare-deploy-builder
USER_DEPLOYMENTS_API_BASE_URL=http://localhost:8804

# @url cloudflare-deploy-dispatcher
USER_DEPLOYMENTS_DISPATCHER_URL=http://localhost:8799

# @url cloudflare-webhook-agent-ingest
WEBHOOK_AGENT_URL=http://localhost:8793

# @url cloud-agent-next
NEXT_PUBLIC_CLOUD_AGENT_WS_URL=ws://localhost:8794

# @url cloud-agent-next
NEXT_PUBLIC_CLOUD_AGENT_NEXT_WS_URL=ws://localhost:8794
93 changes: 66 additions & 27 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,20 +161,23 @@ All tests should pass against the local PostgreSQL database.

## Common Development Commands

| Command | Description |
| ----------------------- | ------------------------------------------------------------------------------ |
| `pnpm dev` | Start the Next.js dev server (Turbopack) |
| `pnpm test` | Run the Jest test suite |
| `pnpm typecheck` | Run the TypeScript type checker |
| `pnpm lint` | Lint all source files |
| `pnpm lint:changed` | Lint only files changed since `main` |
| `pnpm format` | Format all supported files with oxfmt |
| `pnpm format:changed` | Format only files changed since `main` |
| `pnpm validate` | Run typecheck, lint changed, format changed, tests, and dependency cycle check |
| `pnpm drizzle migrate` | Apply pending database migrations |
| `pnpm drizzle generate` | Generate a new migration after schema changes |
| `pnpm stripe` | Start Stripe webhook forwarding to localhost |
| `pnpm test:e2e` | Run Playwright end-to-end tests |
| Command | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| `pnpm dev` | Start the Next.js dev server (Turbopack) |
| `pnpm dev:start` | Start all local services in a tmux dashboard |
| `pnpm dev:stop` | Stop the tmux session and all services |
| `pnpm dev:env` | Sync `.dev.vars` files from `.env.local` (see [Worker `.dev.vars` setup](#worker-dev-vars-setup)) |
| `pnpm test` | Run the Jest test suite |
| `pnpm typecheck` | Run the TypeScript type checker |
| `pnpm lint` | Lint all source files |
| `pnpm lint:changed` | Lint only files changed since `main` |
| `pnpm format` | Format all supported files with oxfmt |
| `pnpm format:changed` | Format only files changed since `main` |
| `pnpm validate` | Run typecheck, lint changed, format changed, tests, and dependency cycle check |
| `pnpm drizzle migrate` | Apply pending database migrations |
| `pnpm drizzle generate` | Generate a new migration after schema changes |
| `pnpm stripe` | Start Stripe webhook forwarding to localhost |
| `pnpm test:e2e` | Run Playwright end-to-end tests |

## Git Workflow

Expand Down Expand Up @@ -300,31 +303,67 @@ AI inference works locally without any extra services. The Next.js app includes

### Running workers locally

Each worker in the workspace can be started individually with `wrangler dev` (or `pnpm dev`) from its directory. Workers communicate with Next.js over HTTP using env vars like `CLOUD_AGENT_API_URL`, `CODE_REVIEW_WORKER_URL`, etc.
Each worker in the workspace can be started individually with `wrangler dev` (or `pnpm dev`) from its directory. Workers communicate with Next.js over HTTP using env vars like `CLOUD_AGENT_API_URL`, `CODE_REVIEW_WORKER_URL`, etc. Dev ports are defined in each worker's `wrangler.jsonc`.

| Worker | Dev Port | Env Var | What it does |
| --------------------------------- | -------- | --------------------------- | ------------------------------------------------------ |
| `cloud-agent` | 8788 | `CLOUD_AGENT_API_URL` | CLI agent orchestration (Durable Objects + Containers) |
| `cloud-agent-next` | 8794 | `CLOUD_AGENT_NEXT_API_URL` | Next-gen CLI agent orchestration |
| `cloudflare-session-ingest` | 8787 | `SESSION_INGEST_WORKER_URL` | Session data ingestion |
| `cloudflare-code-review-infra` | 8789 | `CODE_REVIEW_WORKER_URL` | Automated code reviews |
| `cloudflare-app-builder` | 8790 | `APP_BUILDER_URL` | App Builder sandbox |
| `cloudflare-auto-triage-infra` | 8791 | `AUTO_TRIAGE_URL` | Auto-triage for security findings |
| `cloudflare-auto-fix-infra` | 8792 | `AUTO_FIX_URL` | Auto-fix for security findings |
| `cloudflare-webhook-agent-ingest` | 8793 | `WEBHOOK_AGENT_URL` | Incoming webhook processing |
| `kiloclaw` | 8795 | `KILOCLAW_API_URL` | OpenClaw AI assistant (proxies to Fly.io) |
The easiest way to run workers is with `pnpm dev:start` (see [Common Development Commands](#common-development-commands)), which starts groups of related services in a tmux dashboard.

### Worker `.dev.vars` setup

Most workers require a `.dev.vars` file with secrets like `NEXTAUTH_SECRET` and `INTERNAL_API_SECRET`. A script automates this:

```bash
pnpm dev:env
```

The script (`dev/local/env-sync/`) scans every `.dev.vars.example` in the repo, resolves each variable's value, and writes (or patches) the corresponding `.dev.vars` file. Before applying, it shows a diff of what will change and asks for confirmation.

Values are resolved using annotations in `.dev.vars.example` comment lines:

| Annotation | What it does | Example |
| ------------------ | ---------------------------------------------------------------------------------- | ----------------------------------------- |
| _(none)_ | Copies the value from `.env.local` if the key matches, otherwise keeps the default | `INTERNAL_API_SECRET=your-secret-here` |
| `# @url <service>` | Builds `http://localhost:<port>` from the service's dev port in `wrangler.jsonc` | `# @url nextjs` → `http://localhost:3000` |
| `# @from <KEY>` | Copies the value of a _different_ key from `.env.local` | `# @from CODE_REVIEW_WORKER_AUTH_TOKEN` |
| `# @pkcs8` | Copies from `.env.local` and converts PKCS#1 PEM keys to PKCS#8 format | `# @pkcs8` above a private key var |

For example, in a `.dev.vars.example`:

```bash
# @url nextjs
API_URL=http://localhost:3000

# @from CODE_REVIEW_WORKER_AUTH_TOKEN
BACKEND_AUTH_TOKEN=your-backend-auth-token
```

The `@url` annotation accepts multiple comma-separated services (e.g., `# @url svc-a,svc-b`) and appends path suffixes (e.g., `# @url nextjs/api/events`).

Run `pnpm dev:env` again after pulling changes that add new env vars to any `.dev.vars.example`.

### Limitations in local dev

- **Service bindings** between workers don't function in local `wrangler dev`. This affects chains like session-ingest → o11y, webhook-agent → cloud-agent, and app-builder → db-proxy/git-token-service.
- **Cloudflare Containers** (used by cloud-agent, cloud-agent-next, app-builder) always run on Cloudflare's remote infrastructure, even in dev mode. Purely local execution is not possible.
- **Cloudflare-specific features** like Analytics Engine, Pipelines, and dispatch namespaces don't work locally.
- Most workers require a `.dev.vars` file (created from `.dev.vars.example` in each worker directory) with secrets like `NEXTAUTH_SECRET` and `INTERNAL_API_SECRET`.

### What works without running any workers

The core Next.js app handles profiles, organizations, usage tracking, billing, and the OpenRouter inference proxy without any workers. Features that require a specific worker (e.g., Cloud Agent sessions, code reviews, app builder) will fail gracefully or show connection errors if that worker isn't running.

### Multi-worktree support

If you use `git worktree` to run multiple checkouts simultaneously, set the `KILO_PORT_OFFSET` environment variable to avoid port collisions between worktrees:

```bash
# Automatic offset derived from the worktree directory name (0 for the primary worktree):
export KILO_PORT_OFFSET=auto

# Or a fixed numeric offset (added to every service port):
export KILO_PORT_OFFSET=100
```

With `auto`, the primary worktree gets offset 0 (default ports), and secondary worktrees get a deterministic offset based on the directory name. The offset is added to the Next.js port (3000), all worker dev ports, and the URLs generated by `pnpm dev:env`.

## Troubleshooting

### Node version mismatch
Expand Down
16 changes: 11 additions & 5 deletions cloud-agent-next/.dev.vars.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ INTERNAL_API_SECRET=your-internal-api-secret-here
# Affects:
# - Session environment variables (KILOCODE_TOKEN and KILOCODE_ORG_ID)
#
# Note: With the introduction of server backed sessionsthese should probably not be used any more,
# Note: With the introduction of server-backed sessions, these should probably not be used any more,
# you should set KILOCODE_BACKEND_BASE_URL instead and use local dev only.
#KILOCODE_TOKEN_OVERRIDE=your-override-token-here
#KILOCODE_ORG_ID_OVERRIDE=your-override-org-id-here
Expand All @@ -19,15 +19,18 @@ INTERNAL_API_SECRET=your-internal-api-secret-here
# For local development, point to your local kilocode-backend
# Note: you wanna use your actual privatenet address here and not "localhost"
# pnpm run dev of kilocode-backend usually gives you both addrs on boot.
KILOCODE_BACKEND_BASE_URL=http://192.168.200.70:3000
KILO_OPENROUTER_BASE=http://192.168.200.70:3000/api
# @url nextjs
KILOCODE_BACKEND_BASE_URL=http://192.168.x.x:3000
# @url nextjs/api
KILO_OPENROUTER_BASE=http://192.168.x.x:3000/api

# Worker base URL used by the wrapper to connect to /ingest.
# Use a host-reachable IP (not localhost) so sandbox containers can connect back.
WORKER_URL=http://192.168.200.72:8794
# @url cloud-agent-next
WORKER_URL=http://192.168.x.x:8794

# Timeout overrides (optional)
CLI_TIMEOUT_SECONDS=700
CLI_TIMEOUT_SECONDS=900
REAPER_INTERVAL_MS=300000
STALE_THRESHOLD_MS=600000
PENDING_START_TIMEOUT_MS=300000
Expand All @@ -46,11 +49,13 @@ GITHUB_APP_BOT_USER_ID=242397087
# GITHUB_APP_PRIVATE_KEY: The raw PKCS#8 private key (use \n for newlines in env var)
# Note that the nextjs app uses PKCS#1 but the worker uses WebCrypto and requires a PKCS#8
GITHUB_APP_ID=2245043
# @pkcs8
GITHUB_APP_PRIVATE_KEY=

# GitHub Lite App credentials (for OSS organizations with read-only permissions)
# Same format as standard app credentials above
GITHUB_LITE_APP_ID=
# @pkcs8
GITHUB_LITE_APP_PRIVATE_KEY=

# Agent Environment Profile Secrets Decryption
Expand All @@ -68,4 +73,5 @@ R2_ATTACHMENTS_READONLY_ACCESS_KEY_ID=""
R2_ATTACHMENTS_READONLY_SECRET_ACCESS_KEY=""

# Local dev worker origins allowed to connect to /stream
# @url nextjs,cloud-agent-next
WS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8794
7 changes: 6 additions & 1 deletion cloud-agent/.dev.vars.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ INTERNAL_API_SECRET=your-internal-api-secret-here
# Affects:
# - Session environment variables (KILOCODE_TOKEN and KILOCODE_ORG_ID)
#
# Note: With the introduction of server backed sessionsthese should probably not be used any more,
# Note: With the introduction of server-backed sessions, these should probably not be used any more,
# you should set KILOCODE_BACKEND_BASE_URL instead and use local dev only.
#KILOCODE_TOKEN_OVERRIDE=your-override-token-here
#KILOCODE_ORG_ID_OVERRIDE=your-override-org-id-here
Expand All @@ -21,10 +21,12 @@ INTERNAL_API_SECRET=your-internal-api-secret-here
# For local development, point to your local kilocode-backend
# Note: you wanna use your actual privatenet address here and not "localhost"
# pnpm run dev of kilocode-backend usually gives you both addrs on boot.
# @url nextjs
KILOCODE_BACKEND_BASE_URL=http://192.168.200.70:3000

# Worker base URL used by the wrapper to connect to /ingest.
# Use a host-reachable IP (not localhost) so sandbox containers can connect back.
# @url cloud-agent
WORKER_URL=http://192.168.200.72:8788

# Timeout overrides (optional)
Expand All @@ -48,11 +50,13 @@ GITHUB_APP_BOT_USER_ID=242397087
# GITHUB_APP_PRIVATE_KEY: The raw PKCS#8 private key (use \n for newlines in env var)
# Note that the nextjs app uses PKCS#1 but the worker uses WebCrypto and requires a PKCS#8
GITHUB_APP_ID=2245043
# @pkcs8
GITHUB_APP_PRIVATE_KEY=

# GitHub Lite App credentials (for OSS organizations with read-only permissions)
# Same format as standard app credentials above
GITHUB_LITE_APP_ID=
# @pkcs8
GITHUB_LITE_APP_PRIVATE_KEY=

# Agent Environment Profile Secrets Decryption
Expand All @@ -70,4 +74,5 @@ R2_ATTACHMENTS_READONLY_ACCESS_KEY_ID=""
R2_ATTACHMENTS_READONLY_SECRET_ACCESS_KEY=""

# Local dev worker origins allowed to connect to /stream
# @url nextjs,cloud-agent
WS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8788
1 change: 1 addition & 0 deletions cloudflare-ai-attribution/wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"main": "src/ai-attribution.worker.ts",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"dev": { "port": 8787 },
"logpush": true,
"observability": {
"enabled": true,
Expand Down
18 changes: 13 additions & 5 deletions cloudflare-app-builder/.dev.vars.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@
# Copy this file to .dev.vars and update with your actual values

# Authentication token for REST API endpoints (init, preview status, build triggers, logs)
AUTH_TOKEN=dev-token-change-this-in-production
# @from APP_BUILDER_AUTH_TOKEN
AUTH_TOKEN=

# Allowed CORS origins (comma-separated)
# @url nextjs
ALLOWED_ORIGINS=http://localhost:3000

# Base hostname for preview deployments (e.g., builder.yourdomain.com or your-subdomain.ngrok-free.dev)
# Preview URLs will be: https://{appId}.{BUILDER_HOSTNAME}
# Can use [your-lan-ip].nip.io to support subdomains on local ip
# For example 192-168-0-1.nip.io will resolve to 192.168.0.1
# This needs to be a lan address because Cloud Agent will need to push changes to git repo
BUILDER_HOSTNAME=192-168-0-1.nip.io
# @url cloudflare-app-builder
BUILDER_HOSTNAME=localhost:8790

# Backend push notification (optional - enables auto-build on push)
BACKEND_PUSH_NOTIFICATION_URL=http://192.168.0.1:3000/api/app-builder/push-notification
# @url nextjs/api/app-builder/push-notification
BACKEND_PUSH_NOTIFICATION_URL=http://localhost:3000/api/app-builder/push-notification

# JWT secret for generating git authentication tokens (must be at least 32 bytes)
# Generate with: openssl rand -base64 32
Expand All @@ -23,5 +30,6 @@ GIT_JWT_SECRET=your-secret-key-at-least-32-bytes-long
# In dev mode previews are accessed using regular app builder url
DEV_MODE=true

# DB Proxy Worker
DB_PROXY_URL=http://192.168.1.1:8792
# URL of the DB proxy worker for database provisioning
# @url cloudflare-db-proxy
DB_PROXY_URL=http://localhost:8798
Loading
Loading