Last Light

Keep the lights on after you've moved on

An open-source agent that looks after repos in maintenance mode. Triages issues, reviews PRs, chases down stale items — so you can focus on what's next.

Keeping the lights on

Issue triage, PR review, on-request builds, weekly health reports, Slack chat — all driven by YAML workflows you can fork and edit.

Issue Triage

Labels, deduplicates, and chases missing info. Real-time with webhooks, or every 15 minutes via cron.

PR Review

Reads the diff, leaves honest feedback. Instant via webhooks, or polled every 30 minutes. Critical issues first, nits last.

Health Reports

Monday morning summary of what's piling up, what's gone stale, and what needs you. Delivered to Slack.

Build on Request

@mention the bot on an issue and it runs the full Guardrails → Architect → Executor → Reviewer cycle with fix-feedback loops, then opens a PR. See how it works.

Slack Chat

DM the bot or @mention it in a channel. Every thread becomes a growing conversation — the agent resumes the same session on every turn, so context holds for hours or days. Every turn persisted.

Approval Gates

Workflows can pause at human-in-the-loop checkpoints. Approve or reject from a GitHub comment, a Slack slash command, or the dashboard — the run resumes exactly where it stopped.

YAML Workflows

Every behavior — triage, review, build, health — is a YAML workflow you can fork. Phases run linear or as a DAG. The runner knows nothing about "build" vs "triage"; it just executes what you declare.

Permission Profiles

Every workflow runs with a downscoped GitHub App token: read, issues-write, review-write, or repo-write. A triage run literally cannot push code.

How it works

Built on agentic-pi — it runs on any model the pi coding agent supports — Claude, GPT, Gemini, Llama, and more (default anthropic/claude-sonnet-4-6). Each workflow phase runs in its own sandbox — gondolin micro-VM by default, Docker on opt-in. Authenticates as its own GitHub App — every action is clearly from the bot, not you.

1
Point it at your repos

List what you want watched in agent-context/rules.md

2
You move on to other things

Cron jobs keep running — scanning for new issues, unreviewed PRs, stale items

3
Last Light gets to work

Labels, reviews, closes duplicates, writes reports

4
The repo stays healthy

Everything happens on GitHub — comments, labels, reviews. No extra dashboard to check

Build requests use a role-based Architect→Executor→Reviewer cycle — read how it works for the full picture. Already have an AGENTS.md or CLAUDE.md in your repo? Last Light reads those automatically — your coding conventions, testing requirements, and architectural guardrails carry over.

Light it up

Two ways to get going. Let Claude Code stand it up for you (recommended), or run the steps by hand. For the full walkthrough — creating the GitHub App with the right permissions, deploying to production with Caddy TLS, wiring up Slack chat + OAuth login, and every env var the harness reads — start with the quick start.

Option A — Set it up with Claude Code recommended

Last Light ships Claude Code skills that install, configure and launch the whole stack for you. Install the CLI and the skills:

npm i -g lastlight          # or run it via npx
lastlight skills install    # adds the bundled Claude Code skills

Then open Claude Code in an empty directory and ask:

"set up a Last Light server"

The lastlight-server skill checks prerequisites, scaffolds the working directory, walks you through the GitHub App, model and managed repos, launches the docker stack, and verifies it's healthy. Sibling skills cover the rest — lastlight-client (point a CLI at a server), lastlight-overlay (customize workflows & persona), and lastlight-evals (scaffold an evals workspace). See the quick start or the CLI reference for details.

Option B — Set it up by hand

Step 1 Set a model API key

Last Light runs on any model the pi coding agent supports — Claude, GPT, Gemini, Llama, and more. Set the key matching your chosen model in .env:

ANTHROPIC_API_KEY=sk-ant-...
# or
OPENAI_API_KEY=sk-...
# or use one OpenRouter key for Claude / GPT / Gemini / Llama / ...
OPENROUTER_API_KEY=sk-or-v1-...

The default model is anthropic/claude-sonnet-4-6. Override it — globally or per-phase — via LASTLIGHT_MODEL / LASTLIGHT_MODELS.

Step 2 Clone Last Light

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

Step 3 Create a GitHub App

