Follow Discord
Sweep 25 Sep 2026 · 19:33Z Build v2.1.283 504 read Stable v2.1.274 Latest v2.1.283 Next v2.1.283 Feeds RSS JSON llms.txt llms-full.txt Unofficial
Mods API · 03 of 03

Types

Every declaration in the file, verbatim, with the doc comment above it.

Declarations570over 12 pages
Mined from2.1.283the shipped binary

Every named declaration in the file, 570 of them, verbatim and in the order Claude Code wrote them, 50 to a page. This is the page to land on from a signature: a verb that returns ToolCallResult links here, at whichever page it is on, and what you get is the declaration itself rather than a description of it.

The source is 13,820 lines of TypeScript mined from build 2.1.283. Anything longer than 12 lines is folded; click the line count to open it. To find a name on another page, search every symbol.

Names on this page, 451 to 500 of 570

TurnStartInput type # line 11510

In the first published surface (2.1.259)

The input of turn.start: the prompt a model turn begins with, after prompt.submit settled the text and the UserPromptSubmit settings hooks ran.

  export type TurnStartInput = {
      /**
       * The user's text as the turn proceeds with it ("" for a turn started without
       * a typed prompt, e.g. a continuation).
       */
      text: string;
      /**
       * The turn's id, minted here; the same one every `turn.step` and the
       * `turn.complete` of this turn carry.
       */
      turnId: string;
  };

TurnStartResult type # line 11527

In the first published surface (2.1.259)

What a turn.start hook returns and what next(e) resolves to: { turnId }, echoed by core; a hook's own value does not change the turn.

  export type TurnStartResult = {
      turnId: string;
  };

TurnStepChunk type # line 11539

Added in 2.1.269

One piece of a turn.step response as it streams through the chain: what a hook's next(e) yields and what the hook yields up in turn.

Text, thinking, a tool call's start and arguments, and the stop are plain data a hook reads and rewrites; engine is the rest, passed on unread. What leaves the outermost hook is what is shown and recorded.

  export type TurnStepChunk = TurnStepTextChunk | TurnStepThinkingChunk | TurnStepToolChunk | TurnStepInputChunk | TurnStepStopChunk | TurnStepEngineChunk;

TurnStepEngineChunk type # line 11549

Added in 2.1.269

An item of the engine's stream the other chunk kinds do not model (the envelope, a block's start and end, a retry marker), opaque by ref.

Pass it on where it came. A hook that yields its own response has none to yield, and the engine supplies what the response needs around the chunks it does yield.

  export type TurnStepEngineChunk = {
      kind: 'engine';
      /**
       * The engine's handle on the item; opaque, this step's only.
       */
      ref: number;
  };

TurnStepInput type # line 11566

In the first published surface (2.1.259) · changed in 2.1.267, 2.1.269, 2.1.271

The input of turn.step: one model request inside a turn, at the moment the engine is about to send it; the bottom of the chain sends it.

