Node SDK¶
The Node SDK lets you drive TOVIO from JavaScript or TypeScript. It is not a wrapper that shells
out to the tovio binary and parses its text --- it calls the same engine the CLI uses,
in-process, through native bindings. You get the engine's exact behavior with none of the
subprocess overhead, and structured values instead of scraped output.
This page shows how to install the SDK and what it exposes.
Implemented and publish-ready, not published
The Node SDK (tovio-node-sdk) and N-API bindings (tovio-node-bindings) are implemented, build
successfully, and have release packaging gates. No npm package is publicly available until the
accepted release manifest and provenance publication gates pass. The install commands below describe
the post-publication interface; until then, build both from a workspace checkout
(pnpm --filter tovio-node-bindings run build:debug, then pnpm --filter tovio-node-sdk run build)
or invoke the tovio CLI with --json from a source build.
How it works¶
TOVIO's version-control logic lives in one pure Rust library. The SDK reaches it across a single, deliberate FFI boundary: a prebuilt NAPI native addon. Two things follow from that design:
- After publication, no Rust toolchain will be required. The release pipeline builds a prebuilt native addon for each of the six supported platform/architecture targets --- Linux, macOS, and Windows on x64 and arm64 --- and packs them into one checksummed npm tarball. Once the provenance gates pass, installing the SDK will be a plain package install with no compiler or local build step.
- The calls are coarse-grained. The SDK exposes whole operations --- open a repository, read a change, commit, list conflicts --- not per-object chatter across the boundary. That keeps the in-process advantage intact: you are calling the engine, not a chatty proxy of it.
Post-publication install interface¶
These commands are intentionally not available yet. Use them only after the downloads page links an accepted, attested release manifest and the npm provenance gate has passed.
After publication, the package will pull in tovio-node-bindings, which ships a prebuilt native addon
for every supported platform and architecture in one tarball and loads the matching one at import time ---
no compiler, no local build step.
A first script¶
Every SDK session is bound to a capability token --- the cap_… id
that tovio agent new prints (or the raw token bytes). The SDK acts as that token's agent identity, on
its agent/<name>/** lane, never as your human login; a refused token yields no client at all. Connect
to a repository and read your current state:
import { TovioClient, unwrap } from "tovio-node-sdk";
const client = TovioClient.connect(process.cwd(), "cap_7r4qy9m2x8k3v6bd0n1p5h");
console.log(client.scope.pathScope); // the effective scope echoed at connect --- informational
const { status } = unwrap(client.status());
console.log(status.branch); // "agent/docs-bot/…"
console.log(status.change?.changeId); // "chg:xkqm7y"
console.log(status.openConflicts.length); // 0
Stage an edit and commit it:
const session = client.openWriteSession();
session.writeFile("src/app.ts", "export const ready = true;\n");
const { changeId, commit, branch, verified } = unwrap(session.commit("wire up CGM sync"));
console.log(changeId); // stable across later rewrites
console.log(commit); // "blake3:…"
Provenance --- model, task, prompt hash, and the human who issued the token --- is computed by the engine from the token; the caller supplies only the message, an optional reasoning summary, and an optional structured rationale.
What it exposes¶
The SDK surfaces the engine's read and write operations as typed methods --- the same operations the MCP server exposes as tools, because both are thin shells over the same bindings:
- Connect ---
TovioClient.connect(repoRoot, token)opens the repository, checks the bindings ABI, and runs the token handshake;client.scopeechoes the effective scope. - Reads ---
status(),log(),diff(),readFile(), andlistConflicts(), each filtered to the token's path scope;readFilereturns the bytes plustextwhen they are valid UTF-8. - Semantic context ---
searchSymbols(),symbolContext(),symbolRelations(),changeImpact(),projectContext(), andprovenanceGraph()over the L6 symbol graph and signed provenance. - Write sessions ---
openWriteSession()returns a reusable session withwriteFile(),deleteFile(),moveFile(),resolveConflict(),commit(), andissueSubToken()for delegation. - Pipelines --- the
tovio-node-sdk/pipelineentry point is the config-as-code builder thattovio ci compilereads.
Repository initialisation, lane management, and sync are not SDK operations; they stay in the CLI.
Structured in, structured out --- and no decoration
The SDK returns plain objects and passes the engine's error envelope through with the same stable error codes as the CLI. The warmth, color, and celebration you see in an interactive terminal never appear here --- the SDK is a machine contract, by design. A change ID is a string; a conflict list is an array; a permission failure is an envelope with a code, not a sentence.
Error handling¶
The engine returns denials rather than throwing them, and the SDK keeps that shape: every operation
returns { ok: true, … } or { ok: false, error }, where error is the Error Catalog envelope
(code, title, cause, exit_code, context) verbatim. unwrap() is the scripting convenience
that throws the envelope as a typed TovioError instead:
import { TovioClient, TovioError, unwrap } from "tovio-node-sdk";
const client = TovioClient.connect(process.cwd(), "cap_7r4qy9m2x8k3v6bd0n1p5h");
const read = client.readFile("config/prod.env");
if (!read.ok && read.error.code === "TVO-PERM-001") {
// no clearance for this protected path --- handle gracefully
}
try {
const { content } = unwrap(client.readFile("config/prod.env"));
} catch (err) {
if (err instanceof TovioError && err.envelope.code === "TVO-PERM-001") {
// the same denial, thrown
} else {
throw err;
}
}
Four members throw instead of returning an outcome: TovioClient.connect on a refused token (a
TVO-TOKEN-* code, or TVO-CORE-001 when the native addon's ABI does not match the SDK),
openWriteSession, and a write session's branch getter and stagedPaths(). The codes are
the same ones documented in the CLI reference; a failure means the same thing
whether you hit it from a script, the CLI, or your editor.
When to reach for the SDK¶
Use the Node SDK when you are building TOVIO into a larger Node program --- a custom tool, a bot, a service --- and want the engine's behavior directly. If you only need to register and bound an AI coding agent, look at AI agents & automation instead: the MCP server is the purpose-built surface for that, and it is itself built on these same bindings.
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure