# zidane-ui/session/headless

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

## Functions

### `arrangeHomeBlocks`

Function.

The blocks shown, in the user's order and at the widths they picked, and the ones they hid.

```ts
function arrangeHomeBlocks(
  blocks: readonly HomeBlock[],
  prefs: HomePrefs,
  defaults?: readonly string[],
): { hidden: HomeBlock[]; shown: HomeBlock[] }
```

**Parameters**

- `blocks` (`readonly HomeBlock[]`): The blocks in default order ([`homeBlocksOf`](https://zidane.si/docs/reference/ui-session-headless.md#homeBlocksOf)).
- `prefs` (`HomePrefs`): The user's arrangement.
- `defaults?` (`readonly string[]`): The blocks shown before the user adds any. Absent: every block.

**Returns** `{ hidden: HomeBlock[]; shown: HomeBlock[] }`

Source: [ui/src/session/headless/home-layout.ts:105](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L105)

### `attachmentsKey`

Function.

An equality key for a wire attachment list: type, name, length and both ends of the data (the whole payload would
cost tens of ms per change for multi-MB images).

```ts
function attachmentsKey(attachments: readonly PromptAttachment[]): string
```

**Parameters**

- `attachments` (`readonly PromptAttachment[]`): The wire attachments.

**Returns** `string`

Source: [ui/src/session/headless/queue-attachments.ts:63](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue-attachments.ts#L63)

### `buildDiffTree`

Function.

Builds the tree of the changed files: folders before files, both by name, a
chain of single-folder folders merged into one row, totals on each folder.

```ts
function buildDiffTree(
  files: readonly DiffListFile[],
  root: string | null,
): DiffTreeNode[]
```

**Parameters**

- `files` (`readonly DiffListFile[]`): The changed files.
- `root` (`string | null`): The session's folder: paths inside it show relative to it.

**Returns** `DiffTreeNode[]`

Source: [ui/src/session/headless/diff-tree.ts:86](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L86)

### `canKeepSchedule`

Function.

Whether Keep applies: a repeat the agent made, which the backend turns off at `expiresAt` unless you keep it.

```ts
function canKeepSchedule(schedule: Schedule): boolean
```

**Parameters**

- `schedule` (`Schedule`): The schedule.

**Returns** `boolean`

Source: [ui/src/session/headless/schedules.ts:208](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L208)

### `collectSessionDiffs`

Function.

The patches of a session's edits, in order (several edits to one file stay separate entries).

```ts
function collectSessionDiffs(events: readonly SessionEditEvent[]): SessionDiffEntry[]
```

**Parameters**

- `events` (`readonly SessionEditEvent[]`): The session's transcript events.

**Returns** `SessionDiffEntry[]`

Source: [ui/src/session/headless/session-diffs.ts:58](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-diffs.ts#L58)

### `countArtifacts`

Function.

The number of artifacts across groups: the indicator badge.

```ts
function countArtifacts(groups: readonly SessionArtifactGroup[] | null): number
```

**Parameters**

- `groups` (`readonly SessionArtifactGroup[] | null`): A session's groups, `null` while unread.

**Returns** `number`

Source: [ui/src/session/headless/artifacts.ts:59](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/artifacts.ts#L59)

### `createArtifactsState`

Function.

Creates an [`ArtifactsState`](https://zidane.si/docs/reference/ui-session-headless.md#ArtifactsState).

```ts
function createArtifactsState(
  list: (sessionId: string) => Promise<readonly SessionArtifactGroup[]>,
): ArtifactsState
```

**Parameters**

- `list` (`(sessionId: string) => Promise<readonly SessionArtifactGroup[]>`): Reads one session's groups from the backend.

**Returns** `ArtifactsState`

Source: [ui/src/session/headless/artifacts.ts:27](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/artifacts.ts#L27)

### `createKeyedState`

Function.

Creates a [`KeyedState`](https://zidane.si/docs/reference/ui-session-headless.md#KeyedState).

```ts
function createKeyedState<V, Fallback = null>(
  fallback: Fallback,
): KeyedState<V, Fallback>
```

**Type parameters**

- `V`
- `Fallback` (default `null`)

**Parameters**

- `fallback` (`Fallback`): What a key's store reads while it holds no value.

**Returns** `KeyedState<V, Fallback>`

Source: [ui/src/session/headless/keyed.ts:27](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/keyed.ts#L27)

### `createPlansState`

Function.

Creates a [`PlansState`](https://zidane.si/docs/reference/ui-session-headless.md#PlansState).

```ts
function createPlansState(
  read: (sessionId: string) => Promise<PlansSnapshot | null>,
): PlansState
```

**Parameters**

- `read` (`(sessionId: string) => Promise<PlansSnapshot | null>`): Reads one session's snapshot from the backend (`null`: unknown session).

**Returns** `PlansState`

Source: [ui/src/session/headless/plans.ts:36](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L36)

### `createProviderUsageState`

Function.

Creates a [`ProviderUsageState`](https://zidane.si/docs/reference/ui-session-headless.md#ProviderUsageState). The cadence (when to auto-load) is the reader's: `useProviderUsage`.

```ts
function createProviderUsageState(
  source: ProviderUsageSource,
  now?: () => number,
): ProviderUsageState
```

**Parameters**

- `source` (`ProviderUsageSource`): The backend calls.
- `now?` (`() => number`, default `Date.now`): The clock. Default `Date.now`.

**Returns** `ProviderUsageState`

Source: [ui/src/session/headless/usage.ts:314](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L314)

### `createQueueState`

Function.

Creates a [`QueueState`](https://zidane.si/docs/reference/ui-session-headless.md#QueueState).

```ts
function createQueueState(backend: QueueBackend): QueueState
```

**Parameters**

- `backend` (`QueueBackend`): The backend's queue calls.

**Returns** `QueueState`

Source: [ui/src/session/headless/queue.ts:67](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue.ts#L67)

### `createRunningWorkState`

Function.

Creates a [`RunningWorkState`](https://zidane.si/docs/reference/ui-session-headless.md#RunningWorkState).

```ts
function createRunningWorkState(
  list: (sessionId: string) => Promise<readonly RunningWorkItem[]>,
): RunningWorkState
```

**Parameters**

- `list` (`(sessionId: string) => Promise<readonly RunningWorkItem[]>`): Reads one session's work from the backend.

**Returns** `RunningWorkState`

Source: [ui/src/session/headless/running-work.ts:55](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/running-work.ts#L55)

### `createSchedulesState`

Function.

Creates a [`SchedulesState`](https://zidane.si/docs/reference/ui-session-headless.md#SchedulesState).

```ts
function createSchedulesState(backend: SchedulesBackend): SchedulesState
```

**Parameters**

- `backend` (`SchedulesBackend`): Reads the status and the list.

**Returns** `SchedulesState`

Source: [ui/src/session/headless/schedules.ts:73](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L73)

### `createSecretsState`

Function.

Creates a [`SecretsState`](https://zidane.si/docs/reference/ui-session-headless.md#SecretsState).

```ts
function createSecretsState(
  list: (sessionId: string) => Promise<readonly SecretEntry[]>,
): SecretsState
```

**Parameters**

- `list` (`(sessionId: string) => Promise<readonly SecretEntry[]>`): Reads one session's entries from the backend.

**Returns** `SecretsState`

Source: [ui/src/session/headless/secrets.ts:28](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/secrets.ts#L28)

### `createSessionActions`

Function.

The session actions over an app's hosts.

```ts
function createSessionActions(deps: SessionActionsDeps): SessionActions
```

**Parameters**

- `deps` (`SessionActionsDeps`): What they run over.

**Returns** `SessionActions`

Source: [ui/src/session/headless/session-actions.ts:104](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L104)

### `createSideRequests`

Function.

Creates an empty [`SideRequests`](https://zidane.si/docs/reference/ui-session-headless.md#SideRequests): one per window.

```ts
function createSideRequests(): SideRequests
```

**Returns** `SideRequests`

Source: [ui/src/session/headless/side.ts:38](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/side.ts#L38)

### `createUsageSummaryState`

Function.

Creates a [`UsageSummaryState`](https://zidane.si/docs/reference/ui-session-headless.md#UsageSummaryState).

```ts
function createUsageSummaryState(
  fetchSummary: (range: UsageRange) => Promise<UsageSummary>,
  options?: UsageSummaryStateOptions,
): UsageSummaryState
```

**Parameters**

- `fetchSummary` (`(range: UsageRange) => Promise<UsageSummary>`): Reads one range from the backend.
- `options?` (`UsageSummaryStateOptions`, default `{}`): Where the snapshot is mirrored.

**Returns** `UsageSummaryState`

Source: [ui/src/session/headless/usage.ts:198](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L198)

### `displayedPlan`

Function.

The plan a session shows: the session scope's applying plan, else its most
recent stopped one, else the last that closed (read-only). Never a
proposal: the Inbox shows those. Sub-agent plans are not shown here.

```ts
function displayedPlan(plans: readonly PlanView[]): PlanView | null
```

**Parameters**

- `plans` (`readonly PlanView[]`): The snapshot's plans, oldest first.

**Returns** `PlanView | null`

Source: [ui/src/session/headless/plans.ts:78](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L78)

### `fileDiffCounts`

Function.

Changed-line counts for a parsed working-tree file. pierre's
`FileDiffMetadata.additionLines` / `deletionLines` are the LINE CONTENTS
(context included), not counts; rendering them printed file content where
the list should show `+12 −3`. The hunks carry the real `+` / `-` counts.

```ts
function fileDiffCounts(
  file: { hunks: readonly { additionLines: number; deletionLines: number }[] },
): { added: number; removed: number }
```

**Parameters**

- `file` (`{ hunks: readonly { additionLines: number; deletionLines: number }[] }`): A parsed file diff (its hunks' counts).

**Returns** `{ added: number; removed: number }`

Source: [ui/src/session/headless/session-diffs.ts:103](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-diffs.ts#L103)

### `fileOrder`

Function.

Files in tree order, collapsed folders included.

```ts
function fileOrder(tree: readonly DiffTreeNode[]): DiffTreeFile[]
```

**Parameters**

- `tree` (`readonly DiffTreeNode[]`): The tree from [`buildDiffTree`](https://zidane.si/docs/reference/ui-session-headless.md#buildDiffTree).

**Returns** `DiffTreeFile[]`

Source: [ui/src/session/headless/diff-tree.ts:153](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L153)

### `formatTokens`

Function.

Number and day helpers of the usage views. The usage card's own words
(costs, hours, the comparison line) are zidane's (`zidane/chat/pure`:
`formatCost`, `formatHour`, `tokenComparison`), shared with the usage block.

```ts
function formatTokens(n: number): string
```

**Parameters**

- `n` (`number`): A token count.

**Returns** `string`

Source: [dist/chat/pure.d.ts:1832](https://github.com/Tahul/zidane/blob/main/dist/chat/pure.d.ts#L1832)

### `groupArtifactRows`

Function.

Groups rendered artifacts by kind, the built-in kinds first, the others alphabetically; rows keep their order.

```ts
function groupArtifactRows(
  rows: readonly SessionArtifactRow[],
  kindLabel?: (kind: string) => string,
): SessionArtifactGroup[]
```

**Parameters**

- `rows` (`readonly SessionArtifactRow[]`): The artifacts and their rows, newest first.
- `kindLabel?` (`(kind: string) => string`): A kind's group label. Default: the raw kind.

**Returns** `SessionArtifactGroup[]`

Source: [ui/src/session/headless/artifacts.ts:72](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/artifacts.ts#L72)

### `groupByPath`

Function.

The entries per path, in first-seen order, with summed counts: the file list on top of the panel.

```ts
function groupByPath(
  entries: readonly SessionDiffEntry[],
): { added: number; entries: SessionDiffEntry[]; path: string; removed: number }[]
```

**Parameters**

- `entries` (`readonly SessionDiffEntry[]`): The session's diff entries.

**Returns** `{ added: number; entries: SessionDiffEntry[]; path: string; removed: number }[]`

Source: [ui/src/session/headless/session-diffs.ts:121](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-diffs.ts#L121)

### `hideHomeBlock`

Function.

`prefs` with block `id` hidden.

```ts
function hideHomeBlock(prefs: HomePrefs, id: string): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `id` (`string`): The block.

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:200](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L200)

### `homeBlocksOf`

Function.

The panels that are blocks, in default order (`home.order`, then catalog order).

```ts
function homeBlocksOf(panels: readonly HomeBlockSource[]): HomeBlock[]
```

**Parameters**

- `panels` (`readonly HomeBlockSource[]`): The folder's panel summaries.

**Returns** `HomeBlock[]`

Source: [ui/src/session/headless/home-layout.ts:82](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L82)

### `homeRows`

Function.

The rows the shown blocks make.

```ts
function homeRows(shown: readonly HomeBlock[]): HomeRow[]
```

**Parameters**

- `shown` (`readonly HomeBlock[]`): The shown blocks, in order.

**Returns** `HomeRow[]`

Source: [ui/src/session/headless/home-layout.ts:130](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L130)

### `inboxPlans`

Function.

Splits a session's plans into the Inbox's "In progress" and "Recent". Session scope only: sub-agent plans close with
their run and are not listed.

```ts
function inboxPlans(plans: readonly PlanView[]): InboxPlans
```

**Parameters**

- `plans` (`readonly PlanView[]`): The snapshot's plans, oldest first.

**Returns** `InboxPlans`

Source: [ui/src/session/headless/plans.ts:102](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L102)

### `isScheduleFinished`

Function.

Whether a reminder is finished: on, but with no next time (a one-off that was sent).

```ts
function isScheduleFinished(schedule: Schedule): boolean
```

**Parameters**

- `schedule` (`Schedule`): The schedule.

**Returns** `boolean`

Source: [ui/src/session/headless/schedules.ts:181](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L181)

### `isUsageSummary`

Function.

Enough of the shape to render without throwing; anything else is dropped.

```ts
function isUsageSummary(value: unknown, range: UsageRange): value is UsageSummary
```

**Parameters**

- `value` (`unknown`): A stored or received value.
- `range` (`UsageRange`): The range it should cover.

**Returns** `value is UsageSummary`

Source: [ui/src/session/headless/usage.ts:130](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L130)

### `localDayString`

Function.

Local `YYYY-MM-DD` for a Date. Matches SQLite's `date(…, 'localtime')`
buckets the backend aggregates by, or streak math drifts at midnight.

```ts
function localDayString(d: Date): string
```

**Parameters**

- `d` (`Date`): The date.

**Returns** `string`

Source: [ui/src/session/headless/usage-format.ts:14](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage-format.ts#L14)

### `moveHomeBlock`

Function.

`prefs` with block `id` moved `delta` places among the shown blocks.

```ts
function moveHomeBlock(
  prefs: HomePrefs,
  shown: readonly HomeBlock[],
  id: string,
  delta: number,
): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `shown` (`readonly HomeBlock[]`): The shown blocks, in order (what the user sees).
- `id` (`string`): The block.
- `delta` (`number`): 1 up, +1 down.

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:153](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L153)

### `parseHomePrefs`

Function.

Every project's arrangement from its stored form; `undefined` for anything unrecognised.

```ts
function parseHomePrefs(raw: string): Record<string, HomePrefs> | undefined
```

**Parameters**

- `raw` (`string`): The stored JSON.

**Returns** `Record<string, HomePrefs> | undefined`

Source: [ui/src/session/headless/home-layout.ts:272](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L272)

### `parseSideCommand`

Function.

Reads `/side` with an optional question: the question (`''` for none), or `null` for any other prompt.

```ts
function parseSideCommand(text: string): string | null
```

**Parameters**

- `text` (`string`): The prompt.

**Returns** `string | null`

Source: [ui/src/session/headless/side.ts:15](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/side.ts#L15)

### `pickUsageSummary`

Function.

The summary to show for `range`: its own, or while it loads another range's (the one on screen, else any).

```ts
function pickUsageSummary(
  all: UsageSummaries,
  range: UsageRange,
  shown: UsageRange,
): { standIn: boolean; summary: UsageSummary | null }
```

**Parameters**

- `all` (`UsageSummaries`): The summaries held.
- `range` (`UsageRange`): The range asked for.
- `shown` (`UsageRange`): The range on screen before.

**Returns** `{ standIn: boolean; summary: UsageSummary | null }`

Source: [ui/src/session/headless/usage.ts:253](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L253)

### `placeHomeBlock`

Function.

`prefs` with block `id` moved to the place of block `target` among the shown
blocks (a drop on that card): before it when coming from below, after it
when coming from above.

```ts
function placeHomeBlock(
  prefs: HomePrefs,
  shown: readonly HomeBlock[],
  id: string,
  target: string,
): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `shown` (`readonly HomeBlock[]`): The shown blocks, in order (what the user sees).
- `id` (`string`): The block moved.
- `target` (`string`): The block it was dropped on.

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:174](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L174)

### `plainArtifactRow`

Function.

A plain row for a stored artifact: its label as the title, a web URI as the link. For a backend that answers
stored artifacts without rendering them.

```ts
function plainArtifactRow(artifact: SessionArtifact): SessionArtifactRow
```

**Parameters**

- `artifact` (`SessionArtifact`): The stored artifact.

**Returns** `SessionArtifactRow`

Source: [ui/src/session/headless/artifacts.ts:96](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/artifacts.ts#L96)

### `planTally`

Function.

A plan's steps per status, as the tally chips show them.

```ts
function planTally(plan: Pick<PlanView, 'steps'>): TodoTallyCounts
```

**Parameters**

- `plan` (`Pick<PlanView, 'steps'>`): The plan.

**Returns** `TodoTallyCounts`

Source: [ui/src/session/headless/plans.ts:120](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L120)

### `readReminderWhen`

Function.

Reads the Reminders form's time field (`in 20m`, `tomorrow 9:00`, `weekdays 9:00`, `cron "0 9 * * 1-5"`) in the
client's time zone. The prompt has its own field, so words after the time are refused.

```ts
function readReminderWhen(text: string, now: number, tz?: string): ReminderWhen
```

**Parameters**

- `text` (`string`): What the person typed.
- `now` (`number`): Epoch ms.
- `tz?` (`string`): The IANA time zone for cron triggers. Default: the client's.

**Returns** `ReminderWhen`

Source: [ui/src/session/headless/schedules.ts:229](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L229)

### `relativeTo`

Function.

`key` relative to `root` when inside it; untouched otherwise.

```ts
function relativeTo(root: string | null, key: string): string
```

**Parameters**

- `root` (`string | null`): The session's folder, or `null`.
- `key` (`string`): A file's path.

**Returns** `string`

Source: [ui/src/session/headless/diff-tree.ts:73](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L73)

### `remindersSummary`

Function.

The composer badge's summary of a session's schedules. `null` when none will fire.

```ts
function remindersSummary(list: readonly Schedule[] | null): RemindersSummary | null
```

**Parameters**

- `list` (`readonly Schedule[] | null`): The session's schedules (`null` until read).

**Returns** `RemindersSummary | null`

Source: [ui/src/session/headless/schedules.ts:198](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L198)

### `sameRunningWork`

Function.

Same items, in the same order and states: the list on screen stays.

```ts
function sameRunningWork(
  a: readonly RunningWorkItem[],
  b: readonly RunningWorkItem[],
): boolean
```

**Parameters**

- `a` (`readonly RunningWorkItem[]`): One list.
- `b` (`readonly RunningWorkItem[]`): The other.

**Returns** `boolean`

Source: [ui/src/session/headless/running-work.ts:23](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/running-work.ts#L23)

### `sessionKeyCommands`

Function.

The session actions as key commands on the session on show (`sessionGenerateTitle`, `sessionCompact`,
`sessionExportMarkdown`, `sessionExportJson`, `sessionDelete`, `sessionCopyId`, `sessionFavorite`). None without a
session; no favorite on the main session.

```ts
function sessionKeyCommands(
  actions: SessionActions,
  session: SessionActionTarget | null,
): KeyCommands
```

**Parameters**

- `actions` (`SessionActions`): The app's session actions.
- `session` (`SessionActionTarget | null`): The session on show, or `null`.

**Returns** `KeyCommands`

Source: [ui/src/session/headless/session-actions.ts:182](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L182)

### `setHomeBlockView`

Function.

`prefs` with one control of block `id` set.

```ts
function setHomeBlockView(
  prefs: HomePrefs,
  id: string,
  control: string,
  value: string | readonly string[],
): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `id` (`string`): The block.
- `control` (`string`): The control id.
- `value` (`string | readonly string[]`): The picked option, or the picked options of a `multi` control.

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:240](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L240)

### `setHomeBlockWidth`

Function.

`prefs` with block `id` at `width`.

```ts
function setHomeBlockWidth(
  prefs: HomePrefs,
  id: string,
  width: 'full' | 'half',
): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `id` (`string`): The block.
- `width` (`'full' | 'half'`): Full row, or half (shares a row with a half neighbour).

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:189](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L189)

### `showHomeBlock`

Function.

`prefs` with block `id` shown (added, or hidden and shown again), after every shown block.

```ts
function showHomeBlock(
  prefs: HomePrefs,
  blocks: readonly HomeBlock[],
  id: string,
  defaults?: readonly string[],
): HomePrefs
```

**Parameters**

- `prefs` (`HomePrefs`): The arrangement.
- `blocks` (`readonly HomeBlock[]`): The blocks in default order ([`homeBlocksOf`](https://zidane.si/docs/reference/ui-session-headless.md#homeBlocksOf)).
- `id` (`string`): The block.
- `defaults?` (`readonly string[]`): The blocks shown before the user adds any ([`arrangeHomeBlocks`](https://zidane.si/docs/reference/ui-session-headless.md#arrangeHomeBlocks)).

**Returns** `HomePrefs`

Source: [ui/src/session/headless/home-layout.ts:213](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L213)

### `sortSchedules`

Function.

Schedules as the Reminders panel lists them: the ones that will fire, soonest first, then the rest, newest first.

```ts
function sortSchedules(list: readonly Schedule[]): Schedule[]
```

**Parameters**

- `list` (`readonly Schedule[]`): Schedules in any order.

**Returns** `Schedule[]`

Source: [ui/src/session/headless/schedules.ts:169](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L169)

### `sortSecrets`

Function.

Secrets by name, as the panel lists them.

```ts
function sortSecrets(entries: readonly SecretEntry[]): SecretEntry[]
```

**Parameters**

- `entries` (`readonly SecretEntry[]`): The entries in any order.

**Returns** `SecretEntry[]`

Source: [ui/src/session/headless/secrets.ts:65](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/secrets.ts#L65)

### `stagedToWire`

Function.

Staged attachments → wire attachments. An entry whose data URL can't be parsed is dropped.

```ts
function stagedToWire(
  attachments: readonly Pick<StagedAttachment, 'name' | 'mediaType' | 'dataUrl'>[],
): PromptAttachment[]
```

**Parameters**

- `attachments` (`readonly Pick<StagedAttachment, 'name' | 'mediaType' | 'dataUrl'>[]`): The staged attachments.

**Returns** `PromptAttachment[]`

Source: [ui/src/session/headless/queue-attachments.ts:29](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue-attachments.ts#L29)

### `toQueuedMessages`

Function.

The queue rows of a session's entries.

```ts
function toQueuedMessages(
  sessionId: string,
  items: readonly QueuedItem[],
): QueuedMessage[]
```

**Parameters**

- `sessionId` (`string`): The session the entries belong to.
- `items` (`readonly QueuedItem[]`): The backend's entries.

**Returns** `QueuedMessage[]`

Source: [ui/src/session/headless/queue.ts:49](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue.ts#L49)

### `upcomingSchedules`

Function.

The schedules that will fire, soonest first: on, with a next time.

```ts
function upcomingSchedules(list: readonly Schedule[]): Schedule[]
```

**Parameters**

- `list` (`readonly Schedule[]`): Schedules in any order.

**Returns** `Schedule[]`

Source: [ui/src/session/headless/schedules.ts:158](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L158)

### `visibleRows`

Function.

The rows on screen: a collapsed folder hides what is below it.

```ts
function visibleRows(
  tree: readonly DiffTreeNode[],
  collapsed: ReadonlySet<string>,
): DiffTreeNode[]
```

**Parameters**

- `tree` (`readonly DiffTreeNode[]`): The tree from [`buildDiffTree`](https://zidane.si/docs/reference/ui-session-headless.md#buildDiffTree).
- `collapsed` (`ReadonlySet<string>`): Paths of the collapsed folders.

**Returns** `DiffTreeNode[]`

Source: [ui/src/session/headless/diff-tree.ts:163](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L163)

### `wireToStaged`

Function.

Wire attachments → staged ones. `size` comes from the base64 length; `name` falls back to `''` so the round trip
keeps [`attachmentsKey`](https://zidane.si/docs/reference/ui-session-headless.md#attachmentsKey) stable.

```ts
function wireToStaged(attachments: readonly PromptAttachment[]): StagedAttachment[]
```

**Parameters**

- `attachments` (`readonly PromptAttachment[]`): The wire attachments.

**Returns** `StagedAttachment[]`

Source: [ui/src/session/headless/queue-attachments.ts:47](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue-attachments.ts#L47)

## Constants

### `DEFAULT_SESSION_LABELS`

Constant.

The default English strings of the session panels. Override any of them through `SessionProvider`.

```ts
const DEFAULT_SESSION_LABELS: { artifactCopyLink: string; artifactCopyPath: string; artifactCopySha: string; artifactHideDetails: string; artifactOnRemote: (machine: string) => string; artifactOpen: (path: string) => string; artifactPathUnavailable: string; artifactRemove: string; artifactReveal: string; artifactsCount: (label: string, count: number) => string; artifactsEmpty: string; artifactsEmptyHint: string; artifactsGroup: (label: string, count: number) => string; artifactShowDetails: string; artifactsLabel: string; artifactsUnsupported: string; cacheBreaks: (count: number) => string; cacheColumns: Record<'prompt' | 'dropped' | 'turn' | 'cached' | 'reread' | 'ttft' | 'energy', string>; cacheExpired: string; cacheExpiresIn: (until: string) => string; cacheExpiryHint: string; cacheHideRequests: string; cacheScopeAll: (total: number) => string; cacheScopeLast: (shown: number, total: number) => string; cacheShowRequests: string; cacheUncached: (pct: number) => string; detailsAccountHint: string; detailsAccountSignedOut: string; detailsActivity: string; detailsAgent: string; detailsAttachHint: string; detailsCache: string; detailsChange: string; detailsCompact: string; detailsCompactHint: string; detailsCompacting: string; detailsCompactNow: string; detailsCopied: string; detailsCopyId: string; detailsCopyIdHint: string; detailsCreated: string; detailsDefaultModel: string; detailsDelete: string; detailsDeleting: string; detailsDetach: string; detailsDetachHint: string; detailsEffortHint: string; detailsExport: string; detailsExportHint: string; detailsExporting: string; detailsFolder: string; detailsFolderElsewhere: (where: string) => string; detailsFolderGone: (cwd: string) => string; detailsFolderLocation: (where: FolderLocation) => string; detailsGenerate: string; detailsGenerateHint: string; detailsGenerating: string; detailsId: string; detailsJson: string; detailsMainDescription: string; detailsMainEverySpace: string; detailsMainHasNoFolder: string; detailsMainKeepsName: string; detailsMainNoFolder: string; detailsMainTitle: string; detailsMarkdown: string; detailsMessages: (count: number) => string; detailsModel: string; detailsNoFolder: string; detailsPickOther: string; detailsProviderHint: string; detailsReveal: string; detailsRevealHint: (cwd: string) => string; detailsRuns: (count: number) => string; detailsSave: string; detailsSavedTo: string; detailsSetFolder: string; detailsSpace: string; detailsSpaceHint: string; detailsSpaceLabel: string; detailsStatus: string; detailsStatusLabel: Record<'error' | 'running' | 'idle' | 'completed', string>; detailsStopToChange: string; detailsStopToDetach: string; detailsTitle: string; detailsTitleFact: string; detailsTitleLabel: string; detailsTurns: (count: number) => string; detailsUnknown: string; detailsUpdated: string; diffChangedFiles: string; diffFiles: (files: number) => string; diffFindings: (errors: number, warnings: number) => string; headerChangeFolder: (cwd: string) => string; headerChat: string; headerChatAttach: string; headerChatRunning: string; headerDetails: string; headerFolderOnServer: (cwd: string, server: string | null) => string; headerMainFolder: string; headerOnServer: (server: string | null) => string; headerRename: string; headerServerGone: string; planDrop: string; planDropCancel: string; planDropConfirm: (applying: boolean) => 'Drop this plan and stop the run?' | 'Drop this plan?'; planDropHint: string; planDropYes: string; planHideBody: string; planMaybeInterrupted: string; planNoSteps: string; planResume: string; planResumeHint: string; planShowBody: string; planState: Record<PlanState, string>; planStop: string; planStopHint: string; planStopped: (step: number | null, reason: PlanStopReason | undefined) => string; planUntitled: string; projectHomeAddBlock: string; projectHomeBlockMenu: (block: string) => string; projectHomeCustomize: string; projectHomeDismiss: string; projectHomeDone: string; projectHomeDrag: (block: string) => string; projectHomeFullWidth: string; projectHomeHalfWidth: string; projectHomeHide: string; projectHomeLabel: (project: string | null) => string; projectHomeMoveDown: string; projectHomeMoveUp: string; projectHomeOpenEditor: string; projectHomeOpenFiles: (path: string) => string; projectHomeOpenRepo: (repo: string, web: boolean) => string; projectHomeRefresh: string; projectHomeRemote: string; projectHomeReveal: string; projectHomeSwitch: string; queueAttach: string; queueAttachmentName: (attachment: { mediaType: string; name?: string }) => string; queueCancel: string; queueCount: (count: number) => string; queueEdit: string; queueEditHint: string; queueEditLabel: string; queueEmpty: string; queueEmptyHint: string; queueHintCancel: string; queueHintNewline: string; queueHintPush: string; queueHintSave: string; queueListLabel: string; queueOrder: string; queuePush: string; queueRemove: string; queueSave: string; queueSaveAndPush: string; queueViewAttachments: (count: number, first: string) => string; reminderCancel: string; reminderCountdown: (ms: number) => string; reminderCreate: string; reminderCreator: (creator: ScheduleCreator) => string; reminderDelete: (label: string) => string; reminderDone: string; reminderExpires: (when: string) => string; reminderFireLate: string; reminderFireOutcome: (outcome: ScheduleFireOutcome) => string; reminderHistoryHide: (label: string) => string; reminderHistoryLabel: (label: string) => string; reminderHistoryShow: (label: string) => string; reminderKeep: (label: string) => string; reminderLastSent: (when: string) => string; reminderNew: string; reminderNext: (when: string) => string; reminderNoFires: string; reminderOff: string; reminderOffReason: (reason: string) => string; reminderOnce: string; reminderPause: (label: string) => string; reminderPreview: (when: string) => string; reminderPromptLabel: string; reminderPromptPlaceholder: string; reminderResume: (label: string) => string; reminderRunNow: (label: string) => string; remindersCount: (n: number) => string; remindersEmpty: string; remindersEmptyAll: string; remindersEmptyHint: string; remindersFinished: string; remindersLabel: string; remindersListLabel: string; remindersOff: string; remindersOffHint: string; remindersScopeAll: string; remindersScopeLabel: string; remindersScopeSession: string; remindersUnsupported: string; reminderTargetExtension: (extension: string) => string; reminderTargetNew: (folder: string) => string; reminderTargetOpen: (title: string) => string; reminderTargetOther: string; reminderTargetUntitled: string; reminderWhenError: (reason: 'unknown' | 'empty' | 'extra') => 'Type when to send it.' | 'Only the time goes here. Put the message below.' | 'Try in 20m, at 9:00, tomorrow 9:00, every 2h, daily 9:00, weekdays 9:00 or cron "0 9 * * 1-5".'; reminderWhenLabel: string; reminderWhenPick: (words: string) => string; reminderWhenPicks: readonly string[]; reminderWhenPlaceholder: string; runningWorkCancel: string; runningWorkCancelAll: string; runningWorkCancelling: string; runningWorkDescription: string; runningWorkEmpty: string; runningWorkKind: Record<'task' | 'tool', string>; runningWorkRefresh: string; runningWorkShowTerminal: string; runningWorkTitle: string; secretCancel: string; secretExpiry: (left: SecretTimeLeft) => string; secretNameInvalid: string; secretNameLabel: string; secretNamePlaceholder: string; secretReplace: (name: string) => string; secretReplacesSaved: (name: string) => string; secretRevoke: (name: string) => string; secretsAdd: string; secretSave: string; secretSavedElsewhere: string; secretSavedHere: string; secretsEmpty: string; secretsEmptyHint: string; secretsLabel: string; secretsListLabel: string; secretsNote: string; secretValueLabel: string; shellClose: string; sideComposerLabel: string; sideEmptyHint: string; sideEmptyTitle: string; sidePlaceholder: string; sideRefusal: (reason: 'unavailable' | 'no-conversation' | 'no-panel') => 'Send a message first. A side chat follows a conversation.' | 'Side chats work only on this computer\'s conversations' | 'This window has no side panel for side chats'; sideResetDescription: string; sideResetFailed: (reason: string) => string; stepAdded: string; stepAgentNote: (note: string) => string; stepCancel: string; stepCancelHint: string; stepCancelledByYou: string; stepDroppedByAgent: string; todoAdd: string; todoAddLabel: string; todoAddPlaceholder: string; todoEdit: string; todoRetry: string; todoRetryHint: string; todosEmpty: string; todosEmptyHint: string; todosProgress: (done: number, total: number) => string; todoStatus: (status: TodoStatus) => string; todoTally: Record<TodoStatus, string>; turnAfter: (count: number) => string; turnBefore: (count: number) => string; turnCancel: string; turnCopied: string; turnCopy: string; turnCopyFailed: (message: string) => string; turnCopyHint: string; turnDelete: string; turnDeleteHint: string; turnEdit: string; turnEditHint: string; turnFork: string; turnForkHint: string; turnLoading: string; turnNoText: string; turnRole: (role: string | null) => string; turnSave: string; turnSaving: string; turnStopFirst: string; turnTextLabel: string; turnTitle: string; usageChecking: string; usageCredits: string; usageDescription: string; usageGithub: string; usageInUse: string; usageModelProviders: string; usageNone: string; usageOff: string; usageRefresh: string; usageRefreshing: string; usageResetConfirm: string; usageResetConfirmMessage: (count: number, title?: string | null) => string; usageResetConfirmTitle: (provider: string) => string; usageResetDates: (grantedAt: number | null, expiresAt: number | null) => string; usageResetOutcome: (code: 'failed' | 'reset' | 'nothing_to_reset' | 'no_credit' | 'already_redeemed', error?: string | null) => string; usageResets: string; usageResetsLeft: (count: number) => string; usageResetUntitled: string; usageResetUse: string; usageResetUseOne: (title: string) => string; usageResetUseShort: string; usageResetUsing: string; usageTitle: string; usageUnavailable: (unauthorized: boolean, error?: string | null) => string; usageWindowUsed: (window: string, percent: string) => string; welcomeDate: (date: Date) => string; welcomeGreeting: (hour: number, name: string | null) => string; welcomeUsageLabel: string }
```

Source: [ui/src/session/headless/labels.ts:335](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/labels.ts#L335)

### `EMPTY_HOME_PREFS`

Constant.

Nothing arranged yet.

```ts
const EMPTY_HOME_PREFS: HomePrefs
```

Source: [ui/src/session/headless/home-layout.ts:70](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L70)

### `USAGE_RANGES`

Constant.

The ranges, in the order a range switcher shows them.

```ts
const USAGE_RANGES: readonly UsageRange[]
```

Source: [ui/src/session/headless/usage.ts:35](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L35)

### `USAGE_SNAPSHOT_KEY`

Constant.

The default storage key of the usage snapshot.

```ts
const USAGE_SNAPSHOT_KEY = 'zg:usage-summary:v1'
```

Source: [ui/src/session/headless/usage.ts:164](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L164)

## Interfaces

### `ActivePlanSummary`

Interface.

The one-line summary the composer pill and the TUI footer show.

```ts
interface ActivePlanSummary
```

**Properties**

- `planId` (`string`): Plan id.
- `progress` (`PlanProgress`): Step counts.
- `state` (`PlanState`): Its state: applying or stopped.
- `title` (`string`): Title (empty for adhoc).

Source: [dist/index-Bq87OcGy.d.ts:18861](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L18861)

### `ArtifactsState`

Interface.

The artifact groups of every session a host has seen.

```ts
interface ArtifactsState
```

**Properties**

- `groups` (`(sessionId: string) => Readable<readonly SessionArtifactGroup[] | null>`): The session's groups store (`null` until first read).
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session from the backend. Rejects when the read fails.
- `wake` (`(sessionId: string) => void`): The backend said the session's artifacts changed: re-read once this tick.

Source: [ui/src/session/headless/artifacts.ts:13](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/artifacts.ts#L13)

### `DiffListFile`

Interface.

One changed file, as a diff source lists it.

```ts
interface DiffListFile
```

**Properties**

- `added` (`number`): Lines added.
- `key` (`string`): Stable id: the file's path as the diff source knows it (new path for a rename).
- `prevPath?` (`string`): Old path of a rename.
- `removed` (`number`): Lines removed.

Source: [ui/src/session/headless/diff-tree.ts:13](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L13)

### `DiffTreeDir`

Interface.

A folder row of the tree.

```ts
interface DiffTreeDir
```

**Properties**

- `added` (`number`): Lines added by the files below.
- `children` (`DiffTreeNode[]`): Folders, then files, by name.
- `depth` (`number`): Nesting level, 0 at the root.
- `fileKeys` (`string[]`): Every file below, for totals and highlighting.
- `kind` (`'dir'`): A folder.
- `name` (`string`): Row label: the folder name, or a merged chain (`src/components`).
- `path` (`string`): Full folder path, the collapse key.
- `removed` (`number`): Lines removed by the files below.

Source: [ui/src/session/headless/diff-tree.ts:25](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L25)

### `DiffTreeFile`

Interface.

A file row of the tree.

```ts
interface DiffTreeFile
```

**Properties**

- `added` (`number`): Lines added.
- `depth` (`number`): Nesting level, 0 at the root.
- `key` (`string`): The file's `DiffListFile.key`.
- `kind` (`'file'`): A file.
- `name` (`string`): Row label: the file name.
- `path` (`string`): Path below the tree root (cwd-relative when the file is inside it).
- `prevPath?` (`string`): Old path of a rename.
- `removed` (`number`): Lines removed.

Source: [ui/src/session/headless/diff-tree.ts:45](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L45)

### `HomeBlock`

Interface.

A block of the home.

```ts
interface HomeBlock
```

**Properties**

- `icon?` (`PanelIcon`): Its icon.
- `id` (`string`): Its panel id.
- `label` (`string`): Its name (menus, the hidden list).
- `owner` (`string`): The extension that registered it.
- `ownerIcon?` (`PanelIcon`): That extension's own icon: its mark stands in for a block without one.
- `ownerName?` (`string`): That extension's display name.
- `width` (`'full' | 'half'`): Shares a row with another half block.

Source: [ui/src/session/headless/home-layout.ts:38](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L38)

### `HomeBlockSource`

Interface.

What the home needs of a panel summary.

```ts
interface HomeBlockSource
```

**Properties**

- `home?` (`PanelHomeLayout`): Its default place on the home (order, width).
- `icon?` (`PanelIcon`): Its icon.
- `id` (`string`): The panel id.
- `label` (`string`): The panel's name.
- `owner` (`string`): The extension that registered it.
- `ownerIcon?` (`PanelIcon`): That extension's own icon: its mark stands in for a panel without one.
- `ownerName?` (`string`): That extension's display name.
- `surfaces?` (`readonly PanelSurface[]`): Where it may show; only panels that list `'home'` become blocks.

Source: [ui/src/session/headless/home-layout.ts:18](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L18)

### `HomePrefs`

Interface.

How the user arranged one project's home.

```ts
interface HomePrefs
```

**Properties**

- `added` (`readonly string[]`): Block ids the user added (not shown by default).
- `hidden` (`readonly string[]`): Block ids the user hid.
- `order` (`readonly string[]`): Block ids in the order the user put them.
- `views` (`Readonly<Record<string, PanelView>>`): Each block's view, by block id.
- `widths` (`Readonly<Record<string, HomeBlock['width']>>`): The width the user picked, by block id; a block without one keeps its panel's default.

Source: [ui/src/session/headless/home-layout.ts:56](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L56)

### `InboxPlans`

Interface.

A session's plans as the Inbox shows them.

```ts
interface InboxPlans
```

**Properties**

- `current` (`PlanView | null`): The plan in progress: the applying one, else the last stopped one (it can resume).
- `recent` (`readonly PlanView[]`): Closed plans (and any other stopped one), newest first. Proposals are never here: they wait under "Needs you".

Source: [ui/src/session/headless/plans.ts:89](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L89)

### `KeyedState`

Interface.

A map of values whose keys each have a readable store.

```ts
interface KeyedState<V, Fallback = null>
```

**Type parameters**

- `V`
- `Fallback` (default `null`)

**Properties**

- `clear` (`() => void`): Forgets every key.
- `delete` (`(key: string) => void`): Forgets `key` (a deleted session): its readers see the fallback.
- `get` (`(key: string) => V | undefined`): The value under `key`, `undefined` when unset.
- `readable` (`(key: string) => Readable<V | Fallback>`): The store of one key, the same object for the same key. Reads `fallback` while unset.
- `set` (`(key: string, value: V) => void`): Sets the value under `key`; its readers hear it when it changed by identity.

Source: [ui/src/session/headless/keyed.ts:9](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/keyed.ts#L9)

### `PlansSnapshot`

Interface.

What a window shows of a session's plans.

```ts
interface PlansSnapshot
```

**Properties**

- `active` (`ActivePlanSummary | null`): The plan worth a glance (composer pill, TUI footer), or `null`.
- `plans` (`PlanView[]`): Every kept plan, oldest first; an applying plan with no live run carries `possiblyInterrupted`.

Source: [dist/media-type-BzRZ4FqT.d.ts:7173](https://github.com/Tahul/zidane/blob/main/dist/media-type-BzRZ4FqT.d.ts#L7173)

### `PlansState`

Interface.

The plan snapshots of every session a host has seen.

```ts
interface PlansState
```

**Properties**

- `forget` (`(sessionId: string) => void`): Forgets a deleted session.
- `push` (`(sessionId: string, snapshot: PlansSnapshot) => void`): A snapshot the backend pushed (or answered to an edit).
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session from the backend: one request per session at a time, never rejects.
- `snapshot` (`(sessionId: string) => Readable<PlansSnapshot | null>`): The session's snapshot store (`null` until known).

Source: [ui/src/session/headless/plans.ts:20](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L20)

### `PlanStep`

Interface.

One step of a plan; the todo item the agent tracks.

```ts
interface PlanStep
```

**Properties**

- `added?` (`true`): Added after approval (by the agent's `todowrite` or the user), not part of the approved proposal.
- `cancelledBy?` (`StepCancelledBy`): Set when `status` is `cancelled`: the agent left it out of a write, or the user cancelled it.
- `description?` (`string`): Longer detail, from the proposal.
- `id` (`string`): Stable id: the proposal's step id, or the id the agent gave in `todowrite`.
- `note?` (`string`): An approved step: the agent's latest wording of it in `todowrite`, when it
  differs from the title. The approved title never changes under the agent.
- `status` (`TodoStatus`): Progress.
- `title` (`string`): One-line title.
- `updatedAt` (`number`): Last status or title change, epoch ms (UI hints only, never sent to the model).

Source: [dist/index-Bq87OcGy.d.ts:18582](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L18582)

### `PlanView`

Interface.

The plan a session shows as "in progress", with a display-only liveness flag.

```ts
interface PlanView extends Plan
```

**Properties**

- `awaiting?` (`'user' | 'revision'`, from `Plan`): While `proposed`: waiting on the user's decision, or on the agent's revision.
- `body?` (`string`, from `Plan`): Proposal body (Markdown).
- `closedAt?` (`number`, from `Plan`): Entered a closed state (or `stopped`), epoch ms.
- `createdAt` (`number`, from `Plan`): Created, epoch ms.
- `history?` (`PlanRevision[]`, from `Plan`): Earlier proposals, newest last, at most `MAX_PLAN_HISTORY`.
- `id` (`string`, from `Plan`): Plan id.
- `kind` (`'proposal' | 'adhoc'`, from `Plan`): Proposed through `present_plan`, or started by a plain `todowrite`.
- `parentPlanId?` (`string`, from `Plan`): A sub-agent plan: the parent scope's plan it works for.
- `parentStepId?` (`string`, from `Plan`): A sub-agent plan: the parent step that was in progress when it started.
- `pendingNotes?` (`string[]`, from `Plan`): User edits the agent has not been told about yet (delivered at the next turn boundary).
- `pendingRevisionComment?` (`string`, from `Plan`): While awaiting a revision: the user's note, moved into history by the revision.
- `possiblyInterrupted?` (`true`): An applying plan whose run is not live and whose lease has lapsed: it
  may have crashed. Display only; the next lease claim settles it.
- `requestId?` (`string`, from `Plan`): The `present_plan` request (tool call id) of the current proposal.
- `revision` (`number`, from `Plan`): Revision number, 1 for the first proposal.
- `runId?` (`string`, from `Plan`): The run that last applied this plan. A run end only closes the plans it applied.
- `scope` (`string`, from `Plan`): `SESSION_SCOPE`, or a sub-agent run id.
- `state` (`PlanState`, from `Plan`): Lifecycle state.
- `steps` (`PlanStep[]`, from `Plan`): The steps, in order.
- `stoppedAt?` (`string`, from `Plan`): While `stopped`: the step it stopped at.
- `stopReason?` (`PlanStopReason`, from `Plan`): While `stopped`: why.
- `title` (`string`, from `Plan`): Title. Empty for an adhoc plan.
- `updatedAt` (`number`, from `Plan`): Last change, epoch ms.

Source: [dist/index-Bq87OcGy.d.ts:18845](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L18845)

### `PromptAttachment`

Interface.

Attachment carried alongside the prompt text (base64, no data-URL prefix).

```ts
interface PromptAttachment
```

**Properties**

- `data` (`string`): Base64 content.
- `mediaType` (`string`): MIME type of the attachment.
- `name?` (`string`): File name, when known.
- `original?` (`{ data: string; mediaType: string; name?: string }`): The file as the user picked it, when the composer converted it before
  sending (an image re-encoded to fit the provider's cap): the host saves
  these bytes for the agent's tools, the model gets `data`. Absent when
  `data` is the file itself.

Source: [dist/media-type-BzRZ4FqT.d.ts:7246](https://github.com/Tahul/zidane/blob/main/dist/media-type-BzRZ4FqT.d.ts#L7246)

### `ProviderResetCredit`

Interface.

One banked reset.

```ts
interface ProviderResetCredit
```

**Properties**

- `expiresAt` (`number | null`): Epoch ms it expires, or `null` when it never does.
- `grantedAt` (`number | null`): Epoch ms it was granted, or `null` when unknown.
- `id` (`string`): The provider's id: redeem this one with it.
- `title` (`string | null`): The provider's name for it (`Full reset (Weekly + 5 hr)`), or `null`.

Source: [dist/index-Bq87OcGy.d.ts:14397](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L14397)

### `ProviderResetOutcome`

Interface.

What redeeming a banked reset did. `reset`: the windows were emptied;
`nothing_to_reset`: no window had usage, so nothing was spent; `no_credit`:
no reset left; `already_redeemed`: this request was already applied;
`failed`: the request failed (`error` says why), possibly before reaching
the provider.

```ts
interface ProviderResetOutcome
```

**Properties**

- `code` (`'failed' | 'reset' | 'nothing_to_reset' | 'no_credit' | 'already_redeemed'`): What happened (see above).
- `error` (`string | null`): Short failure reason when `code` is `failed`.
- `windowsReset` (`number`): Windows the reset emptied (`0` unless `code` is `reset`).

Source: [dist/index-Bq87OcGy.d.ts:14414](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L14414)

### `ProviderResetTarget`

Interface.

Which account a banked reset is spent on: a snapshot's provider and credential.

```ts
interface ProviderResetTarget
```

**Properties**

- `credentialKey` (`string`): The snapshot's `credentialKey`.
- `creditId?` (`string`): Which reset to spend (`ProviderResetCredit.id`). Absent: the provider picks.
- `providerKey` (`string`): The snapshot's `providerKey`.

Source: [ui/src/session/headless/usage.ts:22](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L22)

### `ProviderUsageSnapshot`

Interface.

Usage of one credential of a provider, as probed at one moment.

```ts
interface ProviderUsageSnapshot
```

**Properties**

- `account` (`string | null`): Account name for OAuth-backed snapshots (`Default`, `work`, …); `null` for
  API-key probes. Surfaces show it only when the provider has more than one
  snapshot, so a single-account provider stays quiet.
- `activeCredential` (`boolean`): True when this credential is the one requests use (the canonical slot).
- `credentialId?` (`string`): Stable id of that credential (`ProviderCredential.id`): unlike
  `credentialKey` it does not move when another account is promoted,
  so a session pinned to an account finds its snapshot by it. Absent for
  an env-only key or an entry written before ids.
- `credentialKey` (`string`): Credentials-file key of the credential this snapshot was probed with. A
  provider holding several OAuth accounts yields one snapshot per account;
  this is what tells them apart (and the stable list key).
- `credits` (`ProviderUsageCredits | null`): Credit balance, or `null` when the provider reports none.
- `error` (`string | null`): Short failure reason when `status` is not `ok`.
- `fetchedAt` (`number`): Epoch milliseconds when the snapshot was taken.
- `label` (`string`): Display label for the provider.
- `note?` (`string`): A short hint shown under the windows (GitHub's "anonymous: run `gh auth login`").
- `plan` (`string | null`): Plan name when the provider reports one.
- `providerKey` (`string`): Registry key (`anthropic`, `openai`, …).
- `resets?` (`ProviderUsageResets`): Banked resets, when the provider reports them (Codex). Redeem one with `redeemProviderReset`.
- `status` (`ProviderUsageStatus`): Outcome of the probe.
- `windows` (`readonly ProviderUsageWindow[]`): Rate-limit windows with their usage.

Source: [dist/index-Bq87OcGy.d.ts:14425](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L14425)

### `ProviderUsageSource`

Interface.

The backend calls a [`ProviderUsageState`](https://zidane.si/docs/reference/ui-session-headless.md#ProviderUsageState) makes.

```ts
interface ProviderUsageSource
```

**Properties**

- `github?` (`(options?: { probe?: boolean }) => Promise<readonly ProviderUsageSnapshot[]>`): GitHub's API limits. Absent: no GitHub section.
- `providers` (`(options?: { refresh?: boolean }) => Promise<readonly ProviderUsageSnapshot[]>`): The model providers' snapshots. Never rejects on a provider error (it lands in the snapshot).
- `redeemReset?` (`(target: ProviderResetTarget) => Promise<ProviderResetOutcome>`): Spends one banked reset. Absent: no reset button.

Source: [ui/src/session/headless/usage.ts:291](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L291)

### `ProviderUsageState`

Interface.

One cache of subscription usage, shared by every reader.

```ts
interface ProviderUsageState
```

**Properties**

- `redeemReset` (`((target: ProviderResetTarget) => Promise<ProviderResetOutcome>) | null`): Spends one banked reset, then refreshes. `null` when the source can't redeem.
- `view` (`Readable<ProviderUsageView>`): What is shown. A quiet probe that changes nothing keeps the same object.
- `lastLoad` (`() => number`): When the last provider fetch landed (ms), `0` before any.
- `load` (`(refresh: boolean) => Promise<void>`): Fetches the providers (and GitHub). `refresh`: bypass the backend's cache; one landing mid-fetch runs after it.
- `loadGithub` (`(probe: boolean) => Promise<void>`): GitHub alone: `probe` asks GitHub, otherwise what was observed.

Source: [ui/src/session/headless/usage.ts:277](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L277)

### `ProviderUsageView`

Interface.

What the subscription-usage readers see.

```ts
interface ProviderUsageView
```

**Properties**

- `github` (`readonly ProviderUsageSnapshot[]`): GitHub's API limits, one snapshot per host. Never read as a model provider.
- `loaded` (`boolean`): At least one fetch completed (auto or manual).
- `loading` (`boolean`): A fetch is in flight.
- `snapshots` (`readonly ProviderUsageSnapshot[]`): The model providers' snapshots.

Source: [ui/src/session/headless/usage.ts:265](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L265)

### `QueueAddOptions`

Interface.

What goes with a message added to the queue.

```ts
interface QueueAddOptions
```

**Properties**

- `activatedSkills?` (`string[]`): Skills activated with the message.
- `attachments?` (`PromptAttachment[]`): Attachments with their bytes.
- `delivery?` (`MessageDelivery`): While a run works: `steer` hands it to the run, `queue` holds it for the run's end. Absent: the host's setting.

Source: [ui/src/session/headless/host.ts:77](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L77)

### `QueueBackend`

Interface.

The backend calls the queue state makes.

```ts
interface QueueBackend
```

**Properties**

- `list` (`(sessionId: string) => Promise<readonly QueuedItem[]>`): The session's entries.
- `remove` (`(sessionId: string, id: string) => Promise<unknown>`): Drops an entry.
- `update` (`(sessionId: string, id: string, text: string, attachments?: PromptAttachment[]) => Promise<unknown>`): Replaces an entry's text (and attachments when given).

Source: [ui/src/session/headless/queue.ts:16](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue.ts#L16)

### `QueuedAttachment`

Interface.

An attachment on a queued prompt, without its bytes.

```ts
interface QueuedAttachment
```

**Properties**

- `mediaType` (`string`): MIME type of the attachment.
- `name?` (`string`): File name, when known.

Source: [dist/media-type-BzRZ4FqT.d.ts:7384](https://github.com/Tahul/zidane/blob/main/dist/media-type-BzRZ4FqT.d.ts#L7384)

### `QueuedMessage`

Interface.

One message waiting in a session's queue, as the queue panel shows it.

```ts
interface QueuedMessage
```

**Properties**

- `attachments?` (`readonly QueuedAttachment[]`): What rides with the text, without the bytes (`queue.attachments` fetches them).
- `id` (`string`): The entry's id, assigned by the backend.
- `sessionId` (`string`): The session the entry belongs to, so a row can act on the queue without its parent's help.
- `text` (`string`): The message text.

Source: [ui/src/session/headless/host.ts:59](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L59)

### `QueueState`

Interface.

The queues of every session a host has seen.

```ts
interface QueueState
```

**Properties**

- `drop` (`(sessionId: string, id: string) => void`): Drops an entry at once and tells the backend.
- `edit` (`(sessionId: string, id: string, text: string, attachments?: PromptAttachment[]) => Promise<void>`): Edits an entry at once and tells the backend; resolves when it answered (never rejects).
- `items` (`(sessionId: string) => Readable<readonly QueuedMessage[]>`): The session's entries store (empty when none).
- `refresh` (`(sessionId: string) => void`): Reads the session from the backend and remembers it as the active one. Best effort.
- `replace` (`(sessionId: string, items: readonly QueuedItem[]) => void`): The entries the backend broadcast for a session.
- `reset` (`(reread: boolean) => void`): Forgets every queue (the backend changed: a reconnect), then re-reads the active session when `reread`.

Source: [ui/src/session/headless/queue.ts:26](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue.ts#L26)

### `RemindersSummary`

Interface.

What the composer's Reminders badge shows: how many will fire, and the soonest time.

```ts
interface RemindersSummary
```

**Properties**

- `count` (`number`): Schedules of the session that are on and have a next time.
- `next` (`number`): The soonest next time (epoch ms).

Source: [ui/src/session/headless/schedules.ts:186](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L186)

### `RunningWorkItem`

Interface.

Parent-level cancellable tool call or background task.

```ts
interface RunningWorkItem
```

**Properties**

- `childId?` (`string`): Id of the subagent that started the item, when it was not the parent.
- `id` (`string`): Tool call id or task id.
- `kind` (`'task' | 'tool'`): Whether the item is a tool call or a background task.
- `label` (`string`): Short description shown to the user.
- `resuming?` (`true`): A call of a batch a durable run resumed after a process death, that the
  dead process did not finish (its `tool` event says `resuming`). A
  window attaching mid-run reads it from here. Optional: older hosts never
  send it.
- `startedAt` (`number`): Start time in epoch ms.

Source: [dist/media-type-BzRZ4FqT.d.ts:7192](https://github.com/Tahul/zidane/blob/main/dist/media-type-BzRZ4FqT.d.ts#L7192)

### `RunningWorkState`

Interface.

The running work of every session a host has seen.

```ts
interface RunningWorkState
```

**Properties**

- `ensure` (`(sessionId: string) => void`): Reads the session once, the first time it is asked for. Never rejects (the snapshots fill it in).
- `items` (`(sessionId: string) => Readable<readonly RunningWorkItem[]>`): The session's work (empty for none). One store per session id.
- `push` (`(sessionId: string, items: readonly RunningWorkItem[]) => void`): The backend's snapshot of the session's work.
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session now and records it, unless a snapshot landed meanwhile. Rejects when the read fails.

Source: [ui/src/session/headless/running-work.ts:39](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/running-work.ts#L39)

### `Schedule`

Interface.

A stored schedule.

```ts
interface Schedule
```

**Properties**

- `action` (`ScheduleAction`): What a fire does: a prompt, or an extension handler.
- `catchUp` (`ScheduleCatchUp`): What a fire missed while no host ran does when a host comes back.
- `createdAt` (`number`): Made, epoch ms.
- `createdBy` (`ScheduleCreator`): Who made it: the user, the agent of a session, or an extension.
- `disabledReason?` (`string`): Why the host turned it off (its extension was removed, it expired). Cleared when you turn it on.
- `enabled` (`boolean`): Off: it never fires. Fires again from now when you turn it back on.
- `expiresAt?` (`number`): The host disables it after this time (epoch ms). Set on recurring schedules that the agent made.
- `id` (`string`): Schedule id.
- `lastFire?` (`ScheduleFire`): The last fire, for lists.
- `name?` (`string`): A short name for lists and the transcript. Absent: the start of the prompt or the handler name.
- `nextFireAt` (`number | null`): The next fire (epoch ms). `null`: none (a fired `at`, a cron with no next time, or disabled).
- `trigger` (`ScheduleTrigger`): When it fires.
- `updatedAt` (`number`): Last changed, epoch ms.

Source: [dist/index-Bq87OcGy.d.ts:774](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L774)

### `ScheduleFire`

Interface.

One fire of a schedule, newest first in `schedules.fires`.

```ts
interface ScheduleFire
```

**Properties**

- `dueAt` (`number`): The time the fire was due (epoch ms).
- `error?` (`string`): Why it failed.
- `firedAt` (`number`): The time it ran (epoch ms).
- `id` (`string`): Fire id.
- `late?` (`boolean`): It ran after a host was down past `dueAt`.
- `outcome` (`ScheduleFireOutcome`): What the fire did.
- `scheduleId` (`string`): The schedule that fired.
- `sessionId?` (`string`): The session the prompt went to (a `newSession` action: the session it created).

Source: [dist/index-Bq87OcGy.d.ts:755](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L755)

### `ScheduleInput`

Interface.

What `schedules.create` takes.

```ts
interface ScheduleInput
```

**Properties**

- `action` (`ScheduleAction`): What a fire does.
- `catchUp?` (`ScheduleCatchUp`): Absent: `once` for `at`, `skip` for `every` and `cron`.
- `enabled?` (`boolean`): Absent: `true`.
- `name?` (`string`): A short name for lists. Absent: the start of the prompt or the handler name.
- `trigger` (`ScheduleTrigger`): When it fires.

Source: [dist/index-Bq87OcGy.d.ts:803](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L803)

### `SchedulePatch`

Interface.

What `schedules.update` takes: the fields to change. `expiresAt: null` keeps a schedule for good (you pinned it).

```ts
interface SchedulePatch
```

**Properties**

- `action?` (`ScheduleAction`): A new action.
- `catchUp?` (`ScheduleCatchUp`): A new catch-up rule.
- `enabled?` (`boolean`): On or off. Turning it on counts the next fire from now.
- `expiresAt?` (`null`): `null`: keep it for good (no expiry).
- `name?` (`string | null`): A new name; `null` clears it.
- `trigger?` (`ScheduleTrigger`): A new trigger: the next fire counts from now.

Source: [dist/index-Bq87OcGy.d.ts:816](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L816)

### `SchedulesBackend`

Interface.

What a [`SchedulesState`](https://zidane.si/docs/reference/ui-session-headless.md#SchedulesState) reads from the backend.

```ts
interface SchedulesBackend
```

**Properties**

- `list` (`() => Promise<readonly Schedule[]>`): Every schedule (zidane's `schedules.list`). Rejects while the feature is off.
- `status` (`() => Promise<SchedulesStatus>`): Whether the feature is on and the store keeps schedules (zidane's `schedules.status`). Never rejects.

Source: [ui/src/session/headless/schedules.ts:39](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L39)

### `SchedulesState`

Interface.

The reminders a host holds, as stores.

```ts
interface SchedulesState
```

**Properties**

- `all` (`Readable<readonly Schedule[] | null>`): Every schedule, in the backend's order: `null` until read, and while the feature is off.
- `status` (`Readable<SchedulesStatus | null>`): Whether the feature is on: `null` until read.
- `apply` (`(schedule: Schedule) => void`): Writes a schedule an action answered (created or changed) at once.
- `drop` (`(id: string) => void`): Drops a removed schedule at once.
- `ensure` (`() => void`): Reads once, the first time something asks. Never rejects.
- `forSession` (`(sessionId: string) => Readable<readonly Schedule[] | null>`): The schedules whose prompt goes to `sessionId` (`null` like `all`). The same store for the same id.
- `refresh` (`() => Promise<void>`): Reads the status, then the list while the feature is on. Rejects when a read fails.
- `wake` (`() => void`): Something changed on the backend: re-reads once this tick, when read so far.

Source: [ui/src/session/headless/schedules.ts:19](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L19)

### `SchedulesStatus`

Interface.

Whether reminders are on (`Settings.schedules`) and whether the backend's store keeps them (zidane's `schedules.status`).

```ts
interface SchedulesStatus
```

**Properties**

- `enabled` (`boolean`): The setting is on and the store keeps schedules. Off: nothing about reminders shows.
- `supported` (`boolean`): The store keeps schedules at all.

Source: [ui/src/session/headless/host.ts:218](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L218)

### `SecretsState`

Interface.

The secret lists of every session a host has read.

```ts
interface SecretsState
```

**Properties**

- `entries` (`(sessionId: string) => Readable<readonly SecretEntry[] | null>`): The session's entries store (`null` until first read).
- `forget` (`(sessionId: string) => void`): Forgets a session (deleted).
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session from the backend. Rejects when the read fails.
- `wakeAll` (`() => void`): A store changed somewhere: every session read so far re-reads once this tick.

Source: [ui/src/session/headless/secrets.ts:12](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/secrets.ts#L12)

### `SessionActions`

Interface.

The session actions; each one present only when its capability is.

```ts
interface SessionActions
```

**Properties**

- `compact?` (`(session: SessionActionTarget) => Promise<void>`): Summarizes older turns to free context.
- `copyId?` (`(session: SessionActionTarget) => Promise<void>`): Copies the session's id.
- `exportJson?` (`(session: SessionActionTarget) => Promise<void>`): Writes the transcript as JSON.
- `exportMarkdown?` (`(session: SessionActionTarget) => Promise<void>`): Writes the transcript as Markdown.
- `fork?` (`(sessionId: string, turnId: string, onCreated?: (newId: string) => void) => Promise<string>`): Forks the session from a turn: creates it, calls `onCreated`, re-reads the list and shows it. Resolves the new
  session's id; rejects when the fork failed.
- `generateTitle?` (`(session: SessionActionTarget) => Promise<void>`): Writes a title generated from the conversation, then re-reads the list.
- `remove?` (`(session: SessionActionTarget) => Promise<boolean>`): Asks, then deletes. Resolves whether it was deleted.
- `toggleFavorite?` (`(session: SessionActionTarget) => Promise<void>`): Marks or unmarks the session as a favorite. Absent on the main session's actions too (see `sessionKeyCommands`).

Source: [ui/src/session/headless/session-actions.ts:77](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L77)

### `SessionActionsDeps`

Interface.

What the session actions run over. Each member left out removes the actions that need it.

```ts
interface SessionActionsDeps
```

**Properties**

- `labels?` (`{ activityCompacting: string; activityRetrying: string; activityThinking: string; activityWriting: string; addDiagnosticToChat: (message: string) => string; addFavorite: string; additionalInstructions: string; additionalInstructionsHint: string; additionalInstructionsPlaceholder: string; address: string; addressPlaceholder: string; addSpace: string; addToChat: string; agent: string; agentDraftNote: string; agentGroupDefault: string; agentProfiles: string; archive: string; archiveConfirmLabel: string; archived: string; archiveProjectMessage: (count: number) => 'It stays under Archived, where you can restore it.' | 'They stay under Archived, where you can restore them.'; archiveProjectTitle: (count: number, project: string) => string; attachFile: string; attachmentEmpty: (name: string) => string; attachmentExportPdf: (name: string) => string; attachmentNotices: string; attachmentReadFailed: (name: string) => string; attachments: string; attachmentTitle: (name: string, detail: string) => string; attachmentTooLarge: (name: string, size: string, limit: string) => string; attachmentUnreadableImage: (name: string) => string; attachmentUnsupported: (name: string) => string; authCancel: string; authCard: string; authCopied: string; authCopyDetails: string; authEnterCode: (code: string) => string; authFailed: (message: string) => string; authFixed: string; authHeadline: (auth: AuthFailure, label: string) => string; authOpeningBrowser: string; authOpenPage: string; authPaste: string; authPasteSend: string; authSettings: string; authSettingsHint: string; authSignedIn: string; authSignedInRetrying: string; authSignInAgain: string; authSwitching: (account: string) => string; authTryAgain: string; authUseAccount: (account: string) => string; authWaiting: string; autoDenied: string; back: string; badgeCopied: string; badgeNoComposer: string; badgeOpenIn: (app: string) => string; badgeOpenInBrowserPane: string; badgePathUnavailable: string; blockRunAgain: string; blockRunAttach: string; blockRunAttachmentName: string; blockRunCopy: string; blockRunFailed: (reason: string) => string; blockRunHere: string; blockRunInTerminal: string; blockRunMenu: string; blockRunNeedsTerminal: string; blockRunning: string; blockRunOutput: string; blockRunRemove: string; blockRunStop: string; blockRunStopped: string; blockRunTimedOut: string; blockRunTruncated: string; cancel: string; changeIconFor: (project: string) => string; changeMainIcon: string; changeProjectIcon: string; changeSpaceIcon: string; chats: string; chipBranch: (name: string) => string; chipChat: (name: string) => string; chipCommand: (name: string) => string; chipCommit: (sha: string) => string; chipFactAliases: string; chipFactBranch: string; chipFactChanges: string; chipFactContext: string; chipFactDate: string; chipFactModel: string; chipFactPrompts: string; chipFactSize: string; chipFactTurns: string; chipFactUpdated: string; chipLoading: string; chipNotAmongChats: string; chipNotFound: (title: string) => string; chipRemoteFile: (path: string, host: string) => string; chipSessionError: string; chipSessionRunning: string; chipSkill: (name: string) => string; chipTokens: (count: string) => string; chipUntitledChat: string; chooseImage: string; chooseModel: string; chooseProjectIcon: string; chooseSpaceIcon: string; clearSearch: string; clickToAnswer: string; close: string; closeTab: (name: string) => string; code: string; collapseGroup: (label: string) => string; collapseItem: (title: string) => string; collapseSidebar: string; commandDetail: string; commandSuggestions: string; compactingTitle: string; completionSuggestions: string; composerBadges: string; composerLabel: string; composerPlaceholder: string; composerPlaceholderQueue: string; composerPlaceholderSteer: string; confirm: string; confirmNo: string; confirmYes: string; contextActiveSkills: string; contextAutoCompact: (pct: number) => string; contextCacheRead: string; contextCacheWrite: string; contextClickToCopy: (hasDescription: boolean) => string; contextCopied: string; contextDeferred: string; contextDetail: string; contextEstimated: string; contextFreshInput: string; contextLastTurn: string; contextNoBreakdown: string; contextOutput: string; contextRunCount: (runs: number) => string; contextSessionCost: string; contextSummary: (used: string, window: string, pct: number) => string; contextSummaryCost: (summary: string, cost: string) => string; contextWindow: string; continue: string; continueHint: string; continueRun: string; copied: string; copy: string; copyCode: string; copyDiagramSource: string; copyImage: string; copyImageBase64: string; copyImageDataUrl: string; current: string; customEmoji: string; declineSecret: string; declineSecretHint: string; defaultAgent: string; defaultSpaceName: string; delete: string; deleteConfirmLabel: string; deleteProjectArchived: (archived: number) => string; deleteProjectCannotUndo: string; deleteProjectSandboxes: (sandboxed: number) => string; deleteProjectTitle: (count: number, project: string) => string; deleteSessionQuestion: (title: string) => string; deleteSessionSandbox: (kind: string) => string; deleteSpace: string; deleteSpaceMessage: (fallback: string) => string; deleteSpaceNamed: (name: string) => string; deleteSpaceQuestion: (name: string) => string; diagnosticsCheckedBy: (source: string) => string; diagnosticsChecking: string; diagnosticsNone: string; diagram: (type: string | null) => string; diagramError: (message: string, at: string) => string; diagramErrorAt: (line: number, column: number) => string; dismiss: string; dismissHint: string; dotAttached: string; dotAttention: string; dotCompleted: string; dotError: string; dotIdle: string; dotPending: string; dotRunning: string; earlierHistory: string; earlierLines: (count: number) => string; earlierMessages: (count: number) => string; editorConflict: string; editorConflictDetail: string; editorEmpty: string; editorOverwrite: string; editorReadFailed: (message: string) => string; editorReload: string; effortLevel: (level: string) => string; emojiPlaceholder: string; environmentActionFailed: (action: string, message: string) => string; environmentKept: (reason?: string) => string; environmentKinds: Readonly<Record<string, string>>; environmentOnBranch: (kind: string, branch: string) => string; environmentOnMachine: (kind: string, machine: string) => string; environmentPaused: (where: string) => string; environmentSettingUp: (where: string) => string; environmentSetupFailed: (where: string, error?: string) => string; environmentsKept: (count: number) => string; errorFailed: (region: string) => string; errorStack: string; errorTryAgain: string; estimateDue: string; estimateDueTitle: string; estimateOver: string; estimateOverTitle: string; estimatePausedTitle: (left: string) => string; estimateProblemTitle: (reason: string, message?: string) => string; estimateTitle: (left: string) => string; expandGroup: (label: string) => string; expandItem: (title: string) => string; expandSidebar: string; favorites: string; filePath: (path: string) => string; fileReadOnly: (path: string) => string; fileTree: string; fileUnsaved: string; fileUnsavedTitle: (path: string) => string; filterActivities: { '1d': string; '30d': string; '3d': string; '7d': string; all: string }; filterActivity: string; filterAgent: string; filterAllAgents: string; filterAllAgentsOption: string; filterAllProjects: string; filterAllProjectsOption: string; filterAny: string; filterNoAgents: string; filterNoProjects: string; filterOrigin: string; filterOrigins: { all: string; scheduled: string; unscheduled: string }; filterPicked: (count: number) => string; filterProject: string; filterSaveView: string; filterSessions: string; filterSort: string; filterSorts: { alphabetical: string; createdTime: string; recency: string }; filterSpaceDefault: string; filterStatus: string; filterStatuses: { active: string; all: string; archived: string }; filterView: string; filterViews: { agent: string; date: string; host: string; none: string; project: string; state: string }; findClose: string; findCloseHint: string; findInConversation: string; findInConversationClose: string; findInFile: string; findMatchCase: string; findNext: string; findNextHint: string; findNoResults: string; findPrevious: string; findPreviousHint: string; findReferences: string; fitDiagram: string; foldOutcomes: (ok: number, failed: number) => string; foldSteps: (count: number) => string; footerSettings: string; footerSettingsWithNote: (note: string) => string; footerSignIn: string; footerSignInTitle: string; generatedImage: string; generatingImage: (model: string | null) => string; generatingImages: (count: number, model: string | null) => string; goToDefinition: string; goToStep: (step: string) => string; hiddenSpaces: string; hideSpace: string; hostBadgeTitle: (host: string, status: string) => string; hostCollapse: (name: string) => string; hostExpand: (name: string) => string; hostOpenSettings: (host: string) => string; hostPicker: string; hostRunsOn: (name: string) => string; hostRunsOnSection: string; hostStatusError: (status: string, error: string) => string; hostStatuses: { 'auth-refused': string; connected: string; connecting: string; identity: string; local: string; offline: string; reconnecting: string; 'version-mismatch': string }; hostThisMachine: string; imageModelReferences: string; imageModelReferencesHint: string; imageModelsNone: string; imageModelsPill: string; imageModelTransparency: string; imageModelTransparencyHint: string; inboxEmpty: string; inboxInProgress: string; inboxNeedsYou: string; inboxPreviousSession: string; inboxRecent: string; inputCaption: string; interactionAnsweredBy: (who: string) => string; interactionApproved: string; interactionDismissed: string; interactionPlan: string; interactionQuestion: string; interactionRejected: string; interactionRevise: string; interactionsLabel: string; interactionWaitingAnswers: string; interactionWaitingDecision: string; itemActions: (title: string) => string; itemOpenFailed: (message: string) => string; justNow: string; loadEarlierHistory: string; loadFullOutput: string; loading: string; loadingEarlierHistory: string; loadingEarlierMessages: string; loadingFullOutput: string; mainSession: string; mentionSuggestions: string; menuAddFavorite: string; menuArchive: string; menuArchiveProject: string; menuCopyPath: string; menuDelete: string; menuDeleteProject: string; menuMoveProjectToSpace: string; menuMoveTo: string; menuMoveToSpace: string; menuOpenChatWindow: string; menuOpenPanelsWindow: string; menuOpenWindow: string; menuRemoveFavorite: string; menuRename: string; menuRetryEnvironment: string; menuReveal: string; menuUnarchive: string; modalBack: string; modalFailed: string; modelAccountBlocked: (provider: string) => string; modelChain: string; modelChainNoModel: string; modelChainOrderHint: string; modelFallback: string; modelFallbackHint: string; modelFallbackPosition: (n: number) => string; modelFeatures: string; modelForNextChat: string; modelInUse: string; modelKinds: string; modelLegacy: string; modelLegacyHint: string; modelNotInCatalog: string; modelNotInCatalogHint: string; modelOptions: string; modelOptionsEmpty: string; modelOptionsHint: string; modelPrimary: string; modelPrimaryHint: string; modelReasoning: string; modelReasoningHint: string; modelRemoveFallback: (n: number) => string; modelRemoveFromChain: string; modelRemovePrimary: string; modelsChatTab: string; modelsCustomId: string; modelServing: (picked: string, serving: string) => string; modelServingFallback: string; modelsImageTab: string; modelsInUse: string; modelsJumpHint: (provider: string, digit: number | null) => string; modelsJumpToProvider: string; modelsLegacy: string; modelsLegacyHidden: (count: number) => string; modelsLoadFailed: (error: string) => string; modelsLoading: string; modelsNoMatch: (query: string) => string; modelsNoProviders: string; modelsSelected: (count: number) => string; modelsShowLegacy: string; modelsShowLegacyHint: string; modelsShownOf: (shown: number, total: number) => string; modelsTypeAnId: string; modelUnavailable: string; modelVerdictTitle: (approved: boolean, model: string, confidence: string | null) => string; modelVia: string; modelViaHint: (modelId: string, provider: string) => string; months: readonly string[]; moreActions: string; moreAttachments: (count: number) => string; moveProjectFailed: (message: string) => string; moveSessionFailed: (message: string) => string; moveSpaceDown: (name: string) => string; moveSpaceLeft: string; moveSpaceRight: string; moveSpaceUp: (name: string) => string; newSession: string; newSessionIn: (project: string) => string; newSessionTitle: string; newSpaceName: (n: number) => string; next: string; noAnswer: string; noChatsMatchFilters: string; noChatsYet: string; noMatches: (query: string) => string; noReferences: string; noSessions: string; noSuggestions: string; of: (index: number, count: number) => string; openFiles: string; openGroup: (label: string) => string; openImageFile: (path: string) => string; openInNewTab: string; openNamedSession: (title: string) => string; openSecrets: string; openSession: string; outputCaption: string; paletteBack: string; paletteBackHint: string; paletteChoose: string; paletteEmpty: string; paletteFilter: string; paletteLabel: string; paletteLoading: string; paletteNoMatch: (query: string) => string; paletteOpen: string; paletteRun: string; paletteScopeHint: string; paletteTurnOff: string; paletteTurnOn: string; pickModel: string; pickOneOrMore: string; pinNamed: (project: string) => string; pinProject: string; planApprove: string; planReject: string; planRejectAndStop: string; planRejectNote: string; planRejectPlaceholder: string; planRevise: string; planReviseNote: string; planRevisePlaceholder: string; planSendRevision: string; previewFailed: (name: string) => string; previewTooLarge: (name: string, size: string) => string; previous: string; queryGroupOther: string; questionCount: (count: number) => string; queueHint: string; queueMessage: string; reasoningEffort: string; receiptAgent: string; receiptAgentSwitched: string; receiptCost: string; receiptDuration: string; receiptModel: string; receiptModelOthers: (others: number) => string; receiptSpeed: string; receiptTokens: (sent: string, received: string) => string; receiptTurns: (turns: number) => string; reload: string; removeAttachment: (name: string) => string; removeFavorite: string; rename: string; requiredHint: string; requiredMark: string; resetFilters: string; resetsAt: (time: string) => string; resetToFolder: string; resetToInitial: string; retry: string; retryEnvironmentFailed: (message: string) => string; retryHint: string; rowNeedsYou: string; rowRunning: string; rowScheduled: string; rowWorking: string; runningFor: (elapsed: string) => string; runReceipt: string; runRetrying: (attempt: number, max: number, source?: string) => string; runWaiting: string; savedViewName: (n: number) => string; saveSecurely: string; saveViewFailed: (message: string) => string; screenBack: (screen: string) => string; screenBackKey: string; scriptCallsDone: (done: number) => string; scriptCallsFailed: (failed: number) => string; scriptCallsOf: (done: number, total: number) => string; scriptCallsRunning: (running: number) => string; scriptLineCalls: (calls: number) => string; scriptLiveOutput: string; scriptLoop: string; scriptLoopRound: (round: number) => string; scriptLoopRounds: (rounds: number) => string; scriptLoopRuns: (runs: number) => string; scriptOptionOutput: string; scriptOptions: string; scriptOptionTimeout: string; scriptOptionTokens: (tokens: number) => string; scriptPercent: (percent: number) => string; scriptProgress: string; scriptWaitLeft: (seconds: number) => string; searchingSessions: string; searchModels: string; searchModelsPlaceholder: string; searchSessions: string; searchSessionsLabel: string; secretDeclined: (name: string) => string; secretNote: (ttl: SecretTtl) => string; secretReused: (name: string) => string; secretSaved: (name: string, left: SecretTimeLeft) => string; secretSent: (name: string) => string; secretTtlLabel: string; secretTtlName: (ttl: SecretTtl) => string; secretValueLabel: string; secretValuePlaceholder: string; selectTurnCopied: string; selectTurnCopy: string; selectTurnDetails: string; selectTurnExit: string; selectTurnFork: string; selectTurnForkFailed: string; selectTurnMove: string; selectTurnNothingToCopy: string; selectTurnSelecting: string; sendAnswers: (count: number) => string; sendHint: string; sendMessage: string; sessionActions: string; sessionEventLabel: (title: string, verb: string, needsAttention: boolean) => string; sessions: string; setModelOptions: string; shellCancelled: string; shellExit: (code: number) => string; shellKilled: string; showDiagram: string; showDiagramSource: string; showHiddenSpace: (name: string) => string; showMore: string; showMoreAttachments: (count: number) => string; showOutput: string; showSystemPrompt: string; sidebarNoMatches: string; signInCopyCode: string; signInDone: (account?: string) => string; signInEnterCode: (host: string) => string; signInFailed: string; signInInBrowser: (service: string) => string; signInNotOpened: string; signInOpenPage: string; signInPaste: string; signInStarting: string; signInSubmit: string; skip: string; spaceFromExtension: (extension: string) => string; spaceNamed: (name: string) => string; spaceNameOf: (name: string) => string; spaceOptions: (name: string) => string; spaces: string; spacesTitle: string; spawnResumes: (childId: string) => string; spawnTask: string; stateCompleted: string; stateError: string; stateIdle: string; stateRunning: string; steerHint: string; steerMessage: string; stepDone: string; stepFailed: string; stepOf: (index: number, count: number) => string; stepResuming: string; stepRunning: string; steps: string; stepWaiting: string; stopCommand: string; stopHint: string; stopped: string; stoppedByYou: string; stopRun: string; switchAgent: string; switchingAgent: string; switchModel: string; terminal: string; terminalExited: (code: number) => string; terminalLoadFailed: (message: string) => string; thinkingLive: string; thoughtFor: (seconds: number) => string; thoughts: string; thoughtTimes: (count: number) => string; today: string; toolAttachments: string; transcriptLoading: string; turnMenuCopy: string; turnMenuCopySelection: string; turnMenuCopySelectionFailed: string; turnMenuDelete: string; turnMenuEdit: string; turnMenuEditNeedsComposer: string; turnMenuFork: string; turnMenuRewind: string; turnMenuSent: (age: string) => string; turnMenuStopFirst: (label: string) => string; turnsCompacted: string; unarchive: string; unpinNamed: (project: string) => string; unpinProject: string; unsupportedInteraction: (tool: string) => string; usagePanelHint: string; usageWindow: (window: string, percent: string) => string; useSpaces: string; useSpacesDescription: string; viewAttachment: (name: string) => string; waitingForSlot: (max: number) => string; workerContinues: string; workerModel: string; workerSystemPrompt: string; workerSystemReplaced: string; workerType: string; working: string; wrapLines: string; yesterday: string; yourSpaces: string; zoomFit: string; zoomInDiagram: string; zoomOutDiagram: string; zoomPercent: (percent: number) => string }`): The delete confirmation's wording.
- `session?` (`Pick<SessionHost, 'details' | 'turns'>`): The session host: `details` (title, compact, export) and `turns` (fork).
- `sessions?` (`{ remove?(sessionId: string): Promise<unknown>; setFavorite?(sessionId: string, favorite: boolean): Promise<void> }`): The session list's writes (`ChatHost.sessions`, or the app's directory, which also re-reads the list).
- `confirm?` (`(options: SessionConfirmOptions) => Promise<boolean>`): Asks before a delete. Absent: no delete action (a delete is never unasked).
- `copyText?` (`(text: string) => Promise<void>`): Writes text to the clipboard. Absent: no copy-id action.
- `idOf?` (`(sessionId: string) => string`): The id to copy: the one the session's host knows it by. Absent: the session's id.
- `onError?` (`(action: SessionActionName, error: unknown) => void`): Hears a failed action. Absent: failures are dropped.
- `open?` (`(sessionId: string) => void`): Shows a session (the fork).
- `refresh?` (`() => void | Promise<unknown>`): Re-reads the session list after a write the list shows (a title, a fork).

Source: [ui/src/session/headless/session-actions.ts:52](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L52)

### `SessionActionTarget`

Interface.

The session an action runs on: what the actions read off its row.

```ts
interface SessionActionTarget
```

**Properties**

- `environment?` (`SessionEnvironmentSummary`): Where it runs, for the delete confirmation (a remote sandbox goes with it).
- `favorite?` (`boolean`): Whether it is a favorite (what `toggleFavorite` flips).
- `id` (`string`): The session's id (the app's key).
- `isMain?` (`boolean`): The pinned main session: never a favorite.
- `title?` (`string | null`): Its title, for the delete confirmation. Absent: the id.

Source: [ui/src/session/headless/session-actions.ts:22](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L22)

### `SessionArtifact`

Interface.

A recorded output of a session, such as a pull request, a branch, a commit or a file.

```ts
interface SessionArtifact
```

**Properties**

- `createdAt` (`number`): Creation time as epoch milliseconds.
- `id` (`string`): Stable id (uuid). Preserved across upserts of the same `(kind, uri)`.
- `kind` (`string`): Open kind string. Built-ins in `ARTIFACT_KINDS`.
- `label` (`string`): Human line. Always present — the rendering fallback for unknown kinds.
- `meta?` (`JsonValue`): Kind-specific payload, ≤ `ARTIFACT_META_MAX_BYTES`.
- `projectRoot?` (`string`): Project the artifact landed in, resolved at emission time from where
  the thing actually is (a worktree, a sibling repo), defaulting to the
  session's own `projectRoot`. Drives "everything produced from this
  repo" queries.
- `runId?` (`string`): Run that produced it. A `persist`-spawned subagent shares the parent
  session and records under its OWN run id (detection reaches it via the
  `child:tool:transform` bubble; see `presets/artifacts.ts`).
- `sessionId` (`string`): Id of the session the artifact belongs to.
- `turnId?` (`string`): Tool-result turn that produced it — the transcript anchor.
- `updatedAt` (`number`): Last update time as epoch milliseconds.
- `uri` (`string`): Canonical locator: PR URL, `git:<repo>#<branch>`, `file://<abs path>`, …

Source: [dist/index-Bq87OcGy.d.ts:55](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L55)

### `SessionArtifactGroup`

Interface.

A session's artifacts of one kind.

```ts
interface SessionArtifactGroup
```

**Properties**

- `kind` (`string`): The artifact kind id (`pull_request`, `commit`…).
- `label` (`string`): The kind's label (`Pull request`), the raw kind when unregistered.
- `rows` (`SessionArtifactRow[]`): The artifacts of this kind, newest first.

Source: [ui/src/session/headless/host.ts:121](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L121)

### `SessionArtifactRow`

Interface.

One artifact and its rendered row.

```ts
interface SessionArtifactRow
```

**Properties**

- `artifact` (`SessionArtifact`): The stored artifact.
- `row` (`SessionArtifactRowView`): How it shows.

Source: [ui/src/session/headless/host.ts:113](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L113)

### `SessionArtifactRowView`

Interface.

An artifact's row, rendered by the backend (the kind registry lives there).

```ts
interface SessionArtifactRowView
```

**Properties**

- `badges?` (`readonly { text: string; title?: string; tone?: 'success' | 'warn' | 'neutral' | 'diff' }[]`): Small facts after the title (older rows).
- `color?` (`string`): Exact color for the icon and status word, over `tone`.
- `diff?` (`{ added: number; files?: number; href?: string; removed: number }`): A change size, painted in the diff colors.
- `facts?` (`readonly ExtensionArtifactRowFact[]`): Quiet facts after the diff.
- `href?` (`string`): Where "open" goes: a URL or an absolute path.
- `icon?` (`ExtensionBadgeIcon`): The state icon.
- `lead?` (`{ href?: string; mono?: boolean; text: string }`): A short id (a commit hash, `owner/repo#12`); `mono` for hashes.
- `status?` (`string`): Short state tag (`open`, `merged`…).
- `subtitle?` (`string`): Secondary line under the title (older rows; `lead` / `diff` / `facts` replace it).
- `title` (`string`): Row title.
- `tone?` (`ExtensionBadgeTone`): Tints the icon and the status word.

Source: [ui/src/session/headless/host.ts:87](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L87)

### `SessionArtifacts`

Interface.

What a session produced: pull requests, branches, commits, files, extension kinds.

```ts
interface SessionArtifacts
```

**Properties**

- `groups` (`(sessionId: string) => Readable<readonly SessionArtifactGroup[] | null>`): The session's artifacts by kind: `null` until first read. One store per session id.
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session's artifacts (also the first read). Rejects when the read fails.
- `refreshRow?` (`(sessionId: string, artifact: SessionArtifact, options?: { force?: boolean }) => Promise<void>`): Re-resolves one artifact (is the pull request merged? its diff size?); a change re-reads the groups through the
  usual wake-up. `force` bypasses the backend's freshness cache. Never rejects.
- `remove?` (`(sessionId: string, artifactId: string, owner?: string) => Promise<boolean>`): Removes one artifact. Resolves `false` when the backend has no artifact support. `owner` is the session the
  artifact was recorded in, when the list shows another session's (a child's).

Source: [ui/src/session/headless/host.ts:172](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L172)

### `SessionConfirmOptions`

Interface.

What `confirm` is asked before a delete.

```ts
interface SessionConfirmOptions
```

**Properties**

- `confirmLabel` (`string`): The confirm button's text.
- `destructive` (`true`): Always `true`: a delete is undo-less.
- `message?` (`string`): What else goes with it.
- `title` (`string`): The question.

Source: [ui/src/session/headless/session-actions.ts:36](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L36)

### `SessionDetailsActions`

Interface.

The session details dialog's actions on one session.

```ts
interface SessionDetailsActions
```

**Properties**

- `cacheReport?` (`(sessionId: string) => Promise<CacheReport | null>`): What the prompt cache did for the last requests (the numbers `/cache` prints); `null` when there is none.
- `compact?` (`(sessionId: string) => Promise<void>`): Summarizes older turns to free context.
- `export?` (`(sessionId: string, format: SessionExportFormat) => Promise<string>`): Writes the transcript to a file. Resolves its absolute path.
- `generateTitle?` (`(sessionId: string) => Promise<string>`): Writes a title generated from the conversation. Resolves it.
- `setFolder?` (`(sessionId: string, folder: string | null) => Promise<void>`): Attaches a folder (`null` detaches it: a plain chat). Refused mid-run.
- `titleStatus?` (`(sessionId: string) => Promise<readonly string[] | null>`): How the title came about (`['auto', 'from 3 turns']`); `null` when unknown.

Source: [ui/src/session/headless/host.ts:285](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L285)

### `SessionDiffEntry`

Interface.

One edit the agent made, as a patch.

```ts
interface SessionDiffEntry
```

**Properties**

- `added` (`number`): Added lines.
- `id` (`string`): Stable id: the call (or turn) id and the entry's position.
- `patch` (`string`): A unified diff with bare header paths.
- `path` (`string`): The edited file.
- `removed` (`number`): Removed lines.
- `tool` (`'edit' | 'multi_edit' | 'write_file'`): The tool that made it.

Source: [ui/src/session/headless/session-diffs.ts:24](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-diffs.ts#L24)

### `SessionEditEvent`

Interface.

A transcript event as the Diffs panel reads it: a tool event may carry the edit it made.

```ts
interface SessionEditEvent
```

**Properties**

- `callId?` (`string`): The tool call's id.
- `edit?` (`EditPayload`): The edit the tool call made.
- `kind` (`string`): The event kind; only `tool` events carry edits.
- `turnId?` (`string`): The turn's id.

Source: [ui/src/session/headless/session-diffs.ts:12](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-diffs.ts#L12)

### `SessionHost`

Interface.

The session panels' host. Every member is optional: what a host leaves out is not shown.

```ts
interface SessionHost
```

**Properties**

- `artifacts?` (`SessionArtifacts`): The recorded artifacts. Absent: no Artifacts panel.
- `details?` (`SessionDetailsActions`): The details dialog's actions. Absent: the dialog shows facts only.
- `plans?` (`SessionPlans`): The plans. Absent: no Todos panel.
- `queue?` (`SessionQueue`): The type-ahead queues. Absent: no queue.
- `runningWork?` (`SessionRunningWork`): The cancellable work. Absent: no running work dialog.
- `schedules?` (`SessionSchedules`): Reminders (zidane's schedules). Absent: no Reminders panel, no badge.
- `secrets?` (`SessionSecrets`): The saved secrets of a session's project. Absent: no Secrets panel.
- `side?` (`SessionSideChats`): `/side` chats about a session. Absent: no side chat.
- `turns?` (`SessionTurns`): The stored turns. Absent: no turn details dialog.
- `usage?` (`SessionUsage`): Usage. Absent: no usage card, no usage panel.

Source: [ui/src/session/headless/host.ts:342](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L342)

### `SessionPlans`

Interface.

A session's plans: the one the agent applies, the ones that stopped or closed.

```ts
interface SessionPlans
```

**Properties**

- `control?` (`(sessionId: string, planId: string, action: PlanControlAction) => Promise<void>`): Stops or drops a plan (and the run applying it). The snapshot follows. Rejects with the backend's reason.
- `edit?` (`(sessionId: string, planId: string, op: PlanEditOp) => Promise<void>`): Applies a user edit to a plan's steps (add, rename, cancel: a step is never deleted). The snapshot follows.
  Rejects with the backend's reason (a closed plan, another process running the session). Absent: read-only.
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session's plans (also the first read). Never rejects: the next push catches up.
- `retry?` (`(sessionId: string, message: string) => Promise<void>`): Sends a message into the session's run (it steers a live run, starts one when idle): a step's retry, a
  stopped plan's resume. Absent: no retry, no resume.
- `snapshot` (`(sessionId: string) => Readable<PlansSnapshot | null>`): The session's snapshot: `null` until read, or for an unknown session. One store per session id.

Source: [ui/src/session/headless/host.ts:134](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L134)

### `SessionQueue`

Interface.

A session's type-ahead queue: messages sent while the agent works, delivered when the run ends.

```ts
interface SessionQueue
```

**Properties**

- `add?` (`(sessionId: string, text: string, options?: QueueAddOptions) => Promise<QueueAddDelivery>`): Queues a message (the backend sends it right away when the session is idle).
- `attachments?` (`(sessionId: string, id: string) => Promise<PromptAttachment[] | null>`): An entry's attachments with their bytes; `null` when the entry is gone.
- `items` (`(sessionId: string) => Readable<readonly QueuedMessage[]>`): The session's entries, in delivery order (empty when none). One store per session id.
- `pushNow?` (`(sessionId: string, id: string) => Promise<QueuePushDelivery>`): Pushes an entry into the live run now.
- `refresh` (`(sessionId: string) => void`): Reads the session's queue (on activation). Best effort.
- `remove?` (`(sessionId: string, id: string) => void`): Drops an entry. The store drops it at once; the backend converges.
- `update?` (`(sessionId: string, id: string, text: string, attachments?: PromptAttachment[]) => Promise<void>`): Replaces an entry's text, and its attachments when given (`[]` removes them). Resolves once the backend has it.

Source: [ui/src/session/headless/host.ts:154](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L154)

### `SessionRunningWork`

Interface.

A session's cancellable work: parent-level tool calls and background tasks.

```ts
interface SessionRunningWork
```

**Properties**

- `cancel?` (`(sessionId: string, id: string, reason?: string) => Promise<boolean>`): Cancels one item, or `'all'`. Resolves `false` when nothing was cancelled.
- `ensure` (`(sessionId: string) => void`): Reads the session once, the first time something shows it. Never rejects.
- `items` (`(sessionId: string) => Readable<readonly RunningWorkItem[]>`): The session's work, live (empty for none). One store per session id.
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session's work now (a dialog opening, Refresh). Rejects when the read fails.

Source: [ui/src/session/headless/host.ts:253](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L253)

### `SessionSchedules`

Interface.

Reminders (zidane's schedules): prompts sent to a session at a set time, once or on a repeat. The Reminders panel
and the composer badge. Every action rejects with the backend's reason (the feature is off, a refused input).

```ts
interface SessionSchedules
```

**Properties**

- `all` (`Readable<readonly Schedule[] | null>`): Every schedule of the backend: `null` until read, and while the feature is off.
- `status` (`Readable<SchedulesStatus | null>`): Whether the feature is on: `null` until read. While `enabled` is false nothing about reminders shows.
- `create?` (`(input: ScheduleInput) => Promise<Schedule>`): Creates a schedule (the trigger exact: the client reads the time words in its own time zone). Absent: no create form.
- `ensure` (`() => void`): Reads once, the first time something shows reminders. Never rejects.
- `fires?` (`(id: string, limit?: number) => Promise<readonly ScheduleFire[]>`): A schedule's fires, newest first. Absent: no history.
- `forSession` (`(sessionId: string) => Readable<readonly Schedule[] | null>`): The schedules whose prompt goes to `sessionId` (`null` like `all`). One store per session id.
- `refresh` (`() => Promise<void>`): Reads the status, then the list while on. Rejects when a read fails.
- `remove?` (`(id: string) => Promise<boolean>`): Removes a schedule and its fires. Resolves `false` when it was gone. Absent: no Delete.
- `runNow?` (`(id: string) => Promise<ScheduleFire>`): Runs a schedule's action now; its next time does not move. Absent: no Run now.
- `update?` (`(id: string, patch: SchedulePatch) => Promise<Schedule>`): Changes a schedule (pause, resume, keep for good with `expiresAt: null`). Absent: read-only rows.

Source: [ui/src/session/headless/host.ts:229](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L229)

### `SessionSecretInput`

Interface.

What a secret saved by hand takes: its name, its value, how long it stays.

```ts
interface SessionSecretInput
```

**Properties**

- `name` (`string`): Env-style name (`API_TOKEN`): capital letters, digits and `_`, starting with a letter.
- `ttl` (`SecretTtl`): How long it stays.
- `value` (`string`): The value. Sent once, never read back.

Source: [ui/src/session/headless/host.ts:193](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L193)

### `SessionSecrets`

Interface.

The saved secrets of a session's project (`Settings.secrets`): the Secrets panel. Values go in, never out: the
entries carry names and expiry times only. The backend lists none while the setting is off.

```ts
interface SessionSecrets
```

**Properties**

- `entries` (`(sessionId: string) => Readable<readonly SecretEntry[] | null>`): The project's valid secrets, as the session sees them: `null` until first read. One store per session id.
- `refresh` (`(sessionId: string) => Promise<void>`): Reads the session's secrets (also the first read). Rejects when the read fails.
- `revoke?` (`(sessionId: string, name: string) => Promise<boolean>`): Removes a secret. Resolves `false` when it did not exist. Absent: no Revoke.
- `save?` (`(sessionId: string, input: SessionSecretInput) => Promise<SecretEntry>`): Adds or replaces a secret. Rejects with the backend's reason (the setting is off, a plain-text remote link). Absent: read-only.

Source: [ui/src/session/headless/host.ts:206](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L206)

### `SessionSideChats`

Interface.

`/side` chats: a hidden session about another one (never listed, deleted with it), running read-only tools that
read the parent, while the parent's own run streams.

```ts
interface SessionSideChats
```

**Properties**

- `create` (`(parentId: string, cwd: string, from: SideChatSession | null) => Promise<SideChatSession>`): Creates `parentId`'s side chat in `cwd`, starting on `from`'s model and effort (the parent's row).
- `lookup` (`(parentId: string) => Promise<SideChatLookup>`): The side chat of `parentId`, and `parentId`'s row.
- `remove` (`(sideId: string) => Promise<void>`): Deletes a side chat, stopping its answer first when one runs. Rejects with what went wrong.
- `subscribe?` (`(onChange: (sessionId: string) => void) => () => void`): Calls `onChange` with a session's id when its row changes (a model pick). Returns the unsubscribe.

Source: [ui/src/session/headless/host.ts:330](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L330)

### `SessionTurn`

Interface.

One persisted turn of a session: a user prompt, an assistant response, or a system or command entry.

```ts
interface SessionTurn
```

**Properties**

- `aborted?` (`true`): On a `role: 'assistant'` turn: model output a process death cut off,
  rebuilt when its durable run resumed. Shown in the transcript, left out
  of the model context; the request is sent again.
- `content` (`SessionContentBlock[]`): Content blocks of the turn, in order.
- `createdAt` (`number`): Unix timestamp (Date.now()) when the turn was created
- `display?` (`string`): Display-only replacement for transcript rendering — the full `content`
  still reaches the model unchanged. Set by command context notes
  (`ctx.appendContext`) so a replayed session renders the same one-line
  marker the live path showed (with the full note as a collapsed detail)
  instead of duplicating bulky note bodies as a wall of user text.
  Mirrors `SessionRun.origin.display`, at turn granularity, for turns
  that belong to no run.
- `id` (`string`): Unique turn id. Provider-loop turns are minted from AgentClock.randomUUID().
- `injected?` (`InjectedTurnReason`): Set on a `role: 'user'` turn the agent loop injected rather than the user
  typed (a refusal retry, an output-limit or pause "Please continue.", a
  tool-output-budget warning). The content still reaches the model; hosts
  use the marker to keep the turn out of everything that treats user turns
  as prompts (transcript bubbles, prompt matching, usage counts).
- `role` (`'system' | 'user' | 'command' | 'assistant'`): Conversational role, plus `'command'` — a display-only turn emitted by a
  `/` command's local output. `'command'` turns are persisted + rendered
  but excluded from every model-message builder (they never reach the LLM),
  mirroring how `'system'` turns are filtered from the wire.
- `runId?` (`string`): Run that produced this turn (e.g. 'run_1')
- `systemSnapshot?` (`SystemPromptSnapshot`): On a `role: 'system'` turn: the conversation's frozen system prompt, which
  `content` holds as one text block. The latest snapshot for a prompt key
  wins. Recorded by hosts that pass `AgentRunOptions.systemFreeze`.
- `usage?` (`TurnUsage`): Token usage — only present on assistant turns

Source: [dist/index-Bq87OcGy.d.ts:7293](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L7293)

### `SessionTurns`

Interface.

A session's stored turns: what the turn details dialog reads and does.

```ts
interface SessionTurns
```

**Properties**

- `delete?` (`(sessionId: string, turnId: string) => Promise<void>`): Deletes the turn and its tool calls. Refused while a run is in progress.
- `editText?` (`(sessionId: string, turnId: string, text: string) => Promise<void>`): Replaces the turn's text blocks. Refused while a run is in progress.
- `fork?` (`(sessionId: string, turnId: string) => Promise<string>`): A new session with the history up to this turn. Resolves the new session's id.
- `get` (`(sessionId: string, turnId: string) => Promise<SessionTurn | null>`): One turn as stored; `null` when it is gone.
- `rewind?` (`(sessionId: string, turnId: string, options: { inclusive: boolean }) => Promise<void>`): Cuts the history after the turn (`inclusive`: the turn stays) or just before it. Refused while a run is in progress.

Source: [ui/src/session/headless/host.ts:265](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L265)

### `SessionUsage`

Interface.

Usage: spend summaries and the providers' subscription windows.

```ts
interface SessionUsage
```

**Properties**

- `github?` (`(options?: { probe?: boolean }) => Promise<readonly ProviderUsageSnapshot[]>`): GitHub's API limits. `probe` asks GitHub; otherwise what was observed. Absent: no GitHub section.
- `providers?` (`(options?: { refresh?: boolean }) => Promise<readonly ProviderUsageSnapshot[]>`): The model providers' subscription windows. `refresh` bypasses the backend's cache. Absent: no usage panel.
- `redeemReset?` (`(target: ProviderResetTarget) => Promise<ProviderResetOutcome>`): Spends one banked reset on a snapshot's account (Codex). Absent: no reset button.
- `summary?` (`(range: UsageRange) => Promise<UsageSummary>`): Token spend over a range (the welcome screen). Absent: no usage card.

Source: [ui/src/session/headless/host.ts:301](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L301)

### `SideChatLookup`

Interface.

A session's side chat (`null` until the first send creates it) and the session's own row.

```ts
interface SideChatLookup
```

**Properties**

- `parent` (`SideChatSession | null`): The session the side chat is about, or `null` when unknown.
- `side` (`SideChatSession | null`): The side chat's session, or `null`.

Source: [ui/src/session/headless/host.ts:319](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L319)

### `SideChatSession`

Interface.

A session row as the side chat needs it: its id; the app's pickers read the rest.

```ts
interface SideChatSession
```

**Properties**

- `id` (`string`): The session's id.

Source: [ui/src/session/headless/host.ts:313](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L313)

### `SideRequests`

Interface.

The `/side` hand-over between a composer and the side chat.

```ts
interface SideRequests
```

**Properties**

- `request` (`(parent: string | null, question: string, options: { available: boolean; open: (() => void) | null }) => SideRefusal | null`): Opens `parent`'s side chat with `question` (`''`: just opens it) through `open`. Returns why it can't instead,
  or `null` once handed over.
- `subscribe` (`(onRequest: () => void) => () => void`): Calls `onRequest` when a question starts waiting. Returns the unsubscribe.
- `take` (`(parent: string) => string | undefined`): The waiting question for `parent`, removed as it is returned.

Source: [ui/src/session/headless/side.ts:21](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/side.ts#L21)

### `StagedAttachment`

Interface.

An attachment staged in the queue editor.

```ts
interface StagedAttachment
```

**Properties**

- `dataUrl` (`string`): A `data:` URL with the bytes.
- `id` (`string`): A local id, stable while staged.
- `mediaType` (`string`): The media type.
- `name` (`string`): The file name (`''` when it had none).
- `size` (`number`): Bytes.

Source: [ui/src/session/headless/queue-attachments.ts:9](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/queue-attachments.ts#L9)

### `TodoItem`

Interface.

One item of a `todowrite` call.

```ts
interface TodoItem
```

**Properties**

- `content` (`string`): One-line task summary.
- `id` (`string`): Stable id: the model picks it, or reuses a plan step's id.
- `status` (`TodoStatus`): Current progress.

Source: [dist/index-Bq87OcGy.d.ts:18504](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L18504)

### `UsageHeatmapDay`

Interface.

One heatmap cell. Sparse: days without activity are left out.

```ts
interface UsageHeatmapDay
```

**Properties**

- `day` (`string`): Local `YYYY-MM-DD`.
- `messages` (`number`): User messages that day.
- `tokens` (`number`): Tokens that day.

Source: [ui/src/session/headless/usage.ts:72](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L72)

### `UsageModelDayPoint`

Interface.

One stacked-bar segment of the models chart: a model's tokens on a day.

```ts
interface UsageModelDayPoint
```

**Properties**

- `day` (`string`): Local `YYYY-MM-DD`.
- `modelId` (`string`): The model id.
- `tokens` (`number`): Tokens that day.

Source: [ui/src/session/headless/usage.ts:54](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L54)

### `UsageModelRow`

Interface.

Per-model usage over the summary's range. `tokensIn` counts prompt input plus cache reads and writes; `cost` is USD.

```ts
interface UsageModelRow
```

**Properties**

- `cost` (`number`): USD.
- `modelId` (`string`): The model id.
- `provider` (`string`): The provider's display name.
- `tokensIn` (`number`): Tokens sent to the model.
- `tokensOut` (`number`): Tokens the model produced.
- `turns` (`number`): Assistant turns.

Source: [ui/src/session/headless/usage.ts:38](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L38)

### `UsageProviderRow`

Interface.

Spend per provider.

```ts
interface UsageProviderRow
```

**Properties**

- `cost` (`number`): USD.
- `provider` (`string`): The provider's display name.

Source: [ui/src/session/headless/usage.ts:64](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L64)

### `UsageSummary`

Interface.

Usage and spend over a range. The heatmap always spans the last \~26 weeks.

```ts
interface UsageSummary
```

**Properties**

- `activeDays` (`number`): Days with activity.
- `currentStreak` (`number`): Consecutive active days up to today.
- `favoriteModel` (`string | null`): The most used model id; `null` without data.
- `generatedAt` (`number`): When the backend computed it (ms).
- `heatmap` (`UsageHeatmapDay[]`): The activity heatmap's days.
- `longestStreak` (`number`): The longest run of active days.
- `messages` (`number`): User messages (prompts the agent spawned excluded).
- `modelDaily` (`UsageModelDayPoint[]`): The models chart's points.
- `models` (`UsageModelRow[]`): Per model, most used first.
- `peakHour` (`number | null`): Local hour (0-23) with the most messages; `null` without data.
- `providers` (`UsageProviderRow[]`): Spend per provider, largest first.
- `range` (`UsageRange`): The range it covers.
- `sessions` (`number`): Sessions in range.
- `tokensIn` (`number`): Tokens sent to models.
- `tokensOut` (`number`): Tokens models produced.
- `totalCost` (`number`): USD, from assistant-turn costs.
- `totalTokens` (`number`): Tokens in and out.
- `userName` (`string | null`): First name for the greeting; `null` when unknown.

Source: [ui/src/session/headless/usage.ts:82](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L82)

### `UsageSummaryState`

Interface.

The usage summaries a host keeps.

```ts
interface UsageSummaryState
```

**Properties**

- `summaries` (`Readable<Partial<Record<UsageRange, UsageSummary>>>`): Every range held so far (a stored snapshot until the first reply).
- `revalidate` (`(range: UsageRange) => Promise<void>`): Fetches `range` (deduped per range). Resolves once the store holds the reply, or the read failed.

Source: [ui/src/session/headless/usage.ts:146](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L146)

### `UsageSummaryStateOptions`

Interface.

Options for [`createUsageSummaryState`](https://zidane.si/docs/reference/ui-session-headless.md#createUsageSummaryState).

```ts
interface UsageSummaryStateOptions
```

**Properties**

- `schedule?` (`(write: () => void) => void`): Defers the snapshot write off the critical path. Default: `requestIdleCallback`, else a 0 ms timeout.
- `storage?` (`Pick<Storage, 'getItem' | 'setItem'> | null`): Where the snapshot is mirrored (`localStorage`). Absent: memory only.
- `storageKey?` (`string`): The storage key. Default `zg:usage-summary:v1`.

Source: [ui/src/session/headless/usage.ts:154](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L154)

## Types

### `DiffTreeNode`

Type.

A row of the Diffs file tree: a folder or a file.

```ts
type DiffTreeNode = DiffTreeDir | DiffTreeFile
```

Source: [ui/src/session/headless/diff-tree.ts:65](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/diff-tree.ts#L65)

### `HomeRow`

Type.

A row of the home: one full block, or two half blocks.

```ts
type HomeRow =
  | { block: HomeBlock; kind: 'full' }
  | { blocks: readonly [HomeBlock, HomeBlock]; kind: 'pair' }
```

Source: [ui/src/session/headless/home-layout.ts:73](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/home-layout.ts#L73)

### `PlanControlAction`

Type.

Stops or drops a plan.

```ts
type PlanControlAction = 'stop' | 'drop'
```

Source: [ui/src/session/headless/host.ts:131](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L131)

### `PlanEditOp`

Type.

A user edit to a plan's steps.

```ts
type PlanEditOp =
  | { kind: 'rename'; stepId: string; title: string }
  | { kind: 'add'; stepId?: string; title: string }
  | { kind: 'cancel'; stepId: string }
```

Source: [dist/index-Bq87OcGy.d.ts:18686](https://github.com/Tahul/zidane/blob/main/dist/index-Bq87OcGy.d.ts#L18686)

### `QueueAddDelivery`

Type.

How the backend delivered a message added to the queue.

```ts
type QueueAddDelivery = 'queued' | 'sent' | 'steer'
```

Source: [ui/src/session/headless/host.ts:71](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L71)

### `QueuePushDelivery`

Type.

How the backend delivered a queued message pushed into the run now (`missing`: the entry was gone).

```ts
type QueuePushDelivery = 'steer' | 'send' | 'queued' | 'missing'
```

Source: [ui/src/session/headless/host.ts:74](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L74)

### `ReminderWhen`

Type.

The time words of the Reminders form, read: a trigger, or why not.

```ts
type ReminderWhen =
  | { ok: true; trigger: ScheduleTrigger }
  | { ok: false; reason: 'empty' | 'unknown' | 'extra' }
```

Source: [ui/src/session/headless/schedules.ts:213](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/schedules.ts#L213)

### `SessionActionName`

Type.

The names `onError` reports.

```ts
type SessionActionName =
  | 'generateTitle'
  | 'compact'
  | 'exportMarkdown'
  | 'exportJson'
  | 'remove'
  | 'toggleFavorite'
  | 'copyId'
```

Source: [ui/src/session/headless/session-actions.ts:48](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/session-actions.ts#L48)

### `SessionCacheReport`

Type.

A session's recent requests and their prompt-cache numbers (zidane's `CacheReport`).

```ts
type SessionCacheReport = NonNullable<IpcResult<'sessions.cacheReport'>>
```

Source: [ui/src/session/headless/host.ts:279](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L279)

### `SessionExportFormat`

Type.

The export formats of a transcript.

```ts
type SessionExportFormat = 'markdown' | 'json'
```

Source: [ui/src/session/headless/host.ts:282](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L282)

### `SessionLabels`

Type.

The shape of the session label dictionary. Some values are functions that build a string.

```ts
type SessionLabels = typeof DEFAULT_SESSION_LABELS
```

Source: [ui/src/session/headless/labels.ts:397](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/labels.ts#L397)

### `SessionSecretEntry`

Type.

One saved secret of a session's project, without its value: name, save time, expiry, the session that saved it.

```ts
type SessionSecretEntry = IpcResult<'secrets.list'>[number]
```

Source: [ui/src/session/headless/host.ts:190](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/host.ts#L190)

### `SideRefusal`

Type.

Why a `/side` cannot open: no conversation yet, a host without side chats there, no side panel to open.

```ts
type SideRefusal = 'no-conversation' | 'unavailable' | 'no-panel'
```

Source: [ui/src/session/headless/side.ts:8](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/side.ts#L8)

### `TodoTallyCounts`

Type.

Steps per status.

```ts
type TodoTallyCounts = Readonly<Record<TodoStatus, number>>
```

Source: [ui/src/session/headless/plans.ts:113](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/plans.ts#L113)

### `UsageRange`

Type.

The time window of a usage summary.

```ts
type UsageRange = 'all' | '30d' | '7d'
```

Source: [ui/src/session/headless/usage.ts:32](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L32)

### `UsageSummaries`

Type.

The summaries held, by range.

```ts
type UsageSummaries = Partial<Record<UsageRange, UsageSummary>>
```

Source: [ui/src/session/headless/usage.ts:122](https://github.com/Tahul/zidane/blob/main/ui/src/session/headless/usage.ts#L122)