The transcript is not on it: messageCount says how many messages the request carries, and $.session.messages() reads them (in a subagent's loop, $.session.messages({ agentId: e.agentId })). A hook rewrites model or effort going down; the rest is pinned.

35 lines
  export type TurnStepInput = {
      /**
       * The turn this step belongs to (`turn.start`'s id; inside a subagent's
       * loop, the id the run's `turn.complete` will carry). Pinned.
       */
      turnId: string;
      /**
       * The step's position in the turn, from 0. Pinned.
       */
      index: number;
      /**
       * Which model the request names, as the engine resolved it for this step
       * (the session's, a fallback's). `next({ ...e, model })` names another.
       */
      model: string;
      /**
       * How hard the request asks the model to think: the session's setting or
       * the model's default, absent for a model without effort; rewritable.
       */
      effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number;
      /**
       * How many messages the request carries (the conversation so far, the
       * turn's tool results included). Pinned: the messages are the engine's.
       */
      messageCount: number;
      /**
       * The loop the request is made in: a subagent's id, the `id`
       * `$.agent.list()` gives it and its `tool.call`s carry; absent on main.
       *
       * Pinned: a different value is refused, one left out is kept. A subagent
       * a hook spawned through `$.agent.spawn` steps past that hook, as its tool
       * calls do; every other hook sees its steps.
       */
      agentId?: string;
  };

TurnStepInputChunk type # line 11610

Added in 2.1.269

A piece of a tool call's arguments as they arrive: JSON text, partial, for the tool chunk of the same index.

The arguments the tool runs with are the pieces concatenated and parsed once the block ends; pieces that do not parse leave the call without arguments it can run on, as a model that wrote broken JSON would.

  export type TurnStepInputChunk = ChunkRef & {
      kind: 'input';
      index: number;
      /**
       * The next piece of the arguments' JSON text.
       */
      json: string;
  };

TurnStepResult type # line 11626

In the first published surface (2.1.259) · changed in 2.1.267, 2.1.269

What a turn.step hook returns and what next(e) resolves to: the model's response to the step's request, once its blocks are all in.

From the bottom, the response the engine streamed; a hook's own value changes what the hooks above it read, never what the engine streamed.

29 lines
  export type TurnStepResult = {
      /**
       * The turn this step belongs to, as received.
       */
      turnId: string;
      /**
       * The step's position in the turn, as received.
       */
      index: number;
      /**
       * The visible text of the response ("" when it only called tools, only
       * thought, or no request was made).
       */
      answer: string;
      /**
       * The tool calls the response made, in order; empty for a text-only step.
       */
      toolUses: readonly TurnStepToolUse[];
      /**
       * Why the model stopped; null when no response arrived (the request
       * failed or was interrupted before a message, or no request was made).
       */
      stopReason: TurnStopReason;
      /**
       * What the request cost as the API reported it, and the model that
       * answered; null when no response arrived or it carried no usage.
       */
      usage: TurnUsage | null;
  };

TurnStepStopChunk type # line 11660

Added in 2.1.269

The response is whole: why the model stopped and what the request cost, as the step's result will carry them. The last chunk of one response.

  export type TurnStepStopChunk = ChunkRef & {
      kind: 'stop';
      stopReason: TurnStopReason;
      usage: TurnUsage | null;
  };

TurnStepTextChunk type # line 11673

Added in 2.1.269

A piece of the response's visible text as it arrives, in block index.

The text the person watches stream and the text the transcript records are both the concatenation of these, in order, per block: a hook that rewrites them rewrites both, one that drops them all drops the block.

  export type TurnStepTextChunk = ChunkRef & {
      kind: 'text';
      /**
       * The content block the piece belongs to, from 0 within one response.
       */
      index: number;
      text: string;
  };

TurnStepThinkingChunk type # line 11690

Added in 2.1.269

A piece of the model's thinking as it arrives, in block index: what the person sees of it live.

The thinking block the transcript keeps is the one the model signed, as the engine received it; thinking a hook streams without the engine's block behind it is shown and not recorded.

  export type TurnStepThinkingChunk = ChunkRef & {
      kind: 'thinking';
      index: number;
      text: string;
  };

TurnStepToolChunk type # line 11703

Added in 2.1.269

The model begins a tool call in block index: the tool's name and the call's id; its arguments follow as input chunks of the same index.

A block whose tool chunk never comes out of the chain is no tool call: the engine records none and runs none.

  export type TurnStepToolChunk = ChunkRef & {
      kind: 'tool';
      index: number;
      /**
       * The call's `tool_use_id`.
       */
      id: string;
      /**
       * The tool's name (`Read`, `Bash`, `mcp__server__tool`).
       */
      name: string;
  };

TurnStepToolUse type # line 11720

In the first published surface (2.1.259)

One tool call the model asked for in a step: the tool's name and its arguments.

  export type TurnStepToolUse = {
      /**
       * The tool's name (`Read`, `Bash`, `mcp__server__tool`).
       */
      name: string;
      /**
       * The arguments the model gave it, as the tool schema shapes them.
       */
      input: unknown;
  };

TurnStopReason type # line 11735

Added in 2.1.269

Why the model stopped, as a turn.step result and its stop chunk carry it: one of the API's stop reasons, or null when no response arrived.

  type TurnStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | 'pause_turn' | 'compaction' | 'refusal' | 'model_context_window_exceeded' | null;

TurnUsage type # line 11743

Added in 2.1.267 · changed in 2.1.268, 2.1.280

What a model turn, or one response inside it, cost as the API reported it: the four token counts (ModelUsage) and the model's id.

A turn's counts are its responses' summed; its model is the last response's.

  export type TurnUsage = ModelUsage & {
      /**
       * Which model answered, by the id the API reports.
       */
      model: string;
  };

UiBlitArgs type # line 11758

Added in 2.1.271 · changed in 2.1.277

What a plugin's $.ui.blit(args) takes: a Raster's next cells (RasterBlitArgs) or a keyed Image's next source (ImageBlitArgs).

Either names an element this plugin's own ui.render hook drew, still mounted; a hook above may rewrite the cells or the source, never the address or which kind it is.

  export type UiBlitArgs = RasterBlitArgs | ImageBlitArgs;

UiBlitResult type # line 11764

Added in 2.1.271

What $.ui.blit resolves to and what a ui.blit hook's { value } holds: {} once the cells or source are the next frame's, or why not.

  export type UiBlitResult = {
      /**
       * Absent when the cells or source were taken; else why not.
       *
       * Nothing of this plugin's is mounted there (another plugin's reads so),
       * the size is not the mounted one, the cells or source are bad, or the
       * Image draws its `alt` there, the reason spelled out for a fallback.
       */
      deny?: string;
  };

UiCopyArgs type # line 11783

Added in 2.1.280

The argument of $.ui.copy and the input of ui.copy: the text, and which surface's clipboard takes it, the caller's choice.

A hook above the caller reads the same two fields: it may rewrite either with next, refuse the copy with { deny }, or answer { value } itself (a plugin whose Client runs on a remote surface can take copies for it).

16 lines
  export type UiCopyArgs = {
      /**
       * What the person pastes afterwards, verbatim: any string, newlines and
       * all; never shown on screen by the copy itself.
       */
      text: string;
      /**
       * Which surface to copy on; the caller's choice, one the session draws on:
       * a press, field or message hook passes `e.surface`.
       *
       * Left out: the first of `$.session.surfaces()`, so a hook on `ui.copy`
       * reads the target either way and a matcher narrows on it
       * (`on("ui.copy", { surface: "desktop" }, ...)`); absent: nothing draws.
       */
      surface?: RenderSurface;
  };

UiCopyResult type # line 11807

Added in 2.1.280

What $.ui.copy resolves to and what a ui.copy hook's { value } holds: whether the text reached a clipboard (isCopied), else why not.

if (!(await $.ui.copy({ text, surface: e.surface })).isCopied) warn()
28 lines
  export type UiCopyResult = {
      /**
       * True: the surface took the text; on the terminal, the machine's
       * clipboard tool where one runs, else the OSC 52 sequence written out.
       *
       * OSC 52 does not report back: a terminal that drops it, with no tool
       * on the machine (pbcopy, wl-copy, xclip, PowerShell, tmux's buffer),
       * still reads true.
       */
      isCopied: true;
  } | {
      /**
       * False: nothing was copied.
       */
      isCopied: false;
      /**
       * Why not, a closed set: `no-surface`, `no-clipboard` or `refused`; a
       * hook above answering without copying says `refused`.
       *
       * `no-surface`: nothing draws (a `-p` run, the SDK), or the named
       * surface is not attached. `no-clipboard`: it draws but the engine
       * cannot write its clipboard (a remote surface; OSC 52 past its bound).
       *
       * @example
       * on('ui.copy', { surface: 'mobile' }, () => ({ value: REFUSED }))
       */
      reason: 'no-surface' | 'no-clipboard' | 'refused';
  };

UiFocusArgs type # line 11844

Added in 2.1.271

What a plugin's $.ui.focus(args) takes: one of its own elements, by the key it drew it under, in one of its sites that holds the keyboard now.

The engine resolves it to that site's ring and raises ui.focus under the plugin's origin; the keyboard is the person's to give, so a site that does not hold it, or holds it on another plugin's element, is { deny }.

16 lines
  export type UiFocusArgs = {
      /**
       * The site, by the `requestId` this plugin draws it under: one of its
       * panes' ids, or the band's.
       */
      requestId: string;
      /**
       * The element's `key`: a `Button`, `Input` or `Select` this plugin drew in
       * that site; of several under one key, the first in document order.
       *
       * One the site's next drawing brings is waited for, bounded, except from
       * inside that drawing's own hook, which cannot wait on itself; one it
       * never draws is `{ deny }` once the wait is over.
       */
      key: string;
  };

UiFocusComponent type # line 11865

Added in 2.1.271

The render components whose site keeps a focus ring: a pane's body and the band above the prompt, each a ring over the elements hooks drew there.

  export type UiFocusComponent = 'Pane' | 'AbovePrompt';

UiFocusInput type # line 11875

Added in 2.1.271

The input of ui.focus: a site's focus ring about to move onto one of the elements a hook drew in it (a Button, Input or Select), or off them.

Every key but element is the engine's word, pinned: next(e) passes them on, a rewrite that leaves one out keeps it, one that changes it fails the hook. element is the hook's to rewrite; the ring has not moved yet.

28 lines
  export type UiFocusInput = {
      /**
       * Which site: a `Pane` body or the `AbovePrompt` band.
       */
      component: UiFocusComponent;
      /**
       * The instance the `ui.render` hook drawing the site sees: the pane's id,
       * or the band's one id.
       */
      requestId: string;
      /**
       * Whose `ui.render` hook drew the element taking the ring; absent with
       * `element`. Read-only.
       */
      plugin?: string;
      /**
       * The `key` of the element taking the ring, as `ui.press` names it; absent
       * for one of the engine's own stops (a pane's close mark or another's tab).
       *
       * `next({ ...e, element })` lands it on another element `plugin` drew in
       * the site instead; one not drawn there is core's `{ deny }`.
       */
      element?: string;
      /**
       * Who moves it (UiFocusOrigin), set by the engine where the move starts.
       */
      origin: UiFocusOrigin;
  };

UiFocusOrigin type # line 11910

Added in 2.1.271

Who moves the ring at ui.focus, as the engine stamps it where the move starts; a closed set a matcher narrows on.

next(e) passes it on as received; no hook sets one.

17 lines
  export type UiFocusOrigin = {
      /**
       * The person, by Tab, the arrows or a click while the site holds the
       * keyboard.
       */
      kind: 'person';
  } | {
      /**
       * A plugin's `$.ui.focus`, or its `autoFocus` element taking the ring
       * as the site takes the keyboard.
       */
      kind: 'plugin';
      /**
       * The focusing plugin's name.
       */
      name: string;
  };

UiFocusResult type # line 11934

Added in 2.1.271

What a ui.focus hook returns, what next(e) resolves to, and what $.ui.focus hands back: {} once the ring moved, or why it did not.

As ui.scroll spells it.

  export type UiFocusResult = {
      /**
       * Absent when the ring is where the chain left it; else why nothing
       * moved.
       *
       * A hook kept the ring (no `next`); the site is not this plugin's, does
       * not hold the keyboard, or another plugin's element holds it; no element
       * of `plugin` is drawn under `element`; another move landed first.
       */
      deny?: string;
  };

UiInputArgument type # line 11953

Added in 2.1.260 · changed in 2.1.268

The argument of ui.input: a change of, or a submit from, an Input a render hook drew. Flat and frozen like every event's.

Another plugin addresses one field by matcher: on("ui.input", { plugin: "roster", element: "reply" }, ...).

34 lines
  export type UiInputArgument = {
      /**
       * Whose `ui.render` hook drew the element.
       */
      plugin: string;
      /**
       * The `key` the hook gave its `Input`: its address, what a matcher names.
       */
      element: string;
      /**
       * The render component the element was drawn in (`AbovePrompt`,
       * `ToolUse`, ...).
       */
      component: RenderComponent;
      /**
       * The instance the element was drawn in: the `requestId` the `ui.render`
       * hook that drew it saw (a tool row's tool_use_id, a pane's id).
       */
      requestId: string;
      /**
       * Where the typing came from, one literal per member, so
       * `if (e.surface === "terminal")` narrows `e`.
       */
      surface: RenderSurface;
      /**
       * `change` after every edit of the text; `submit` on Enter.
       */
      kind: 'change' | 'submit';
      /**
       * The field's whole text at that moment; a hook above may rewrite it for
       * the plugins beneath and the element's own handler.
       */
      value: string;
  };

UiInputResult type # line 11995

Added in 2.1.260 · changed in 2.1.268

What a ui.input hook returns and what next(e) resolves to.

Beneath every hook, core runs the element's onInput (kind change) or onSubmit (kind submit) closure in its plugin's environment with the value as the chain left it, and answers { element, value }.

  export type UiInputResult = {
      /**
       * Which handler the input reached, by its Input's `key`.
       */
      element: string;
      /**
       * The text the handler received.
       */
      value: string;
  };

UiLogOptions type # line 12009

Added in 2.1.275

Options of $.ui.log.

  export type UiLogOptions = {
      /**
       * Where the line goes (UiLogSink); `transcript` when left out. A hook on
       * `ui.log` reads it as `e.to` and may send the line elsewhere.
       */
      to?: UiLogSink;
  };

UiLogSink type # line 12024

Added in 2.1.275

Where a $.ui.log line goes: transcript, a dim row of its own (and the debug log, as every line); debug, the debug log alone, nothing on screen.

The debug log is claude --debug or the --debug-file; either way the line is led by the plugin's name.

  export type UiLogSink = 'transcript' | 'debug';

UiMessageArgument type # line 12034

Added in 2.1.267

The argument of ui.message: what a Client instance's surface module posted (surface.post(data)), addressed by where the instance is drawn.

The origin is client: code sent it, on nobody's behalf, so data is input to validate, not a fact. Everything but data is the engine's word and a hook may not rewrite it.

30 lines
  export type UiMessageArgument = {
      /**
       * Where the instance is drawn: `terminal`, or `desktop` once it has them.
       */
      surface: RenderSurface;
      /**
       * The render component the `Client` was drawn in (`AbovePrompt`, `Pane`,
       * ...).
       */
      component: RenderComponent;
      /**
       * The engine's id for the drawing the `Client` sits in: the `requestId` the
       * `ui.render` hook that drew it saw.
       */
      requestId: string;
      /**
       * The `Client`'s `key`: which instance posted.
       */
      element: string;
      /**
       * The `Client`'s `module`: which surface module runs there, as its path
       * under the plugin's folder.
       */
      module: string;
      /**
       * What the instance posted: plain data (JsonValue), bounded as a tree's
       * text is; typed `unknown` since it came from code. Rewritable.
       */
      data: unknown;
  };

UiMessageResult type # line 12073

Added in 2.1.267

What a ui.message hook returns and what next(e) resolves to.

Core answers {}: the message was heard and nothing changes. A hook that answers { props } hands the posting instance its next props directly, its local state kept, with no ui.render run; the plugin's next redraw hands props again as usual.

  export type UiMessageResult = {
      /**
       * The instance's next props, plain data (JsonValue) bounded as a `Client`'s
       * props are; absent leaves the instance's props as they were.
       */
      props?: unknown;
  };

UiOpenResult type # line 12101

Added in 2.1.280

What $.ui.open resolves to and what a ui.open hook's { value } holds.

Whether a surface draws the pane now, in $.ui.panes()' word (isPlaced).

Asked (the hook of a command the person typed or a prompt they entered, a Button, Input or Select they worked; never a timer, session.start, a queued prompt, nor focus) a pane is placed at any width: docked beside a fullscreen transcript from 110 columns, else inline above the prompt. Unasked it is placed from 144 terminal columns (110 for an id the person opened from this plugin before, in this session or an earlier one, and has not closed by hand since) and waits undrawn below that, no ui.render raised, until the person opens it or the terminal widens to the floor. Where a surface seated it (dock, inline) is on the Pane render props, per surface; a plugin's tests answer with a hook beneath.

const opened = await $.ui.open({ id: "clock" })
25 lines
  export type UiOpenResult = {
      /**
       * True: the pane is open and drawn (or retitled in place); the first
       * `ui.render` for `{ component: "Pane", requestId: id }` follows.
       */
      isPlaced: true;
  } | {
      /**
       * False: the pane is open but waits undrawn: opened unasked on a narrow
       * terminal, or in a session whose attached surfaces place no panes.
       */
      isPlaced: false;
      /**
       * Why it waits and what seats it: the floor it fell under (144 columns
       * unasked, 110 for an id the person once opened) and the width now.
       *
       * Or the attached surfaces that place nothing (an older desktop); it is
       * seated when one that places panes attaches. With no terminal measured
       * and no surface attached (a bare `-p` run) this arm never comes back.
       *
       * @example
       * on('ui.open', { id }, () => ({ value: { isPlaced: false, reason } }))
       */
      reason: string;
  };

UiPane type # line 12134

Added in 2.1.275

One of this plugin's open panes as $.ui.panes() lists it: the pane's id and title, and where it stands with the person right now.

Where a surface seated it (dock or inline) is that surface's to say, on the Pane render props (placement); a session may draw on several.

27 lines
  export type UiPane = {
      /**
       * What `$.ui.open({ id })` named it, which `$.ui.close` and its
       * `ui.render` `requestId` name too.
       */
      id: string;
      /**
       * Its tab's label: the `title` of its latest open, or the id.
       */
      title: string;
      /**
       * True for the one pane the surface shows; the rest are tabs behind it.
       */
      isShown: boolean;
      /**
       * True while the person has given it the keyboard.
       */
      isFocused: boolean;
      /**
       * False while it waits undrawn: opened unasked on a terminal too narrow
       * for an unrequested pane, its `$.ui.open` answered `{ isPlaced: false }`.
       *
       * It turns true when the person opens the pane or the terminal is widened
       * to its floor (UiOpenResult `reason`).
       */
      isPlaced: boolean;
  };

UiPressArgument type # line 12169

Added in 2.1.268 · changed in 2.1.274

The argument of ui.press: a press on a Button a render hook drew, or on an answered Markdown link. Flat and frozen like every event's.

Another plugin addresses one button by matcher: on("ui.press", { plugin: "explainer", element: "explain" }, ...).

34 lines
  export type UiPressArgument = {
      /**
       * Whose `ui.render` hook drew the element.
       */
      plugin: string;
      /**
       * The `key` the hook gave its `Button` or `Markdown`: its address, what a
       * matcher names.
       */
      element: string;
      /**
       * The render component the element was drawn in (`ToolUse`,
       * `AssistantMessage`, ...).
       */
      component: RenderComponent;
      /**
       * The instance the element was drawn in: the `requestId` the `ui.render`
       * hook that drew it saw (a tool row's tool_use_id, a pane's id).
       */
      requestId: string;
      /**
       * Where the press came from, one literal per member, so
       * `if (e.surface === "terminal")` narrows `e`.
       */
      surface: RenderSurface;
      /**
       * Where the press landed, when the element is a `Markdown` whose links
       * its plugin answers (`onLinkPress`); absent for a `Button`.
       *
       * A hook may rewrite its `href` for the hooks and the closure beneath; one
       * that adds or drops it fails, and the press goes on beneath it.
       */
      link?: PressedLink;
  };

UiPressResult type # line 12211

In the first published surface (2.1.259)

What a ui.press hook returns and what next(e) resolves to.

Beneath every hook, core runs the element's onPress closure in its plugin's environment with e as the chain left it, and answers { element }.

  export type UiPressResult = {
      /**
       * Which handler the press reached, by its Button's `key`.
       */
      element: string;
  };

UiScrollArgs type # line 12226

Added in 2.1.271

What a plugin's $.ui.scroll(args) takes: what to bring into view, in which of its sites, and where in the window it lands.

The engine resolves it to a window and an offset and raises ui.scroll under the plugin's origin; a transcript row is the person's to move, so it is revealed only while the plugin answers the person's own input.

20 lines
  export type UiScrollArgs = {
      /**
       * What to reveal (UiScrollTarget): a render instance by `requestId`, one
       * of this plugin's elements by `key`, or the `start` or `end` of `in`.
       */
      to: UiScrollTarget;
      /**
       * The site to scroll, by the `requestId` this plugin draws it under: one
       * of its panes' ids, or the band's.
       *
       * Required with `start` and `end`; with `{ key }` it picks the site when
       * the key is drawn in several.
       */
      in?: string;
      /**
       * Where the target lands in the window (UiScrollBlock); `nearest` when
       * left out, so a row already showing does not move.
       */
      block?: UiScrollBlock;
  };

UiScrollBlock type # line 12256

Added in 2.1.271

Where in its scrollable a revealed row lands, as the DOM's scrollIntoView({ block }) names it.

nearest moves the least that shows the row whole, and not at all when it already shows; start, center and end put its top, middle or bottom at that edge of the window. A row taller than the window shows its top.

  export type UiScrollBlock = 'start' | 'center' | 'end' | 'nearest';

UiScrollComponent type # line 12262

Added in 2.1.271

The render components whose site the engine scrolls: a pane's body and the band above the prompt, each a window over the tree a hook drew there.

  export type UiScrollComponent = 'Pane' | 'AbovePrompt';

UiScrollInput type # line 12272

Added in 2.1.271

The input of ui.scroll: a site's window asked to move over the tree a hook drew in it (a pane's body, the band above the prompt).

