A terminal-native AI coding agent built with Bun and pnpm.
labunbun -p "fix the failing tests" # headless: one prompt, print result
labunbun # interactive REPL
- Multi-provider LLM support — Anthropic plus any OpenAI-compatible API (DeepSeek, Kimi, GLM, OpenRouter, custom endpoints) via settings.
- Core coding tools — Bash (incl.
run_in_backgroundwith BashOutput / KillBash), Read, Write, Edit (exact string replace with diff preview), Grep, Glob, LS, WebFetch, WebSearch; parallel execution of safe tools, started mid-stream as soon as their arguments finish arriving. - Task list — TaskCreate/TaskList/TaskGet/TaskUpdate let the agent plan and track multi-step work; progress renders in the REPL.
- Interactive dialogs — permission approvals plus structured AskUserQuestion multiple-choice prompts.
- Permission system — rule engine (
Bash(git *),Edit(src/**),mcp__server__*), five permission modes, interactive approval dialog, "don't ask again" session rules. - Sessions — append-only JSONL tree per project (
~/.labunbun/projects/), crash-safe resume with--resume, prompt history with ↑ recall. - Context management — automatic compaction at the context-window threshold (structured summary + re-injected recent files), microcompaction, live context-remaining indicator.
- Hooks — user-configurable
PreToolUse/PostToolUse/Stop/SessionStart… command hooks with a JSON stdin/stdout contract. - MCP client — stdio + StreamableHTTP servers from
.mcp.json; tools merge into the registry asmcp__server__tool. - Subagents — the Task tool runs nested agent sessions (sidechain
transcripts persisted); custom agents via frontmatter
.mdfiles. - Skills —
SKILL.mdfolders become prompt-expanding slash commands. - Plan mode — read-only research then plan approval before mutations.
- Model fallback chain —
fallbackModelsin settings are tried in order when the primary model fails before streaming any content. - Terminal UX — virtualized transcript (sealed history + live tail),
ctrl+O full-transcript browser, vim modal editing (
vimMode: true), eight token-based themes withautobackground detection and third-party theme files. - Headless output —
--output-format text|json|stream-json. - Config import —
labunbun migratemaps an existing agent-tool setup (--from claude-code|codex) onto labunbun's own config; dry run by default.
pnpm install
export ANTHROPIC_API_KEY=sk-... # or DEEPSEEK_API_KEY etc.
bun run dev # interactive REPL
bun run dev -p "list files here" # headless~/.labunbun/settings.json:
{
"model": "myprovider/my-model",
"providers": {
"openaiCompatible": [
{
"id": "myprovider",
"baseUrl": "https://api.example.com/v1",
"apiKeyEnv": "MYPROVIDER_API_KEY",
"models": [{ "id": "my-model", "contextWindow": 128000, "maxOutputTokens": 8192 }]
}
]
}
}Already configured another agent tool? Copy over what has an equivalent:
bun run dev migrate # dry run: report only, writes nothing
bun run dev migrate --from codex # one source (claude-code | codex | all)
bun run dev migrate --apply # write it
bun run dev migrate --apply --force # also overwrite values that existSources are only read, never modified. Model names, env, MCP servers, skills
and rules carry over; anything without an equivalent is reported as skipped with
a reason rather than dropped silently, and existing values are kept unless
--force says otherwise. The report names every written file that ends up
holding a credential. /migrate does the same from inside the REPL.
/theme # list every theme, marking the active one
/theme high-contrast-dark # switch immediately and remember the choice
/theme auto # match the terminal background| Name | For |
|---|---|
dark |
default; follows the terminal's own palette |
light |
light backgrounds, where terminal-default colors wash out |
high-contrast-dark |
maximum contrast on dark, every state bold |
high-contrast-light |
maximum contrast on light, every state bold |
deuteranopia-dark |
red/green color blindness — success is blue, not green |
tritanopia-dark |
blue/yellow color blindness — avoids the blue/green pair |
spiderman |
red and blue |
splatoon |
green and magenta |
theme in settings.json selects one; "auto" asks the terminal for its
background color (OSC 11, then COLORFGBG) and picks light or dark. Detection
never blocks startup: a terminal that does not answer gets dark.
State is never carried by color alone. Success, warning, error, pending and the selected row each render a symbol as well, so the transcript stays readable to a colorblind reader and through anything that strips ANSI.
Drop a JSON file in ~/.labunbun/themes/ (or .labunbun/themes/ for one
project, which wins on a name collision):
{
"name": "midnight",
"appearance": "dark",
"extends": "dark",
"tokens": {
"accent": "#7aa2f7",
"error": "#f7768e",
"codeText": "#9aa5ce",
"marks": { "error": "×" }
}
}extends names a built-in that supplies every token the file leaves out, so a
theme that changes a handful of colors does not have to restate the two dozen it
is happy with. Values are anything Ink accepts: "red", "#d55e00",
"rgb(215,95,0)".
The full token list is the Theme interface in
packages/tui/src/themes/tokens.ts, where each token documents what it colors.
A broken theme file never stops the REPL from starting; run /doctor to see
which file failed and why — including misspelled token names, which otherwise
just do nothing.
| Package | Purpose |
|---|---|
@labunbun/ai |
Provider-neutral message model, streaming protocol, Anthropic/OpenAI-compat adapters, retry, faux test provider |
@labunbun/agent |
Agent loop, Tool interface, execution pipeline, permission engine, JSONL session tree, compaction |
@labunbun/tools |
Built-in coding tools behind an FS/exec operations abstraction |
@labunbun/mcp |
MCP client (stdio/HTTP), tool adaptation |
@labunbun/tui |
React Ink REPL: store, message views, editor, dialogs, themes |
@labunbun/coding-agent |
CLI entry, settings hierarchy, commands, memory, hooks, subagents, skills |
Dependency direction is strictly layered: ai ← agent ← tools/mcp/tui ← coding-agent.
The loop never imports provider adapters directly — they arrive via injected
StreamFn, which is what makes the zero-network faux-provider test strategy work.
pnpm typecheck # tsc over all packages (source-mapped, no build step)
pnpm test # bun test — 400+ tests, no network needed
pnpm lint # biome check
bun run scripts/smoke.ts anthropic/claude-sonnet-5 # live smoke test
pnpm bin:build # standalone executable via bun build --compileTypeScript runs in erasable-syntax-only mode and packages export their src/
directly — Bun executes TS natively, so there is no build step in the dev loop.
- User:
~/.labunbun/—settings.json,.mcp.json,MEMORY.md,rules/*.md,agents/,skills/,themes/ - Project:
.labunbun/—settings.json,settings.local.json(gitignored),rules/*.md,agents/,skills/,themes/ - Memory files:
LABUNBUN.mdorAGENTS.mdper directory, walked cwd → root - Base URLs are overridable per provider via
<PROVIDER>_BASE_URL, e.g.ANTHROPIC_BASE_URLfor a gateway or proxy
If LaBunbun Code saves you time, consider supporting development:
| Network | Address |
|---|---|
| BTC | bc1qv9zhpzzdddyakzsetgwr4tkznl4ycsuxn7d00g |
| ETH | 0x8dFB632F494C694a1a0Ff4CC2566617230530020 |
| SOL | AdryGzPCKyH5PPzEmZ9ZxW77A5kCbBuapmrqeYFGcPna |
MIT © 2026 zayoka — see LICENSE.