Last Light
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.
Issue triage, PR review, on-request builds, weekly health reports, Slack chat — all driven by YAML workflows you can fork and edit.
Labels, deduplicates, and chases missing info. Real-time with webhooks, or every 15 minutes via cron.
Reads the diff, leaves honest feedback. Instant via webhooks, or polled every 30 minutes. Critical issues first, nits last.
Monday morning summary of what's piling up, what's gone stale, and what needs you. Delivered to Slack.
@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.
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.
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.
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.
Every workflow runs with a downscoped GitHub App token: read, issues-write, review-write, or repo-write. A triage run literally cannot push code.
Built on the Claude Agent SDK with a custom MCP server packing 28+ GitHub tools. Authenticates as its own GitHub App — every action is clearly from the bot, not you.
List what you want watched in agent-context/rules.md
Cron jobs keep running — scanning for new issues, unreviewed PRs, stale items
Labels, reviews, closes duplicates, writes reports
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.
The short version is below. 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 docs.
curl -fsSL https://claude.ai/install.sh | bash
claude login The Agent SDK uses your Claude Code login (subscription). No separate API key needed. To use an API key instead, set ANTHROPIC_API_KEY in .env.
git clone https://github.com/cliftonc/lastlight.git
cd lastlight
npm install 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.
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 # 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.
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, 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.
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.
/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
Check the roadmap for what's coming next
Webhooks and cron handle the same jobs — use one or the other, not both.
Real-time. GitHub sends events as they happen — issues triaged instantly, PRs reviewed on open. Requires a public endpoint.
Periodic sweeps. No public endpoint needed — the agent polls GitHub on a schedule. Simpler to set up, but slower to respond.
The weekly health report runs regardless of mode — it's useful either way.
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.