Every key but offset is the engine's word, pinned: next(e) passes them on, a rewrite that leaves one out keeps it, one that changes or adds one fails the hook. offset is the hook's to rewrite; nothing moved yet.

51 lines
  export type UiScrollInput = {
      /**
       * Which site: a `Pane` body or the `AbovePrompt` band.
       */
      component: UiScrollComponent;
      /**
       * The instance the `ui.render` hook drawing the site sees: the pane's id,
       * or the band's one id.
       */
      requestId: string;
      /**
       * The first row the window is to show, 0 at the top: the row it shows
       * now plus `by`, clamped to the tree, or where `$.ui.scroll` resolved.
       *
       * `next({ ...e, offset })` moves it elsewhere (a clamp); one past the
       * tree's end lands at the end. Nothing has moved when a hook reads it.
       */
      offset: number;
      /**
       * The rows the move asks for, signed, negative toward the top; what the
       * DOM's `scrollBy` takes. Read-only.
       *
       * The person's: a wheel tick `-1` or `1` at rest, more as ticks crowd or
       * summed in flight; an arrow a row while the engine has rows to scroll, a
       * page key `bodyRows`, Home and End `contentRows`. A plugin's: its distance.
       */
      by: number;
      /**
       * How many rows of the tree the window shows at once, as drawn now.
       * Read-only.
       */
      bodyRows: number;
      /**
       * How many rows the tree has, as drawn now: the window's last offset is
       * `contentRows - bodyRows`, none when the tree fits. Read-only.
       */
      contentRows: number;
      /**
       * Who moves it (UiScrollOrigin), set by the engine where the move starts.
       */
      origin: UiScrollOrigin;
      /**
       * The body cell the person's wheel or trackpad was over (UiScrollPointer);
       * absent for the scroll keys and for `$.ui.scroll`. Read-only.
       *
       * Moves summed while a dispatch was in flight carry the latest one's. A
       * hook pinning a list over rows it scrolls itself tells a tick over the
       * list (`row` among its list's rows) from one over the body.
       */
      pointer?: UiScrollPointer;
  };

