KanBot
One screen for every coding agent you run — live terminals you can type into from anywhere, exact working / blocked / idle state, and a task queue that drives them.
Run instantly: uvx kanbot (or pipx install kanbot && kanbot up) · Live demo: https://getkanbot.vercel.app
You run a lot of terminal coding agents (Claude Code, Codex, Gemini, …). KanBot's
runner owns a real terminal for each one, so the agents keep running when you
close the tab, sleep the laptop, or switch machines — and you pick them back up
exactly where they were, from the web board, your phone, or kanbot attach.
- See state, not spinners. Every agent is
working,blocked(waiting on you),idle, ordone. Claude Code reports it through lifecycle hooks — exact, no guessing; other CLIs are read off the screen. Blocked agents jump to the top of the board, flash the tab title, and ping you (macOS banner, or any command you configure — Telegram, ntfy, Slack). - Type into any agent from the board. A real xterm in the browser plus
one-tap keys (
⏎ynesc^C) for answering permission prompts from a phone. Orkanbot attach <id>from any terminal —Ctrl-]detaches, the agent keeps going. - Agent-native API. The CLI and the local socket API are the same surface
your own scripts (or other agents) drive:
kanbot agent start claude "…",kanbot agent wait <id> --until idle,kanbot agent read <id>,kanbot agent prompt <id> "now add tests". - Still a queue. Cards, workflows, gates, and the 10-hour goal spree all run inside panes now — so unattended runs are watchable and interruptible live.
- Multi-machine. Runners on any box connect to one board; every pane shows which machine it lives on.
┌─ board (web) ─────────────────────────────────────────────────┐
│ NEEDS YOU ◆ codex "Allow command?" ┌─ live terminal ─┐ │
│ AGENTS ● claude fixing tests gpu-box │ $ claude … │ │
│ ○ gemini idle │ Do you want to… │ │
│ QUEUE · ship-feature (workflow) │ ❯ 1. Yes │ │
│ PICK UP ↻ yesterday's claude session └── ⏎ y n esc ^C ─┘ │
└────────────────────────────────────────────────────────────────┘
▲ ws ▲ ws
╔════════════════════╗ ╔════════════════════╗
║ runner @ laptop ║ ║ runner @ gpu-box ║
║ pane ● claude (pty)║ ║ pane ● claude (pty)║
║ pane ◆ codex (pty)║ ~/.kanbot/ ║ hooks → state ║
║ socket API + CLI ║ runner.sock ║ socket API + CLI ║
╚════════════════════╝ ╚════════════════════╝
Quickstart
Easiest (isolated, sidesteps Homebrew's PEP 668 externally-managed error):
pipx install kanbot && kanbot up # or zero-install: uvx kanbot up
From source (until it's on PyPI):
python3 -m venv .venv && . .venv/bin/activate
pip install -e .
kanbot up # server + local runner, board at :8787
Don't use bare
pip installon macOS Homebrew Python — it errors withexternally-managed-environment(PEP 668).pipx/uvhandle the env for you.
Press + (or n), give an agent a task, and it opens as a live pane you can
watch and type into. Your recent Claude/Codex sessions from disk show under
Pick up a session — one click resumes any of them in a pane.
Live terminals — the Herdr part
The runner owns a PTY per agent. Panes outlive every client: close the browser,
kanbot attach from another terminal, or open the board from your phone — the
scrollback replays and you are back where it left off.
kanbot ps # every agent on this machine, with state
kanbot agent start claude "fix the flaky test" --cwd ~/repo # open a live Claude Code TUI
kanbot agent start codex --headless "run the suite" --cwd ~/repo
kanbot attach 3f2a # your terminal becomes that pane; Ctrl-] detaches
kanbot agent wait 3f2a --until idle # block until it's ready for you (or blocked/done)
kanbot agent read 3f2a --lines 40 # the screen as plain text
kanbot agent prompt 3f2a "now add tests" # type + Enter
kanbot agent keys 3f2a y Enter # answer a permission prompt
kanbot agent keys 3f2a C-c # interrupt
kanbot agent kill 3f2a
State is one of working · blocked (needs a human) · idle · done.
Claude Code panes (and GLM/Kimi via Claude Code) report it through lifecycle
hooks injected with --settings, so it is exact: UserPromptSubmit/PreToolUse
→ working, Notification → blocked, Stop → idle. Every other CLI is classified
from the last lines of its screen (a (y/n), Allow command?, or a ❯ 1. Yes
menu means blocked; a bare prompt means idle). kanbot agent get <id> shows
which source is speaking (state_source).
Notifications. When an agent turns blocked (or a live TUI finishes) the runner
runs notify_command from ~/.kanbot/config.json with KANBOT_TITLE,
KANBOT_BODY, KANBOT_STATE, KANBOT_PANE_ID, KANBOT_AGENT in its env. Unset,
macOS gets a banner. Point it anywhere:
{ "notify_command": "curl -s -d \"$KANBOT_TITLE — $KANBOT_BODY\" ntfy.sh/my-agents" }
The board links straight to a pane: http://host:8787/#pane=<id> — put that in
your notification and a tap opens the agent that needs you.
Socket API. ~/.kanbot/runner.sock, newline-delimited JSON, the same methods
the CLI uses: ping · agent.list · agent.get · agent.read · agent.start ·
agent.prompt · agent.send_keys · agent.wait · agent.kill ·
events.subscribe (a stream of state changes) · pane.attach (raw bytes).
Over HTTP the board exposes the same for every runner: GET /api/panes,
POST /api/panes/start, GET /api/panes/{id}/read, POST /api/panes/{id}/input
({"text":"…"} or {"keys":["y","Enter"]}), POST /api/panes/{id}/kill.
Headless vs live. Cards default to a live TUI. Untick Live terminal for
the agent's print/exec mode (claude -p, codex exec): the run still happens in
a pane you can watch, and its stdout lines feed the card, workflows, and gates
as before. Plan-before-execute is headless only.
Panes die with the runner, like tmux panes die with the tmux server. Keep the runner alive as a service (launchd/systemd), or run
kanbot upin a tmux.
Run the pieces separately (e.g. runner on another machine):
kanbot server # the board / API
kanbot runner --server http://HOST:8787 --name gpu-box
Tracking other agents (Hermes, OpenCode, your own…)
Claude Code and Codex are tracked out of the box. Any agent that logs
newline-delimited JSON transcripts can be added with no code change — point
KanBot at its store in ~/.kanbot/config.json:
{
"discovery_sources": [
{
"name": "hermes",
"label": "Hermes",
"root": "~/.hermes/sessions",
"pattern": "*.jsonl",
"recursive": true,
"fmt": "claude"
}
]
}
fmt:"claude"for flat records ({type, message, cwd, timestamp}) or"codex"for payload-nested records ({payload: {role, content, cwd}}).kanbot agentsshows which trackers are active and where they read from.
Run agents
kanbot agents lists the CLIs detected on this machine. Built-in catalog:
| agent | run | resume |
|---|---|---|
claude |
claude -p "<prompt>" |
claude --resume <id> -p "<prompt>" |
codex |
codex exec --sandbox workspace-write "<prompt>" |
codex exec resume <id> "<prompt>" |
gemini |
gemini -y -p "<prompt>" |
— |
glm |
Claude Code w/ ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic |
✓ |
opencode, aider, cursor-agent, hermes, shell |
see kanbot/agents.py |
— |
Override or add any agent's command in ~/.kanbot/config.json →
agent_overrides. A card set to auto runs on whatever the matched runner has.
Custom command per card. Need to run literally any CLI for one task? Open a
card → ⚡ custom command and write it yourself, e.g.
claude -p "{prompt}" --model opus --add-dir /data. It runs instead of the
agent's default; {prompt} and {session_id} expand. Blank = use the agent.
Images. Paste or drop an image onto any prompt box (composer or card). KanBot uploads it and hands the agent a local path it can read; thumbnails are shown and removable, and the card gets a 📎 badge.
Safety: by default agents run with auto-approve flags so tasks run unattended (Claude
--dangerously-skip-permissions, Codexworkspace-write). For safe mode — agents run without those flags (Codex read-only, Claude without skip-permissions) — start withkanbot up --safeor set it persistently withkanbot config --safe(--unsafeto revert). The runner shows a 🔒 safe badge on the board when safe mode is on.
Workflows — long autonomous runs
A single prompt is a sprint; a workflow is the marathon. A workflow is an
ordered chain of agent steps that runs as one card — a session per step,
auto-advancing on success — built to drive 1–5 hour autonomous runs from
Claude/Codex. Open ⛓ Workflows (or press w).
Each step has its own prompt, agent override, Ralph loop (loop_max /
loop_until), and two switches: carry context (inject the previous step's
output into this prompt) and continue on fail. Steps run with fresh context,
so durable, file-based handoff (PLAN.md, NOTES.md in the repo) is the pattern —
e.g. Plan → Build until tests pass → Review → Report.
The point of 0.4.0 is making workflows easy to get, not just run:
- Suggest — open ⛓ Automations → ✨ Suggest from my sessions and Deckhand reads every Claude/Codex session you've run and proposes automations (per project + cross-cutting patterns), each with a rationale and its source sessions.
- Refine (distillation) — the suggestions start as raw drafts (your actual transcript turns). Hit ✨ Refine and a connected agent (claude, codex, glm, gemini — whichever your runner advertises) rewrites them into clean, generalized, short guided step-prompts that work in fresh context — adding test/verify loops where you were iterating. This is the difference between parroting your chat and a real reusable automation. (Needs a reasoning agent on a connected runner; the same ✨ Distill button lives in the builder.)
- Templates — a built-in starter library (Ship a feature, Harden until green, Deep refactor); pick one and tweak.
- Extract — turn a single Claude/Codex session into a draft workflow: open ⟳ sessions → ⛓ workflow.
- Export / import — every workflow exports to portable JSON you can share, version, or paste into another board.
- Clone & edit — duplicate and adjust in the builder.
API: GET /api/workflow-templates, …/workflows (CRUD), …/workflows/import,
…/workflows/extract, …/workflows/{id}/export, …/workflows/{id}/run. The full
spec is under </> API in the app.
Goal Spree — hand it one goal, walk away for 10+ hours
Playbooks are first-class now (the ▤ playbooks button). The headline is the ⚡ Set off a goal spree: give it one big goal, a repo, a budget (hours) and an optional verify command, and it runs unattended — engineered so a skittish agent that wants to quit after five minutes can't end the run.
How it beats the early-stop problem:
- It splits the goal. A first pass writes
PROGRESS.md— a checklist of small, independently-verifiable tasks plus a concrete## DONE WHEN. The agent never faces "do the whole thing", only "do the next box". - One task per fresh context. Each iteration does exactly one unchecked item,
verifies it, checks it off, and commits — then ends. The next iteration re-reads
PROGRESS.md, so a 10-hour run survives context resets. - It can't talk its way out. The loop's stop condition is a real shell predicate — no unchecked boxes and your verify command passes. When the agent says "good stopping point", the runner re-checks and relaunches with fresh context until it's actually done. The prompt also explicitly rejects "the rest is straightforward" / "I'll let you take it from here".
- Bounded + safe to leave. A wall-clock budget and an iteration cap bound the run; between iterations the runner auto-commits any work the agent left uncommitted (so nothing is ever lost), and stops if there's no progress for several passes instead of spinning.
- Resumable. If a run hits its budget or is interrupted, ⚡ Continue spree
picks up against the existing
PROGRESS.mdexactly where it left off.
You can seed a spree with a saved playbook (its method is folded into the plan) and apply a prompt mode (e.g. lean) to every step.
Creating playbooks (not just from sessions)
- ✎ Draft from an idea — describe what the playbook should do (optionally point it at a repo to ground in) and an agent writes the 3–6 steps for you, live.
- ✨ Build from my sessions — distill your real Claude/Codex transcripts into reusable playbooks (results are cached in the local DB, never re-generated).
- + New (manual) — author steps by hand, with a ✨ Distill button to clean them up.
- ◇ Template / ⬇ Import — starter library and portable JSON.
API: POST /api/boards/{id}/spree, …/workflows/draft, …/workflows/build,
GET /api/spree/progress?cwd=….
Self-improving (Training)
A workflow's job is to distill a whole conversation into a procedure that reproduces the outcome with far less prompting — cards show the estimated "↓ ~Nx less prompting." Deckhand improves at this on its own, locally, using your agents:
- Grounded distillation. Extraction runs an agent read-only inside the session's real repo, so workflows are verified against actual code, not hallucinated from chat.
- Evaluate. After Analyze, ⚖ Evaluate grades a workflow against the session's real outcome (git diff/commits) — fidelity, reusability, baked-in takeaways — and writes a grounded critique.
- Exemplar library. Anything scoring ≥75 is banked as a proven exemplar and injected as few-shot into future distillation — the system bootstraps off its own wins. See ⛓ Automations → 🧠 Training.
- Improvement pass. "🧠 Run an improvement pass" distills + judges your richest sessions and banks the winners (cost-capped; real agent runs).
- Sandbox replay (opt-in). A deeper reward: replay a workflow in a throwaway
git worktreeat the session's pre-state and judge the diff it produces against the real one (sandboxflag on the eval/improve API).
API: …/workflows/from-session (deep extract), …/workflows/eval,
…/workflows/improve, …/exemplars.
Tags & insights
Tags are colored labels; a tag can also be an insight provider (◆) that pulls
live context onto any card: git (branch/diff), files (recent changes), or
a custom command (e.g. pytest -q).
CLI
kanbot up server + local runner (best first run)
kanbot server board / API only
kanbot runner background runner only (--server, --name, --concurrency)
kanbot ps live agents on this machine (state · agent · cwd · title)
kanbot attach ID your terminal becomes that agent's pane (Ctrl-] detaches)
kanbot agent … start / prompt / keys / read / wait / kill / get / rm
kanbot agents detected agents + active session trackers
kanbot config server URL, token, runner name, enable/disable agents
kanbot open open the board
kanbot review multi-agent code review of local changes (--gate for chains)
Config: ~/.kanbot/config.json · data: ~/.kanbot/kanbot.db · socket: ~/.kanbot/runner.sock.
Set KANBOT_TOKEN on the server to require a matching --token from runners.
License
MIT
Release files for kanbot 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kanbot-0.7.0.tar.gz | 161.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kanbot-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 332.7 kB
Release files / kanbot-0.7.0.tar.gz
| Download URL | kanbot-0.7.0.tar.gz |
|---|---|
| Size | 161.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc13aafb6e6c0b6d592895bf6f2cca7edb542a9b9e4bb74edaea1193802ea215
|
|
BLAKE2b-256 checksum How to use checksums |
db7e76e2541420a44a2e1b5c10b058c19c5a74461036d82c989ba6b9327354bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / kanbot-0.7.0-py3-none-any.whl
| Download URL | kanbot-0.7.0-py3-none-any.whl |
|---|---|
| Size | 171.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db80b21d0c51d52a3e90f39a0f264f7d5f103f2bfabdf86a551015b7f3dde962
|
|
BLAKE2b-256 checksum How to use checksums |
4ab90834abd6aaf1dd4209023d3fd1418ff519778188707481e9b2f3093975b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|