An agent that shows its work.
io-cli is a terminal agent that shows you what it is allowed to do, what it is spending and what it refused — while it works. io-harness is the embeddable Rust runtime underneath it. Both are Apache-2.0, both run on your own provider keys.
Every artifact is checked against SHA256SUMS before it is unpacked
License
Apache-2.0
Core
Rust 1.95+
Pricing
Starts at ₹0
Keys
Keys stay local
Currently shipping
One runtime. One terminal on top of it.
We build the load-bearing layer and give it away. What you build on top is yours.
io-harness
on crates.ioThe base. An embeddable agent runtime for Rust. You hand it a contract — the task, the workspace it may touch, and what it may read, write, run and dial — and it runs the loop and hands back an outcome.
- One line in Cargo.toml: cargo add io-harness. No daemon, no account, no telemetry
- OpenRouter, Anthropic and OpenAI natively, plus 21 OpenAI-shaped presets — 8 of them local runtimes
- Every step, refusal and budget draw in a SQLite trace you own
io-cli
terminalThe terminal agent built on it. Every finished line goes into the terminal’s own scrollback; two sticky rows say what is happening now, what it has spent, and what it is allowed to do.
- A write stops the run and shows the diff: y, a or n, then Enter — answered where it was asked
- The posture is on the footer, and Shift+Tab changes it from the next turn
- /resume reopens a session and answers whatever its last run stopped on
01 — harness
Embeddable, not hosted
Add it as a crate and call it in-process. No binary to install, no daemon, no UI, no account and no telemetry — the default build compiles no optional dependency at all.
02 — harness
Durable by the step
After every completed step the trace, the budget draw and a checkpoint commit in one transaction. A crash resumes the whole tree without re-running steps or double-charging.
03 — harness
Any provider
OpenRouter, Anthropic and OpenAI over the crate's own HTTP+SSE client, one Compatible provider for any OpenAI-shaped endpoint, 21 vendor presets, and fallback between them.
04 — harness
The boundary, traced
Layered, deny-first rules over read, write, exec and network. Every refusal is in the trace, attributed to the rule and the layer that produced it.
05 — cli
It never takes your terminal
No alternate screen and no mouse capture, in any mode, behind any flag. Your terminal's search, selection and tmux copy-mode keep working, and a test fails the build if that changes.
06 — cli
Approvals in place
A write stops the run and shows the diff it proposes. Answer y, a or n and confirm with Enter, where it was asked — so a letter inside a sentence cannot decide a write. Allow for this session remembers that act on that target.
07 — cli
Your key, never on screen
The wizard verifies a key against the live endpoint, writes the file at mode 0600, and writes no key at all when the provider's own environment variable is already set.
08 — cli
Spend, and whether it worked
/cost commits the money and the token split by run, session, model and day; /stats commits the outcomes, first-try counts, gate failures and latencies. Nothing is estimated.
A durable conversation about one repository
use io_harness::{ApproveAll, OpenRouter, Policy, Session, Store};
let provider = OpenRouter::from_env()?;
let store = Store::open("runs.db")?;
let policy = Policy::default()
.layer("app")
.allow_read("*")
.allow_write("src/*")
.deny_read("secrets/*")
.allow_exec("cargo test*")
.deny_exec("cargo publish*");
let mut session = Session::open(&store, "/path/to/repo")?;
let turn = session
.turn("the test suite is failing; why?", &provider, &store, &policy, &ApproveAll)
.await?;
println!("{}", turn.reply.unwrap_or_default());Thirty-six commands, in four groups
ioWith no subcommand, opens an interactive session in this repository/modelChange the model the next turn is sent to — this session only/resumeReopen an earlier session and answer whatever its last run stopped on/statusCommit the whole session state into the scrollback: policy layers, sandbox backend, caps, budgets, connectionsReleases and stability
India first
Built here. Priced here.
Most agent tooling is priced in dollars and tested only on gigabit English. We start from the other end: a student in Coimbatore on shared wifi, a four-person team in Indore on a ₹3,000 budget, a bank in Mumbai whose code cannot leave the building.
01 — Rupee-native
Billed in rupees, UPI at checkout. No FX markup on a dev tool.
02 — Thin-pipe tolerant
A stopped run is resumable: /resume answers what it stopped on and carries on from that step, not from the top of the turn.
03 — Indic in the loop
Prompt and eval packs that hold up on Hindi, Tamil and code-mixed English — being built now, in the open.
04 — Data stays home
Run fully local, or self-host in an Indian region. DPDP-aware defaults from day one.
Pricing · in ₹, not converted
Free is not a trial.
Connect your own providers and use everything. Apache-2.0, self-hostable, no seat count, no sign-up wall, no telemetry.
- Bring your own keys — any provider, including local models
- Unlimited sessions on your own machine
- The full io-harness runtime, embeddable in your own code
- A layered permission boundary and a SQLite trace of every run
- Community support in GitHub Discussions
Will Free get worse when the paid plans ship?
No. Nothing that works today moves behind a paywall. Paid plans are hosting and team features, not the runtime.
Do I need an io account?
Not for Free. Install, add your provider key, run. No sign-up wall.
Are model costs included?
On Free you pay your provider directly — we never mark up tokens. Managed inference is what the Go plan adds.
Install
One command, on any of the four platforms.
Both scripts pick the right build for your machine, verify it against the published SHA256SUMS before unpacking, and install into a directory you own — no administrator rights, and no edit to your shell profile or PATH. The tap and the bucket live in this repository rather than in two of their own, which is why brew tap and scoop bucket add name a URL. There is no crates.io publish: Rust 1.95 or later to build from source.
Thirty-six commands, four groups
Everything you can type.
Grouped by what you are doing rather than by which part of the harness answers, and each group is capped at ten. Eleven of them run while a turn is in flight and the rest are refused — the rule is what a command does, not how harmless it looks.
the session
/clear · /resume · /fork · /profile · /contain · /setup · /exit
this turn
/model · /effort · /undo · /plan · /steer · /compact · /image · /copy · /copy diff · /commit
inspect
/help · /status · /context · /expand · /fleet · /skills · /cost · /stats · /store · /export
configure
/config · /theme · /remember · /memory · /mcp · /provider · /plugin · /gates · /import
What arrives with the crate
The runtime under both of them.
io-cli is one program built on io-harness. This is what the crate itself arrives with — the same boundary, ledger and trace whether a turn came from a terminal, an editor or a CI job.
Permission boundary
Layered, deny-first rules over read, write, exec and network. Every refusal is attributed to the rule and the layer.
Containment
Commands run in the host’s own sandbox backend, writing to the workspace and nowhere else, with per-host egress.
Durable runs
Trace, budget draw and checkpoint commit in one transaction after every completed step. A crash resumes the whole tree.
Budgets
Steps, wall-clock and token spend, from one ledger a whole tree shares and no child can raise.
Verification
The project’s own test command, a second model against a rubric, or no gate at all.
Composition
Nested sub-agents over a shared workspace, inherit-and-narrow — and every agent in the tree has an address.
Accounting
Token split, latency and TTFT per call; cost derived on read from a price table you own. An unpriced model makes a total a floor.
Extensibility
The Tool trait in-process, MCP over stdio and streamable HTTP, markdown skills, capability bundles and hooks.
Reach
A browser under the policy, LSP navigation, provider-executed web search, documents, images and fixed-argv git.
Get the launch note.
One email when io-harness reaches 1.0 and when the Go plan opens. Nothing else.