UiScrollOrigin type # line 12330

Added in 2.1.271

Who moves the window at ui.scroll, as the engine stamps it where the move starts; a closed set a matcher narrows on.

next(e) passes it on as received; no hook sets one.

16 lines
  export type UiScrollOrigin = {
      /**
       * The person, by the wheel over the site or its scroll keys while
       * they hold it.
       */
      kind: 'person';
  } | {
      /**
       * A plugin's `$.ui.scroll`.
       */
      kind: 'plugin';
      /**
       * The scrolling plugin's name.
       */
      name: string;
  };

UiScrollPointer type # line 12355

Added in 2.1.271

The cell the pointer was over when the person's wheel raised ui.scroll, in the site's body: the box its ui.render hook draws into, as painted.

The DOM's clientY - body.top in cells, the window's offset not added: a hook drawing its own window reads row as its tree's row, one the engine scrolls adds the scroll.offset it drew with. The frame lies outside.

15 lines
  export type UiScrollPointer = {
      /**
       * 0 at the body's left edge, as `bodyColumns` counts them; negative, or
       * `bodyColumns` and past, over an inline pane's side borders.
       */
      column: number;
      /**
       * 0 at the body's first showing row, as `bodyRows` counts them.
       *
       * The tree's row is `scroll.offset + row` under the engine's window, and
       * `row` itself under a hook's own (offset 0); negative over a pane's top
       * border or tab row, `bodyRows` or more over its bottom border.
       */
      row: number;
  };

