# zidane/ipc

> The shared chat host, its unix-socket daemon and the typed client that keeps several windows in sync.

Import: `import { … } from 'zidane/ipc'`. Source: [src/ipc/index.ts](https://github.com/Tahul/zidane/blob/main/src/ipc/index.ts).

Use `zidane/ipc` when several windows must share one set of live agents. `startIpcDaemon` serves the chat host over a unix socket, `startInProcessHost` runs it in your process, and `connectIpcClient` and `connectOrSpawnDaemon` return a typed client. [The daemon](https://zidane.si/docs/daemon.md) explains how the apps use it. [Server protocol](https://zidane.si/docs/server-protocol.md) lists the methods and signals.

```ts
import { connectIpcClient, defaultSocketPath } from 'zidane/ipc'

const client = await connectIpcClient({ socketPath: defaultSocketPath() })
const sessions = await client.request('sessions.list', {})
const stop = client.onSignal(signal => console.log(signal.kind))
console.log(sessions.length)
stop()
client.close()
```

## Functions

### `connectIpcClient`

Function.

Connects to a daemon over its unix socket and completes the `ipc.hello` handshake.
On a protocol, build or code version mismatch it throws [`IpcVersionMismatchError`](https://zidane.si/docs/reference/ipc.md#IpcVersionMismatchError). Unless `drainOnMismatch` is `false`, it first asks the stale daemon to drain. Rejects when nothing listens on the socket.

```ts
function connectIpcClient(options: IpcClientOptions): Promise<IpcClient>
```

**Parameters**

- `options` (`IpcClientOptions`): Socket path and client settings.

**Returns** `Promise<IpcClient>`: A typed client. Requests are checked against [`IpcMethods`](https://zidane.si/docs/reference/ipc-browser.md#IpcMethods).

**Example**

```ts
import { connectIpcClient, defaultSocketPath } from 'zidane/ipc'

const client = await connectIpcClient({ socketPath: defaultSocketPath() })
const sessions = await client.request('sessions.list', {})
const stop = client.onSignal(signal => console.log(signal.kind))
console.log(sessions.length)
stop()
client.close()
```

Source: [src/ipc/client.ts:59](https://github.com/Tahul/zidane/blob/main/src/ipc/client.ts#L59)

### `connectOrSpawnDaemon`

Function.

One-call convenience for windows: make sure a daemon is up (spawning if
needed), connect, and — when the running daemon speaks an older protocol
— drain it and spawn a fresh one before retrying once.

```ts
function connectOrSpawnDaemon(
  options?: Omit<IpcClientOptions, 'socketPath'> & EnsureDaemonOptions,
): Promise<IpcClient>
```

**Parameters**

- `options?` (`Omit<IpcClientOptions, 'socketPath'> & EnsureDaemonOptions`, default `{}`): Client options without `socketPath`, plus the daemon spawn options.

**Returns** `Promise<IpcClient>`: A connected client.

Source: [src/ipc/client.ts:123](https://github.com/Tahul/zidane/blob/main/src/ipc/client.ts#L123)

### `createDaemonEnvironment`

Function.

The daemon's environment: its own config, per-cwd extension discovery, multi-process.

```ts
function createDaemonEnvironment(
  options: Omit<HostEnvironmentOptions, 'shared'>,
): Promise<DaemonEnvironment>
```

**Parameters**

- `options` (`Omit<HostEnvironmentOptions, 'shared'>`): Broadcast sink and boot settings. `shared` is not accepted.

**Returns** `Promise<DaemonEnvironment>`: The environment.

Source: [src/ipc/daemon/environment.ts:204](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L204)

### `createFileApprovalsStore`

Function.

File-backed pending-approvals persistence (`pending-approvals.json` next
to `state.json`). Small, rewritten atomically enough for its purpose —
the queue holds at most a handful of rows.

```ts
function createFileApprovalsStore(path: string): PendingApprovalsStore
```

**Parameters**

- `path` (`string`): Path of the JSON file. A missing or unreadable file reads as empty.

**Returns** `PendingApprovalsStore`: A store that persists approvals to that file.

Source: [src/ipc/daemon/environment.ts:90](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L90)

### `createHostEnvironment`

Function.

Disk-backed host environment: the daemon's, or (with `shared`) a host
sharing the window's process and setup.

```ts
function createHostEnvironment(
  options: HostEnvironmentOptions,
): Promise<DaemonEnvironment>
```

**Parameters**

- `options` (`HostEnvironmentOptions`): Broadcast sink, boot settings and the optional shared window setup.

**Returns** `Promise<DaemonEnvironment>`: The environment.

Source: [src/ipc/daemon/environment.ts:216](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L216)

### `createHostImagePort`

Function.

The image port of a host's `ctx.generate` (`GeneratePort.image`).

```ts
function createHostImagePort(
  deps: HostImagePortDeps,
): (request: GenerateImageRequest) => Promise<GenerateImageResult>
```

**Parameters**

- `deps` (`HostImagePortDeps`): Providers, the default model, the fallback folder and the session bridge.

**Returns** `(request: GenerateImageRequest) => Promise<GenerateImageResult>`: The port member.

Source: [src/ipc/daemon/extensions/image-port.ts:107](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/extensions/image-port.ts#L107)

### `createHostTranscriptPager`

Function.

A host's pager. The worker is used only for a store that is a SQLite file
(`sqliteStoreFile`), with the kill switch off; it spawns lazily, on the
first page, for the first such file (one host, one store).

```ts
function createHostTranscriptPager(
  options?: { replays?: TranscriptReplayCache; worker?: (dbPath: string) => TranscriptHistoryWorker },
): HostTranscriptPager
```

**Parameters**

- `options?` (`{ replays?: TranscriptReplayCache; worker?: (dbPath: string) => TranscriptHistoryWorker }`, default `{}`): Options.

**Returns** `HostTranscriptPager`

Source: [src/ipc/history/transcript.ts:150](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L150)

### `createMachineHandlers`

Function.

Builds the `machines.list`, `machines.forget` and `machines.listDirs` handlers.
`machines.forget` broadcasts a `machine:status` signal with the machine offline when it removed one. `machines.listDirs` is confined to the machine's declared roots and throws for a path outside them.

```ts
function createMachineHandlers(
  options: { broadcast: (signal: HostSignal) => void; host: ChatHost },
): Handlers<'machines.list' | 'machines.forget' | 'machines.listDirs'>
```

**Parameters**

- `options` (`{ broadcast: (signal: HostSignal) => void; host: ChatHost }`): The chat host and the signal broadcast sink.

**Returns** `Handlers<'machines.list' | 'machines.forget' | 'machines.listDirs'>`: The three method handlers.

Source: [src/ipc/daemon/handlers/machines.ts:18](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/machines.ts#L18)

### `createMachineLinkHandlers`

Function.

Builds the `machines.share.*`, `machines.useServer` and `machines.links.status` handlers.
The links load lazily and only while remote hosts are enabled. On a zidane-server every method throws. Turning remote hosts off stops every link.

```ts
function createMachineLinkHandlers(
  options: MachineLinksHandlerOptions,
): Handlers<Methods>
```

**Parameters**

- `options` (`MachineLinksHandlerOptions`): Host, environment, broadcast sink and pacing.

**Returns** `Handlers<Methods>`: The four method handlers.

Source: [src/ipc/daemon/handlers/machine-links.ts:57](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/machine-links.ts#L57)

### `createTranscriptHistoryWorker`

Function.

A client of the history worker over `dbPath`. The worker spawns on the
first page.

```ts
function createTranscriptHistoryWorker(
  options: { create?: () => WorkerLike; dbPath: string } & Pick<WorkerRpcClientOptions, 'timeoutMs' | 'maxCrashes' | 'backoffMs' | 'onDegraded'>,
): TranscriptHistoryWorker
```

**Parameters**

- `options` (`{ create?: () => WorkerLike; dbPath: string } & Pick<WorkerRpcClientOptions, 'timeoutMs' | 'maxCrashes' | 'backoffMs' | 'onDegraded'>`): The database, and (tests, a Node host) how to spawn the worker.

**Returns** `TranscriptHistoryWorker`

Source: [src/ipc/history/transcript.ts:90](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L90)

### `createTranscriptReader`

Function.

Whole-session reads that build on the last one while a session runs. Its
version moves with every turn saved, so each page asked of it reads the
session again: the whole of it, hundreds of ms on a long one. A live read
keeps what it parsed and, next time, reads only the rows added since.

Saving appends rows. Anything else (compaction, a rewind, a full save)
deletes rows or writes them again, so a kept read is used only when every
row it holds is still there at the same `seq` with the same size: one
query over the rows' headers (`octet_length` reads no row's content). A
history edit keeping every size is the one change it cannot see, and the
host refuses history edits while a session runs: a kept read serves the run
it was read in, and the first read of a new run reads whole. Kept reads are
bounded by stored size (`KEPT_READ_MAX_BYTES`, `KEPT_READS_MAX_BYTES`):
a bigger session is read whole on each change. A read that is not live
reads everything and drops what was kept; so does a live one when the
incremental read fails.

```ts
function createTranscriptReader(
  driver: SqliteDriver,
  limits?: { readBytes?: number; totalBytes?: number },
): TranscriptReader
```

**Parameters**

- `driver` (`SqliteDriver`): The connection; the reads of one live read share a snapshot.
- `limits?` (`{ readBytes?: number; totalBytes?: number }`, default `{}`): The kept reads' bounds by stored size; default `KEPT_READ_MAX_BYTES` and `KEPT_READS_MAX_BYTES`.

**Returns** `TranscriptReader`

Source: [src/ipc/history/transcript-reader.ts:134](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript-reader.ts#L134)

### `createTranscriptReplayCache`

Function.

A replay and document cache.

```ts
function createTranscriptReplayCache(
  options?: { maxBytes?: number; maxSessions?: number; replay?: (turns: SessionTurn[], runs: readonly SessionRun[]) => { events: StreamEvent[]; turnStarts: number[] } },
): TranscriptReplayCache
```

**Parameters**

- `options?` (`{ maxBytes?: number; maxSessions?: number; replay?: (turns: SessionTurn[], runs: readonly SessionRun[]) => { events: StreamEvent[]; turnStarts: number[] } }`, default `{}`): Bounds and a seam.

**Returns** `TranscriptReplayCache`

Source: [src/ipc/daemon/handlers/transcript-cache.ts:197](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-cache.ts#L197)

### `createWorkerRpcClient`

Function.

A worker RPC client. The worker spawns on the first request.

```ts
function createWorkerRpcClient<Req, Res>(
  options: WorkerRpcClientOptions,
): WorkerRpcClient<Req, Res>
```

**Type parameters**

- `Req`
- `Res`

**Parameters**

- `options` (`WorkerRpcClientOptions`): How to spawn the worker, its `init`, the timeout and the crash policy.

**Returns** `WorkerRpcClient<Req, Res>`

Source: [src/ipc/history/rpc-client.ts:124](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L124)

### `daemonSocketName`

Function.

Socket file name. Dev builds (`ZIDANE_DEV=1`, set by every `dev` script
in the repo) get their OWN socket so a checkout's TUI, GUI and `zidane
daemon` pair up among themselves and never attach to — or get refused by
— the installed daemon. Without this, a protocol bump in the working
tree turned the dev GUI's dot red against the stable daemon, and a dev
daemon could drain the one the installed TUI relies on.

```ts
function daemonSocketName(env?: ProcessEnv): 'daemon.sock' | 'dev.sock'
```

**Parameters**

- `env?` (`ProcessEnv`, default `process.env`): Environment to read `ZIDANE_DEV` from.

**Returns** `'daemon.sock' | 'dev.sock'`: `dev.sock` for a dev build, else `daemon.sock`.

Source: [src/ipc/daemon/lifecycle.ts:99](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L99)

### `decisionsPort`

Function.

`ctx.generate.decide`: the decisions model the settings pick
(`resolveDecisionsOption`), resolved at each call since settings and
credentials change.

Each decision fires `decision:start` / `decision:end` on `hooks`: the
daemon hands its registry's agent-hook fan-out there, so the extensions'
`hooks.on('decision:end')` observers see the decisions extensions make
outside any run as they see an agent's. (Inside a hook observer of a run
`ctx.generate.decide` uses that run's decider instead, journaled like the
agent's own.)

```ts
function decisionsPort(
  providers: () => Readonly<Record<string, ProviderDescriptor>>,
  readSettings: () => HostSettings,
  buildProvider: (providers: Readonly<Record<string, ProviderDescriptor>>, key: string) => Provider,
  hooks?: Hookable<AgentHooks>,
): AgentDecide
```

**Parameters**

- `providers` (`() => Readonly<Record<string, ProviderDescriptor>>`): The folder's providers.
- `readSettings` (`() => HostSettings`): The host's live settings.
- `buildProvider` (`(providers: Readonly<Record<string, ProviderDescriptor>>, key: string) => Provider`): Builds a provider of the registry.
- `hooks?` (`Hookable<AgentHooks>`): Where the `decision:*` events go. Default: nowhere.

**Returns** `AgentDecide`

Source: [src/ipc/daemon/extensions/host-ports.ts:203](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/extensions/host-ports.ts#L203)

### `defaultSocketPath`

Function.

Path of the daemon socket this process uses.
The `ZIDANE_DAEMON_SOCKET` environment variable wins. Otherwise it is `<stateDir>/daemon/<socket name>`, see [`daemonSocketName`](https://zidane.si/docs/reference/ipc.md#daemonSocketName).

```ts
function defaultSocketPath(): string
```

**Returns** `string`: The socket path.

Source: [src/ipc/daemon/lifecycle.ts:108](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L108)

### `ensureDaemonRunning`

Function.

Makes sure a daemon is listening on the socket, spawning one when nothing is. Concurrent calls for the same socket share one start.
Rejects when the spawn fails or the daemon does not accept connections within `timeoutMs`.

```ts
function ensureDaemonRunning(options?: EnsureDaemonOptions): Promise<string>
```

**Parameters**

- `options?` (`EnsureDaemonOptions`, default `{}`): Socket, spawn command and timeout.

**Returns** `Promise<string>`: The socket path once a connection succeeds.

Source: [src/ipc/daemon/lifecycle.ts:239](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L239)

### `exchangeBoundaries`

Function.

Per turn: does a run start there (a parent-run user turn carrying no tool result, not loop-injected)?

```ts
function exchangeBoundaries(
  turns: readonly SessionTurn[],
  runs: readonly SessionRun[],
): boolean[]
```

**Parameters**

- `turns` (`readonly SessionTurn[]`): Turns of the session, in order.
- `runs` (`readonly SessionRun[]`): Runs of the session, used to tell child runs from parent runs.

**Returns** `boolean[]`: One flag per turn.

Source: [src/ipc/daemon/handlers/transcript-page.ts:33](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-page.ts#L33)

### `fixPath`

Function.

Merge the login shell's PATH into `process.env.PATH`. No-op on Windows or when no shell answers.

```ts
function fixPath(): void
```

Source: [src/ipc/daemon/shell-path.ts:141](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/shell-path.ts#L141)

### `historyWorkerUrl`

Function.

The history worker's module: the sibling source file in development, the
sibling `history-worker.js` entry in the published dist, and the entry
embedded under the binary's root in a compiled executable
(`scripts/build-executables.ts`, `scripts/build-server.ts`).

```ts
function historyWorkerUrl(): URL
```

**Returns** `URL`

Source: [src/ipc/history/transcript.ts:55](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L55)

### `hostRefOf`

Function.

The host's identity from a hello (or `daemon.info`) reply; `null` from a host that predates it.

```ts
function hostRefOf(hello: HelloResult): HostRef | null
```

**Parameters**

- `hello` (`HelloResult`): The `hello` or `daemon.info` result.

**Returns** `HostRef | null`: The host reference, or `null` when the reply carries no host id or kind.

Source: [src/ipc/protocol.ts:1909](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1909)

### `isClientScope`

Function.

Whether a string is a [`ClientScope`](https://zidane.si/docs/reference/ipc-browser.md#ClientScope).

```ts
function isClientScope(value: unknown): value is 'chat' | 'admin'
```

**Parameters**

- `value` (`unknown`): The value to check (a CLI flag, a stored token's scope).

**Returns** `value is 'chat' | 'admin'`

Source: [src/ipc/scopes.ts:38](https://github.com/Tahul/zidane/blob/main/src/ipc/scopes.ts#L38)

### `loadAllEvents`

Function.

A session's whole transcript, loaded a page at a time from the end so no
single reply carries it all (a long session with images can outgrow a
transport's message size). A page refused as too large is asked again at
half the turns, down to one; a single turn that still doesn't fit fails
the load. An older host answers the whole transcript to the first call.

```ts
function loadAllEvents(
  request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,
  sessionId: string,
  options?: { pageTurns?: number },
): Promise<StreamEvent[]>
```

**Parameters**

- `request` (`(method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>`): Sends `sessions.loadEvents` to the host.
- `sessionId` (`string`): Session to load.
- `options?` (`{ pageTurns?: number }`, default `{}`): Paging options.

**Returns** `Promise<StreamEvent[]>`: Every stream event of the session.

Source: [src/ipc/protocol.ts:2001](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2001)

### `loadEventsPage`

Function.

One page of `sessions.loadEvents` (see its paging). An older host answers
the whole transcript: it comes back as one page with no cursor.

```ts
function loadEventsPage(
  request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,
  params: { sessionId: string } & LoadEventsPaging,
): Promise<SessionEventsPage>
```

**Parameters**

- `request` (`(method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>`): Sends `sessions.loadEvents` to the host.
- `params` (`{ sessionId: string } & LoadEventsPaging`): Session id and paging.

**Returns** `Promise<SessionEventsPage>`: The page, normalized from either host reply shape.

Source: [src/ipc/protocol.ts:1977](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1977)

### `loadSessionDocument`

Function.

A session's whole document, read a page of turns at a time so no reply
carries it all (`sessions.getTurns` pages, then the `sessions.get`
`turns: false` head; a page refused as too large is asked again at half
the turns). Every page and the head name the snapshot they come from: a
version change mid-read (a turn appended, a compaction) starts the read
over, so the result is one version, never pages of two. After
`SESSION_DOCUMENT_RESTARTS` restarts (a session busier than the
read), the whole document comes in one reply. A host that predates
`sessions.getTurns` sends it that way too; one that names no version is
read as before. `null` when the host doesn't know the session.

```ts
function loadSessionDocument(
  request: SessionDocumentRequest,
  sessionId: string,
  options?: { pageTurns?: number },
): Promise<SessionData | null>
```

**Parameters**

- `request` (`SessionDocumentRequest`): Sends `sessions.get` and `sessions.getTurns` to the host.
- `sessionId` (`string`): Session to read.
- `options?` (`{ pageTurns?: number }`, default `{}`): Paging options.

**Returns** `Promise<SessionData | null>`: The session document, or `null` when unknown.

Source: [src/ipc/protocol.ts:2108](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2108)

### `mcpStatusOf`

Function.

`ctx.mcp.list()` of a folder, for hosts that run extensions outside a daemon (the desktop app's in-process host).

```ts
function mcpStatusOf(
  deps: { cwd: string; dataDir: string; host: DaemonChatHostPort | undefined; prefix: string; runtime: ExtensionRuntime | undefined; settings: HostSettings },
): McpPortStatus[]
```

**Parameters**

- `deps` (`{ cwd: string; dataDir: string; host: DaemonChatHostPort | undefined; prefix: string; runtime: ExtensionRuntime | undefined; settings: HostSettings }`): The folder, its runtime, the storage prefix, settings, data dir and chat host.

**Returns** `McpPortStatus[]`

Source: [src/ipc/daemon/extensions/host-ports.ts:49](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/extensions/host-ports.ts#L49)

### `mergePath`

Function.

Entries of `current` the shell doesn't know about (ad-hoc prepends from the
launching terminal) stay in front; then the shell's PATH in its own order.
From the Dock every launchd entry is already in the shell PATH, so the
result is exactly the shell PATH, with the shell's precedence intact.

```ts
function mergePath(current: string | undefined, shell: string | undefined): string
```

**Parameters**

- `current` (`string | undefined`): The PATH of this process.
- `shell` (`string | undefined`): The PATH reported by the login shell.

**Returns** `string`: The merged PATH string.

Source: [src/ipc/daemon/shell-path.ts:133](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/shell-path.ts#L133)

### `probeSocket`

Function.

True when something accepts connections on `socketPath`. Distinguishes a
live daemon from a stale socket file left by a crashed one.

```ts
function probeSocket(socketPath: string, timeoutMs?: number): Promise<boolean>
```

**Parameters**

- `socketPath` (`string`): Path of the socket to try.
- `timeoutMs?` (`number`, default `1000`): How long to wait for the connection, in milliseconds.

**Returns** `Promise<boolean>`

Source: [src/ipc/daemon/lifecycle.ts:176](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L176)

### `readTranscript`

Function.

Every turn (with its `seq`) and run of a session; `null` when it does not exist.

```ts
function readTranscript(driver: SqliteDriver, id: string): TranscriptRead | null
```

**Parameters**

- `driver` (`SqliteDriver`): The connection.
- `id` (`string`): The session.

**Returns** `TranscriptRead | null`

Source: [src/ipc/history/transcript-reader.ts:51](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript-reader.ts#L51)

### `readTurnsAt`

Function.

The session's turns stored at `seqs`, in `seq` order; a missing or corrupt row is skipped.

```ts
function readTurnsAt(
  driver: SqliteDriver,
  id: string,
  seqs: readonly number[],
): SessionTurn[]
```

**Parameters**

- `driver` (`SqliteDriver`): The connection.
- `id` (`string`): The session.
- `seqs` (`readonly number[]`): The rows' `seq`s.

**Returns** `SessionTurn[]`

Source: [src/ipc/history/transcript-reader.ts:74](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript-reader.ts#L74)

### `runAttach`

Function.

Runs the `zidane attach` terminal client: picks or creates a session on the daemon (or a remote server), replays its transcript, and relays input and live signals until the user detaches.
Rejects when the connection to the daemon or server drops. It does not exit the process.

```ts
function runAttach(options?: AttachOptions): Promise<void>
```

**Parameters**

- `options?` (`AttachOptions`, default `{}`): Connection target, session choice and streams.

**Returns** `Promise<void>`: A promise that resolves when the user detaches.

Source: [src/ipc/attach.ts:76](https://github.com/Tahul/zidane/blob/main/src/ipc/attach.ts#L76)

### `runRemoteOAuth`

Function.

Runs the client half of a remote OAuth sign-in against a host.
Starts the flow on the host, opens the URL through the UI, forwards the code from the loopback listener or from `paste`, and resolves with the host's outcome, which never carries a token. Rejects when aborted or when the UI cannot answer a question the provider asks.

```ts
function runRemoteOAuth(
  client: Pick<IpcClient, 'request'>,
  target: RemoteOAuthTarget,
  ui: RemoteOAuthUi,
): Promise<HostOAuthComplete>
```

**Parameters**

- `client` (`Pick<IpcClient, 'request'>`): Client used for the `auth.oauth.*` requests.
- `target` (`RemoteOAuthTarget`): Provider or MCP server to sign in to.
- `ui` (`RemoteOAuthUi`): Browser, prompt and abort hooks.

**Returns** `Promise<HostOAuthComplete>`: The sign-in outcome: the provider status or the MCP server name.

Source: [src/ipc/remote-oauth.ts:79](https://github.com/Tahul/zidane/blob/main/src/ipc/remote-oauth.ts#L79)

### `runWorkspaceExecStream`

Function.

Runs a command in a session's workspace on a host and streams its output.
The result has the shape of a local `!` run. A host without `sessions.workspaceExecStream` gets the buffered `sessions.workspaceExec` instead, and then an abort stops the wait, not the command.

```ts
function runWorkspaceExecStream(
  client: Pick<IpcClient, 'request' | 'onSignal'>,
  params: { command: string; cwd?: string; sessionId: string },
  options?: WorkspaceExecStreamOptions,
): Promise<WorkspaceExecStreamResult>
```

**Parameters**

- `client` (`Pick<IpcClient, 'request' | 'onSignal'>`): Client used for requests and signals.
- `params` (`{ command: string; cwd?: string; sessionId: string }`): Session, command and optional working directory.
- `options?` (`WorkspaceExecStreamOptions`, default `{}`): Abort signal, chunk callback and timeouts.

**Returns** `Promise<WorkspaceExecStreamResult>`: The output, exit code and flags describing how it ended.

Source: [src/ipc/workspace-exec-stream.ts:52](https://github.com/Tahul/zidane/blob/main/src/ipc/workspace-exec-stream.ts#L52)

### `selfDaemonSpawnCommand`

Function.

Spawn command that re-enters the CURRENT zidane program as `… daemon`.

Three launch shapes:

- compiled Bun binary — `Bun.main` is the virtual `/$bunfs/…` entry the
  binary self-inserts as argv\[1], so the spawn must NOT repeat it
  (verified: repeating it makes the child parse the junk path as its
  subcommand and boot the full TUI instead of the daemon).
- dev (`bun run cli.ts`) — the script path must ride along.
- Node hosts (no `Bun` global) — fall back to the published bin.

```ts
function selfDaemonSpawnCommand(): string[]
```

**Returns** `string[]`

Source: [src/ipc/daemon/lifecycle.ts:156](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L156)

### `serveWorkerRpc`

Function.

Serve `handler` on this worker thread.

```ts
function serveWorkerRpc<Init, Req, Res>(
  handler: WorkerRpcHandler<Init, Req, Res>,
  port?: WorkerPortLike,
): Promise<void>
```

**Type parameters**

- `Init`
- `Req`
- `Res`

**Parameters**

- `handler` (`WorkerRpcHandler<Init, Req, Res>`): `init` and the request handler.
- `port?` (`WorkerPortLike`): The port to the parent; default: Node's `parentPort`, else the Web worker scope.

**Returns** `Promise<void>`

Source: [src/ipc/history/rpc-serve.ts:50](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-serve.ts#L50)

### `shellPath`

Function.

Reads the PATH of the user's interactive login shell, blocking until it answers.
Tries the user's shell, then `/bin/zsh` and `/bin/bash`. Returns `undefined` on Windows, or when no shell answers in time.

```ts
function shellPath(options?: ShellPathOptions): string | undefined
```

**Parameters**

- `options?` (`ShellPathOptions`, default `{}`): Shell, environment and timeout overrides.

**Returns** `string | undefined`: The PATH string, or `undefined`.

Source: [src/ipc/daemon/shell-path.ts:80](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/shell-path.ts#L80)

### `shellPathAsync`

Function.

[`shellPath`](https://zidane.si/docs/reference/ipc.md#shellPath) without blocking the event loop: same shells, args,
timeout and parsing, run with `runBounded` (a timeout ends the shell's
whole tree; under Bun its output survives a shell that exits before Bun
watches it). For hosts (the GUI main process) that can start on a cached
PATH and refresh in the background.

```ts
function shellPathAsync(options?: ShellPathOptions): Promise<string | undefined>
```

**Parameters**

- `options?` (`ShellPathOptions`, default `{}`): Shell, environment and timeout overrides.

**Returns** `Promise<string | undefined>`: The PATH string, or `undefined`.

Source: [src/ipc/daemon/shell-path.ts:109](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/shell-path.ts#L109)

### `startInProcessHost`

Function.

Starts a chat host in this process. Clients from `connect` behave like socket clients, without a socket or a second process.

```ts
function startInProcessHost(options: InProcessHostOptions): Promise<InProcessHost>
```

**Parameters**

- `options` (`InProcessHostOptions`): Environment factory and version.

**Returns** `Promise<InProcessHost>`: The host handle.

Source: [src/ipc/memory.ts:284](https://github.com/Tahul/zidane/blob/main/src/ipc/memory.ts#L284)

### `startIpcDaemon`

Function.

Starts a unix-socket daemon around a chat host. Each peer must open with `ipc.hello`.
A stale socket file left by a dead daemon is replaced. Throws when a live daemon already listens on `socketPath`.

```ts
function startIpcDaemon(options: IpcDaemonOptions): Promise<IpcDaemon>
```

**Parameters**

- `options` (`IpcDaemonOptions`): Socket path, environment and lifecycle settings.

**Returns** `Promise<IpcDaemon>`: The running daemon.

**Example**

```ts
import { startIpcDaemon } from 'zidane/ipc'

const daemon = await startIpcDaemon({
  socketPath: '/tmp/zidane-demo/daemon/ipc.sock',
  onLog: line => console.log(line),
})
console.log(daemon.peerCount())
await daemon.close()
```

Source: [src/ipc/daemon/server.ts:136](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/server.ts#L136)

### `transcriptPage`

Function.

`[from, to)` of the page, and the cursor of the one before it, over the
turns' [`exchangeBoundaries`](https://zidane.si/docs/reference/ipc.md#exchangeBoundaries) (run starts) and [`turnCutPoints`](https://zidane.si/docs/reference/ipc.md#turnCutPoints)
(where a run too long to send whole may be split; run starts when absent).

```ts
function transcriptPage(
  boundaries: readonly boolean[],
  paging: LoadEventsPaging,
  cuts?: readonly boolean[],
  turnIds?: readonly string[],
): { cursor?: number; from: number; to: number }
```

**Parameters**

- `boundaries` (`readonly boolean[]`): Run starts per turn, from [`exchangeBoundaries`](https://zidane.si/docs/reference/ipc.md#exchangeBoundaries).
- `paging` (`LoadEventsPaging`): The `before` cursor and `limit` of the request.
- `cuts?` (`readonly boolean[]`, default `boundaries`): Allowed cut points per turn, from [`turnCutPoints`](https://zidane.si/docs/reference/ipc.md#turnCutPoints).
- `turnIds?` (`readonly string[]`): Id per turn: where a `beforeTurnId` anchor sits (it wins over `before`).

**Returns** `{ cursor?: number; from: number; to: number }`: The turn range of the page and the cursor of the page before it.

Source: [src/ipc/daemon/handlers/transcript-page.ts:60](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-page.ts#L60)

### `turnCutPoints`

Function.

Per turn: can a page start there without leaving a tool call's result behind (not a tool-result turn)?

```ts
function turnCutPoints(turns: readonly SessionTurn[]): boolean[]
```

**Parameters**

- `turns` (`readonly SessionTurn[]`): Turns of the session, in order.

**Returns** `boolean[]`: One flag per turn.

Source: [src/ipc/daemon/handlers/transcript-page.ts:46](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-page.ts#L46)

### `watchFileChanges`

Function.

Call `onChange` after `file` changes. Returns the function that stops watching.

```ts
function watchFileChanges(
  file: string,
  onChange: () => void,
  options?: { pollMs?: number; watch?: { (filename: PathLike, options?: BufferEncoding | WatchOptionsWithStringEncoding | null, listener?: WatchListener<string>): FSWatcher; (filename: PathLike, options: WatchOptionsWithBufferEncoding | 'buffer', listener: WatchListener<NonSharedBuffer>): FSWatcher; (filename: PathLike, options: BufferEncoding | WatchOptions | 'buffer' | null, listener: WatchListener<string | NonSharedBuffer>): FSWatcher; (filename: PathLike, listener: WatchListener<string>): FSWatcher } },
): () => void
```

**Parameters**

- `file` (`string`): The file to watch.
- `onChange` (`() => void`): Called once per change, after its events settle.
- `options?` (`{ pollMs?: number; watch?: { (filename: PathLike, options?: BufferEncoding | WatchOptionsWithStringEncoding | null, listener?: WatchListener<string>): FSWatcher; (filename: PathLike, options: WatchOptionsWithBufferEncoding | 'buffer', listener: WatchListener<NonSharedBuffer>): FSWatcher; (filename: PathLike, options: BufferEncoding | WatchOptions | 'buffer' | null, listener: WatchListener<string | NonSharedBuffer>): FSWatcher; (filename: PathLike, listener: WatchListener<string>): FSWatcher } }`, default `{}`): Options.

**Returns** `() => void`

Source: [src/ipc/daemon/watch-file.ts:35](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/watch-file.ts#L35)

## Classes

### `IpcVersionMismatchError`

Class.

Thrown when the host refuses the handshake because its protocol, build or code version does not match the client's.

```ts
class IpcVersionMismatchError extends Error
```

**Constructor**

```ts
new IpcVersionMismatchError(message: string, daemon?: HelloResult)
```

**Parameters**

- `message` (`string`): Description of the mismatch.
- `daemon?` (`HelloResult`): The host's handshake data, when it sent any.

**Returns** `IpcVersionMismatchError`

**Properties**

- `daemon?` (`HelloResult`, readonly): The host's handshake data, when it sent any.

Source: [src/ipc/transports/client-core.ts:40](https://github.com/Tahul/zidane/blob/main/src/ipc/transports/client-core.ts#L40)

### `WorkerRequestError`

Class.

The worker's handler threw: `remoteName` and `message` are the thrown error's.

```ts
class WorkerRequestError extends Error
```

**Constructor**

```ts
new WorkerRequestError(remoteName: string, message: string)
```

**Parameters**

- `remoteName` (`string`): The thrown error's `name`.
- `message` (`string`): The thrown error's `message`.

**Returns** `WorkerRequestError`

**Properties**

- `remoteName` (`string`, readonly): The thrown error's `name`.

Source: [src/ipc/history/rpc-client.ts:57](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L57)

### `WorkerUnavailableError`

Class.

No worker served the request: do the work on this thread. `degraded`: none will until the client is recreated.

```ts
class WorkerUnavailableError extends Error
```

**Constructor**

```ts
new WorkerUnavailableError(message: string, degraded: boolean)
```

**Parameters**

- `message` (`string`): Why no worker served.
- `degraded` (`boolean`): No worker will serve until the client is recreated.

**Returns** `WorkerUnavailableError`

**Properties**

- `degraded` (`boolean`, readonly): No worker will serve until the client is recreated.

Source: [src/ipc/history/rpc-client.ts:45](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L45)

## Constants

### `HISTORY_WORKER_KILL_SWITCH`

Constant.

Kill switch: `1` pages on the host's thread, with no worker.

```ts
const HISTORY_WORKER_KILL_SWITCH = 'ZIDANE_NO_HISTORY_WORKER'
```

Source: [src/ipc/history/transcript.ts:34](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L34)

### `IPC_BUILD_ID`

Constant.

Build fingerprint for the handshake. Running from source it is the newest
mtime under the `src/` tree at import time. Bundled, it is the mtime of this
module's own file. Client and daemon load the same files from disk, so a
daemon spawned before a rebuild (or a source edit in dev) reports a
different id than a freshly-started client, and the client drains +
respawns it. This closes the "same protocol version, different code"
gap that a hand-bumped version constant can't: during development the
daemon process is frozen at spawn while the tree keeps moving.

Compiled binaries (`/$bunfs/…` virtual paths) can't be stat'ed and
report `'unknown'`; the check is skipped when EITHER side is unknown,
so released builds rely on `IPC_PROTOCOL_VERSION` alone — correct,
since their code only changes when the version does.

```ts
const IPC_BUILD_ID: string
```

Source: [src/ipc/daemon/lifecycle.ts:33](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L33)

### `LOAD_EVENTS_MAX_PAGE_TURNS`

Constant.

Largest `limit` a host honors.

```ts
const LOAD_EVENTS_MAX_PAGE_TURNS = 1000
```

Source: [src/ipc/protocol.ts:1925](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1925)

### `LOAD_EVENTS_PAGE_TURNS`

Constant.

Turns per `sessions.loadEvents` page when only `before` is given.

```ts
const LOAD_EVENTS_PAGE_TURNS = 200
```

Source: [src/ipc/protocol.ts:1923](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1923)

### `MACHINE_PROTOCOL_VERSION`

Constant.

Bumped on an incompatible change; a host refuses any other version.

```ts
const MACHINE_PROTOCOL_VERSION = 1
```

Source: [src/chat/machine-protocol.ts:11](https://github.com/Tahul/zidane/blob/main/src/chat/machine-protocol.ts#L11)

### `MachineErrorCode`

Constant.

Error codes of the machine protocol (JSON-RPC server-error range, apart from `IpcErrorCode`).

```ts
const MachineErrorCode: { readonly Busy: -32045; readonly IdBound: -32044; readonly MethodNotAllowed: -32040; readonly NameTaken: -32042; readonly OutsideRoots: -32043; readonly VersionSkew: -32041 }
```

Source: [src/chat/machine-protocol.ts:184](https://github.com/Tahul/zidane/blob/main/src/chat/machine-protocol.ts#L184)

### `REDACTED`

Constant.

Every secret-bearing value of a catalog entry is replaced by this.

```ts
const REDACTED = '<redacted>'
```

Source: [src/ipc/protocol.ts:2195](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2195)

### `SESSION_TURNS_MAX_PAGE`

Constant.

Largest `limit` a host honors for `sessions.getTurns`.

```ts
const SESSION_TURNS_MAX_PAGE = 1000
```

Source: [src/ipc/protocol.ts:2077](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2077)

### `SESSION_TURNS_PAGE`

Constant.

Turns per `sessions.getTurns` page by default.

```ts
const SESSION_TURNS_PAGE = 200
```

Source: [src/ipc/protocol.ts:2075](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2075)

### `SIGNAL_SEQ_FIELD`

Constant.

Session-scoped signals fanned out to every peer carry their number in
their session as this extra field on the `ipc.signal` params (clients
predating it ignore it; `IpcClient` strips it and hands it to listeners as
[`SignalMeta`](https://zidane.si/docs/reference/ipc-browser.md#SignalMeta)). Per session, from 1, gap-free within one host process.

```ts
const SIGNAL_SEQ_FIELD = '$seq'
```

Source: [src/ipc/protocol.ts:458](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L458)

### `WHOLE_RUN_PAGES`

Constant.

A run longer than this many pages is split (by `limit`, so the client's
halving retry on a reply too large still converges).

```ts
const WHOLE_RUN_PAGES = 5
```

Source: [src/ipc/daemon/handlers/transcript-page.ts:21](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-page.ts#L21)

## Interfaces

### `AttachOptions`

Interface.

Options for [`runAttach`](https://zidane.si/docs/reference/ipc.md#runAttach).

```ts
interface AttachOptions
```

**Properties**

- `appVersion?` (`string`): Client version, surfaced in the host's diagnostics.
- `createNew?` (`boolean`): Create a fresh session instead of picking.
- `cwd?` (`string`, default `process.cwd()`): Working directory of a new session. Its project decides which sessions the picker lists.
- `host?` (`{ token?: string; url: string }`): Attach to a remote zidane-server instead of the local daemon (`zidane
  attach --host <wss-url> --token <t>`). Nothing is spawned or drained.
- `sessionId?` (`string`): Attach to this session id (prefix match against the list).
- `socketPath?` (`string`, default `defaultSocketPath()`): Path of the daemon socket.
- `spawnCommand?` (`string[]`): Spawn-on-demand command when no daemon is listening.
- `stdin?` (`ReadableStream`): Injectable streams for tests.
- `stdout?` (`WritableStream`, default `process.stdout`): Stream the output is written to.

Source: [src/ipc/attach.ts:33](https://github.com/Tahul/zidane/blob/main/src/ipc/attach.ts#L33)

### `CreateSessionParams`

Interface.

Params of `sessions.create`.

```ts
interface CreateSessionParams
```

**Properties**

- `account?` (`string`): The stored account of `providerKey` to run on (credential id). Additive: older hosts ignore it.
- `agentId?` (`string`): Id of the agent the session runs as.
- `cwd` (`string`): Tool-execution directory — `projectRoot` is derived from it host-side.
- `effort?` (`'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'adaptive'`): The model pick's reasoning effort and options, stamped with it.
- `environment?` (`EnvironmentRequest`): Where the session's work happens. Omitted → local.
- `extensionEdit?` (`boolean`): Mark as an extension-authoring session (auto-activates the docs skill).
- `fallbacks?` (`ModelFallbackRef[]`): Seed an ordered fallback chain alongside the model pick.
- `modelId?` (`string`): Model the session runs on.
- `modelOptions?` (`Record<string, boolean>`): Model-specific boolean options, stamped with the model pick.
- `pinnedSkills?` (`string[]`): Skills pinned from the first turn (an authoring session's docs skill).
- `policy?` (`SessionPolicy`): The session's rules (`sessions.setPolicy`). Additive: older hosts ignore it.
- `providerKey?` (`string`): Provider the session runs on.
- `sideOf?` (`string`): Create it as a hidden `/side` session of this parent. Additive: older hosts ignore it.
- `skillEdit?` (`{ name: string }`): Mark as a skill-authoring session for the named skill (dir = `cwd`).
- `spaceId?` (`string`): The space the session belongs to. Omitted → Default. Additive: older hosts ignore it.
- `title?` (`string`): Title of the session. Omitted: the host picks one.

Source: [src/ipc/protocol.ts:2582](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2582)

### `DaemonEnvironment`

Interface.

The host environment of a daemon or an embedded host: a [`ChatHostEnvironment`](https://zidane.si/docs/reference/chat.md#ChatHostEnvironment) backed by disk, with settings writes and runtime-config control.

```ts
interface DaemonEnvironment extends ChatHostEnvironment
```

**Properties**

- `applyAuthEnv?` (`() => void`, from `ChatHostEnvironment`): Re-apply provider auth env right before building a provider.
- `approvalsPersistence?` (`PendingApprovalsStore`, from `ChatHostEnvironment`): Durable pending-approval persistence. Defaults to in-memory only.
- `broadcast` (`(signal: HostSignal) => void`, from `ChatHostEnvironment`): Push a signal to every connected client. Must never throw.
- `cacheDir?` (`() => string`, from `ChatHostEnvironment`): Root of the per-session artifact tree (`<dir>/sessions/<id>/`): persisted
  tool outputs, background-task logs, MCP warning logs. Forks re-home and
  deletes clean there. Defaults to `userDataDir`.
- `config` (`ResolvedConfig`): Base config resolved at daemon boot (paths, store, state).
- `debugStream?` (`boolean`, from `ChatHostEnvironment`): Opt-in verbose stream logging to the host console.
- `environmentIdleSweepMs?` (`number`, from `ChatHostEnvironment`): How often idle environments are checked against their kind's `idleSuspendMinutes`. Default 60 s (tests shorten it).
- `environments?` (`EnvironmentRegistry`, from `ChatHostEnvironment`): Session environment providers (`chat/environment.ts`). Defaults to the
  built-ins (`local`). Hosts add kinds here (worktree, docker, sandboxes).
- `environmentSecrets?` (`() => EnvironmentSecrets`, from `ChatHostEnvironment`): Environment secret store. Defaults to `<userDataDir>/environment-credentials.json`.
- `extensionRuntimes?` (`DaemonExtensionsHost`): The extension API side: the real ports every folder's extension runtime is
  built over, and the runtimes, for the protocol (`./extensions/host`).
  Absent: a host whose registries another process builds (a window's
  shared setup), or a test environment.
- `extensionsConfigSync?` (`ExtensionsConfigSync`): Declarative install: reconciles the `extensions` entries of the user and
  project `config.json` for every folder's registry, in the background and
  again when a config or lock file changes. Absent: a host whose registries
  another process builds, or one built with `extensionsConfigSync: false`.
- `forgetRuntime` (`() => () => void`): Drop the memo WITHOUT disposing: the next `runtimeConfig` builds fresh
  registries while agents still running on the old ones keep working.
  Returns the disposer for what was dropped; call it once no agent
  holds those registries (`runtime.reload` after every session rebuilt).
- `gateExtensionReloads?` (`(runActiveIn: (cwd: string) => boolean) => void`): Gives the live reload of extensions (`watchExtensions`) and the runtime
  cache's eviction the check they wait on: a folder's registry reloads, or
  leaves the cache, only while `runActiveIn(cwd)` is `false` (no run in a
  session reading that folder's extensions). The dispatcher sets it from
  its chat host. Absent: an environment that does not watch extensions.
- `hostId?` (`string`, from `ChatHostEnvironment`): The id this host reports as `HelloResult.hostId`: stamped on `ctx.sessions.list` rows and facet snapshots (`hostId`). Absent: left out.
- `hostRuntime?` (`ExtensionHostRuntimeBridge`, from `ChatHostEnvironment`): The extension host-runtime bridge the host passed to its registry
  builds (`discoverAndBuildExtensionRegistry({ hostRuntime })`). The
  engine scopes a per-session impl onto it for the duration of each `/`
  command, so `ctx.workspace` / `ctx.runtime` / `ctx.sessions` resolve to
  the invoking session instead of reading as detached. Absent → those
  surfaces stay detached (extensions get the documented guard error).
- `instrumentAgent?` (`(agent: Agent, context: { sessionId: string }) => void`, from `ChatHostEnvironment`): Called with every agent the host builds (rebuilds included), before its
  first run. The embedder's own instrumentation, such as lifecycle logging
  into the TUI's Logs tab for a host in the TUI's process.
- `invalidateRuntime` (`() => void`): Drop the per-cwd runtime-config memo (settings changed) and dispose the registries it held.
- `linkHostId?` (`string`, from `ChatHostEnvironment`): The host id session links name (`zidane://session/<id>?host=<hostId>`): set on a server, absent on This computer, whose links carry no host.
- `logger?` (`Logger`, from `ChatHostEnvironment`): The host's own log, for what belongs to no session: a shared MCP
  server's output while several sessions (or none) call it. Dropped when
  unset.
- `machineHost?` (`{ principalLive?: (principal: string) => boolean }`, from `ChatHostEnvironment`): Set by a zidane-server: it takes machines whatever its `remoteHosts`
  setting (a server is remote by nature). Unset (local hosts): machines
  exist only while remote hosts are on; off, `machines.json` is never read
  and no machine kind resolves. `principalLive` answers whether a machine
  token is still valid: a machine id is bound to the token that first
  registered it until that token is revoked (`docs/MACHINES.md` § Security model).
- `mcpCredentialStore?` (`() => McpCredentialStore`, from `ChatHostEnvironment`): OAuth credential store for MCP servers, when the host supports MCP auth.
- `multiProcess?` (`boolean`, from `ChatHostEnvironment`): Force the cross-process run guard + marker heartbeat ON regardless of
  the `useDaemon` setting. The daemon sets this: `zidane attach` /
  `zidane daemon` are explicit opt-ins that run sessions with the
  setting off, making the daemon a multi-writer surface by
  construction. Embedders with a single writer (the GUI's in-process
  host) leave it unset and inherit the setting-gated behavior.
- `peekRuntimeConfig?` (`(cwd: string) => Promise<ResolvedConfig> | undefined`, from `ChatHostEnvironment`): The config `runtimeConfig(cwd)` already built or is building, without
  building one. Facet work (`./session-facets`) computes only with a
  loaded runtime. Absent: facet work calls `runtimeConfig`, which suits an
  embedder whose `runtimeConfig` never builds per folder (one config).
- `readSettings` (`() => HostSettings`, from `ChatHostEnvironment`): Current user settings — read fresh on every call.
- `runtimeConfig` (`(cwd: string) => Promise<ResolvedConfig>`, from `ChatHostEnvironment`): cwd-aware resolved runtime config (providers, agents, extensions).
  Hosts own caching/invalidation — the engine calls this per agent build.
- `stateDir?` (`() => string`, from `ChatHostEnvironment`): Where the host keeps runtime records that must outlive a crash: the pids
  of the MCP servers it shares, ended on its next start when it died
  without closing them. Defaults to `userDataDir`.
- `store` (`SessionStore`, from `ChatHostEnvironment`): Canonical session store shared with every other surface.
- `terminals?` (`boolean`, from `ChatHostEnvironment`): Whether this host has a surface that can show terminals (the GUI).
  `false` (a host in the TUI's own process) turns the terminal feature off
  for its agents: no terminal tools, background tasks on plain pipes.
  Default `true`; the `terminal*` settings still apply on top.
- `userDataDir` (`() => string`, from `ChatHostEnvironment`): The host's user folder, which is the config folder (`~/.zidane`, or `~/.config/zidane` under XDG). It holds the safelist and the tool-result blobs.
- `watchSettings?` (`(onChange: () => void) => () => void`): Calls `onChange` after the settings file changes, whoever wrote it (another
  daemon or window on the same `state.json`). Returns the function that stops
  watching. Absent when the settings live in no file.
- `workspaceRoots?` (`readonly string[]`, from `ChatHostEnvironment`): Confine the host to these folders (a zidane-server's `workspaceRoots`;
  they must exist). The host checks them at every entry point that takes
  a folder or a path (`ChatHost.workspace`, `../workspace-confinement`):
  session creation (the wire, orchestration workers), folder changes,
  launch-override `cwd`s (dropped), command / environment scans, and the
  workspace file and exec methods, which also never reach the data dir
  (`userDataDir`). A session without a folder works in the first root.
  Unset (local hosts): unconfined.
- `writeSettings` (`(patch: Partial<HostSettings>, reset?: readonly (keyof Settings | 'safeMode')[]) => HostSettings`): Merges a patch into the stored settings, drops the `reset` keys it doesn't set, and returns the settings in effect afterwards.

Source: [src/ipc/daemon/environment.ts:39](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L39)

### `DaemonExtensionsHost`

Interface.

The extension host of one daemon or server process.

```ts
interface DaemonExtensionsHost
```

**Properties**

- `bindHost` (`(host: DaemonChatHostPort) => void`): Late-bound: the chat host, for built-in commands, slash runs, command invocations, session settings and MCP status.
- `bindMcp` (`(mcp: ExtensionMcpHost) => void`): Late-bound: the MCP connections behind `ctx.mcp.call` (the environment's `createExtensionMcpHost`).
- `bindPeers` (`(peers: { broadcastExcept: (origin: HostPeer | null, signal: HostSignal) => void }) => void`): Late-bound: extension signals go out unnumbered through the peer fan-out once it exists.
- `bundles` (`(adopted: AdoptedRuntime) => Promise<Record<string, WireUiBundle>>`): The compiled `ui` bundle of each active extension of an adopted folder, by id. Never rejects.
- `clients` (`UiClientDirectory`, readonly): The windows connected to this host, and the routing of dialogs and UI requests to them.
- `close` (`() => void`): Closes the storage ports and watchers.
- `entries` (`(adopted: AdoptedRuntime) => Promise<WireExtensionEntry[]>`): The extensions of an adopted folder, as windows list them (`extensions.entries`). Never rejects.
- `flows` (`FlowRegistry`, readonly): The integration sign-in flows in progress, and the input each waits for.
- `kind` (`'server' | 'daemon'`, readonly): `daemon`, or `server` for a zidane-server.
- `prepare` (`(target: { cwd: string; projectRoot?: string }) => PreparedBuild`): The runtime build options and the adopt step of one registry build for `cwd`.
- `publish` (`(signal: ExtensionsSignal, origin?: HostPeer | null) => void`): Sends an extension signal to every client (except `origin`).
- `release` (`(registry: ExtensionRegistry) => void`): The registry is being disposed: its runtime stops publishing and is no longer found.
- `removeSession` (`(sessionId: string) => void`): A session was deleted: its UI items go.
- `rpcCall` (`(params: unknown, caller: RpcRemoteCaller, signal?: AbortSignal, authorize?: (scope: AccessScope) => boolean) => Promise<RpcResponseEnvelope>`): Runs a remote RPC call: the runtime of `params.cwd` when given, else the
  newest runtime holding the contract. `authorize`: whether the caller's
  token reaches a method's `scope` (absent: a local connection, not
  limited). Never rejects.
- `runtimeFor` (`(cwd: string) => AdoptedRuntime | undefined`): The newest runtime adopted for `cwd`.
- `runtimes` (`() => AdoptedRuntime[]`): Every adopted runtime, newest first.
- `sessionOpened` (`(sessionId: string) => Promise<void>`): A client opened a session: its `'session'` storage is loaded into every runtime. Never rejects.
- `storage` (`StorageSyncHub`, readonly): The synced storage of each project, shared by every client.
- `uiBundles` (`UiBundleStore`, readonly): The extensions' compiled `ui` bundles (a server's routes serve them, a daemon writes them to its cache).

Source: [src/ipc/daemon/extensions/host.ts:109](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/extensions/host.ts#L109)

### `EnsureDaemonOptions`

Interface.

Options for [`ensureDaemonRunning`](https://zidane.si/docs/reference/ipc.md#ensureDaemonRunning).

```ts
interface EnsureDaemonOptions
```

**Properties**

- `socketPath?` (`string`, default `defaultSocketPath()`): Socket the daemon listens on.
- `spawnCommand?` (`string[]`): Command used to spawn the daemon when nothing is listening. Defaults to
  `['zidane-daemon']` (the published bin). The child is detached and
  unref'd — it outlives the spawning client by design.
- `timeoutMs?` (`number`): Total time to wait for the daemon to accept connections. Default 8000 ms.

Source: [src/ipc/daemon/lifecycle.ts:214](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/lifecycle.ts#L214)

### `FsDirEntry`

Interface.

One folder in an [`FsDirListing`](https://zidane.si/docs/reference/ipc.md#FsDirListing).

```ts
interface FsDirEntry
```

**Properties**

- `isGitRepo` (`boolean`): Holds a `.git`.
- `name` (`string`): Folder name.
- `path` (`string`): Real path (a symlink resolved).

Source: [src/ipc/protocol.ts:2450](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2450)

### `FsDirListing`

Interface.

A folder listing from `fs.listDirs`.

```ts
interface FsDirListing
```

**Properties**

- `entries` (`FsDirEntry[]`): Sorted by name.
- `parent` (`string | null`): The folder above, or `null` at a root.
- `path` (`string`): The listed folder, as a real path.
- `roots` (`string[]`): Real paths of the browsable roots.
- `truncated?` (`boolean`): More folders than the listing returns.

Source: [src/ipc/protocol.ts:2474](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2474)

### `FsRoots`

Interface.

Folders a host lets clients browse, from `fs.roots`.

```ts
interface FsRoots
```

**Properties**

- `confined` (`boolean`): Session folders must be inside `roots` (a server).
- `roots` (`string[]`): Real paths, the default first.

Source: [src/ipc/protocol.ts:2442](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2442)

### `HelloParams`

Interface.

Params of the `hello` handshake.

```ts
interface HelloParams
```

**Properties**

- `appVersion` (`string`): Client's zidane version — surfaced in daemon diagnostics.
- `buildId?` (`string`): Build fingerprint (module mtime; `'unknown'` in compiled binaries).
  When BOTH sides report a real id and they differ, the daemon rejects
  the handshake like a protocol-version mismatch — the client drains it
  and respawns. Closes same-version code drift during development.
- `codeVersion?` (`string`): Version of the zidane code the client runs (`ZIDANE_VERSION`, inlined at
  build). Unlike `buildId` this survives compiled binaries, so it closes
  the gap released builds had: same protocol version, older code. A
  client STRICTLY NEWER than the daemon is rejected like a build mismatch
  and the stale daemon is drained; an older client is accepted and
  degrades via `optional()`.
- `minProtocolVersion?` (`number`): The oldest version the client can speak down to ([`IPC_MIN_PROTOCOL_VERSION`](https://zidane.si/docs/reference/ipc-browser.md#IPC_MIN_PROTOCOL_VERSION)).
  A zidane-server accepts when the ranges overlap. Absent: `protocolVersion` only. Additive.
- `pid` (`number`): Process id of the client.
- `protocolVersion` (`number`): Protocol version the client speaks.

Source: [src/ipc/protocol.ts:2622](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2622)

### `HistoryWorkerInit`

Interface.

What `./worker.ts` takes as `init`.

```ts
interface HistoryWorkerInit
```

**Properties**

- `dbPath` (`string`): The sessions database, opened read-only by the worker.

Source: [src/ipc/history/transcript.ts:37](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L37)

### `HostAuthMethod`

Interface.

One credential source of a host's provider (`auth.status`); no secret.

```ts
interface HostAuthMethod
```

**Properties**

- `active` (`boolean`): A stored credential the provider resolves (`env` never is).
- `detail` (`string`): Display detail: `credentials.json`, an OAuth account and its expiry, an env var name.
- `email?` (`string`): Email of an OAuth account, when known. Additive.
- `key?` (`string`): Credentials-file key of a stored credential: the `account` of `auth.remove`.
- `label?` (`string`): OAuth account name.
- `source` (`'oauth' | 'apikey' | 'env'`): Where the credential comes from: a stored API key, an OAuth login, or an environment variable.

Source: [src/ipc/protocol.ts:2367](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2367)

### `HostCatalogError`

Interface.

A config file that failed to parse (or an informational skip).

```ts
interface HostCatalogError
```

**Properties**

- `informational?` (`boolean`): `true` when the entry is a skip notice, not a failure.
- `message` (`string`): Why it failed or was skipped.
- `path` (`string`): Path of the config file.
- `source` (`'user' | 'project'`): Whether the file is the project's or the user's.

Source: [src/ipc/protocol.ts:2228](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2228)

### `HostCatalogExtension`

Interface.

An extension in the host's catalog.

```ts
interface HostCatalogExtension extends HostCatalogToggle
```

**Properties**

- `capabilities?` (`string[]`): What it contributes: `tools`, `skills`, `mcps`, `commands`, …
- `description?` (`string`): What the extension does.
- `dir?` (`string`): Directory of the extension on the host's machine.
- `displayName?` (`string`): Its display name (the definition's `displayName`, else the manifest's). Absent: the name. Additive.
- `enabled` (`boolean`, from `HostCatalogToggle`): The host's settings enable it (always `false` for an entry that cannot load).
- `error?` (`string`): Why it did not load.
- `icon?` (`{ gui?: string; tui?: string }`): Its icon (the definition's `icon`, else the manifest's): what `extensionMark` reads. Additive.
- `name` (`string`, from `HostCatalogToggle`)
- `origin?` (`ExtensionInstallOrigin`): The source it was installed from (`.install.json`), which an update follows. Absent: not installed from a source. Additive.
- `source` (`'user' | 'project' | 'inline' | 'builtin'`): Where the extension was found.
- `toggleable` (`boolean`, from `HostCatalogToggle`): Its own allowlist governs it (`enabledSkills`, …). `false`: contributed
  by a plugin or extension (their toggle governs it), or broken.
- `version?` (`string`): Version from the extension manifest.

Source: [src/ipc/protocol.ts:2240](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2240)

### `HostCatalogMcp`

Interface.

An MCP server in the host's catalog. Secret values are redacted.

```ts
interface HostCatalogMcp extends HostCatalogToggle
```

**Properties**

- `args?` (`string[]`): Arguments of the command.
- `auth?` (`'oauth'`): `oauth` when the server signs in with OAuth.
- `command?` (`string`): Command that starts a `stdio` server.
- `cwd?` (`string`): Working directory of the command.
- `enabled` (`boolean`, from `HostCatalogToggle`): The host's settings enable it (always `false` for an entry that cannot load).
- `env?` (`Record<string, string>`): Names only: every value is [`REDACTED`](https://zidane.si/docs/reference/ipc.md#REDACTED).
- `headers?` (`Record<string, string>`): Header names. Every value is [`REDACTED`](https://zidane.si/docs/reference/ipc.md#REDACTED).
- `name` (`string`, from `HostCatalogToggle`)
- `path` (`string`): The config file on the host's machine.
- `scope?` (`'context' | 'host'`): `context` runs the server in the agent's execution context. `host` runs it on the host. Always sent for a `stdio` server (absent from an older host).
- `shared?` (`boolean`): Its config's `shared` (absent: `true`): one process for every session. The host's `mcpSharing` setting wins over it.
- `source` (`'user' | 'project'`): Whether the config is the project's or the user's.
- `status?` (`McpServerStatus`): Its sign-in state, tools as last listed and last Test (`mcp.test`) on the host. Absent from an older host.
- `toggleable` (`boolean`, from `HostCatalogToggle`): Its own allowlist governs it (`enabledSkills`, …). `false`: contributed
  by a plugin or extension (their toggle governs it), or broken.
- `transport` (`'sse' | 'stdio' | 'streamable-http'`): How the server is reached.
- `url?` (`string`): Credentials and query values redacted.

Source: [src/ipc/protocol.ts:2198](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2198)

### `HostCatalogPlugin`

Interface.

A plugin in the host's catalog.

```ts
interface HostCatalogPlugin extends HostCatalogToggle
```

**Properties**

- `description?` (`string`): What the plugin does.
- `enabled` (`boolean`, from `HostCatalogToggle`): The host's settings enable it (always `false` for an entry that cannot load).
- `error?` (`string`): Why the manifest was rejected, when `ok` is `false`.
- `mcpServers` (`string[]`): Names of the MCP servers the plugin contributes.
- `name` (`string`, from `HostCatalogToggle`)
- `ok` (`boolean`): `false`: the manifest was rejected (`error` says why).
- `origin` (`{ dir: string; kind: 'disk'; scope: 'user' | 'project' } | { dir: string; extensionName: string; kind: 'extension' }`): Where the plugin comes from: a directory on disk, or an extension.
- `skills` (`string[]`): Names of the skills the plugin contributes.
- `toggleable` (`boolean`, from `HostCatalogToggle`): Its own allowlist governs it (`enabledSkills`, …). `false`: contributed
  by a plugin or extension (their toggle governs it), or broken.
- `version?` (`string`): Version from the plugin manifest.

Source: [src/ipc/protocol.ts:2262](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2262)

### `HostCatalogSkill`

Interface.

A skill in the host's catalog.

```ts
interface HostCatalogSkill extends HostCatalogToggle
```

**Properties**

- `contributedBy?` (`string`): Name of the plugin or extension that contributes the skill, when `origin` is not `disk`.
- `description` (`string`): What the skill is for.
- `enabled` (`boolean`, from `HostCatalogToggle`): The host's settings enable it (always `false` for an entry that cannot load).
- `location?` (`string`): `SKILL.md` on the host's machine.
- `name` (`string`, from `HostCatalogToggle`)
- `origin` (`'extension' | 'plugin' | 'disk'`): `disk`: a scan path; else the plugin or extension that contributes it (`contributedBy`).
- `source?` (`'user' | 'project' | 'inline' | 'builtin'`): Where the skill was found.
- `toggleable` (`boolean`, from `HostCatalogToggle`): Its own allowlist governs it (`enabledSkills`, …). `false`: contributed
  by a plugin or extension (their toggle governs it), or broken.

Source: [src/ipc/protocol.ts:2181](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2181)

### `HostEnvironmentOptions`

Interface.

Options for [`createHostEnvironment`](https://zidane.si/docs/reference/ipc.md#createHostEnvironment).

```ts
interface HostEnvironmentOptions
```

**Properties**

- `broadcast` (`(signal: HostSignal) => void`): Sink that fans a signal out to every connected client.
- `cwd?` (`string`): Daemon only: base cwd for its own boot-time config resolution. Default: `process.cwd()`.
- `debugStream?` (`boolean`): Turns on verbose stream logging to the host console.
- `extensionsConfigSync?` (`false | Pick<ExtensionsConfigSyncOptions, 'port' | 'watch'>`): Install the extensions config files declare (`extensions` in
  `config.json`), in the background, and follow their changes. Default on;
  `false` turns it off; an object replaces the install port or the file
  watch (tests). Ignored with `shared`.
- `extensionsHost?` (`'server' | 'daemon'`): What the extensions see as `ctx.app.host`: a zidane-server passes `'server'`. Default `'daemon'`.
- `logSink?` (`LogSink`): Also receives its extensions' setup and runtime log records (stderr gets the warnings either way).
- `shared?` (`SharedHostSetup`): Share the embedding window's setup instead of resolving the daemon's
  own: a host in the window's process. Absent: the daemon (own config,
  per-cwd extension discovery, multi-process).
- `watchExtensions?` (`boolean | ExtensionFolderWatchOptions`): Reload an extension when its folder changes, load a folder that appears
  under a scan root, unload one that goes (`./extension-watch`). Only
  that extension reloads; the others keep running. Default `true`;
  `false` leaves changes to `/reload`. Ignored with `shared`.

Source: [src/ipc/daemon/environment.ts:138](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L138)

### `HostImagePortDeps`

Interface.

What [`createHostImagePort`](https://zidane.si/docs/reference/ipc.md#createHostImagePort) reads at call time.

```ts
interface HostImagePortDeps
```

**Properties**

- `bridge?` (`ExtensionHostRuntimeBridge`): The session behind a save: its folder (`sessionControl`) and, without a `sessionId`, the active one.
- `buildProvider` (`(providers: Readonly<Record<string, ProviderDescriptor>>, key: string) => Provider`): Builds a provider of the registry. May throw (no credentials).
- `folder` (`string`): Where `save` writes without a session: the project root, else the folder.
- `imageModel` (`() => string | undefined`): `Settings.imageModel` (`<provider>/<model>`): the default model, as the tool's.
- `providers` (`() => Readonly<Record<string, ProviderDescriptor>>`): The folder's providers.
- `recordArtifact?` (`(artifact: SessionArtifact) => Promise<unknown>`): Stores an artifact on its session. Default: the active session's artifact
  scope on `bridge` (`record`, else `store.upsertArtifact`).

Source: [src/ipc/daemon/extensions/image-port.ts:37](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/extensions/image-port.ts#L37)

### `HostModelInfo`

Interface.

`ModelInfo` as it crosses the wire.

```ts
interface HostModelInfo
```

**Properties**

- `contextWindow` (`number`): Context window in tokens.
- `cost?` (`{ cacheRead?: number; cacheWrite?: number; input: number; output: number }`): Price per million tokens, by token kind.
- `id` (`string`): Model id.
- `input?` (`('text' | 'image')[]`): Input kinds the model accepts.
- `maxTokens?` (`number`): Maximum output tokens.
- `name?` (`string`): Display name.
- `options?` (`{ costMultiplier?: { cacheRead?: number; cacheWrite?: number; input?: number; output?: number }; description?: string; id: string; label: string }[]`): Model-specific boolean options, with an optional cost multiplier per token kind.
- `provider?` (`string`): Provider that serves the model.
- `reasoning?` (`boolean`): Whether the model supports reasoning.

Source: [src/ipc/protocol.ts:2345](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2345)

### `HostModelProvider`

Interface.

One provider a host can run, with its models (`models.list`).

```ts
interface HostModelProvider
```

**Properties**

- `accounts?` (`{ active: boolean; id: string; label: string; models?: HostModelInfo[] }[]`): The host's stored accounts of the provider a session can be pinned to
  (`ProviderAuth.accounts`), when it has several. Ids are the host's own:
  a pick on a server names one of its accounts. `models`: that account's
  own list (an extension's `models.set(id, list, { account })`), sent only
  when it differs from `HostModelProvider.models`; absent, the
  account runs on `models`. Additive.
- `decisionModels?` (`HostDecisionModel[]`): Decision models of the provider's Decisions endpoint, with whether this
  host's credentials can use them. Absent on providers without one, and
  from hosts that predate decisions. Additive.
- `imageModels?` (`HostImageModel[]`): Image models of the provider's image endpoint, with whether this host's
  credentials can use them. Absent on providers without one, and from
  hosts that predate image generation. Additive.
- `key` (`string`): Provider key.
- `label` (`string`): Display name.
- `models` (`HostModelInfo[]`): Models the provider offers on this host.

Source: [src/ipc/protocol.ts:2280](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2280)

### `HostOAuthBegin`

Interface.

Result of `auth.oauth.begin`.

```ts
interface HostOAuthBegin
```

**Properties**

- `expiresAt` (`number`): Epoch ms: the host forgets the flow after it.
- `flowId` (`string`): Random, single-use, bound to the connection that began it.
- `instructions?` (`string`): Text to show the user while they sign in.
- `mode` (`'device' | 'step' | 'browser' | 'loopback'`): How the client gets the code back. `step`: answer `step` (`auth.oauth.respond`) before the URL exists.
- `redirectUri?` (`string`): `loopback`: where the browser is sent back, on the client's machine.
- `step?` (`HostOAuthStep`): A question to answer before the URL exists. Set when `mode` is `step`.
- `url` (`string`): The authorization URL (a device flow: its verification URL); `''` while a `step` comes first.
- `userCode?` (`string`): `device`: the code to enter at `url`.

Source: [src/ipc/protocol.ts:2392](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2392)

### `HostOAuthComplete`

Interface.

`auth.oauth.complete`: the outcome, never a token.

```ts
interface HostOAuthComplete
```

**Properties**

- `mcpServer?` (`string`): An MCP server sign-in: its name.
- `provider?` (`HostProviderAuth`): A provider sign-in: its new status.
- `step?` (`HostOAuthStep`): Not finished: the sign-in asks this. Answer it (`auth.oauth.respond`), then `complete` again.

Source: [src/ipc/protocol.ts:2412](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2412)

### `HostProviderAuth`

Interface.

Sign-in state of one provider on a host, from `auth.status`. Holds no secret.

```ts
interface HostProviderAuth
```

**Properties**

- `configured` (`boolean`): Some credential source is present.
- `configuredFields?` (`Record<string, string>`): The non-secret field values set now (stored, else from the host's environment). Additive.
- `customFields?` (`ProviderFieldView[]`): Its configuration fields (a local server's URL, a cloud's region), what `auth.configure` takes. Additive.
- `envKey?` (`string`): The env var it reads, when it declares one.
- `key` (`string`): Provider key.
- `label` (`string`): Display name.
- `methods` (`HostAuthMethod[]`): Credential sources of the provider.
- `oauth` (`boolean`): The provider signs in with OAuth (on the host's machine only).

Source: [src/ipc/protocol.ts:2422](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2422)

### `HostRef`

Interface.

Which host a client is talking to, as clients keep it (from `hostRefOf`).

```ts
interface HostRef
```

**Properties**

- `id` (`string`): Stable across restarts: persisted in the host's data dir.
- `kind` (`HostKind`): What kind of host it is.
- `name` (`string`): Display name: the machine's hostname by default.

Source: [src/ipc/protocol.ts:2659](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2659)

### `HostTranscriptPager`

Interface.

Where a host's paged `sessions.loadEvents` are served: the history worker when it can, else the in-thread cache.

```ts
interface HostTranscriptPager
```

**Properties**

- `close` (`() => void`): Terminates the worker (the host is shutting down); later pages are served in-thread.
- `forget` (`(sessionId: string) => void`): The session is gone: forget it here and in the worker.
- `observe` (`(signal: HostSignal) => void`): A host signal: one that follows a change to a session drops its replay, here and in the worker.
- `page` (`(store: SessionStore, sessionId: string, paging: LoadEventsPaging) => Promise<SessionEventsPage>`): One page of a session of `store` (the worker serves it when `store` is a SQLite file).
- `replays` (`TranscriptReplayCache`): The in-thread cache: the fallback pages, and the host's other whole-session reads (`document`).
- `usage` (`(store: SessionStore) => Promise<UsageBuckets | null>`): The usage summary's day buckets of `store`; `null` for a store that is not a SQLite file (it keeps no usage to scan).

Source: [src/ipc/history/transcript.ts:116](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L116)

### `InProcessClientOptions`

Interface.

Options for `InProcessHost.connect`.

```ts
interface InProcessClientOptions
```

**Properties**

- `appVersion?` (`string`): Client version, surfaced in the host's diagnostics.
- `onClose?` (`() => void`): Called when the host shuts down under a still-open client.

Source: [src/ipc/memory.ts:51](https://github.com/Tahul/zidane/blob/main/src/ipc/memory.ts#L51)

### `InProcessHost`

Interface.

A chat host running in the caller's process, with clients that call it directly.

```ts
interface InProcessHost
```

**Properties**

- `close` (`() => Promise<void>`): Shut the host down: refuse new work, suspend and await every run
  (`ChatHost.drain`), then close the clients still open (their `onClose`
  fires). Idempotent.
- `connect` (`(options?: InProcessClientOptions) => Promise<IpcClient>`): A new client, already past the `ipc.hello` handshake.
- `host` (`ChatHost`): The chat host.
- `peerCount` (`() => number`): Number of open clients.

Source: [src/ipc/memory.ts:65](https://github.com/Tahul/zidane/blob/main/src/ipc/memory.ts#L65)

### `InProcessHostOptions`

Interface.

Options for [`startInProcessHost`](https://zidane.si/docs/reference/ipc.md#startInProcessHost).

```ts
interface InProcessHostOptions
```

**Properties**

- `appVersion?` (`string`): Reported to clients as the host's `appVersion`.
- `createEnvironment` (`(broadcast: (signal: HostSignal) => void) => DaemonEnvironment | Promise<DaemonEnvironment>`): The host's environment, given the broadcast sink wired to client fan-out.

Source: [src/ipc/memory.ts:43](https://github.com/Tahul/zidane/blob/main/src/ipc/memory.ts#L43)

### `IpcClient`

Interface.

A connected host client, shared by every transport. Requests are checked against [`IpcMethods`](https://zidane.si/docs/reference/ipc-browser.md#IpcMethods).

```ts
interface IpcClient
```

**Properties**

- `close` (`() => void`): Closes the connection. Pending requests reject.
- `hello` (`HelloResult`): The host's answer to the `ipc.hello` handshake.
- `notify` (`<M extends keyof IpcMethods>(method: M, params: IpcParams<M>) => void`): Fire-and-forget notification — same method table as `request`, but no
  id, no response, no pending-promise bookkeeping. The hot path for
  high-frequency writes (per-keystroke draft sync). Daemons that don't
  know the method ignore it silently.
- `onSignal` (`(cb: SignalListener) => () => void`): Host signals, with their number in their session when they have one (`SignalMeta`).
- `request` (`<M extends keyof IpcMethods>(method: M, params: IpcParams<M>) => Promise<IpcResult<M>>`): Calls a host method and resolves with its result. Rejects with a `JsonRpcRemoteError` when the host answers with an error, or with `JsonRpcConnectionClosedError` when the connection closes first.
  A request not answered within its deadline (30 s, longer for slow methods) rejects and drops the connection. `machine.call` has no deadline.

Source: [src/ipc/transports/client-core.ts:16](https://github.com/Tahul/zidane/blob/main/src/ipc/transports/client-core.ts#L16)

### `IpcClientOptions`

Interface.

Options for [`connectIpcClient`](https://zidane.si/docs/reference/ipc.md#connectIpcClient).

```ts
interface IpcClientOptions
```

**Properties**

- `appVersion?` (`string`): Client zidane version, surfaced in daemon diagnostics.
- `drainOnMismatch?` (`boolean`): On a version/build mismatch, ask the stale daemon to drain before
  throwing (default). PASSIVE clients (the presence watcher) must set
  this false: they retry on a timer, and an old-build window left open
  across a protocol bump would otherwise drain the NEW daemon in a
  loop, aborting every other window's runs.
- `onClose?` (`() => void`): Called when the daemon connection drops (socket close/error).
- `socketPath` (`string`): Path of the daemon's unix socket.

Source: [src/ipc/client.ts:25](https://github.com/Tahul/zidane/blob/main/src/ipc/client.ts#L25)

### `IpcDaemon`

Interface.

A running unix-socket daemon.

```ts
interface IpcDaemon
```

**Properties**

- `close` (`() => Promise<void>`): Drains the host, disconnects every peer and removes the socket file. Calling it again returns the same promise. With a shared `dispatcher`, the host is left to its owner.
- `dispatcher` (`HostDispatcher`): The dispatcher it serves, to connect an in-process client to it (`../memory` `connectInProcess`).
- `host` (`ChatHost`): The chat host it serves.
- `peerCount` (`() => number`): Number of connected peers.
- `socketPath` (`string`): Path of the socket it listens on.

Source: [src/ipc/daemon/server.ts:100](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/server.ts#L100)

### `IpcDaemonOptions`

Interface.

Options for [`startIpcDaemon`](https://zidane.si/docs/reference/ipc.md#startIpcDaemon).

```ts
interface IpcDaemonOptions
```

**Properties**

- `appVersion?` (`string`, default `'dev'`): zidane version reported in the handshake.
- `createEnvironment?` (`(broadcast: (signal: HostSignal) => void) => DaemonEnvironment | Promise<DaemonEnvironment>`): Environment factory — the production daemon uses the disk-backed
  `createDaemonEnvironment`; tests inject an in-memory one. Receives the
  broadcast sink wired to peer fan-out.
- `deferResume?` (`boolean`): See `HostDispatcherOptions.deferResume`: the caller calls `dispatcher.resumeAfterRestart()`. Ignored with a shared `dispatcher`.
- `dispatcher?` (`HostDispatcher`): Serve this already-built host instead of creating one: another front-end
  (zidane-server's WebSocket) serves it too. Its owner drains it and owns
  its lifecycle, so `createEnvironment`, `appVersion` and the idle options
  are ignored, and `close()` only closes this socket's connections.
- `idleShutdownMs?` (`number`): Milliseconds the daemon may have zero peers and no running session before
  it calls `onIdle`. Unset or 0: never. Ignored with a shared `dispatcher`.
- `maxBufferedBytes?` (`number`): A peer with more than this of signals queued for sending (it stopped
  reading) is dropped; it re-attaches and resumes. Replies are bounded by
  `maxMessageBytes` instead (`../transports/send-budget`). Default
  `PEER_WRITE_HIGH_WATERMARK` (8 MiB).
- `maxMessageBytes?` (`number`): A bigger reply goes out as an `IpcErrorCode.ResponseTooLarge` error. Default `SOCKET_MAX_REPLY_BYTES`.
- `onIdle?` (`() => void`): Called when the daemon has had no peers for `idleShutdownMs` and no session is active, or when it retires after a newer client attached mid-work. The CLI exits the process; embedded servers ignore it.
- `onLog?` (`(line: string) => void`): Receives one diagnostic line per event, such as peers connecting.
- `socketPath` (`string`): Path of the unix socket to listen on. Its directory is created with mode 0700 and the socket gets mode 0600.
- `updateWatch?` (`Pick<WatchDaemonUpdateOptions, 'cacheDir' | 'watch' | 'spec' | 'currentVersion' | 'pollMs' | 'idlePollMs'>`): Watch this package for a newer install and restart (close, then
  `onIdle`) at the first fully idle point after one lands. Only for a
  daemon run from an installed build. Ignored with a shared `dispatcher`.

Source: [src/ipc/daemon/server.ts:42](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/server.ts#L42)

### `LoadEventsPaging`

Interface.

Paging options of `sessions.loadEvents`.

```ts
interface LoadEventsPaging
```

**Properties**

- `before?` (`number`): Turn position (exclusive) the page ends at: a previous page's `cursor`.
- `beforeTurnId?` (`string`): The page ends right before the turn with this id (same alignment as
  `before` at its position); wins over `before`. A turn the stored
  transcript doesn't hold fails the request (invalid params, the message
  names `beforeTurnId`). An older host ignores it: see
  `SessionEventsPage.beforeTurnId`.
- `limit?` (`number`): Turns in the page.

Source: [src/ipc/protocol.ts:1928](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1928)

### `MachineLinksHandlerOptions`

Interface.

Options for [`createMachineLinkHandlers`](https://zidane.si/docs/reference/ipc.md#createMachineLinkHandlers): the host, settings access and the signal sink.

```ts
interface MachineLinksHandlerOptions
```

**Properties**

- `appVersion` (`string`): zidane version reported when dialing a server.
- `broadcast` (`(signal: HostSignal) => void`): Sink that fans a signal out to every connected client.
- `env` (`Pick<DaemonEnvironment, 'readSettings' | 'userDataDir'>`): Environment accessors for reading settings and locating the user data directory.
- `host` (`ChatHost`): The chat host whose machine registry the links feed.
- `hostId` (`string | undefined`): Id of this host, when it has one.
- `pacing?` (`{ heartbeatMs?: number; maxDelayMs?: number; minDelayMs?: number; pollMs?: number }`): Connection pacing for the links (tests shrink it).
- `server?` (`boolean`): A zidane-server: it has no links (a server is shared from, never shares from here); every method is refused.

Source: [src/ipc/daemon/handlers/machine-links.ts:24](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/machine-links.ts#L24)

### `ModelFallbackRef`

Interface.

One ordered model-fallback target (primary excluded).

```ts
interface ModelFallbackRef
```

**Properties**

- `account?` (`string`): The stored account of the provider (credential id); omitted = its active account. Additive.
- `modelId` (`string`): Id of the fallback model.
- `providerKey` (`string`): Provider of the fallback model.

Source: [src/ipc/protocol.ts:2496](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2496)

### `RemoteOAuthStart`

Interface.

Result of `auth.oauth.begin`.

```ts
interface RemoteOAuthStart extends HostOAuthBegin
```

**Properties**

- `expiresAt` (`number`, from `HostOAuthBegin`): Epoch ms: the host forgets the flow after it.
- `flowId` (`string`, from `HostOAuthBegin`): Random, single-use, bound to the connection that began it.
- `instructions?` (`string`, from `HostOAuthBegin`): Text to show the user while they sign in.
- `listenError?` (`string`): Why it doesn't (a busy port).
- `listening` (`boolean`): This machine catches the redirect (else: paste, or wait for a device / polling flow).
- `mode` (`'device' | 'step' | 'browser' | 'loopback'`, from `HostOAuthBegin`): How the client gets the code back. `step`: answer `step` (`auth.oauth.respond`) before the URL exists.
- `redirectUri?` (`string`, from `HostOAuthBegin`): `loopback`: where the browser is sent back, on the client's machine.
- `step?` (`HostOAuthStep`, from `HostOAuthBegin`): A question to answer before the URL exists. Set when `mode` is `step`.
- `url` (`string`, from `HostOAuthBegin`): The authorization URL (a device flow: its verification URL); `''` while a `step` comes first.
- `userCode?` (`string`, from `HostOAuthBegin`): `device`: the code to enter at `url`.

Source: [src/ipc/remote-oauth.ts:27](https://github.com/Tahul/zidane/blob/main/src/ipc/remote-oauth.ts#L27)

### `RemoteOAuthUi`

Interface.

Hooks a window supplies to [`runRemoteOAuth`](https://zidane.si/docs/reference/ipc.md#runRemoteOAuth): open the browser, take pasted input, answer the provider's questions, and abort.

```ts
interface RemoteOAuthUi
```

**Properties**

- `onStart?` (`(start: RemoteOAuthStart) => void`): The flow started: the URL, the mode, a device code, whether the loopback listens.
- `openUrl` (`(url: string) => void | Promise<void>`): Open the browser here (best effort; the URL is shown too).
- `paste?` (`() => Promise<string>`): What the user pastes (a code or the address the browser landed on); offered in every mode.
- `prompt?` (`(step: { allowEmpty?: boolean; id: string; kind: 'prompt'; message: string; placeholder?: string }) => Promise<string>`): The provider asks the user a question (default: `paste`).
- `renderPage?` (`OAuthCallbackPageRenderer`): The page the browser lands on at the loopback.
- `select?` (`(step: { id: string; kind: 'select'; message: string; options: { id: string; label: string }[] }) => Promise<string | undefined>`): The provider asks the user to choose (its option id; `undefined` cancels).
- `signal?` (`AbortSignal`): Aborts the sign-in. The run rejects with "OAuth login aborted".

Source: [src/ipc/remote-oauth.ts:35](https://github.com/Tahul/zidane/blob/main/src/ipc/remote-oauth.ts#L35)

### `ReplayData`

Interface.

What a client's own load gives `replay`.

```ts
interface ReplayData
```

**Properties**

- `runs` (`SessionRun[]`): The session's runs (they tell child runs from parent runs).
- `seqs?` (`number[]`): A per-turn position the client keeps with the replay (the GUI store's `seq`).
- `turns` (`SessionTurn[]`): The session's turns, in order.

Source: [src/ipc/daemon/handlers/transcript-cache.ts:76](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-cache.ts#L76)

### `ReplayRead`

Interface.

A client's own read of a stored session, for `replay`.

```ts
interface ReplayRead
```

**Properties**

- `background?` (`boolean`): A read ahead of the user: a hit leaves the order as is, a miss is kept only when that evicts nothing.
- `load` (`() => ReplayData | Promise<ReplayData | null> | null`): Loads the session on a miss; `null` when it is unknown.
- `variant?` (`string`): Appended to the version: what else the load depends on.

Source: [src/ipc/daemon/handlers/transcript-cache.ts:86](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-cache.ts#L86)

### `SequencedSignal`

Interface.

A session signal with its position in the session, as kept in the host's replay log.

```ts
interface SequencedSignal
```

**Properties**

- `seq` (`number`): Position of the signal in its session.
- `signal` (`HostSignal`): The signal itself.

Source: [src/ipc/protocol.ts:467](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L467)

### `SessionEventsPage`

Interface.

One page of a session's stream events, as `sessions.loadEvents` answers it.

```ts
interface SessionEventsPage
```

**Properties**

- `beforeTurnId?` (`string`): The request's `beforeTurnId`, echoed: absent when the host ignored
  the anchor (an older host, which then paged by `before` / from the end).
- `cursor?` (`number`): Pass as `before` for the page before this one; absent once the first turn is in.
- `events` (`StreamEvent[]`): Stream events of the page.
- `exact?` (`true`): The events are this page's slice of the whole replay, so pages
  concatenate to exactly one whole `loadEvents`. Absent from an older
  host, whose pages replay on their own ([`loadAllEvents`](https://zidane.si/docs/reference/ipc.md#loadAllEvents) restores
  the exchange separator at their joins).
- `start?` (`number`): With `exact`: how many events of the whole replay come before this
  page. Lets a client open on the tail of a long transcript and still
  say how much it left out (`loadEventsTail`). Absent from an
  older host.

Source: [src/ipc/protocol.ts:1944](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L1944)

### `SessionRow`

Interface.

One row of a cross-window session list.

```ts
interface SessionRow
```

**Properties**

- `account?` (`string`): The pinned account of `providerKey` (credential id), when one is. Additive.
- `agentId?` (`string`): Id of the agent the session runs as.
- `archived` (`boolean`): Whether the session is archived.
- `createdAt` (`number`): Creation time, epoch ms.
- `cwd` (`string`): Working directory of the session.
- `effort?` (`'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'adaptive'`): Thinking effort of the session.
- `environment?` (`SessionEnvironmentSummary`): Non-local environment summary (kind, state, branch, error).
- `facets?` (`Record<string, JsonValue>`): Facet values extensions computed for the session (`ctx.sessions.facets`),
  keyed `<extensionId>.<key>`; queries read them as `facet.<extensionId>.<key>`.
  Stored with the session, so a list computes nothing. `sessions:facets`
  announces a change. Absent when it has none, and from older hosts. Additive.
- `favorite?` (`boolean`): Listed first (`metadata.favorite`). Additive.
- `hostId?` (`string`): The host serving this row (`HelloResult.hostId`). Additive: absent from older hosts.
- `id` (`string`): Session id.
- `isMain?` (`boolean`): Orchestration main session — see `SessionMeta.isMain`. Additive.
- `modelFallbacks?` (`ModelFallbackRef[]`): Validated (head-matched) fallback chain tail, for pickers/badges.
- `modelId?` (`string`): Model the session runs on.
- `modelOptions?` (`Record<string, boolean>`): Model-specific boolean options of the session.
- `projectRoot` (`string | null`): Project the session belongs to, or `null` when it has none.
- `providerKey?` (`string`): Provider the session runs on.
- `repoKey?` (`string`): The repository the session's folder is a checkout of (`github.com/owner/repo`,
  see `repoKeyOf`). Copies of one repository on two machines have the same key.
  Absent outside git, without a shared remote, and from older hosts. Additive.
- `runEstimates?` (`RunEstimateView[]`): While `status` is `running`: the estimates of its runs in progress, the
  session's own first, then its subagents' (`Settings.runEstimates`), so a
  window opened mid-run counts down from the same point. Absent when none
  is estimated, and from older hosts. Additive.
- `runStartedAt?` (`number`): While `status` is `running`: when the run in progress began, epoch ms on
  the host's clock, so a client that missed its `run:start` still shows how
  long it has been going. Additive: absent from older hosts.
- `scheduleId?` (`string`): The reminder that started the session (`metadata.scheduleId`, see
  `SCHEDULE_METADATA_KEY`), for a list's clock mark and Origin filter.
  Absent when none did, and from older hosts. Additive.
- `spaceId?` (`string`): The session's space when not Default — see `SessionMeta.spaceId`. Additive.
- `status` (`'error' | 'running' | 'completed' | 'idle'`): Run state of the session.
- `title` (`string`): Session title.
- `updatedAt` (`number`): Time of the last change, epoch ms.

Source: [src/ipc/protocol.ts:2506](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2506)

### `SharedHostSetup`

Interface.

What a host in the window's own process takes from the window.

```ts
interface SharedHostSetup
```

**Properties**

- `config` (`ResolvedConfig`): The window's boot config (paths, store, state file): one store and one
  writer to `state.json` in the process.
- `hostRuntime?` (`ExtensionHostRuntimeBridge`): Host-runtime bridge the window's registries were built with (`ChatHostEnvironment.hostRuntime`).
- `instrumentAgent?` (`(agent: Agent, context: { sessionId: string }) => void`): The window's instrumentation for every agent the host builds (`ChatHostEnvironment.instrumentAgent`).
- `multiProcess?` (`boolean`): Whether another process also drives these sessions. Default `false` (single writer).
- `runtimeConfig` (`{ forget?: () => () => void; invalidate?: () => void; resolve: (cwd: string) => Promise<ResolvedConfig> }`): The window's per-cwd session config. Discovering extensions here instead
  would run every extension's `setup` a second time in the same process.
  `invalidate` / `forget` back `DaemonEnvironment.invalidateRuntime` /
  `forgetRuntime` (settings changes, `runtime.reload`).
- `terminals?` (`boolean`): Whether the window can show terminals (`ChatHostEnvironment.terminals`).

Source: [src/ipc/daemon/environment.ts:172](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/environment.ts#L172)

### `TranscriptHistoryWorker`

Interface.

A client of the history worker, from [`createTranscriptHistoryWorker`](https://zidane.si/docs/reference/ipc.md#createTranscriptHistoryWorker).

```ts
interface TranscriptHistoryWorker
```

**Properties**

- `close` (`() => void`): Terminates the worker; later pages reject [`WorkerUnavailableError`](https://zidane.si/docs/reference/ipc.md#WorkerUnavailableError).
- `drop` (`(sessionId: string, live?: boolean) => void`): The session changed or went away: the worker forgets its replay. `live`: a run here appended to it.
- `isDegraded` (`() => boolean`): True once the worker will not serve again (it could not start, or keeps crashing).
- `page` (`(sessionId: string, paging: LoadEventsPaging) => Promise<SessionEventsPage>`): One `sessions.loadEvents` page, from the worker. Rejects
  [`WorkerUnavailableError`](https://zidane.si/docs/reference/ipc.md#WorkerUnavailableError) when the worker could not serve it (page
  in-thread then), `InvalidParamsError` for bad paging, and the
  worker's error otherwise (an unknown session).
- `usage` (`() => Promise<UsageBuckets>`): The usage summary's day buckets (`runUsageAggregates`). Rejects [`WorkerUnavailableError`](https://zidane.si/docs/reference/ipc.md#WorkerUnavailableError) when the worker could not serve them.

Source: [src/ipc/history/transcript.ts:67](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L67)

### `TranscriptRead`

Interface.

A whole session as a replay needs it.

```ts
interface TranscriptRead
```

**Properties**

- `runs` (`SessionRun[]`): The session's run records.
- `seqs` (`number[]`): The store's `seq` of each turn, same order.
- `turns` (`SessionTurn[]`): Every turn, oldest first.

Source: [src/ipc/history/transcript-reader.ts:14](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript-reader.ts#L14)

### `TranscriptReader`

Interface.

Whole-session reads, from [`createTranscriptReader`](https://zidane.si/docs/reference/ipc.md#createTranscriptReader).

```ts
interface TranscriptReader
```

**Properties**

- `forget` (`(id: string) => void`): Drops the session's kept read: its next read reads it whole.
- `read` (`(id: string, read: { live: boolean }) => TranscriptRead | null`): The whole session, or `null` when it does not exist; `live`: it runs here, so the last read is built on.

Source: [src/ipc/history/transcript-reader.ts:104](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript-reader.ts#L104)

### `TranscriptReplay`

Interface.

A whole-session replay: pages are `transcriptPage` slices of it.

```ts
interface TranscriptReplay extends Versioned
```

**Properties**

- `boundaries` (`boolean[]`): Where each run starts (`exchangeBoundaries`): where a page may start.
- `bytes` (`number`, from `Versioned`)
- `cuts` (`boolean[]`): Where a run too long for one page may be split (`turnCutPoints`).
- `events` (`StreamEvent[]`): Every turn's events, in order: what a whole `sessions.loadEvents` returns.
- `seqs?` (`number[]`): The loaded `seqs`, when the load gave them.
- `turnIds` (`string[]`): Each turn's id: where a `beforeTurnId` anchor sits.
- `turnStarts` (`number[]`): Where each turn's events start (`[turns]` = the end).
- `version` (`string`, from `Versioned`)

Source: [src/ipc/daemon/handlers/transcript-cache.ts:60](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-cache.ts#L60)

### `TranscriptReplayCache`

Interface.

Whole-session replays and documents, kept per session version (see the module header).

```ts
interface TranscriptReplayCache
```

**Properties**

- `cached` (`(sessionId: string, touch?: boolean) => TranscriptReplay | undefined`): The replay kept for a session, whatever its version; `touch` counts it as used.
- `document` (`(store: SessionStore, sessionId: string, live: Session | null) => Promise<DocumentSnapshot | null>`): The document (the live copy when `live` is given, else the stored one, healed in memory), and its version; `null` when unknown.
- `forget` (`(sessionId: string) => void`): Drops the session's entries (it is gone); a read in flight is served but not kept.
- `observe` (`(signal: HostSignal) => void`): A host signal: one that follows a change to a session drops its entries.
- `page` (`(store: Pick<SessionStore, 'load' | 'getMeta'>, sessionId: string, paging: LoadEventsPaging, load?: () => ReplayData | null) => Promise<SessionEventsPage>`): One `sessions.loadEvents` page of a stored session, sliced from its replay. Throws when the session is unknown, `InvalidParamsError` for bad paging.
  `load`: reads the session on a miss instead of `store.load` (`null`: unknown).
- `replay` (`(store: Pick<SessionStore, 'getMeta'>, sessionId: string, read: ReplayRead) => Promise<TranscriptReplay | null>`): A stored session's replay from the client's own `read.load`, versioned like `page`'s; `null` when unknown.
- `sizes` (`() => { entries: number; inFlight: number }`): Entries kept and sessions with a read in flight, across both kinds: what the cache holds.

Source: [src/ipc/daemon/handlers/transcript-cache.ts:106](https://github.com/Tahul/zidane/blob/main/src/ipc/daemon/handlers/transcript-cache.ts#L106)

### `WorkerLike`

Interface.

A worker from either runtime: Bun / Web `Worker` (`addEventListener`) or Node `worker_threads.Worker` (`on`).

```ts
interface WorkerLike
```

**Properties**

- `addEventListener?` (`(type: string, listener: (event: unknown) => void) => void`): Bun / Web events: `message`, `error`, `close`.
- `on?` (`(event: string, listener: (value: unknown) => void) => unknown`): Node's events: `message`, `error`, `exit`.
- `postMessage` (`(message: unknown) => void`): Sends a `WorkerCall` to the worker.
- `ref?` (`() => void`): Lets the worker keep the process alive (while a reply is due).
- `terminate` (`() => unknown`): Ends the worker.
- `unref?` (`() => void`): Stops the worker from keeping the process alive.

Source: [src/ipc/history/rpc-client.ts:18](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L18)

### `WorkerPortLike`

Interface.

A worker's port to its parent, from either runtime.

```ts
interface WorkerPortLike
```

**Properties**

- `addEventListener?` (`(type: 'message', listener: (event: MessageEvent) => void) => void`): A Web worker scope's messages.
- `on?` (`(event: 'message', listener: (data: unknown) => void) => unknown`): Node's `parentPort` messages.
- `postMessage` (`(message: unknown) => void`): Sends a `WorkerMessage` to the parent.

Source: [src/ipc/history/rpc-serve.ts:25](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-serve.ts#L25)

### `WorkerRpcClient`

Interface.

The calling side of a worker RPC, from [`createWorkerRpcClient`](https://zidane.si/docs/reference/ipc.md#createWorkerRpcClient).

```ts
interface WorkerRpcClient<Req, Res>
```

**Type parameters**

- `Req`
- `Res`

**Properties**

- `close` (`() => void`): Terminates the worker and rejects what is pending; later requests reject. Idempotent.
- `isDegraded` (`() => boolean`): True once no worker will serve (it could not start, or crashed `maxCrashes` times in a row).
- `notify` (`(request: Req) => void`): Fire-and-forget, only to a running worker (none: nothing to tell).
- `request` (`(request: Req, options?: { timeoutMs?: number }) => Promise<Res>`): Spawns the worker when none runs. Rejects [`WorkerUnavailableError`](https://zidane.si/docs/reference/ipc.md#WorkerUnavailableError) when no worker can serve, [`WorkerRequestError`](https://zidane.si/docs/reference/ipc.md#WorkerRequestError) when the handler threw.

Source: [src/ipc/history/rpc-client.ts:89](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L89)

### `WorkerRpcClientOptions`

Interface.

How [`createWorkerRpcClient`](https://zidane.si/docs/reference/ipc.md#createWorkerRpcClient) spawns and supervises its worker.

```ts
interface WorkerRpcClientOptions
```

**Properties**

- `backoffMs?` (`{ base: number; max: number }`): Wait before spawning again after a crash: `base` doubled per crash in a row, at most `max`. Default 250 ms / 10 s.
- `create` (`() => WorkerLike`): Spawns the worker. A throw puts the client in degraded mode.
- `init?` (`unknown`): Posted to every worker this client spawns, before any request (`serveWorkerRpc`'s `init`).
- `maxCrashes?` (`number`): Crashes in a row before degraded mode. Default 3.
- `name?` (`string`): What the worker is called in the errors it causes (`<name> unavailable: …`). Default `worker`.
- `onDegraded?` (`(reason: string) => void`): Called once, with the reason, when the client goes degraded: from then on the caller does the work on its own thread.
- `onEvent?` (`(event: unknown) => void`): Each event the worker sends unasked (`emit` in `serveWorkerRpc`).
- `timeoutMs?` (`number`): A request unanswered this long rejects, and the worker counts as crashed. Default 30 s.

Source: [src/ipc/history/rpc-client.ts:69](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-client.ts#L69)

### `WorkerRpcContext`

Interface.

What a handler can do besides answering.

```ts
interface WorkerRpcContext
```

**Properties**

- `emit` (`(event: unknown) => void`): Sends the client an event unasked (its `onEvent`).

Source: [src/ipc/history/rpc-serve.ts:11](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-serve.ts#L11)

### `WorkerRpcHandler`

Interface.

What [`serveWorkerRpc`](https://zidane.si/docs/reference/ipc.md#serveWorkerRpc) runs in the worker.

```ts
interface WorkerRpcHandler<Init, Req, Res>
```

**Type parameters**

- `Init`
- `Req`
- `Res`

**Properties**

- `handle` (`(request: Req, context: WorkerRpcContext) => Res | Promise<Res>`): Answers one request; a throw answers it with the error.
- `init?` (`(value: Init, context: WorkerRpcContext) => void | Promise<void>`): The client's `init`, once, before any request.

Source: [src/ipc/history/rpc-serve.ts:17](https://github.com/Tahul/zidane/blob/main/src/ipc/history/rpc-serve.ts#L17)

### `WorkspaceExecStreamOptions`

Interface.

Options for [`runWorkspaceExecStream`](https://zidane.si/docs/reference/ipc.md#runWorkspaceExecStream).

```ts
interface WorkspaceExecStreamOptions
```

**Properties**

- `cancelGraceMs?` (`number`): How long to wait for the host's exit after a cancel before giving up on it. Default 10 s.
- `fallbackTimeoutSeconds?` (`number`): The buffered fallback's bound. Default 600 s.
- `onChunk?` (`(accumulated: string) => void`): The whole output so far, on every chunk.
- `signal?` (`AbortSignal`): Cancels the command on the host when aborted.

Source: [src/ipc/workspace-exec-stream.ts:31](https://github.com/Tahul/zidane/blob/main/src/ipc/workspace-exec-stream.ts#L31)

### `WorkspaceExecStreamResult`

Interface.

Outcome of [`runWorkspaceExecStream`](https://zidane.si/docs/reference/ipc.md#runWorkspaceExecStream), shaped like a local `!` run.

```ts
interface WorkspaceExecStreamResult
```

**Properties**

- `aborted` (`boolean`): Cancelled through `signal`.
- `durationMs` (`number`): Wall-clock time of the run in milliseconds.
- `exitCode` (`number | null`): `null` when the host killed it (cancel, output cap).
- `output` (`string`): stdout and stderr in arrival order (the buffered fallback: stdout, then stderr).
- `overflowed` (`boolean`): The host's output cap was reached and the process stopped.
- `streamed` (`boolean`): `false`: an older host answered with the buffered exec.

Source: [src/ipc/workspace-exec-stream.ts:15](https://github.com/Tahul/zidane/blob/main/src/ipc/workspace-exec-stream.ts#L15)

## Types

### `HistoryWorkerRequest`

Type.

The history worker's requests.

```ts
type HistoryWorkerRequest =
  | { op: 'page'; paging: LoadEventsPaging; sessionId: string }
  | { live?: boolean; op: 'drop'; sessionId: string }
  | { op: 'usage' }
```

Source: [src/ipc/history/transcript.ts:43](https://github.com/Tahul/zidane/blob/main/src/ipc/history/transcript.ts#L43)

### `HostKind`

Type.

What a host process is: a window's own (`in-process`), the local shared
daemon (`daemon`), or a remote `zidane-server` (`server`).

```ts
type HostKind = 'in-process' | 'daemon' | 'server'
```

Source: [src/ipc/protocol.ts:2656](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2656)

### `HostOAuthStep`

Type.

A question the provider's sign-in asks before (or after) its URL: a choice
between flows, or a free text. The client shows it and answers with
`auth.oauth.respond`; the host never picks for the user.

```ts
type HostOAuthStep =
  | { id: string; kind: 'select'; message: string; options: { id: string; label: string }[] }
  | { allowEmpty?: boolean; id: string; kind: 'prompt'; message: string; placeholder?: string }
```

Source: [src/ipc/protocol.ts:2387](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2387)

### `QueueDelivery`

Type.

What `queue.add` does with a message while a run works: `auto` follows
`Settings.messageDelivery`, `steer` and `followUp` hand it to the run,
`queue` keeps it in the queue until the run ends.

```ts
type QueueDelivery = 'auto' | 'steer' | 'followUp' | 'queue'
```

Source: [src/chat/host/signals.ts:181](https://github.com/Tahul/zidane/blob/main/src/chat/host/signals.ts#L181)

### `RemoteOAuthTarget`

Type.

What to sign in to: a provider by key (`account`: the stored OAuth
account, by its stable id, whose tokens it replaces), or an MCP server by name.

```ts
type RemoteOAuthTarget =
  | { account?: string; provider: string }
  | { cwd?: string; kind?: string; mcpServer: string }
```

Source: [src/ipc/remote-oauth.ts:25](https://github.com/Tahul/zidane/blob/main/src/ipc/remote-oauth.ts#L25)

### `SessionDocumentHead`

Type.

What `sessions.get` answers: the document; with `turns: false`, the
version of the snapshot it was cut from, the one `sessions.getTurns`
pages carry.

```ts
type SessionDocumentHead = SessionData & { version?: string }
```

Source: [src/ipc/protocol.ts:2086](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L2086)

### `SessionResumeResult`

Type.

Result of `sessions.resume`. On success, the signals the client missed after its last position. Otherwise the reason it must reload instead.

```ts
type SessionResumeResult =
  | { ok: true; signals: SequencedSignal[] }
  | { ok: false; reason: 'epoch' | 'gap' }
```

Source: [src/ipc/protocol.ts:475](https://github.com/Tahul/zidane/blob/main/src/ipc/protocol.ts#L475)

## Re-exports

These names are documented on the entry point that owns them.

- [zidane/chat](https://zidane.si/docs/reference/chat.md): [`ApprovalHub`](https://zidane.si/docs/reference/chat.md#ApprovalHub), [`ApprovalOriginator`](https://zidane.si/docs/reference/chat.md#ApprovalOriginator), [`ApprovalRequestInput`](https://zidane.si/docs/reference/chat.md#ApprovalRequestInput), [`ChatHost`](https://zidane.si/docs/reference/chat.md#ChatHost), [`ChatHostEnvironment`](https://zidane.si/docs/reference/chat.md#ChatHostEnvironment), [`CompactionEntry`](https://zidane.si/docs/reference/chat.md#CompactionEntry), [`createApprovalHub`](https://zidane.si/docs/reference/chat.md#createApprovalHub), [`createChatHost`](https://zidane.si/docs/reference/chat.md#createChatHost), [`createInteractionHub`](https://zidane.si/docs/reference/chat.md#createInteractionHub), [`createMemoryApprovalsStore`](https://zidane.si/docs/reference/chat.md#createMemoryApprovalsStore), [`EditOutcomeLedger`](https://zidane.si/docs/reference/chat.md#EditOutcomeLedger), [`extractEditPayloadForGate`](https://zidane.si/docs/reference/chat.md#extractEditPayloadForGate), [`HostSettings`](https://zidane.si/docs/reference/chat.md#HostSettings), [`HostSignal`](https://zidane.si/docs/reference/chat.md#HostSignal), [`InteractionHub`](https://zidane.si/docs/reference/chat.md#InteractionHub), [`PendingAnnotation`](https://zidane.si/docs/reference/chat.md#PendingAnnotation), [`PendingApprovalsStore`](https://zidane.si/docs/reference/chat.md#PendingApprovalsStore), [`PendingInteraction`](https://zidane.si/docs/reference/chat.md#PendingInteraction), [`PlansSnapshot`](https://zidane.si/docs/reference/chat.md#PlansSnapshot), [`PromptAttachment`](https://zidane.si/docs/reference/chat.md#PromptAttachment), [`QueuedItem`](https://zidane.si/docs/reference/chat.md#QueuedItem), [`readFileSafe`](https://zidane.si/docs/reference/chat.md#readFileSafe), [`resolveCwdPath`](https://zidane.si/docs/reference/chat.md#resolveCwdPath), [`resolveStorageDirs`](https://zidane.si/docs/reference/chat.md#resolveStorageDirs), [`runCompaction`](https://zidane.si/docs/reference/chat.md#runCompaction), [`RunningWorkItem`](https://zidane.si/docs/reference/chat.md#RunningWorkItem), [`SendOptions`](https://zidane.si/docs/reference/chat.md#SendOptions), [`SerializedPreview`](https://zidane.si/docs/reference/chat.md#SerializedPreview), [`serializePreview`](https://zidane.si/docs/reference/chat.md#serializePreview), [`SessionPresence`](https://zidane.si/docs/reference/chat.md#SessionPresence), [`StorageDirs`](https://zidane.si/docs/reference/chat.md#StorageDirs), [`WireApprovalRequest`](https://zidane.si/docs/reference/chat.md#WireApprovalRequest)
- [zidane/ipc/browser](https://zidane.si/docs/reference/ipc-browser.md): [`BlockRunClient`](https://zidane.si/docs/reference/ipc-browser.md#BlockRunClient), [`BlockRunOnHostOptions`](https://zidane.si/docs/reference/ipc-browser.md#BlockRunOnHostOptions), [`CLIENT_SCOPES`](https://zidane.si/docs/reference/ipc-browser.md#CLIENT_SCOPES), [`ClientScope`](https://zidane.si/docs/reference/ipc-browser.md#ClientScope), [`createExtensionsClient`](https://zidane.si/docs/reference/ipc-browser.md#createExtensionsClient), [`extensionInstallErrorData`](https://zidane.si/docs/reference/ipc-browser.md#extensionInstallErrorData), [`ExtensionInstallErrorData`](https://zidane.si/docs/reference/ipc-browser.md#ExtensionInstallErrorData), [`ExtensionsClient`](https://zidane.si/docs/reference/ipc-browser.md#ExtensionsClient), [`ExtensionsUiServer`](https://zidane.si/docs/reference/ipc-browser.md#ExtensionsUiServer), [`HelloResult`](https://zidane.si/docs/reference/ipc-browser.md#HelloResult), [`IPC_MIN_PROTOCOL_VERSION`](https://zidane.si/docs/reference/ipc-browser.md#IPC_MIN_PROTOCOL_VERSION), [`IPC_PROTOCOL_VERSION`](https://zidane.si/docs/reference/ipc-browser.md#IPC_PROTOCOL_VERSION), [`IpcErrorCode`](https://zidane.si/docs/reference/ipc-browser.md#IpcErrorCode), [`IpcMethodName`](https://zidane.si/docs/reference/ipc-browser.md#IpcMethodName), [`IpcMethods`](https://zidane.si/docs/reference/ipc-browser.md#IpcMethods), [`IpcParams`](https://zidane.si/docs/reference/ipc-browser.md#IpcParams), [`IpcResult`](https://zidane.si/docs/reference/ipc-browser.md#IpcResult), [`METHOD_SCOPES`](https://zidane.si/docs/reference/ipc-browser.md#METHOD_SCOPES), [`methodScope`](https://zidane.si/docs/reference/ipc-browser.md#methodScope), [`runBlockOnHost`](https://zidane.si/docs/reference/ipc-browser.md#runBlockOnHost), [`scopeAllows`](https://zidane.si/docs/reference/ipc-browser.md#scopeAllows), [`SignalMeta`](https://zidane.si/docs/reference/ipc-browser.md#SignalMeta)
- [zidane/chat/pure](https://zidane.si/docs/reference/chat-pure.md): [`MachineInfo`](https://zidane.si/docs/reference/chat-pure.md#MachineInfo), [`MachineRoot`](https://zidane.si/docs/reference/chat-pure.md#MachineRoot), [`MachineStatusChange`](https://zidane.si/docs/reference/chat-pure.md#MachineStatusChange)
