A minimal AI coding agent runtime. Pure bash + awk, zero runtime dependencies.
C (cagent), Go (goagent), and Rust (rustagent) ports maintain the same semantics.
- Zero dependencies — only bash, awk, curl, rg
- Four aligned runtimes — bash/c/go/rust share the same agent loop, tool, and session semantics
- Async SubAgent — built-in
SubAgenttool delegates subtasks to independent sessions running in parallel, results auto-injected back. Supportsforkmode for context inheritance, session isolation, and failure propagation - Cache-aware compaction — DP economics algorithm decides whether and how much to compact
- Session persistence — project-scoped, resumable, forkable, compactable
- Machine-friendly —
stream-jsonoutputs structured events for client consumption - Skill system — on-demand skill loading without polluting future prompts
# macOS — install via Homebrew (all four editions: bash/c/go/rust)
brew install lloydzhou/tap/bash-agent
# Or install bash-only manually (single file)
curl -fsSL https://github.com/lloydzhou/bash-agent/releases/latest/download/agent.sh \
-o ~/.local/bin/bash-agent && chmod +x ~/.local/bin/bash-agent
# Configure the API key for the service you use
export DEEPSEEK_API_KEY="sk-..."
# export ANTHROPIC_API_KEY="sk-ant-..."
# Run
bash-agent "scan this repo and summarize"
bash-agent -i # interactive mode
bash-agent --output-format stream-json "inspect"export DEEPSEEK_API_KEY="sk-..."
bash-agent "hello" # auto-detected, uses deepseek-v4-flashexport OPENAI_API_KEY="sk-..."
bash-agent -p openai -m gpt-4o "hello"OPENAI_BASE_URL=http://localhost:11434/v1 bash-agent -p openai -m llama3 "hello"brew install lloydzhou/tap/bash-agentInstalls five commands: bash-agent, cagent, ccagent, goagent, rustagent.
# Using yay
yay -S bash-agent
# Or using paru
paru -S bash-agentSee AUR package page for details.
curl -fsSL https://github.com/lloydzhou/bash-agent/releases/latest/download/agent.sh \
-o ~/.local/bin/bash-agent && chmod +x ~/.local/bin/bash-agentAdd the official APT source and install with one command; dependencies (ripgrep, tmux, etc.) are resolved automatically, and upgrades are a single command:
# One-command install (adds the source and installs)
curl -fsSL https://lloydzhou.github.io/bash-agent/install.sh | sudo bash
# Or add the source manually, then install
echo "deb [trusted=yes] https://lloydzhou.github.io/bash-agent/debian stable main" \
| sudo tee /etc/apt/sources.list.d/bash-agent.list
sudo apt update && sudo apt install bash-agentThis installs bash-agent, goagent, rustagent, cagent, and tcode. To upgrade later:
sudo apt update && sudo apt upgrade bash-agentThe APT repository only ships architecture packages (amd64/arm64, with all runtimes), so there is no arch/all selection conflict.
Download the .deb for your architecture from Releases and install with apt (resolves dependencies automatically):
sudo apt install ./bash-agent_<version>_amd64.deb
# or ./bash-agent_<version>_arm64.debThis installs bash-agent, goagent, rustagent, cagent, and tcode.
System requirement: the native Linux runtimes (goagent/rustagent/cagent) require glibc 2.31+, covering Debian 11/12/13, Ubuntu 20.04/22.04/24.04 and newer. Official .deb packages are built in a Debian 11 container (glibc 2.31 baseline), and CI enforces a glibc symbol gate on every release to prevent regressions. On older systems (glibc < 2.31), install the agent.sh single file for the Bash edition.
# Go
go -C go build -o ~/.local/bin/goagent ./cmd/goagent
# Rust
cd rust && cargo build --release && cp target/release/rustagent ~/.local/bin/rustagentPre-built binaries (C / Go / Rust) are available on Releases.
| Flag | Description | Default |
|---|---|---|
-p, --provider |
claude or openai |
claude |
-m, --model |
model name | claude-sonnet-4-20250514 |
--base-url |
override API base URL | - |
--api-key |
override API key | - |
--skill NAME |
load a skill | - |
--max-tokens |
max output tokens | 16384 |
--max-turns |
max agent loop turns | 1000 |
--thinking |
thinking mode: adaptive / enabled / disabled |
adaptive |
--effort |
thinking effort: low / medium / high / xhigh / max |
high |
--max-context |
context budget (100k/1m/1g) |
200000 |
--tool-timeout N |
tool timeout in seconds | 600 |
--session [NAME] |
create or resume a session | - |
--continue |
continue the latest session | - |
--fork |
fork a new session from source (with --session or --continue) |
- |
--list-sessions |
list sessions for the current project | - |
-i |
interactive mode | - |
--output-format FMT |
output format: human or stream-json |
human |
-v |
verbose logging | - |
tmux 3-pane wrapper for the agent, click to expand
tcode is a tmux 3-pane wrapper for the agent, with watch sidebar, agent chat, and input pane.
# Start (defaults to rustagent)
tcode
# Specify agent and passthrough args
tcode goagent
tcode rustagent --session my-session
tcode goagent -p openai -m gpt-4o
# Run directly from release download
./tcodeSupports readline input, resume info on exit, Ctrl+C to interrupt, Ctrl+D to cleanly exit.
Press Ctrl+V in interactive mode to paste an image from the clipboard. A [Image #N] placeholder is inserted and the image is cached in the session directory. When the message is sent, placeholder positions are preserved and an <attached-images> mapping to local absolute paths is appended. If image understanding is needed, the model selects an available visual Skill from skill-index and passes it the corresponding path.
Supported platforms:
- macOS:
osascript(built-in) - Linux Wayland:
wl-paste - Linux X11:
xclip
The runtime does not inspect or describe images automatically and is not tied to a specific visual service; visual capabilities are provided by external Skills on demand.
| Variable | Description |
|---|---|
DEEPSEEK_API_KEY |
DeepSeek API key (auto-detected, uses Anthropic-compatible endpoint) |
ANTHROPIC_API_KEY |
API key for Claude |
MODEL |
Override model name (defaults per CLI table) |
OPENAI_API_KEY |
API key for OpenAI |
ANTHROPIC_BASE_URL |
Claude API base URL |
OPENAI_BASE_URL |
OpenAI API base URL |
BASH_AGENT_HOME |
Override session storage directory (default: $HOME) |
BASH_AGENT_BASH_MODE |
Bash and local file tool permissions as 4 octal rwx digits: system/external/network/workspace; each digit uses 4=read,2=write,1=execute (default: 0467) |
THINKING |
Override thinking mode: adaptive / enabled / disabled; CLI --thinking takes precedence |
EFFORT |
Override thinking effort: low / medium / high / xhigh / max; CLI --effort takes precedence |
BASH_AGENT_BASH_MODE controls what the Bash, Read, Write, Edit, Glob, and Grep tools are allowed to touch. It is a 4-digit octal string:
system external network workspace
Each digit uses 4=read, 2=write, 1=execute. The check is a permission-bit coverage check, not numeric ordering: each command is classified into a required mode, and it is allowed only when allowed contains all required bits in the same positions.
For example, required=1000 means system execute is required. allowed=6677 is numerically larger, but its first digit system=6 has only read+write, not execute, so the command is still blocked. To allow system-level execute, use 7677 or 7777.
Default:
0467
That means:
system=0: no system-scope read/write/execute by defaultexternal=4: allow read access outside the workspacenetwork=6: allow network read/writeworkspace=7: allow read/write/execute inside the workspace
Typical examples:
export BASH_AGENT_BASH_MODE=0467 # default
export BASH_AGENT_BASH_MODE=4447 # allow system read
export BASH_AGENT_BASH_MODE=0457 # allow network execute
export BASH_AGENT_BASH_MODE=7777 # fully open, trusted environments onlyLocal file tools derive equivalent access probes from their paths: Read, Grep, and Glob require read access, while Write and Edit require write access. A missing path is checked against the current workspace. Paths under /tmp and $BASH_AGENT_HOME/.bash-agent/projects that do not contain .. are trusted internal paths, but any path containing .. is checked as a system path to prevent traversal bypasses such as /tmp/../.... A pathless Glob with an absolute pattern or .. segment fails closed as a system read.
Invalid values fail closed to 0000. The model is expressed like Linux-style rwx permission bits. Full classification rules, recommended settings, and the shared block message are documented in docs/bash-tool-policy.md.
DP algorithm environment variables:
| Variable | Default | Description |
|---|---|---|
DP_P_INPUT |
3.0 |
$/MTok, input price without cache |
DP_P_CACHE |
0.30 |
$/MTok, input price with cache |
DP_P_OUT |
15.0 |
$/MTok, output price |
DP_V |
5000 |
Fixed prefix token count |
DP_S |
500 |
Fixed summary length in tokens |
DP_L |
5 |
Avg LLM calls per user input (0=auto) |
DP_BASELINE_E |
8 |
Expected remaining user input turns |
DP_R |
0.8 |
Single summary info retention rate |
DP_BETA |
0.03 |
Info loss penalty coefficient |
DP_QUALITY_PENALTY |
0.2 |
Quality decay penalty (based on "Lost in the Middle" research) |
DP_MIN_KEEP_RATIO |
0.25 |
Minimum message keep ratio |
Compaction uses a cache-aware DP economics algorithm that computes a 5-term net benefit:
- All parameters overridable via env vars (
DP_P_INPUT,DP_L,DP_BETA, etc.) - Safety valve: force compact when context exceeds 90% of limit
The summary request uses the same prefix as normal conversation requests, maximizing API cache hits:
[System prompt + Tools + Old summary] ← cache hit, billed at P_cache
[Dropped old messages H] ← cache hit, billed at P_cache
[Summary instruction] ← only this part is cache-miss
With Claude Sonnet 4 (compacting 45K tokens of history):
| Tokens | Without cache alignment | With cache alignment |
|---|---|---|
| System prompt ~2K | Full: $0.006 | Cached: $0.0006 |
| Tools ~3K | Full: $0.009 | Cached: $0.0009 |
| Dropped messages ~40K | Full: $0.120 | Cached: $0.012 |
| Summary instruction ~200 | Full: $0.0006 | Full: $0.0006 |
| Total ~45.2K | $0.136 | $0.014 |
| Saves ~90% |
Full derivation:
docs/compact-analysis.md.
Read · Write · Edit · Bash · Glob · Grep · TodoWrite · PlanConfirm · PlanClear · Skill · SubAgent
See
docs/tools.mdfor details. TheBashtool permission model is documented indocs/bash-tool-policy.md.
Loaded from these locations (highest priority first):
.claude/skills/<name>/SKILL.md
./skills/<name>/SKILL.md
~/.claude/skills/<name>/SKILL.md
Three-layer mechanism: skill-index (summary) → selected-skills (full load) → Skill tool (on-demand read).
Per scope, loads the highest-priority file: AGENTS.md > AGENT.md > CLAUDE.md > .claude/CLAUDE.md
Scopes: global (~/.bash-agent/) and project (current directory).
| Document | Description |
|---|---|
docs/architecture.md |
Architecture, layering, protocols |
docs/bash-tool-policy.md |
Bash and local file tool permission mode, classification rules, recommended settings |
docs/tools.md |
11 built-in tool references |
docs/compact-analysis.md |
Compaction algorithm derivation |
docs/sessions.md |
Session files and recovery |
make test # run all tests (bash + go unit + rust check)
make test-go-e2e # Go integration tests (build + test.sh)
make test-rust-e2e # Rust integration tests (build + test.sh)MIT