Terminal coding agent · Written in Rust · MIT

notagent is a terminal coding agent that wastes nothing: one Rust binary, any model, half the tool output.

brew install --cask notagentdev/tap/notagent
Read the docs

macOS on Apple Silicon · v0.1.49 Build from source on anything else

Welcome to notagent v0.1.49 Send /help for help information. Directory: ~/projects/notagent Git: main Model: anthropic/claude-fable-5-1
  ❯ Show the cache hit rate in the footer, next to the token counters.   * Thought (2s) (ctrl+o to expand)   EXPLORED  (4s)  Read crates/notagent/src/modes/interactive/components/footer.rs  Searched text cache_read  Read footer.rs L380-460  1 search, 2 reads   * Thought (1s) (ctrl+o to expand)   PATCH  (footer.rs) +2 -1   446 parts.push(format!("R{}", tokens(usage.cache_read)));  -447 parts.push(format!("{context_percent}%/{window}"));  +447 parts.push(format!("CHR{rate:.1}%"));  +448 parts.push(format!("{context_percent}%/{window}"));   BASH  (cargo test -p notagent --test footer)  test result: ok. 60 passed; 0 failed; 0 ignored  bash filter: 624 → 24 tokens, full log kept on disk   ⠿ The footer now prints CHR with one decimal after the cache counters and   keeps the context share last, where it was.   Worked for 41s ❯   auto ↑12.4k ↓1.8k R98.1k CHR91.2% 9.1%/200k(anthropic) claude-fable-5-1 • high

Measured savings

53%

fewer estimated tokens to read a commented Rust source file through read_minified. 15 became 7.

96%

smaller context cost for a 60-test cargo run through the bash filter. 624 tokens became 24.

0

runtime dependencies. One static binary from cargo build. No Node, no Python, no daemon.

Fixture measurements with notagent's deterministic four-units-per-token estimators. They are reproducible, not a promise for every input: savings depend on how much removable structure the input contains.

01  Context

Context is the budget. Spend it on the work.

Most of a coding agent's context goes to reading files and watching commands run. notagent shrinks both before they enter the conversation, and keeps the conversation itself cacheable.

Minified tools

read_minified returns a compact view of a source file: comments removed, blank lines dropped, indentation collapsed to one space per nesting level. patch_minified and multi_patch_minified edit through that same view. A source map translates every edit back to the real file, and nothing is written until every edit succeeds.

read
// The mode leads: whether the agent may
// modify the workspace must be readable.
if let Some(mode) = session.active_mode() {
    stats.push(theme.bold(&theme.fg(
        mode_color(&mode.id, mode.shell),
        &mode.id,
    )));
}

// Build the stats line.
let pwd = location_parts.join(" • ");
15 tokens (est.)
read_minified
if let Some(mode) = session.active_mode() {
 stats.push(theme.bold(&theme.fg(
  mode_color(&mode.id, mode.shell),
  &mode.id,
 )));
}
let pwd = location_parts.join(" • ");
7 tokens (est.)

Bash filter

Conservative, process-free compaction of shell output before it enters the context. Verbose build, test and package-manager output shrinks to what the agent actually needs. The filter never loses information: whenever a compaction would be empty, larger than the raw output or uncertain, the raw output passes through untouched.

/bash-filter on|off

cargo test, raw
running 60 tests
test footer::shows_cache_hit_rate ... ok
test footer::hides_rate_before_first_turn ... ok
test footer::keeps_model_right_aligned ... ok
test footer::truncates_long_paths ... ok
test footer::formats_tokens_compactly ... ok
test footer::goal_badge_gets_own_line ... ok
test footer::mode_leads_the_stats_line ... ok
… 52 more lines
test result: ok. 60 passed; 0 failed; 0 ignored
624 tokens (est.)
what the agent sees
test result: ok. 60 passed; 0 failed; 0 ignored
full output: <log path>
24 tokens (est.)

One agent, cache-friendly modes

Planning and execution stay within the same long-lived agent, conversation and cache identity instead of moving to a separate agent with copied context. Switching modes keeps the shared history intact and changes only the compact mode-specific instructions and tool surface, so provider prompt caches reuse matching prefixes rather than warming a new agent from scratch.

request prefix delta
plan system · history · tools plan rules
execute cache hit execute rules
plan cache hit plan rules
The mode switch changes a few hundred tokens at the end. Everything before them stays cached.

Atomic writes, shared checkout

With /leases on, every mutating file tool takes an advisory, time-bounded lease before it writes. Several agents working in one checkout stop overwriting each other: only one holder may modify a file at a time, a content hash taken at reservation detects a file changed underneath the holder before the commit, and leases expire on their own so a crashed agent never blocks a file.

.notagent/leases

agent A footer.rs · hash 3f9a commit
agent B wait footer.rs · hash 8c21
agent C theme.rs · crashed expired
One holder per file. A stale hash refuses the commit. Expiry frees what a dead agent left behind.

