# Node.js SDK

Embed zot rpc in Node.js and TypeScript apps.

`@patriceckhart/zot-sdk-javascript` is a TypeScript SDK that embeds `zot rpc` in Node.js applications. It starts a long-lived `zot rpc` child process and talks newline-delimited JSON over stdin/stdout, so you get streaming output without hand-rolling the protocol.

> **Server runtimes only**
>
> The SDK spawns a child process. Use it in Node-compatible server runtimes only. Do not import it in browser components or edge runtimes.

## Install

```shell
npm install @patriceckhart/zot-sdk-javascript
# or: pnpm add / yarn add / bun add @patriceckhart/zot-sdk-javascript
```

On install, a `postinstall` step detects your OS and CPU. If `zot` is already on `PATH` it uses that; otherwise it downloads the matching GitHub release asset, verifies `checksums.txt`, and stores the binary under the package `vendor/` directory.

> **Bun lifecycle scripts**
>
> Bun may block the postinstall and print `Blocked 1 postinstall`. Trust the package with Bun, or run the installer manually: `node node_modules/@patriceckhart/zot-sdk-javascript/scripts/install-zot.js`. If `zot` is already on your PATH, no download is needed.

Environment controls: `ZOT_SKIP_INSTALL=1` skips the download, `ZOT_FORCE_INSTALL=1` downloads even when `zot` exists, `ZOT_VERSION=v0.2.31` pins a release tag, and `ZOT_BINARY=/path/to/zot` selects a specific binary at runtime.

## Stream a prompt

```ts
import { ZotClient } from "@patriceckhart/zot-sdk-javascript";

const zot = new ZotClient({
  provider: "anthropic",
  model: "claude-sonnet-4-5",
  cwd: process.cwd(),
});

for await (const event of zot.promptStream("Explain this project in 3 bullets")) {
  if (event.type === "text_delta") process.stdout.write(event.delta);
  if (event.type === "tool_call") console.log("\ntool:", event.name, event.args);
}

zot.close();
```

## One-shot prompt

```ts
import { createZotClient } from "@patriceckhart/zot-sdk-javascript";

const zot = await createZotClient({ provider: "openai", cwd: process.cwd() });
const result = await zot.prompt("Write a tiny README for this app");
console.log(result.text);
zot.close();
```

## Framework usage

`zot rpc` is stateful, so keep one client per chat session on the server. The SDK works in any Node-compatible framework that can spawn child processes (Next.js route handlers with `runtime = "nodejs"`, Nuxt server routes, Express, and others), but not in browser code or edge runtimes.

## API

```ts
const client = new ZotClient(options);
await client.start();
await client.hello();
await client.ping();
await client.prompt("message");
client.promptStream("message");
await client.abort();
await client.compact();
await client.getState();
await client.getMessages();
await client.clear();
await client.setModel("model-id");
await client.getModels();
client.close();
```

Key options: `binary` (defaults to `ZOT_BINARY` or `zot`); `provider`, `model`, `cwd`, `apiKey`, `baseUrl`, `systemPrompt`, `appendSystemPrompt`, `reasoning`, `maxSteps`, `noTools`, and `tools` map to `zot rpc` flags; `rpcToken` sends the initial `hello` token when `ZOTCORE_RPC_TOKEN` is set on the child process.

## State changes while busy

Call `clear()` and `setModel()` only when the agent is idle. The RPC runtime rejects `clear`, `set_model`, and `set_reasoning` with an `agent is busy` error during prompt preparation, model/tool execution, or compaction. State is unchanged and these commands are not queued. Wait for completion, or abort the active operation, wait for it to finish, and retry. An `abort()` acknowledgement alone does not mean the active operation has finished.

## Auth and lifecycle

Use normal zot auth: run `zot` and `/login`, or pass provider keys through environment variables such as `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, or `KIMI_API_KEY`.

- One `ZotClient` wraps one `zot rpc` process, cwd, model, and session.
- Only one prompt or compact operation should be active per client at a time.
- For multiple projects or concurrent chats, create multiple clients.
- The process exits when closed or when stdin closes.

Source and full docs: [https://github.com/patriceckhart/zot-sdk-javascript](https://github.com/patriceckhart/zot-sdk-javascript).