UiScrollResult type # line 12375

Added in 2.1.271

What a ui.scroll hook returns, what next(e) resolves to, and what $.ui.scroll hands back: {} once the window moved, or why it did not.

  export type UiScrollResult = {
      /**
       * Absent when the window is where the chain left it; else why nothing
       * moved, as `tool.call` and `config.set` spell a refusal.
       *
       * A hook kept the window (no `next`); the target is not this plugin's;
       * another move landed first (`the window moved meanwhile`); a transcript
       * row is not the person's ask (`not person-initiated`) or none scrolls.
       */
      deny?: string;
  };

UiScrollTarget type # line 12398

Added in 2.1.271

What $.ui.scroll brings into view: never a row number, always a thing drawn somewhere.

{ requestId } names a render instance by the id its ui.render hook saw (a transcript message's, a tool row's tool_use_id), scrolled into view inside whatever scrolls it. { key } names an element this plugin drew with that key, inside the site it drew it in. start and end are the top and bottom of the site in names; end keeps up with a tree that grows (rows the plugin just added count) until anything next moves it.

  export type UiScrollTarget = {
      requestId: string;
  } | {
      key: string;
  } | 'start' | 'end';

UiSelectArgument type # line 12411

Added in 2.1.260 · changed in 2.1.268

The argument of ui.select: a pick from a Select a render hook drew. Flat and frozen like every event's.