Head to github.com/settings/apps/new and create an app with these permissions:

Generate a private key, save the .pem file into the lastlight folder, and install the app on your repos.

Step 4 Configure

cp .env.example .env

Fill in your GitHub App credentials in .env:

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

Then add your repos to agent-context/rules.md:

## Managed Repositories
- yourname/your-repo
- yourname/another-repo

Step 5 Run it

# Start the server (with hot reload)
npm run dev

Then trigger work via the CLI in another terminal:

# Build cycle for a specific issue
npx tsx src/cli.ts https://github.com/owner/repo/issues/42
npx tsx src/cli.ts owner/repo#42          # shorthand

# Run maintenance tasks
npx tsx src/cli.ts triage owner/repo      # triage scan
npx tsx src/cli.ts review owner/repo      # PR review scan
npx tsx src/cli.ts health owner/repo      # health report

The CLI talks to the running server — it does not execute agents directly. Start the server first.

Step 6 Set up GitHub webhooks

Make Last Light react to repo events in real time — new issues, PRs, comments. The webhook listener is built into the server and starts automatically on port 8644.

In your GitHub App settings, set:

Subscribe to events: Issues, Pull requests, Issue comments, Check runs, Check suites (the last two power the "Re-run checks" buttons), and optionally PR reviews.

The endpoint must be publicly reachable. Use ngrok or Cloudflare Tunnel for testing, or deploy with the included Caddy reverse proxy for automatic TLS. See Run It for Real for production setup.

The deterministic event router handles the logic — issue.opened triggers triage, pr.opened triggers review, @mention from a maintainer triggers the full build cycle. No configuration needed beyond the webhook URL and secret.

Step 7 Connect Slack optional

Talk to Last Light from Slack. Uses Socket Mode (WebSocket) — no public URL needed. The bot responds to DMs and @mentions in channels, with multi-turn conversation support.

Create an app at api.slack.com/apps with Socket Mode enabled and bot token scopes for messaging, then add to .env:

SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...

Optionally restrict access and set a delivery channel for cron reports:

SLACK_ALLOWED_USERS=U01ABC,U02DEF    # limit who can interact
SLACK_DELIVERY_CHANNEL=C01XYZ        # channel for health reports

Chat interactions are read-only by default — the bot can answer questions and create issues, but won't make code changes from Slack. Build requests go through GitHub.

Tricks up its sleeve

/pr-review

Review a PR with structured, severity-ranked feedback

/issue-triage

Label, deduplicate, and prioritize issues

/repo-health

Generate a health report with metrics and action items

/architect

Read-only deep analysis with file:line evidence

Want more?

Check the roadmap for what's coming next

Pick your mode

Webhooks and cron handle the same jobs — use one or the other, not both.

Webhooks recommended

Real-time. GitHub sends events as they happen — issues triaged instantly, PRs reviewed on open. Requires a public endpoint.

Event Response
Issue opened Instant
PR opened Instant
@mention from maintainer Architect→Executor→Reviewer build cycle

Cron

Periodic sweeps. No public endpoint needed — the agent polls GitHub on a schedule. Simpler to set up, but slower to respond.

Job Frequency
Triage new issues Every 15 min
Check PRs awaiting review Every 30 min
Weekly health report Mondays 9am

The weekly health report runs regardless of mode — it's useful either way.

Inside the dashboard

Every agent session — sandbox runs, Slack chats, cron jobs, approval gates — is logged, browsable, and streamable. The dashboard at /admin has four tabs, each answering a different question about what the bot is doing.

Home Live activity, rolling execution / token / cost stats, running containers, and the five most recent workflow runs at a glance.
Workflows Pipeline DAG for every run — Guardrails → Architect → Executor → Reviewer → PR, with fix-feedback loops stacked under the reviewer phase. Click any phase to see its full message stream.
Sandbox Sessions Drill into any sandboxed agent run. Full agent conversation — assistant thinking, tool calls, reviewer verdicts — filterable by skill, repo, and time range.
Chat Sessions DB-backed history for every Slack thread. The bot rehydrates the same pi-ai conversation each turn, so one thread = one growing, coherent conversation.