Docs

Run it locally

Local dev runs the harness on your host (so you get hot reload) but spawns every agent task in a real Docker sandbox, exactly like production. This is deliberate: it's the only honest way to develop against the bot's actual execution model.

1. Clone and install

git clone https://github.com/cliftonc/lastlight.git
cd lastlight
npm install

2. Create .env

cp .env.example .env

Edit .env and fill in the four values you collected in the previous step:

GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY_PATH=./your-app.private-key.pem
GITHUB_APP_INSTALLATION_ID=789012
WEBHOOK_SECRET=your-webhook-secret

Drop the .pem file into the project root (or wherever GITHUB_APP_PRIVATE_KEY_PATH points). It's already in .gitignore, so you won't accidentally commit it.

3. Build the sandbox image (one-time)

docker compose --profile build-only build sandbox

This builds the sandbox image that every agent task runs inside. You only need to rebuild it when sandbox.Dockerfile changes.

4. Log in to Claude Code (if using subscription auth)

claude login

The harness reads your host credentials once and seeds them into ./data/sandbox-claude-home/ on every start. If you later refresh your login, the next npm run dev picks it up automatically.

If you're using API-key mode instead, just set ANTHROPIC_API_KEY in .env and skip this step.

5. Start the harness

# Server + dashboard, with hot reload
npm run dev

# Or individually
npm run dev:server
npm run dev:dashboard

Under the hood, npm run dev:server calls scripts/dev-local.sh, which:

  • Verifies Docker is running and the sandbox image exists.
  • Re-seeds ./data/sandbox-claude-home/.credentials.json from your host credentials.
  • Sets safe defaults: LASTLIGHT_LOCAL_DEV=1, SANDBOX_DATA_VOLUME=./data/sandbox-claude-home, STATE_DIR=./data, ENABLE_DIRECT_FALLBACK=false.
  • Launches the harness with tsx watch src/index.ts.
LASTLIGHT_LOCAL_DEV=1 tells the harness not to touch your personal ~/.gitconfig, ~/.claude/ history, or keychain. Everything sandbox-related stays inside ./data/. Safe to run on a dev laptop.

6. Trigger work via the CLI

The CLI is a thin HTTP client — it POSTs to the running server. Open a second terminal:

# Cheap defaults — single agent invocation
npx tsx src/cli.ts owner/repo#42                          # triage one issue
npx tsx src/cli.ts https://github.com/owner/repo/pull/99  # review one PR
npx tsx src/cli.ts triage owner/repo                       # scan repo for new issues
npx tsx src/cli.ts review owner/repo                       # scan repo for PRs to review
npx tsx src/cli.ts health owner/repo                       # weekly-style health report

# Expensive, opt-in — full Architect → Executor → Reviewer → PR cycle
npx tsx src/cli.ts build owner/repo#42

The default action for a single-issue or single-PR shorthand is the cheap one (triage / review). Build cycles are always opt-in via the explicit build subcommand.

7. Open the dashboard

The admin dashboard is served at http://localhost:8644/admin. It has four tabs: Home, Workflows, Sandbox Sessions, and Chat Sessions. You can watch sessions stream live, drill into any run, and resolve approval gates.

If you set ADMIN_PASSWORD in .env, the dashboard will prompt for it. Otherwise it's open.

Optional: receive real webhooks

To receive real GitHub webhooks in local dev, expose port 8644 with ngrok or cloudflared and point your GitHub App's webhook URL at the public tunnel. Without webhooks you can still trigger every workflow via the CLI.