Another plugin addresses one picker by matcher: on("ui.select", { plugin: "roster", element: "peer" }, ...).

30 lines
  export type UiSelectArgument = {
      /**
       * Whose `ui.render` hook drew the element.
       */
      plugin: string;
      /**
       * The `key` the hook gave its `Select`: its address, what a matcher names.
       */
      element: string;
      /**
       * The render component the element was drawn in (`AbovePrompt`,
       * `ToolUse`, ...).
       */
      component: RenderComponent;
      /**
       * The instance the element was drawn in: the `requestId` the `ui.render`
       * hook that drew it saw (a tool row's tool_use_id, a pane's id).
       */
      requestId: string;
      /**
       * Where the pick came from, one literal per member, so
       * `if (e.surface === "terminal")` narrows `e`.
       */
      surface: RenderSurface;
      /**
       * The picked option's value; a hook above may rewrite it for the plugins
       * beneath and the element's own handler.
       */
      value: string;
  };

UiSelectResult type # line 12449

Added in 2.1.260 · changed in 2.1.268

What a ui.select hook returns and what next(e) resolves to.

Beneath every hook, core runs the element's onSelect closure in its plugin's environment with the value as the chain left it, and answers { element, value }.

  export type UiSelectResult = {
      /**
       * Which handler the pick reached, by its Select's `key`.
       */
      element: string;
      /**
       * What the handler received: the option's value as the chain left it.
       */
      value: string;
  };

