A local-first AI coding agent harness for the terminal, written in Rust.
Multi-crate Cargo workspace with a full agent loop: skills, multi-layer memory, tool calling, streaming LLM providers, and both a TUI and a scriptable CLI. Point it at Ollama, LM Studio, MLX, vLLM, or any OpenAI-compatible endpoint — the model, the memory, and the tool loop all stay on your machine.
Note
KOD is early-stage. The workspace builds, tests pass, and the CLI and TUI are usable, but the public API is still stabilising. See Project Status for what is wired up today versus what is still on the roadmap.
cargo install --locked --path crates/kod-cliOr build the workspace and take the binary directly:
cargo build --release --locked
./target/release/kod doctor # verify the toolchain and config
./target/release/kod profile use local-fast
./target/release/kod tuiEvery tagged release publishes archives for the six targets in the release matrix (Linux x86_64 glibc + musl, Linux aarch64, macOS x86_64
- arm64, Windows x86_64). Each archive ships with a
.sha256, and — when the maintainer has configured a signing key — a.minisig. Verify before unpacking:
sha256sum -c kod-x86_64-unknown-linux-musl.tar.gz.sha256Every archive ships a .sha256 — that is the canonical integrity check
for any release. Minisign signatures (.minisig) are opt-in: they
appear only when the maintainer has configured MINISIGN_SECRET_KEY as
a repository secret for the release workflow. When present, verify with
the maintainer's public key:
minisign -Vm kod-x86_64-unknown-linux-musl.tar.gz -P <public-key>When no .minisig file is present alongside the archive, signing is not
enabled for that release and .sha256 is the integrity check to use.
- Rust 1.99 or newer (
rustup toolchain install 1.99). - A provider endpoint: a local Ollama server, or an OpenAI-compatible
or Anthropic API key.
kod doctorreports what is configured.
- Why local-first
- Features
- Architecture
- Getting Started
- Usage
- Configuration
- Skills
- Development
- Testing
- Project Status
- License
Your code does not leave your machine.
This is the difference between KOD and most terminal coding agents. Cloud-hosted agents are built around a model you do not control, on a schedule you do not set, under terms that can change without your consent. When a vendor deprecates a model, changes a rate limit, or has a bad day, your workflow stops.
KOD is built around the opposite assumption:
- The binary is one Rust program.
cargo build --releaseproduces a single executable that runs the agent, the tools, the memory store, and the terminal UI. No Node runtime, no Python interpreter, no Docker. - The model is one you chose. The default config points at
http://localhost:11434/v1(Ollama). Any OpenAI-compatible endpoint works — LM Studio, MLX Omni Serve, vLLM, OpenAI itself — but only if you want cloud. - Memory is on disk, in a file you can inspect. Long-term memory lives in a
redbdatabase under~/.kod/, or per-project under<cwd>/.kod/whenmemory.scope = "project". - The tool loop is auditable.
kod replay <session.jsonl>re-runs the tool calls a session made, without the model. Everyread_file,write_file, andexecute_commandis checkable against the codebase at any later commit.
If "where does my code go when I run this?" is a question you want a one-line answer to, KOD is for you.
- Skills system — Markdown files with YAML front matter, matched by triggers, tags, capabilities, and name. Hot-reloads on edit.
- Multi-layer memory — Short-term (in-memory, FIFO) and long-term (
redb, persistent). Global or project-scoped, with word-overlap retrieval against the user's prompt. - Tool calling — File system (
read_file,write_file,patch_file,list_files,grep,file_info), git (git_status,git_diff), and shell (execute_command). Every tool is permission-gated throughToolContext. - Streaming agentic loop — The engine classifies tasks, builds a grounded prompt (identity + environment + repo map + skills + history), streams tokens live, executes tool calls, and feeds results back up to a configurable round cap.
- Agent swarm —
kod swarmdecomposes a goal into N subtasks, runs them concurrently, detects file conflicts, and asks the model to merge the results. - Optional sandboxing —
--sandboxruns shell commands throughbwrap(Linux) orsandbox-exec(macOS), failing loudly if the primitive is unavailable rather than silently running unsandboxed. - Session logs and replay — Every tool call is recorded as JSONL and can be re-executed with
kod replayas a regression check. - Model profiles —
kod profileships presets for common local and cloud models.
- TUI — A full ratatui interface with chat, live tool rows, agent panel, search, themes, slash commands, streaming responses, and a context meter.
- CLI — A scriptable command-line interface with
chat,agent,swarm,skills,config,models,profile,sessions,map,replay,doctor,init,test, and shell completions.
- OpenAI-compatible, single code path — Ollama's
/v1, LM Studio, MLX Omni Serve, vLLM, and OpenAI all speak the same chat-completions wire protocol. Base URLs are normalised automatically, so a server root or an.../v1root both work. - Streaming with tool calls — SSE token streaming with
ToolCallStart/ToolCallDeltaframing, so tool calls are assembled live, not buffered.
KOD is a Cargo workspace. Each crate has a single responsibility and a narrow public API, so each phase can be tested in isolation.
| Crate | Description |
|---|---|
kod-types |
Shared types: strongly-typed IDs, messages, skills, memory, tools. |
kod-error |
KodError enum and Result alias. |
kod-config |
KodConfig, LlmConfig, MemoryConfig, SkillsConfig, SwarmConfig, model profiles. |
kod-ast |
Tree-sitter parsing with a process-global parse cache (powers the repo map). |
kod-ast |
Tree-sitter parsing with a process-global parse cache (powers the repo map). |
kod-ast |
Tree-sitter parsing with a process-global parse cache (powers the repo map). |
kod-provider |
LlmProvider trait, GenerationOptions, streaming chunk types. |
kod-provider-openai |
OpenAI-compatible implementation (backed by adk-model). |
kod-provider-anthropic |
Anthropic Messages API provider (native wire; adk-model for the legacy text path). |
kod-lsp |
Minimal Language Server Protocol client: JSON-RPC over stdio, diagnostics, definition, references, hover. |
kod-mcp |
Minimal Model Context Protocol client: spawns MCP servers, lists and calls their tools. |
kod-skills |
Skill parser, loader, matcher, and hot-reload watcher. |
kod-memory |
Short-term memory and long-term redb storage. |
kod-tools |
Tool trait, registry, built-in tools, per-path lock table, sandbox invocation. |
kod-swarm |
Agent lifecycle, communication hub, task coordinator, shared workspace. |
kod-core |
KodEngine, TaskRouter, SwarmRunner, repository map, session log, hooks. |
kod-core-quality |
Codebase analysis, cleanup, and quality gates: snapcompact, shake, repomap. |
kod-core-routing |
Task routing and provider selection policy for the engine. |
kod-core-serve |
Unix-socket daemon and ACP bridge (JSON-RPC over stdio). |
kod-core-state |
Persistent state, journals, ledgers, and cost accounting. |
kod-core-tools |
Adapter layer wrapping KOD's built-in tools for the engine's dispatch loop. |
kod-core-quality |
Codebase analysis, cleanup, and quality gates: snapcompact, shake, repomap. |
kod-core-routing |
Task routing and provider selection policy for the engine. |
kod-core-serve |
Unix-socket daemon and ACP bridge (JSON-RPC over stdio). |
kod-core-state |
Persistent state, journals, ledgers, and cost accounting. |
kod-core-tools |
Adapter layer wrapping KOD's built-in tools for the engine's dispatch loop. |
kod-core-quality |
Codebase analysis, cleanup, and quality gates: snapcompact, shake, repomap. |
kod-core-routing |
Task routing and provider selection policy for the engine. |
kod-core-serve |
Unix-socket daemon and ACP bridge (JSON-RPC over stdio). |
kod-core-state |
Persistent state, journals, ledgers, and cost accounting. |
kod-core-tools |
Adapter layer wrapping KOD's built-in tools for the engine's dispatch loop. |
kod-tui |
Terminal UI: app state, event handling, widgets, keybindings, themes. |
kod-cli |
The kod binary: command definitions and handlers. |
kod-risk |
Path-danger classification: ranks filesystem paths by blast radius for approval and sandboxing. |
kod-schema-dialect |
Per-provider JSON-schema dialect translation for tool definitions. |
kod-minimize |
Shell-output minimizer: reduces a command's output to the lines that matter. |
kod-stats |
Behavioral + per-request analytics, if-bench, and conventional-commit validation. |
kod-telemetry |
OTLP export of turn and session telemetry. |
user input
│
▼
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ TaskRouter │──▶│ Memory + │──▶│ Grounded │ (kod-core, kod-memory, kod-skills)
│ (classify) │ │ Skill match │ │ prompt │
└────────────────┘ └────────────────┘ └────────────────┘
│
▼
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Tool results │◀──│ LLM provider │──▶│ Streaming │ (kod-provider, kod-tools)
│ fed back │ │ (streaming) │ │ chunks → UI │
└────────────────┘ └────────────────┘ └────────────────┘
│
▼
┌────────────────┐ ┌────────────────┐
│ Final reply │──▶│ Session log │ (kod-core::session_log, replay)
│ → CLI / TUI │ │ (JSONL) │
└────────────────┘ └────────────────┘
See docs/ARCHITECTURE.md for the full crate-by-crate breakdown, and docs/SPEC.md for the longer design document.
- Rust 1.99 or newer (install via rustup). The workspace uses the 2024 edition.
- A model server — Ollama is the recommended default, but any OpenAI-compatible endpoint works.
- Git — required for the git tools and for
build.rs(version stamping).
git clone https://github.com/elcoosp/kod.git
cd kod
cargo build --releaseThe binary lands at ./target/release/kod.
# 1. Make sure your model server is running
ollama serve
# 2. Pull a model
ollama pull qwen2.5-coder:7b
# 3. Verify the setup
./target/release/kod doctor
# 4. Point KOD at a model
./target/release/kod profile use local-fast
# 5. Start a session
./target/release/kod tuikod init will walk you through the same steps and write a default config to ~/.config/kod/config.toml if one does not exist.
kod [--verbose] <COMMAND>
Commands:
chat Start a chat session
tui Launch the interactive terminal UI
agent Run an agent with a specific goal
swarm Decompose a goal into N subtasks, run them concurrently, merge
prompt One-shot prompt, non-interactive; reads `-` from stdin
run Like prompt, but streams tokens to stdout as they arrive
serve Long-lived daemon that `--remote` clients attach to
acp Agent Client Protocol bridge on stdin/stdout (editor integration)
skills List, scaffold, edit, or export skills
validate-skills Parse every skill file; exit non-zero on failure
validate-skills-strict Same, but treat missing version fields as failures
config Show, path, edit, validate, or migrate the config
memory Inspect, search, export, or import long-term memory
sessions Inspect, export, import, or clear the saved TUI session
checkpoint List, diff, restore, or clear file checkpoints
replay Re-run the tool calls recorded in a session log
map Print the repository map (symbols per source file)
models List the models the configured provider offers
profile List, show, or switch model profiles
tools List registered tools or print one tool's schema
theme List built-in TUI themes or print one palette
policy Inspect or forget effective tool-policy decisions
sandbox Report whether the platform sandbox primitive is available
jev Jev (TypeSafe AI) status, statistics, and threshold tuning
budget Session cost and current limits
limits Per-tool quotas and counters
plan Plan artifact for the current session
decisions Durable decisions recorded for the current session
trace Inspect the structured turn traces written by the engine
commit-check Validate a conventional-commit message against staged changes
if-bench Run the if-bench instruction-following eval on the default endpoint
fixture Save and replay deterministic streaming fixtures
doctor Print a diagnostics report (config, endpoint, sandbox, git)
init First-run helper: write config, print next commands
test Run the built-in self-tests
update Check GitHub for a newer release (read-only)
completions Print a shell completion script
A few worth calling out:
# Chat with streaming output
kod chat --model qwen2.5-coder:7b
# One-shot agent run
kod agent -g "add a doc comment to every public function in src/lib.rs"
# Run a swarm on a larger goal
kod swarm -g "implement and test a rate limiter for the HTTP client" -n 4
# Switch to a cloud model
kod profile use cloud-openai
# Replay a recorded session
kod replay ~/.kod/sessions/1730000000000.jsonl --executeLaunch with kod tui (or just kod for the entry-point summary). The interface has a header, chat area, status line, and input box.
Key bindings (normal mode):
| Key | Action |
|---|---|
i |
enter insert mode |
Esc |
cancel the running prompt (in normal mode) |
j / k |
scroll down / up |
g / G |
jump to oldest / newest |
PgUp / PgDn |
scroll by page |
t |
toggle tool-output visibility |
o |
expand the newest collapsed tool row |
f |
start a type-ahead search |
n / N |
next / previous search match |
y |
copy the last assistant reply |
r |
retry the last prompt |
e |
edit your last message |
u |
undo a /clear |
? |
help overlay |
q |
quit (asks for confirmation when a generation is running) |
In insert mode: Enter sends, Ctrl+J (or Shift+Enter) inserts a newline, Tab cycles completions, Up/Down walk prompt history, Ctrl+W / Ctrl+U / Ctrl+K edit the line, Ctrl+Left / Ctrl+Right jump by word.
Slash commands:
/help /clear /model [<name>] /skills /goal <text>
/steer /cancel /compact /retry /search [<text>]
/copy /theme /tools /undo /edit
/debug /swarm /quit
Tip
Typing a plain prompt while a generation is running steers it — the same as /steer. This is the fastest way to redirect a run that is heading the wrong direction without losing the work it has already done.
# Bash
kod completions bash > ~/.local/share/bash-completion/completions/kod
# Zsh
kod completions zsh > ~/.zfunc/_kod
# Fish
kod completions fish > ~/.config/fish/completions/kod.fishKOD reads its config from ~/.config/kod/config.toml (Linux) or ~/Library/Application Support/kod/config.toml (macOS). The file is auto-generated on first run.
[llm]
provider = "OpenAICompatible" # or "Ollama" / "OpenAI" (aliases)
model = "qwen2.5-coder:7b"
base_url = "http://localhost:11434/v1"
context_window = 32768
max_tokens = 4096
temperature = 0.2
timeout_secs = 120
[memory]
short_term_capacity = 100
scope = "global" # or "project"
# long_term_db_path = "/custom/path.redb" # overrides scope
[skills]
enable_hot_reload = true
max_skills_per_query = 3
# skills_dir = "/custom/skills" # overrides the standard search paths
[swarm]
max_agents = 5 # clamped to 2–8 by the runner
merge_results = true
[hooks]
enabled = false
# pre_tool_use = { write_file = "rustfmt {path}" }
# post_tool_use = { write_file = "cargo check" }Out-of-range values are clamped with a warning at load time, so a typo does not produce a mysterious failure three prompts later.
Note
The provider field accepts OpenAICompatible, Ollama, and OpenAI — the last two are aliases for the first. Any server that speaks the OpenAI chat-completions protocol works on the same code path: Ollama's /v1, LM Studio, MLX Omni Serve, vLLM, and OpenAI itself.
The kod profile subcommand ships a small set of presets so a first-run user does not have to know what a context_window is to get a working session.
kod profile list # show the built-in presets
kod profile show # print the effective [llm] config
kod profile use local-fast # write the preset's values into config.tomlPresets: local-fast (Qwen 2.5 Coder 7B), local-capable (32B), local-reasoning (DeepSeek-R1 14B), cloud-openai (GPT-4o mini).
Skills are Markdown files with YAML front matter. KOD discovers them in these directories, in order; later directories shadow earlier ones for skills that share a name:
~/.kod/skills— canonical KOD location~/.agents/skills— Claude-style compatibility<project>/.kod/skills— project-local KOD<project>/.agents/skills— project-local Claude-style
Set skills.skills_dir in the config to use a single custom directory instead.
---
name: rust-refactoring
description: Rust refactoring with idiomatic patterns
version: 1.0.0
category: coding
tags: [rust, refactoring, idioms]
capabilities: [code-refactoring, ownership-analysis]
triggers:
- "refactor rust"
- "make more idiomatic"
---
## Instructions
You are an expert Rust refactoring assistant...
## Examples
<example input="Refactor this loop">
...
</example>
## Constraints
- Never change public API without explicit request
- Preserve existing testsThe parser splits the body into instructions, examples, and constraints, and all three reach the model when the skill is matched. Hot reload is on by default — edit a skill file and the next prompt sees it.
kod skills and /skills inside the TUI both list the merged set from every standard directory.
# Build
cargo build --workspace
# Run all tests
cargo test --workspace
# Lint and format
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
# Run the full check suite (format + lint + test + release build)
./scripts/test.sh
# Benchmarks
cargo bench --workspaceA justfile provides shortcuts: just build, just test, just lint, just check, just bench.
Some tests exercise the real provider against a running server. They are #[ignore]-gated so cargo test stays fast and offline:
# Start Ollama, pull a small model, then:
KOD_TEST_MODEL=qwen2.5:0.5b \
cargo test -p kod-provider-openai -- --ignored --nocapture
KOD_TEST_MODEL=qwen2.5:0.5b KOD_TEST_DB=/tmp/kod-test.redb \
cargo test -p kod-tui --test main_loop -- --ignored --nocaptureThe workspace spans 26 crates with 5,678 tests passing (unit, integration, and doc tests combined). cargo nextest run --workspace runs the full suite without external services.
| Crate | Description |
|---|---|
kod-types |
IDs, message serialization, tool and skill types. |
kod-error |
Error creation, display, conversion. |
kod-config |
Defaults, partial-config parsing, LLM validation, profiles, memory scope. |
kod-provider |
(Trait-only; no tests.) |
kod-provider-openai |
Endpoint normalisation, config wiring, model switching. Live test is #[ignore]-gated. |
kod-skills |
Parser, loader, matcher, watcher, and full-pipeline tests. |
kod-memory |
Short-term FIFO eviction, redb round-trips, retrieval, compaction. |
kod-tools |
Built-in tool tests, path resolution, sandbox invocation, permission enforcement. |
kod-core |
Engine lifecycle, task classification, memory wiring, prompt grounding, tool rounds, session log, swarm runner. |
kod-tui |
App state, event handling, keybindings, completion, search, streaming, main loop. |
kod-cli |
Doctor checks, command dispatch, in-process engine tests. |
kod-lsp |
JSON-RPC framing, position math, diagnostics collection. |
kod-mcp |
Protocol framing, tools/list pagination, tool invocation. |
kod-swarm |
Work pool, agent registry, IRC bus, yield queue, cleanse scheduler. |
kod-provider-anthropic |
Wire body construction, cache-control placement, native compaction. |
To see the exact current total:
cargo test --workspace -- --list | tail -1See docs/TESTING.md for the full testing guide, including per-crate test inventories and CI behaviour.
- Workspace builds on Linux, macOS, and Windows.
- CLI commands:
chat,tui,agent,swarm,skills,config,models,profile,sessions,map,replay,doctor,init,test,completions. - OpenAI-compatible provider with live SSE streaming and tool-call assembly.
- Skills loading from four standard directories with hot reload.
- Short-term and long-term memory with project-scoped or global storage.
- File system, git, and shell tools with permission gating and per-path advisory locks.
- Agentic streaming loop with tool rounds, cancellation, steering, and goal looping.
- Multi-agent swarm runner with decomposition, conflict detection, and merge.
- Session log (JSONL) and
kod replayfor tool-call re-execution. - Optional shell sandboxing through
bwrap/sandbox-exec. - Shell hooks (
pre_tool_use,post_tool_use) driven by config templates. - TUI with chat, live tool rows, agent panel, search, themes, keybindings, and slash-command completion.
- Structured provider protocol (AD-01): the engine builds a
CompletionRequestfrom the router'sPromptPlanand the transcript, and callsLlmProvider::complete/LlmProvider::stream_completion. Anthropic'scache_controlon the last cacheable system segment is wired through the wire module; OpenAI-compatible providers preserve the multi-role transcript and tool-call ids on the wire. - Multi-language LSP pool (
LspManager, design D5.1): one language server per language, lazily started, sharing one pool between thelsp_*tools and the post-write diagnostics hook. kod acp: an Agent Client Protocol bridge on stdio so an editor can spawn the process as its agent (design §11.2).- Sandbox auto-detection with
bwrap/sandbox-exec/ Landlock fallback, plus a live badge in the TUI header. /policyin the TUI andkod policy forget <n>in the CLI for dropping session deny rules (design §6.2).
kod chat --remote/kod prompt --remote/kod agent --remoteattach to a runningkod servedaemon. Response routing for approvals andask_useris implemented: the daemon dispatchesrespond_to_approvalandrespond_to_questionmethods, so a client that sees an approval marker can answer it. What is not yet wired is the initial forward of a marker to a client that has not yet connected — a daemon started with a strict policy on a fresh socket is the case that still times out to deny. A client already attached to aprocess_streamingcall receives the marker on the same connection and can answer.- Per-agent heartbeat watchdog is present but coarse.
swarm_runner.rsruns a per-run watchdog that polls every 10 s and aborts any agent whose last heartbeat is older than 90 s, plus a per-agent timeout (agent_timeout_secs, default 300 s = 5 min). What is not yet wired is finer-grained progress reporting inside a single tool round — a single very slow tool call still consumes the full 5-minute budget before the watchdog intervenes. docs/SPEC.mddescribes a larger aspirational system than the workspace implements. It is kept as a design reference;docs/ARCHITECTURE.mdanddocs/TESTING.mddescribe the code as it exists.
Warning
KOD is not a drop-in replacement for a full-featured IDE agent. It is a working harness whose goal is auditability and local-first control. Expect rough edges.
MIT — see LICENSE for the full text. By contributing, you agree that your contributions will be licensed under the same terms.
KOD is a work in progress. Contributions, bug reports, and design discussions are welcome.