02  Everything else

The rest of the agent, without the rest of the stack.

  • /goal

    Goal mode

    Set an objective the agent keeps pursuing across turns, with optional turn and token budgets.

  • /index

    Local code index

    A tree-sitter symbol index the agent queries through a dedicated tool instead of grepping blindly.

  • /fork · /clone · /tree

    Session tree

    Branch and navigate a session. Export it as HTML or JSONL, import JSONL to resume.

  • /btw

    Side questions

    Ask a forked child that already knows the whole conversation. The exchange never enters the conversation itself.

  • notagent-server

    Remote sessions

    A CBOR binary protocol, a Unix-socket session server and SQLite storage, so a session outlives the terminal that started it.

  • /mcp

    MCP

    List, add, inspect and authenticate MCP servers at runtime.

  • ~/.notagent/agent/skills

    Skills

    Four built-in skills for planning, executing, exploring and debugging. Edit them, replace them, or delete one to restore it.

  • hooks.json

    Hooks

    Shell commands on every lifecycle event, from SessionStart to SubagentStop. Blocking or observational, with a strict JSON contract.

  • cargo build --release

    One static binary

    Build it and you are done. No runtime, no node_modules, works offline with the built-in model catalog.

03  Models

Any model. Yours included.

45 providers ship in the binary and are picked up from ambient environment variables such as ANTHROPIC_API_KEY or OPENAI_API_KEY without a login. Ollama, LM Studio and any OpenAI-compatible server are first-class: on a loopback address the key can stay empty. Extra providers and model overrides go in ~/.notagent/agent/models.json.

  • Anthropic
  • OpenAI
  • OpenAI Codex
  • Google
  • Google Vertex
  • Amazon Bedrock
  • Azure OpenAI
  • GitHub Copilot
  • Mistral
  • DeepSeek
  • xAI
  • Groq
  • Cerebras
  • Fireworks
  • Together
  • Baseten
  • NVIDIA
  • Hugging Face
  • OpenRouter
  • Vercel AI Gateway
  • Cloudflare AI Gateway
  • Cloudflare Workers AI
  • Moonshot AI
  • Kimi Coding
  • Qwen
  • MiniMax
  • Xiaomi
  • Z.ai
  • Ant Ling
  • OpenCode
  • Cline
  • Ollama
  • LM Studio
  • MTPLX
  • Any OpenAI-compatible endpoint

Regional variants (CN, SGP, AMS) and token-plan endpoints are not listed separately. Provider docs

04  Programmable

Every lifecycle event has a hook.

Hooks are shell commands attached to agent lifecycle events. PreToolUse and UserPromptSubmit can refuse; every other event observes. Each hook receives one JSON object on stdin and answers with an exit code or one structured document. The contract is deliberately strict, so a malformed answer never passes as a quiet yes.

[
  {
    "event": "PreToolUse",
    "matcher": "write,edit",
    "command": "check-change",
    "timeout_ms": 30000
  },
  {
    "event": "UserPromptSubmit",
    "command": "jq -e '.prompt | length <= 2000' >/dev/null || { echo 'Prompt is too long' >&2; exit 2; }",
    "timeout_ms": 5000
  }
]

Events

  • SessionStart
  • SessionEnd
  • TurnStarted
  • UserPromptSubmit
  • UserPromptQueued
  • PreToolUse
  • PostToolUse
  • PostToolUseFailure
  • PermissionRequest
  • PermissionResult
  • TaskStarted
  • SubagentStart
  • SubagentStop
  • PreCompact
  • PostCompact
  • Stop
  • StopFailure
  • Interrupt
  • Notification
Hook reference

05  Open source

Ten crates, one workspace, MIT.

A Cargo workspace with a pinned toolchain and a single gate: format, clippy with warnings denied, and the whole test suite. notagent builds on work from pi.

notagent
The CLI: TUI, slash commands, sessions, tools
notagent-agent
Agent loop, tool execution, message queues
notagent-ai
Providers, streaming, auth, the model catalog
notagent-tui
Terminal UI with differential rendering
notagent-client
Transport-neutral protocol client with a lease system
notagent-protocol
CBOR binary protocol for remote sessions
notagent-server
Session server core with Unix socket transport
notagent-session-sqlite
SQLite session storage
notagent-telemetry
Vendor-neutral telemetry contracts
notagent-index
Code symbol indexing with tree-sitter

06  Install

Two minutes to the first turn.

The Homebrew cask supports Apple Silicon Macs. notagent checks for new versions in the background and shows the upgrade command when one is available. It never runs Homebrew or replaces its own executable.

Install

brew install --cask notagentdev/tap/notagent

Update

brew upgrade notagent

Or build from source, toolchain pinned by the repository

cargo build --release

Then, inside the TUI

/login