UnionToIntersection type # line 12464

In the first published surface (2.1.259)

The intersection of a union's members (A | B to A & B), by inferring one parameter type from the contravariant positions.

  type UnionToIntersection<U> = (U extends unknown ? (member: U) => void : never) extends (member: infer I) => void ? I : never;

UpdateFunction type # line 12477

Added in 2.1.281

update($, target, fn): reads the value, applies fn here in the plugin's environment, writes with ifVersion, and tries again on a miss.

What a handler closure uses in place of $.state.set(ref, stale + 1): two presses before a redraw both land. Functions do not cross to the host, so the loop lives on the plugin's side. Resolves what it wrote.

<Button key="more" onPress={() => update($, count, n => n + 1)} />
  export type UpdateFunction = {
      <T>($: StateDollar, target: Atom<T>, change: (value: T) => T): Promise<T>;
      <P extends keyof PluginState & string, K extends keyof PluginState[P] & string>($: StateDollar, target: StateRef<P, K>, change: (value: StateValue<P, K> | undefined) => StateValue<P, K>): Promise<StateValue<P, K>>;
  };

UsageUnit type # line 12486

Added in 2.1.275

One unit of what $.session.usage() answers, by its key there: the context window's fill, the rate-limit windows, the session's cost.

  export type UsageUnit = 'context' | 'rateLimits' | 'cost';

UserMessageFrom type # line 12495

Added in 2.1.274

Who sent the message a UserMessage row carries, when someone other than the person did: another agent, a teammate, another session, a channel.

Read-only. The sender's words are not the person's: the model reads them framed as that sender's whatever a hook draws for the row.

  type UserMessageFrom = {
      /**
       * The sender's name as the row shows it: a subagent's name, else its type;
       * a teammate's; another session's title; a channel's sender, else server.
       *
       * One printable line: control and format characters stripped, whitespace
       * collapsed, length bounded. Absent (no `from`) for a teammate block whose
       * frames name different senders or none.
       */
      name: string;
  };

UserMessageTask type # line 12516

Added in 2.1.274

The background task a UserMessage notification row reports on: a subagent, a background shell, a workflow, a remote agent, a monitor.

Every field is the notification's own, so the row names the same task on every draw, a resumed session's included; the session's record of it (name, type, description) is $.agent.list()'s, by id. Each string is one printable line, bounded (a forged envelope's bytes capped). Read-only.

27 lines
  type UserMessageTask = {
      /**
       * The task's id as the notification names it; for a subagent, the
       * `agentId` its `turn.complete` carried and `$.agent.list()` keys.
       */
      id?: string;
      /**
       * How the task ended: `completed`, `failed` or `killed` (stopped, by the
       * person or by Claude), or another word its producer wrote.
       */
      status?: string;
      /**
       * What kind of task, when the notification says (`remote_agent`, an
       * artifact watch's kind); a subagent's and a shell's leave it out.
       */
      type?: string;
      /**
       * Which call started the task: its `tool_use_id`, when the notification
       * carries it.
       */
      toolUseId?: string;
      /**
       * How long the task ran, in milliseconds, when the notification says; the
       * row draws it after the summary (`2m 2s`).
       */
      durationMs?: number;
  };

UserPromptExpansionHookInput type # line 12544

Added in 2.1.265

  type UserPromptExpansionHookInput = BaseHookInput & {
      hook_event_name: 'UserPromptExpansion';
      expansion_type: 'slash_command' | 'mcp_prompt';
      command_name: string;
      command_args: string;
      command_source?: string;
      prompt: string;
  };

UserPromptSubmitHookInput type # line 12553

Added in 2.1.265

  type UserPromptSubmitHookInput = BaseHookInput & {
      hook_event_name: 'UserPromptSubmit';
      prompt: string;
      /**
       * Who authored/injected the prompt: `user` = submitted from the interactive composer, `sdk` = non-interactive entrypoint (`-p` / Agent SDK), `loop_wakeup` = dynamic /loop wakeup, `schedule_wakeup` = scheduled-task fire (CronCreate/routine), `system` = other machine-injected turns (peer/channel messages, task notifications, auto-continuation), `poll_event` = the poll-event channel enqueue-time pass (the hook fires when the host submits an event, before its delivery ack exists - a blocking verdict rejects the event). Payloads may omit it while the field rolls out.
       */
      source?: 'user' | 'sdk' | 'system' | 'loop_wakeup' | 'schedule_wakeup' | 'poll_event';
      session_title?: string;
  };
Feedback