Terminal-native AI coding agent in Rust, built as a client of the Chitragupta kernel.
What is live today • Quickstart • If the daemon is down • Commands and keys • Plugins • Docs map • Development
Read this first — what actually runs.
The live binary is the Rust workspace in
crates/. It is daemon-only: Takumi connects to the Chitragupta daemon at startup and routes every turn through it. Takumi holds no API keys and picks no provider locally.The older TypeScript monorepo (
packages/*,@takumi/*, direct providers, Darpana proxy, headlessexec, desktop shell) is parked — seeKILL.md. None of it is wired into the Rust binary today. If you read a doc that describes those, treat it as history or design direction, not current behavior.
Takumi is a Rust workspace — six crates under crates/:
| Crate | What it is |
|---|---|
takumi |
CLI entry point: connects the daemon, spawns the agent loop, hands the terminal to the TUI |
takumi-tui |
ratatui full-screen UI: transcript, composer, welcome, slash commands, modals |
takumi-core |
shared config, types, session log primitives |
takumi-provider-chitragupta |
the daemon client — Unix-socket NDJSON JSON-RPC (bridge.bootstrap, chat.stream, binding.update) |
takumi-tools |
built-in tool runtime: bash, read, edit, write (workspace-scoped) |
takumi-host-wasm |
the WebAssembly Component Model host for capability-gated plugins |
What you get when you run it:
- a full-screen terminal UI with autoscroll, a live phase-aware thinking indicator, GFM-table rendering, and a Sanskrit-grounded palette
- a streaming agent loop with four built-in tools (
bash,read,edit,write), scoped to the workspace - MCP servers — both extension-bound and global
.mcp.json(Claude Code style), loaded in the background so they never block first paint - a WebAssembly plugin system — sandboxed
.wasmcomponents that contribute tools, hooks, and slash commands under a deny-by-default capability model (Plugins) - live model/provider switching via
/modeland/provider, which rebind the daemon's active route
Takumi (Rust TUI)
└─ Chitragupta daemon (Unix socket, NDJSON JSON-RPC)
├─ owns: routing (provider/model/OAuth), credentials, memory, skills
├─ bridge.bootstrap → registers the session + initial binding
├─ chat.stream → one call per turn; events stream back as notifications
└─ binding.update → /model and /provider rebind here
Chitragupta is the root kernel. It owns models, providers, memory, skills, and routing — Takumi is a client of that truth, not a separate truth-maker. That's why there are no API keys in Takumi's config and no --provider flag.
- Rust ≥ 1.85 (edition 2024)
- the Chitragupta daemon, installed and runnable (
pnpm chitragupta daemon start)
There is no npm package and no direct-provider key path. Takumi will not start without the daemon — that's by design (see If the daemon is down).
# 1. one-time: start the Chitragupta daemon
pnpm chitragupta daemon start
# 2. run Takumi (release build recommended)
cargo run -p takumi --releaseOn connect, the welcome screen shows your live state — the route mode, the model, and the project path. If the daemon landed you on a fallback route, it shows a ⚠ with the reason, so you always know what you're actually talking to before you type.
cargo run -p takumi --release- wait for the welcome line to show
via … • <model> - type
/helpfor the command list - ask a repo question —
summarize the crate layout— and watch it useread/bash /statusto see route, model, and project at any time
Takumi is daemon-only. If the socket isn't there at startup, it does not silently fall back to anything — it exits before the TUI with an actionable error:
Chitragupta daemon socket not found at
~/Library/Caches/chitragupta/daemon/chitragupta.sock.
Start the daemon with `pnpm chitragupta daemon start` and try again.
What to do:
# start it
pnpm chitragupta daemon start
# verify it's up
pnpm chitragupta daemon statusIf the daemon is up but Takumi still can't connect, the error names the usual causes:
- stale bridge token — restart the daemon
- daemon rebuilt but not restarted — restart so it picks up the new build
Once connected, if the daemon puts you on a degraded route, Takumi tells you on the welcome line and in /status rather than pretending the primary route worked.
Not today. The daemon is required. The direct-provider / Darpana-proxy / headless-exec paths that earlier docs describe lived in the parked TypeScript app and are not wired into the Rust binary. If you need a no-daemon path, that's a future-direction item, not current behavior.
The agent runtime registers four built-in tools, all confined to the workspace (the cwd tree by default; widen with TAKUMI_ALLOW_ROOTS):
bash— run shell commands in the working directoryread— read file contentsedit— modify files in placewrite— create or overwrite files
Beyond these, the model can call MCP tools (mcp__<server>__<tool>) and plugin tools (plugin__<name>__<tool>) when servers/plugins are loaded.
Slash commands run locally (no agent round-trip) for meta controls; model/provider/think/recall emit a command the daemon handles.
| Command | Purpose |
|---|---|
/help (/h, /?) |
List available commands and keys |
/status |
Show route mode, model, and project |
/model <name> |
Rebind the daemon's active model |
/provider <name> |
Browse one provider's model catalog |
/think <off|low|medium|high> |
Set the daemon's thinking depth |
/recall <query> (/remember) |
Search cross-session memory (Smriti) |
/clear (/reset) |
Reset the conversation |
/compact [N] |
Collapse all but the last N messages locally (default 8) |
/logs [N] (/log) |
Show the last N lines of the local log (default 30) |
/mcp |
List active MCP servers (extension-bound + .mcp.json) |
/plugins |
List loaded Wasm plugins (tools, capabilities, hooks) |
/extensions (/ext) |
List user-defined extensions with capabilities + MCP status |
/extension new <slash> [desc] |
Scaffold a starter extension template |
/install <path-or-url> |
Install an extension JSON into the user scope |
/uninstall <slash> (/remove) |
Remove an installed extension |
/quit (/q, /exit) |
Quit |
Plugins and extensions add their own slash commands on top of these.
Enter send · Alt-Enter newline · Tab thinking · Ctrl-X cancel
Up/Down scroll · Ctrl-B/F page · Ctrl-U/D half-page
Ctrl-P/N input history · Ctrl-L clear · Ctrl-C quit
Takumi loads compiled WebAssembly Component Model plugins from ~/.config/takumi/plugins/*.wasm. They run sandboxed in wasmtime and can:
- contribute tools the model can call (
plugin__<name>__<tool>) - run hooks in the agent loop —
on-tool-call,on-tool-result,on-message,on-user-prompt,on-session,on-turn(observe, gate, or rewrite) - register slash commands
Plugins are deny-by-default. A plugin declares the capabilities it needs in its manifest using Sanskrit-named tokens; the host links the matching host-function into the plugin's sandbox only if granted. An ungranted plugin physically can't reach the function — enforcement is the runtime, not a checklist.
| Family | Examples | Risk |
|---|---|---|
vidya:* |
read-memory, write-memory |
Low / Medium |
darsana:* |
on-tool-call, on-message, ui, … |
Low |
sanskara:persist-state |
durable per-plugin state | Medium |
vichara:invoke-llm |
subordinate model calls | Medium |
karma:* |
bash, fs-read, fs-write, network (reserved — no host binding yet) |
High |
High-risk capabilities are denied unless you opt in with TAKUMI_PLUGIN_ALLOW_HIGH_RISK=1. See docs/plugin-architecture.md for the full model and examples/sample-plugin for an end-to-end plugin.
User config lives at ~/.config/takumi/config.json (assistant name, theme colors, MCP tool filters). Takumi already talks to Chitragupta through the daemon bridge, so the Chitragupta MCP mirror is denied by default before tools reach the model. Use mcpToolsAllow only when you deliberately want to re-enable a specific Chitragupta MCP tool.
{
"mcpToolsDeny": ["mcp__noisy-server__*"],
"mcpToolsAllow": ["mcp__chitragupta__chitragupta_context"]
}Environment knobs:
| Var | Effect |
|---|---|
TAKUMI_SYSTEM |
Override the default system prompt |
TAKUMI_ALLOW_ROOTS |
Widen the workspace scope for file tools and bash beyond cwd |
TAKUMI_PLUGIN_ALLOW_HIGH_RISK=1 |
Allow plugins to be granted high-risk capabilities |
Logs go to ~/.takumi/log/takumi.log (rotated daily) — never to stderr, since the TUI owns the screen. Tail them in-app with /logs.
cargo build
cargo test # exercises core, tools, tui, and the wasm host + capability tests
cargo clippy --all-targets -- -D warnings
cargo run -p takumi --releaseThe Rust core is held to: every module bounded in LOC, modular and DRY, clippy::pedantic clean, rustdoc on every public item.
docs/plugin-architecture.md— the WebAssembly plugin system, capability model, and WIT contractdocs/takumi-chitragupta-bridge.md— the daemon RPC contract Takumi speaksdocs/chitragupta-asks.md— daemon-side functionality Takumi needsdocs/ARCHITECTURE.md— architecture overview (note: predates the Rust rewrite in places)KILL.md— the parked TypeScript modules and whyDEFECTS.md— the user-facing pains that drove the rewrite
Docs accuracy: much of
docs/was written for the TypeScript app and is being re-derived for the Rust core. Where a doc and the code disagree, the code incrates/wins.
Takumi is part of the broader Chitragupta ecosystem:
| Project | Role |
|---|---|
| Chitragupta | the root kernel — memory, sessions, routing, daemon |
| Darpana | LLM proxy (used by the kernel, not directly by the Rust Takumi) |
Takumi owes a debt to the wider world of terminal coding agents and developer tooling — a lineage of them shaped what a good coding companion in the terminal should feel like. Takumi takes the inspiration and grows its own organs rather than cloning any of it. Thanks to everyone building in this space.
Takumi is licensed under the Apache License 2.0.
Takumi talks to the Chitragupta kernel over a local IPC socket — they are separate programs. Chitragupta is licensed independently (AGPL-3.0); Takumi implements only the client side of the wire protocol and does not link or vendor its source, so the two licenses don't collide.