Skip to content

sefr-sefr/agge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

132 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image

Agge

A single-purpose web board for operating Claude Code background agents across many repositories — with GitHub issues as the backlog. Zero npm dependencies, no build step, self-deploying.

Agge is an operator console, not a project tracker. It serves one person running a fleet of coding agents, and it answers three questions at a glance: what needs me, what's running, what's queued — and each of those words in the header is a control.

Operating mode: the NEEDS YOU strip above live lanes Operating mode. The attention strip holds every judgment moment — an agent waiting on your call, a green PR ready to merge, a conflict being auto-resolved — above lanes that mirror live session state.

The loop

idea ──capture──▶ issue ──plan──▶ planned ──dispatch──▶ agent works ──▶ PR
  ▲                                                        │              │
  └────────────────── merge closes the issue ◀──── merge button ◀────────┘
  • Capture an idea from the board (planning mode, or + new) → it becomes a GitHub issue. There is no local task store; gh is the source of truth, the board is a view + dispatcher.
  • Dispatch an issue → claude --bg launches an agent named #N <title>, prompted to implement and open a PR with Closes #N. An optional per-task instruction note rides along.
  • WIP cap: each repo runs at most CCB_MAX_ACTIVE agents at once (default 6, the cap Codex ships). Dispatch beyond that is queued — the held cards show in the lanes as queued and auto-launch as slots free (a merge, a stop, or an agent finishing). A queued issue clears its dependency gate again on the way out, so a blocker added while it waited still holds it — and it stays held until the issue sweep has actually read that repo, because an unread repo means unknown, not unblocked. This bounds the number of simultaneously-diverged branches, the dominant driver of merge conflicts (research). Conflict resolvers are exempt; CCB_MAX_ACTIVE=0 disables the cap.
  • Watch: cards show live status from the daemon, a liveness line (● active — current tool / ○ quiet 14m) from the session transcript, and the agent's full thread (markdown-rendered) in a detail drawer.
  • Attention strip ("NEEDS YOU"): agents waiting on an answer, PRs ready to merge (with CI state and diff stats), merge conflicts, blocked self-deploys — every judgment moment in one place, with an explicit calm state.
  • Merge from the card: merges the PR, deletes the branch, reclaims the agent (claude rm), and the issue auto-closes — the work item simply leaves the board.
  • Conflicts auto-resolve: a CONFLICTING PR — whether linked to an issue or opened by a free-form session — dispatches a resolver agent (the PR author's own session resumed as a fork when it still exists), once per PR.
  • Open PRs at a glance: a third header view (prs, beside operate/plan) lists every open PR across your repos — others' branches and orphaned PRs the board never triggered, not just its own work — each with CI state, diff size, author, branch, and a ● on board mark (a shortcut into the session) on the ones an agent is already tracking. The segment's count is the untracked PRs — your orphan radar. On-demand with a refresh button, so it spends no GitHub budget beyond one seed fetch (off the live snapshot and the issue sweep).
  • Self-deploy: when this repo's own main advances, the board fast-forwards its checkout and restarts itself — merging an Agge PR is the deploy. Dirty/diverged checkouts block loudly.

On screen

The drawer: dispatch brief, tool calls, markdown reasoning, and the open question

The thread. Every card opens to the full conversation: the dispatch brief, tool calls, the agent's reasoning rendered as markdown, your own interventions as elevated blocks — and when the agent parks on a question, it sits pinned at the top with claude attach <id> one copy-click away. A structured AskUserQuestion is laid out in full there — every option with its description and any preview, the whole group if it asked several — so you can read the choices without attaching (a on the card flags it from the board).

Planning. The backlog is GitHub issues: capture a one-liner into a real issue, label it planned, dispatch it — without leaving the board. Blocked dependencies show up as exactly that.


Planning mode in the light theme Planning mode, light theme. Light and dark are separate designs, not inversions.

The pop theme And for operators who'd rather it looked like 1996: the pop theme — same grammar, louder chrome.

Design principles (load-bearing — do not regress)

  • No status interpretation. Claude Code's session-status vocabulary is unstable (observed shifting in the wild). Lanes are created from the data: one lane per distinct status string, color from a stable hash of the string, no status→meaning map anywhere. The attention strip keys on field presence and GitHub enums only.
  • gh is truth. Open issues are the backlog; labels planned/started drive lanes; GitHub's issue↔PR link drives the merge button. The board persists only genuine user preferences (lane order, server-side).
  • Views, one screen. The header switch flips the board surface in place — Operating (default): attention strip + in-motion lanes; Planning: dense backlog/planned rows with capture; PRs: every open PR across the repos, grouped, as an orphan radar. The attention strip and repo filter stay put across all three; each segment carries its count.
  • Quiet grammar. Two hues at rest — amber means needs your judgment, green means go — everything else neutral. Spacing over borders. Mono for identifiers only. Actions ghosted, never hidden. Light and dark are separate designs: dark elevates with lighter surfaces, light elevates with shadows on warm paper. A third opt-in skin, pop (90s Miami: ink-line enclosures, hard shadows, sunset wash), keeps the same grammar — its candy chrome is uniform, so color still carries meaning, never identity.
  • Escape-first rendering. All markdown (issue bodies, agent prose) is HTML-escaped before any transform; only https?: URLs become links.
  • Mobile is a first-class layout, not a shrink. Under max-width:720px the board goes single-column, the mode switch drops to a full-width segmented control, and the repo filter becomes one swipeable row; the create/dispatch modal turns into a bottom sheet that rides above the on-screen keyboard (--kb, published from the VisualViewport in main.js). viewport-fit=cover + env(safe-area-inset-*) keep every surface off the notch and home indicator, and form fields stay ≥16px on a coarse pointer so iOS never zoom-jumps on focus. Don't regress these when restyling the header, modal, or lanes.

Running it

node agent-board.js                      # http://localhost:4317
CCB_HOST=tailscale node agent-board.js   # also bind the machine's Tailscale IP (never the public NIC)
node agent-board.js --root ~/src         # repos root to auto-discover (default ~/code)

Repos are auto-discovered: every git checkout under the root appears, including one filed under a grouping folder (<root>/clients/acme shows as clients/acme) — three levels down by default (CCB_ROOT_DEPTH), and a checkout's own contents are never searched. No list to maintain. Requires the claude CLI (the daemon does the real work) and an authenticated gh.

Runs durably as a systemd user service — see agent-board.service (install: copy to ~/.config/systemd/user/, daemon-reload, enable). Env knobs: CCB_PORT, CCB_HOST, CCB_REFRESH_MS, CCB_BACKSTOP_MS, CCB_GH_MS (GitHub-issue re-sweep — sized against GitHub's 5,000-points/hour GraphQL budget; see lib/config.js), CCB_GH_TRIES, CCB_DEPLOY_MS (self-deploy git-fetch poll), CCB_MAX_ACTIVE (per-repo cap on simultaneously-active agents — default 6; further dispatches queue and auto-start as slots free; 0 = unlimited), CCB_ROOT_DEPTH (how far below the root discovery looks — default 3, max 8); paths via --root/CCB_ROOT and repeatable --repo/CCB_REPOS for out-of-root extras.

Security model: every API route is host-guarded (exact Host allow-list — DNS-rebinding defense); actions are POST + same-site-gated (CSRF); all child processes are execFile argv, never shell; it never binds 0.0.0.0. Intended for localhost/tailnet use by one trusted operator — there is no auth layer.

Architecture

agent-board.js      entry: wiring + boot order
lib/
  config.js         env/argv/constants
  sessions.js       claude daemon data: live roster + jobs/<id>/state.json, normalize
  timeline.js       thread building: timeline turns + transcript tail, PR scan, liveness
  github.js         gh GraphQL cache: issues, labels, linked PRs, retry + stale-keep
  snapshot.js       the merge: sessions + issues → cards; change signature
  resolver.js       conflict auto-resolve dispatcher
  deploy.js         self-deploy (ff-only pull + restart on remote advance)
  live.js           SSE push: fs watchers, debounce, signature-gated broadcast
  http.js           routes, host/CSRF guards, static serving, listeners
  prefs.js          server-stored user preferences (lane order)
  attachments.js    operator-attached files: store, hand paths to the dispatched agent
public/             the browser app — plain script-tag globals, no bundler;
                    served per-request, so client changes apply on reload

The server pushes snapshots over SSE when content actually changes (file watchers + backstop poll); the client renders lanes/cards/strip from each snapshot and never touches the DOM when markup is unchanged.

Provenance

Built incrementally by Claude Code working with its operator — including many of its own features, dispatched as issues from this very board, implemented by background agents, and merged (then self-deployed) from the cards they produced.

License

Elastic License 2.0 — free to use, copy, modify, and distribute, including at work and commercially. The carve-out: you may not provide Agge to third parties as a hosted or managed service (no selling it as a SaaS).

Copyright © 2026 sefr-sefr

About

Operator console for Claude Code background agents — GitHub issues as the backlog, attention-first board, self-deploying. Zero deps.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages