Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3f792a3
feat(kiloclaw): add redeploy URL to Google setup completion message (…
emilieschario Mar 31, 2026
f639f79
fix(tracking): only resolve signup product when callbackPath was expl…
pedroheyerdahl Mar 31, 2026
e847e79
feat(cloud-agent): add PostHog tracking for remote session events (#1…
eshurakov Mar 31, 2026
c4c2520
fix(kiloclaw): pass instanceId to worker for instance-keyed DO routin…
pandemicsyn Mar 31, 2026
c6e8a76
feat(admin): bulk KiloClaw trial extend/resurrect (#1751)
evanjacobson Apr 1, 2026
44bd6c6
fix(notifications): remove action button from MiniMax notification (#…
kilo-code-bot[bot] Apr 1, 2026
5774383
feat(models): replace arcee free model with qwen3.6 free model (#1802)
kilo-code-bot[bot] Apr 1, 2026
02c240f
Dev - Add tmux-based local dev tooling with multi-worktree port isola…
eshurakov Apr 1, 2026
2d356e9
guide old clients to upgrade if incompatible API is attempted (#1832)
kilo-code-bot[bot] Apr 1, 2026
1092c1a
feat(claw): add Mac/Linux vs Windows toggle for Docker setup command …
kilo-code-bot[bot] Apr 1, 2026
f0b191e
feat(kiloclaw): add org-scoped instance management + per-instance Fly…
pandemicsyn Apr 1, 2026
23103e0
api-request-log: increase retention to 30 days, add admin download pa…
kilo-code-bot[bot] Apr 1, 2026
0d47c5d
don't add cache_control if already present (#1833)
kilo-code-bot[bot] Apr 1, 2026
a66d7f8
feat(kiloclaw): pass org ID header to Kilo Gateway for org instances …
pandemicsyn Apr 1, 2026
c311669
fix(kiloclaw): fix outdated-controller error handling in Kilo CLI rec…
RSO Apr 1, 2026
a9bbb8a
chore: add worktree prepare script (#1798)
jeanduplessis Apr 1, 2026
afbc0f1
Fix formatting of worktree:prepare script entry (#1838)
eshurakov Apr 1, 2026
f1e0eb6
fix(dev): remove -- separator that broke wrangler CLI flags (#1841)
eshurakov Apr 1, 2026
8f0886a
fix(admin): sanitize user ID slashes and colons in download filename …
kilo-code-bot[bot] Apr 1, 2026
9ca38b1
chore(kiloclaw): bump @kilocode/cli to 7.1.13 and auto-upgrade at sta…
RSO Apr 1, 2026
405875e
feat(kiloclaw) webhooks kiloclaw chat target (#1814)
St0rmz1 Apr 1, 2026
98d4488
refactor(chat): replace New Session button with icon in sidebar heade…
eshurakov Apr 1, 2026
b0c74a6
feat(cloud-agent): add Slack to sidebar platform filters (#1780)
eshurakov Apr 1, 2026
ee7819f
fix: env-sync false positives and cloud-agent interrupt handling (#1845)
eshurakov Apr 1, 2026
744befe
chore(gastown): Bump resources
jrf0110 Apr 1, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ supabase/.temp

# @kilocode/trpc build output (rebuilt by: pnpm --filter @kilocode/trpc run build)
packages/trpc/dist/
.plan/
94 changes: 67 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,68 @@ 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.
- **Webhook → KiloClaw Chat** triggers require the KiloClaw worker running on port 8795. The webhook worker calls it via `KILOCLAW_API_URL` (HTTP, not a service binding) to deliver messages to Stream Chat. Stream Chat credentials (`STREAM_CHAT_API_KEY`, `STREAM_CHAT_API_SECRET`) must be in `kiloclaw/.dev.vars`.
- **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