Node SDK quickstart
Connect, read, and write from JavaScript.
Written By Dustin
Last updated 22 minutes ago
The Node SDK (tovio-node-sdk) is a typed TypeScript API over the native NAPI bindings — the same engine the CLI uses, not a wrapper that shells out. It owns no version-control logic and no cryptography: every call crosses into the Rust engine, which re-runs full enforcement each time.
Connect
import { TovioClient, unwrap } from "tovio-node-sdk";const client = TovioClient.connect("/path/to/repo", "cap_…");console.log(client.scope);connect is synchronous — there is nothing to await. It opens the repository, verifies the native module's ABI, resolves the token, runs the handshake, and echoes the effective scope back so you know what you actually hold before you try to use it. The second argument is either a token id (resolved from the repo's token store) or the raw signed token bytes. An optional third argument is the prompt bytes, hashed engine-side into the commit's prompt_hash.
A refused token throws — there is no half-open client. An ABI mismatch between the SDK and the loaded native module throws TVO-CORE-001 rather than partially working.
The scope echo is informational
client.scope carries agent, pathScope, deniedPathScope, branchScope, secretClearance, allowedOps, and promptHash. Use it to decide what to attempt. Do not use it to decide what to allow — the engine re-checks scope on every single call, and that is the only enforcement point.
Read
Write
const session = client.openWriteSession();session.writeFile("src/new.rs", "pub fn added() {}\n");const { changeId, branch, verified } = unwrap(session.commit("feat: add added()"));openWriteSession() is synchronous too. The session stages edits into an in-memory working change: writeFile, deleteFile, moveFile, resolveConflict, then commit lands them on the token's agent/<name> lane. stagedPaths() shows what is staged; session.branch names the lane. Sessions are reusable — commit resets the staged state in place, so one handle supports stage → commit → stage again.
commit takes an optional reasoning summary and a structured rationale, so an automated commit carries the same provenance a person's does. verified in the result means a signed audit entry was appended; false still means the commit landed.
Delegate
const { token, tokenId } = unwrap(session.issueSubToken({ paths: ["src/api/**"], ops: ["read", "write", "commit"], expiresAt: Math.floor(Date.now() / 1000) + 3600,}));A monotonically narrower leaf, signed by the agent's own key. expiresAt is required (unix seconds, inside the parent's window); omitted scope dimensions inherit; canDelegate never inherits — absent means false. The leaf's parent links persist, so a later connect rebuilds and revalidates the whole chain, including ancestor revocation.
Get a token first
tovio agent new my-integration \ --model script --task "nightly dependency bump" --expires-in 4--expires-in is a whole number of hours (default 24), not a duration string. Add --can-delegate only if the integration actually issues sub-tokens; it is off by default.