Follow Discord
Sweep 06 Nov 2026 · 01:32Z Build v2.1.319 537 read Stable v2.1.311 Latest v2.1.318 Next v2.1.319 Feeds RSS JSON llms.txt llms-full.txt Unofficial
Mods API changes

What changed, release by release.

Every release's mods API against the one before it: which nouns, verbs, events and types it added, which it removed, and which changed shape, with the lines that moved. A removal is marked breaking; a change that took something out may break a mod; one that only added to a shape is marked extended.

Releases55 since 2.1.259
Newest2.1.319+9 added · 4 removed · 3 changed · 3 docs only
Machine readablechanges.jsonin pages: counts, and each release's items

v2.1.265

+105 added · 1 removed · 22 changed · 16 docs only since 2.1.263

The engine

  • added $.command noun

    The slash commands the person can run in this session, and running one.

  • added $.command.list verb

    Returns the slash commands the person can run now, built-in, plugin and MCP alike, in the order the typeahead lists them.

  • Declares the slash command /<name> for this session, listed in the typeahead from the next keystroke on.

  • added $.command.run verb

    Runs a slash command as if the person typed /command args: the event command.run, queued and run once the session is idle.

  • added $.ui.close verb

    Closes one of the open panes; an id that is not open is left alone.

  • added $.ui.open verb

    Opens a pane: a framed region the surface places, whose body this plugin draws by hooking ui.render for { component: "Pane" }.

Events

  • added command.describe event

    Fires once per command, when the engine lists it for the typeahead and /help; next(e) resolves to { description, argumentHint, isHidden }.

  • added command.describe result

    { description, argumentHint, isHidden }.

  • added command.list event

    The argument of $.command.list().

  • added command.register event

    The argument of $.command.register(spec).

  • added command.run event

    Fires when a slash command is about to run (/name args typed, or a plugin's $.command.run); next(e) resolves to { text }, its output.

  • added command.run result

    { text } (the command's output, when it printed one).

  • added ui.close event

    The argument of $.ui.close({ id }) with origin plugin; the engine raises it too, for the header's [x] (person) and an unload (unload).

  • added ui.open event

    The argument of $.ui.open({ id, title, focus }); a hook above the opener may retitle it or refuse it with { deny }, never rename it.

Types

  • removed StarOverloads type breaking

    One call signature per event * fans out to (every event but the settings hooks' PreToolUse), intersected: an overload set from EventOf and ResultOf.

  • changed Elements type extended

    The element constructors each surface draws, by e.surface: what $.ui.resolve(e) resolves to, and what a ui.resolve hook passes on.

            Input: ElementConstructor<InputProps>;        Select: ElementConstructor<SelectProps>;        Link: ElementConstructor<LinkProps>;        Code: ElementConstructor<CodeProps>;    };    desktop: {        div: ElementConstructor<DomProps>;…        Select: ElementConstructor<SelectProps>;        Svg: ElementConstructor<SvgProps>;        Link: ElementConstructor<LinkProps>;        Code: ElementConstructor<CodeProps>;    };};
  • changed EventCalls type extended

    The events as calls on $, one signature each: $.<noun>.<event>(input) takes the event's input and resolves to its result, from either side.

        tool: {        call: ToolCallOverloads;        describe: (input: ToolDescribeInput) => Promise<ToolDescribeResult>;    };    command: {        run: (input: CommandRunArgs) => Promise<CommandRunResult>;        describe: (input: CommandDescribeInput) => Promise<CommandDescribeResult>;    };    prompt: {        submit: (input: PromptSubmitArgs) => Promise<PromptSubmitResult>;
  • changed EventOf type may break

    The argument of each event, by event name: what a hook receives as e and what the call on $ takes. Plain data, frozen to every depth.

    export type EventOf = EngineEventOf & OpEventOf;export type EventOf = CoreEventOf & NounEventOf;
  • changed HookFor type may break

    The hook type per pattern: an event's own (Events), *'s (AnyEventHook), or a glob's over the events it selects (GlobHook), as one conditional type.

    export type HookFor<E extends EventName | '*'> = E extends '*' ? AnyEventHook : Events[E & EventName];export type HookFor<P extends Pattern> = P extends '*' ? AnyEventHook : P extends EventName ? Events[P] : GlobHook<P>;
  • changed InvalidatableEventName type may break

    What $.ui.invalidate takes: a render event, or one of the four events whose answers the engine caches for the session.

    export type InvalidatableEventName = RenderEventName | 'prompt.section' | 'prompt.context' | 'tool.describe';export type InvalidatableEventName = RenderEventName | 'prompt.section' | 'prompt.context' | 'tool.describe' | 'command.describe';
  • changed JSX namespace extended
        b: DomProps & { children?: Children }    Svg: SvgProps    Link: LinkProps & { children?: Children }    Code: CodeProps    Button: {      key?: string      label?: string
  • changed KeptEvent type may break

    What next takes in a matched hook: the variants of e the matcher can match (KeptMembers), as declared, so a rewrite of a pinned field passes.

    type KeptEvent<E extends EventName | '*', M> = MatchedNames<E, M> extends infer N extends EventName ? N extends unknown ? KeptMembers<Args<N>, M> : never : never;type KeptEvent<P extends Pattern, M> = MatchedNames<P, M> extends infer N extends EventName ? N extends unknown ? KeptMembers<Args<N>, M> : never : never;
  • changed MatchedEvent type may break

    The argument a matched hook receives: e narrowed by M (Narrowed), per event the registration covers.

    export type MatchedEvent<E extends EventName | '*', M> = MatchedNames<E, M> extends infer N extends EventName ? N extends unknown ? Narrowed<Args<N>, M> : never : never;export type MatchedEvent<P extends Pattern, M> = MatchedNames<P, M> extends infer N extends EventName ? N extends unknown ? Narrowed<Args<N>, M> : never : never;
  • changed MatchedHook type may break

    The hook on(pattern, matcher, hook) takes: ($, e, next) with e narrowed by the matcher (MatchedEvent), and a tagged result the same way.

    export type MatchedHook<E extends EventName | '*', M> = ($: EngineInterface, e: MatchedEvent<E, M>, next: Next<MatchedNames<E, M>, KeptEvent<E, M>, MatchedResult<E, M>, {    [K in MatchedNames<E, M>]: Narrowed<Args<K>, M>;}>) => MatchedResult<E, M> | Promise<MatchedResult<E, M>>;export type MatchedHook<P extends Pattern, M> = ($: EngineInterface, e: MatchedEvent<P, M>, next: Next<MatchedNames<P, M>, KeptEvent<P, M>, MatchedResult<P, M>, {    [K in MatchedNames<P, M>]: Narrowed<Args<K>, M>;}>) => MatchedResult<P, M> | Promise<MatchedResult<P, M>>;
  • changed MatchedNames type may break

    The events a matched registration on P covers: the event named, or for a glob every selected event whose input has each key the matcher names.

    type MatchedNames<E, M = never> = E extends '*' ? {    [N in EventName]: [M] extends [never] ? N : keyof M extends AnyKeyOf<Args<N>> ? N : never;}[EventName] : E;type MatchedNames<P, M = never> = P extends EventName ? P : {    [N in Selected<P & string>]: [M] extends [never] ? N : keyof M extends AnyKeyOf<Args<N>> ? N : never;}[Selected<P & string>];
  • changed MatchedResult type may break

    What a matched hook returns: the event's result, narrowed by M where the result is a union tagged by the matcher's tag keys.

    export type MatchedResult<E extends EventName | '*', M> = MatchedNames<E, M> extends infer N extends EventName ? N extends unknown ? Select<EventResult<N>, Selection<Args<N>, M>> : never : never;export type MatchedResult<P extends Pattern, M> = MatchedNames<P, M> extends infer N extends EventName ? N extends unknown ? Select<EventResult<N>, Selection<Args<N>, M>> : never : never;
  • changed Next type may break

    The rest of the chain, as one hook receives it: made once per dispatch per hook, frozen; next(e) resolves to the downstream result.

        <T extends string>(e: E & ToolNamed<T>): Promise<NextResultFor<N, O, T>>;    (e: E): Promise<O>;    readonly signal: AbortSignal;    readonly is: <M extends N>(name: M, e: unknown) => e is S[M];    readonly is: <M extends PatternOver<N>>(pattern: M, e: unknown) => e is S[Extract<N, Selected<M>>];    readonly event: N;    readonly origin: string;    readonly trace: readonly TraceEntry<N, E, O>[];};
  • changed NoArgsEvent type may break

    The events whose argument is exactly NoArgs (session.cwd, a declared plugin noun's () => ...); their overloads come last (LateOverload).

    type NoArgsEvent = {    [N in OpEventName]: OpEventOf[N] extends NoArgs ? NoArgs extends OpEventOf[N] ? N : never : never;}[OpEventName];    [N in EventName]: Args<N> extends NoArgs ? NoArgs extends Args<N> ? N : never : never;}[EventName];
  • changed On type may break

    Registers hook on the events pattern selects: one by name, every one under a namespace (classic.*), all (*), or all but some (!tool.*).

    export type On = {    <E extends EventName | '*'>(event: E, hook: HookFor<E>): void;    <E extends EventName | '*', const M extends Matcher<Args<MatchedNames<E>>>>(event: E, matcher: M, hook: MatchedHook<E, M>): void;    <P extends Pattern>(pattern: P, hook: NoInfer<HookFor<P>>): void;    <P extends Pattern, const M extends Matcher<Args<MatchedNames<P>>>>(pattern: P, matcher: M, hook: NoInfer<MatchedHook<P, M>>): void;};
  • changed OpEventResult type may break

    The result of a call on $ as its event's hooks see it: { value } (the call's answer) or { deny }.

    export type OpEventResult<N extends OpEventName = OpEventName> = {    value: OpValueOf[N];    deny?: undefined;} | {    deny: string;    value?: undefined;};export type OpEventResult<N extends OpEventName = OpEventName> = ValueOrDeny<OpValueOf[N]>;
  • changed OpValueOf type extended

    What each call on $ answers (the value of its event's result), by event name.

        'tool.register': {        tool: string;    };    'command.list': CommandInfo[];    'command.register': {        command: string;    };    'agent.list': AgentInfo[];    'ui.toast': void;    'ui.status': void;    'ui.log': void;    'ui.notice': void;    'ui.invalidate': void;    'ui.open': void;    'ui.close': void;    'fs.readFile': string;    'fs.writeFile': void;    'fs.listDir': FsEntry[];
  • changed RenderAnswerOptions type may break

    How a site instance asks for its ui.render answer: the version it is on, whether a static frame is drawing, and whose submit it serves.

    export type RenderAnswerOptions = {    version: number;    version: string;    staticFrame: boolean;    submittedBy?: string;};
  • changed RenderComponent type may break

    Everything ui.render can draw: one name per component that has a render site (render-site/); a matcher narrows on it.

    export type RenderComponent = 'AskUserQuestion' | 'UserMessage' | 'AssistantMessage' | 'ToolUse' | 'ToolResult' | 'ToolGroup' | 'Spinner' | 'TurnDuration' | 'InfoNotice' | 'SessionMode' | 'PromptHint' | 'AbovePrompt';export type RenderComponent = 'AskUserQuestion' | 'UserMessage' | 'AssistantMessage' | 'ToolUse' | 'ToolResult' | 'ToolGroup' | 'Spinner' | 'TurnDuration' | 'InfoNotice' | 'SessionMode' | 'PromptHint' | 'AbovePrompt' | 'Pane';
  • changed RenderElement type extended

    What a render hook returns, and what next(e) resolves to: a plain-data tree of elements, strings allowed as children of Text and Box.

        props: LinkProps;    children?: RenderNode[];} | {    type: 'Code';    props: CodeProps;    children?: undefined;} | {    type: 'Svg';    props: SvgProps;    children?: undefined;
  • changed RenderPropsOf type extended

    The plain-data props of each renderable component, as ui.render sees them under e.props; a hook rewrites them with next({ ...e, props }).

            isWorking: boolean;        maxRows: number;    };    Pane: {        title: string;        focused: boolean;        bodyColumns: number;        scroll: PaneScroll;    };};
  • changed ResultOf type may break

    What each event's hook returns, and what its next(e) resolves to, by event name.

    export type ResultOf = EngineResultOf & {export type ResultOf = EngineResultOf & ClassicResultOf & {    [N in OpEventName]: OpEventResult<N>;} & {    [N in NounEventName]: NounEventResult<N>;};
  • changed StarNext type may break

    next in a * hook: the set of events is open at runtime, so e is unknown until next.is(pattern, e) narrows it to events it knows.

    export type StarNext = StarOverloads & {export type StarNext = OrderedOverloads<EventName> & {    (e: unknown): Promise<unknown>;    readonly signal: AbortSignal;    readonly is: <M extends EventName>(name: M, e: unknown) => e is Args<M>;    readonly is: <M extends Pattern>(pattern: M, e: unknown) => e is Args<Selected<M>>;    readonly event: EventName;    readonly origin: string;    readonly trace: readonly TraceEntry<EventName, unknown, unknown>[];};
  • added BaseHookInput type
  • added ClassicEventName type

    The name of a classic hook event as a function-hooks event: the settings hook's own name under classic (classic.Stop, classic.PreToolUse).

  • added ClassicEventOf type

    The classic (settings) hook events, one per classic event name: e is what the classic hook receives on stdin for that event.

  • added ClassicHookEvent type

    The name of a classic hook event: PreToolUse, Stop, and the rest.

  • What a classic hook receives on stdin for each event, by event name: the Agent SDK's <Event>HookInput.

  • added ClassicResult type

    Everything a classic hook event's answer can carry, named as the classic hook's JSON output names it; each event reads its subset (ClassicResultOf).

  • The event-specific fields of ClassicResult each classic event reads (its hookSpecificOutput), by event; an event absent here reads none of them.

  • added ClassicResultOf type

    What each classic hook event's hook returns and its next(e) resolves to: the event's own subset of ClassicResult.

  • added CodeProps type

    The props of Code, source text every surface draws with the engine's own highlighter: coloured tokens, a line gutter on request, or a unified diff.

  • The input of command.describe: how one slash command presents in the typeahead and /help, at the moment the engine lists it.

  • What a command.describe hook returns: the description, hint and hidden flag the menu uses, the name and immediate left where they were.

  • added CommandInfo type

    One slash command as $.command.list() returns it.

  • added CommandRunArgs type

    command.run's input as a plugin's $.command.run takes it: origin is the engine's to set (the calling plugin's name).

  • added CommandRunInput type

    The input of command.run: one slash command about to run, the way the person typed it (/name args), and where the run came from.

  • added CommandRunResult type

    What a command.run hook returns and what next(e) and $.command.run resolve to: the command's output text, when it has one.

  • added CommandSource type

    Where a slash command comes from, as $.command.list() tells them apart.

  • added CommandSpec type

    What $.command.register takes: the slash command this plugin serves.

  • added CoreEventName type

    The name of an event the engine defines itself (a key of CoreEventOf): what EVENT_NAMES lists; EventName adds the declared plugin nouns' events.

  • added CoreEventOf type

    The argument of each event the engine defines itself: its call sites' (EngineEventOf), the classic hooks' (ClassicEventOf), the calls on $.

  • Hook input for the Elicitation event. Fired when an MCP server requests user input. Hooks can auto-respond (accept/decline) instead of showing the dialog.

  • Hook input for the ElicitationResult event. Fired after the user responds to an MCP elicitation. Hooks can observe or override the response before it is sent to the server.

  • added ExitReason type
  • added Glob type

    Every event (*), or every event under a namespace (classic.*: each one whose name starts with classic.).

  • added GlobHook type

    The hook on(pattern, hook) takes for a glob or a negation: one function placed on every selected event, e and the result typed as their union.

  • added GlobNext type

    next in a hook on a glob or a negation: an overload per selected event, then one over their union for an e not yet narrowed.

  • added GlobNextResult type

    What next(e) resolves to in a glob hook before e is narrowed: the NextResult of each selected event, as a union.

  • added HookInput type
  • added LateOverload type

    The events whose overload must come after the rest, lest it shadow them.

  • Hook input for the MessageDisplay event. Fired with each batch of newly completed lines while an assistant message streams. Display-only: the stored message and what the model sees are untouched.

  • added Namespace type

    The prefixes a glob may name: one or more whole leading segments of an event name (tool of tool.call), derived, plugin nouns included.

  • added Negation type

    ! before a name or a glob: every event except the ones it selects. !* would select none, so it is no pattern.

  • added NounEvent type

    The declared plugin nouns' methods as event rows (NounEventRow), one per <noun>.<method> that is a function; a member that is not is no event.

  • added NounEventName type

    The name of a declared plugin noun's event (voice.speak).

  • added NounEventOf type

    The events of the plugin nouns declared on EngineInterface, by name: the argument of each <noun>.<method>. Empty until a plugin declares a noun.

  • added NounEventResult type

    The result of a declared plugin noun's event as its hooks see it: { value } (the method's answer) or { deny }.

  • added NounEventRow type

    One method of a declared plugin noun as an event row: its event's name, argument (the method's first parameter) and value (its awaited result).

  • added NounValueOf type

    What each declared plugin noun's method answers (the value of its event's result), by event name.

  • added OrderedOverloads type

    One call signature per event in Names, intersected, the ambiguous ones (LateOverload) after the rest: next for a hook covering several events.

  • added PaneCloseArgs type

    The argument of $.ui.close: the pane to close ({ id }). origin is the engine's to set: a plugin's call reads plugin at the hooks.

  • added PaneCloseInput type

    The input of ui.close: the pane closing and why (PaneCloseOrigin). Closing an id that is not open does nothing.

  • added PaneCloseOrigin type

    Why a pane closes, as the engine stamped it at ui.close: plugin, a plugin's $.ui.close; person, the header's [x]; unload, the engine's.

  • added PaneOpenArgs type

    The argument of $.ui.open: which pane, its title, and whether the plugin asks the person's keyboard for it.

  • added PaneScroll type

    Where a pane's body window sits over the tree a hook drew in it: the engine's to move (the person scrolls while focused), the plugin's to read.

  • added Pattern type

    What on(pattern, hook) and next.is(pattern, e) take: an event's name, a glob (*, classic.*), or a negation of either (!tool.describe).

  • added PatternOver type

    The patterns next.is takes in a hook covering the events N: their names, *, a glob over one of their namespaces, or a negation.

  • added PermissionMode type

    Permission mode for controlling how tool executions are handled. 'default' - Standard behavior, prompts for dangerous operations. 'acceptEdits' - Auto-accept file edit operations. 'bypassPermissions' - Bypass all permission checks (requires allowDangerouslySkipPermissions). 'plan' - Planning mode, no actual tool execution. 'dontAsk' - Don't prompt for permissions, deny if not pre-approved. 'auto' - Use a model classifier to approve/deny permission prompts.

  • A classic.PermissionRequest answer's decision, as the classic hook's hookSpecificOutput.decision: allow (with a rewrite or rules) or deny.

  • added PermissionUpdate type
  • The permission rules a PermissionRequest allow may add: the shape of the request's own permission_suggestions (the SDK's PermissionUpdate list).

  • added PluginNoun type

    The nouns a plugin declared on $ by merging into EngineInterface; never one the engine's own events are under (tool, flag: isPluginEventName).

  • Hook input for the PostToolBatch event. Fired once after every tool call in a batch has resolved, before the next model request. PostToolUse fires per-tool and may run concurrently for parallel tool calls; PostToolBatch fires exactly once with the full batch.

  • added Selected type

    The events a pattern selects, as a union of names: the one named, every one under a glob's namespace, or every one a negation does not exclude.

  • added SetupHookInput type
  • added StopHookInput type
  • added TraceEntry type

    One settled run of a link beneath the caller, as next.trace lists it: data, not a handle.

  • added TraceOutcome type

    What the chain decided for one link, as next.trace names it.

  • added ValueOrDeny type

    The result of a call on $ as the hooks on its event see it: { value }, the call's answer, or { deny }, the reason the caller's promise rejects.

16 docs only: reworded, same shape
  • $.fs noun

    The file system as the engine's own process reaches it, text only (UTF-8); a relative path is under the session's working directory.

  • Reads the named instruction files in every directory above the session's original working directory, the way the engine reads CLAUDE.md.

  • Returns whether the path exists; never rejects.

  • $.fs.listDir verb

    Lists a directory: { name, kind, size } per entry, by name.

  • $.fs.readFile verb

    Reads a file and returns its text. Rejects when missing.

  • $.fs.writeFile verb

    Writes text to a file, creating it and its directories as needed.

  • $.ui noun

    Display: a line under an open dialog, a redraw request, a transcript line, a pane the surface places.

  • Re-runs an event whose results the engine caches: ui.render draws the instances this plugin may draw again; the others drop the cached answers.

  • The hook on("*", hook) takes: it runs on every event, plugin nouns no declaration names included, so e is unknown and next is StarNext.

  • The props of Button, every surface's pressable leaf: an address, a label, and the closure a press runs.

  • The name of an event: a key of EventOf, the engine's own (CoreEventName) and the declared plugin nouns' (NounEventName).

  • The argument of $.fs.ancestors: the file names to look for in each directory, and the file to walk down to.

  • The decision of a classic.PreToolUse result: allow, ask, deny, or none.

  • What a classic.PreToolUse hook returns: one of allow, ask, deny, or none of them, which passes the call on to the normal permission flow.

  • One tool_result block of a user message.

  • One tool_use block of an assistant message, with its outcome once the transcript holds the call's tool_result (paired by id).

v2.1.263

No change to the surface since 2.1.261

v2.1.261

+0 added · 0 removed · 0 changed · 2 docs only since 2.1.260
2 docs only: reworded, same shape
  • Commands on the host, run as the user the session runs as. CLI only.

  • Where a render event's component is drawn: terminal is Ink, which draws the hook's whole tree; desktop is a surface that draws its own DOM.

v2.1.260

+26 added · 0 removed · 11 changed · 11 docs only since 2.1.259

The engine

  • added $.process noun

    Commands on the host, run as the user the session runs as. CLI only.

  • added $.process.run verb

    Runs a command on the host by its argument vector (no shell) and resolves { exitCode, stdout, stderr } once it exits, any exit code.

Events

  • added ui.input event

    Fires when an Input a render hook drew changes or is submitted; e is { plugin, element, component, surface, kind, value }.

  • added ui.input result

    { element, value }: the field whose handler the input reached, and the text it received.

  • added ui.select event

    Fires when a Select a render hook drew is picked from; e is { plugin, element, component, surface, value }.

  • added ui.select result

    { element, value }: the picker whose handler the pick reached, and the value it received.

Types

  • changed Elements type extended

    The element constructors each surface draws, by e.surface: what $.ui.resolve(e) resolves to, and what a ui.resolve hook passes on.

            div: ElementConstructor<DomProps>;        span: ElementConstructor<DomProps>;        b: ElementConstructor<DomProps>;        Button: ElementConstructor<ButtonProps>;        Input: ElementConstructor<InputProps>;        Select: ElementConstructor<SelectProps>;        Link: ElementConstructor<LinkProps>;    };    desktop: {        div: ElementConstructor<DomProps>;…        b: ElementConstructor<DomProps>;        Box: ElementConstructor<BoxProps>;        Text: ElementConstructor<TextProps>;        Button: ElementConstructor<ButtonProps>;        Input: ElementConstructor<InputProps>;        Select: ElementConstructor<SelectProps>;        Svg: ElementConstructor<SvgProps>;        Link: ElementConstructor<LinkProps>;    };};
  • changed EventCalls type may break

    The events as calls on $, one signature each: $.<noun>.<event>(input) takes the event's input and resolves to its result, from either side.

    export type EventCalls = {    tool: {        call: (input: ToolCallArgs) => Promise<ToolCallResult>;        call: ToolCallOverloads;        describe: (input: ToolDescribeInput) => Promise<ToolDescribeResult>;    };    prompt: {
  • changed JSX namespace extended
        span: DomProps & { children?: Children }    b: DomProps & { children?: Children }    Svg: SvgProps    Link: LinkProps & { children?: Children }    Button: {      key?: string      label?: string…      onPress: () => void      children?: string    }    Input: InputProps    Select: SelectProps  }  interface ElementChildrenAttribute {    children: unknown
  • changed Next type extended

    The rest of the chain, as one hook receives it: made once per dispatch per hook, frozen; next(e) resolves to the downstream result.

    } = {    [K in N]: Args<K>;}> = {    <T extends string>(e: E & ToolNamed<T>): Promise<NextResultFor<N, O, T>>;    (e: E): Promise<O>;    readonly signal: AbortSignal;    readonly is: <M extends N>(name: M, e: unknown) => e is S[M];
  • changed OpValueOf type extended

    What each call on $ answers (the value of its event's result), by event name.

        'store.delete': void;    'store.keys': string[];    'http.fetch': HttpResponse;    'process.run': ProcessRunResult;};
  • changed RenderElement type extended

    What a render hook returns, and what next(e) resolves to: a plain-data tree of elements, strings allowed as children of Text and Box.

            handle: number;    };} | {    type: 'Input';    props: {        key: string;        label?: string;        placeholder?: string;        value?: string;        submitLabel?: string;    };    press: {        plugin: string;        handle: number;    };    children?: undefined;} | {    type: 'Select';    props: {        key: string;        label?: string;        options: readonly SelectOption[];        value?: string;    };    press: {        plugin: string;        handle: number;    };    children?: undefined;} | {    type: 'Link';    props: LinkProps;    children?: RenderNode[];} | {    type: 'Svg';    props: SvgProps;    children?: undefined;
  • changed RenderPropsOf type extended

    The plain-data props of each renderable component, as ui.render sees them under e.props; a hook rewrites them with next({ ...e, props }).

            firstOfReply: boolean;    };    ToolUse: {        tool_use_id: string;        toolName: string;        input: unknown;        running: boolean;…        output?: unknown;    };    ToolResult: {        tool_use_id: string;        toolName: string;        output: unknown;        errored: boolean;…    AbovePrompt: {        hasSurvey: boolean;        isWorking: boolean;        maxRows: number;    };};
  • changed ToolCallResult type may break

    What a tool.call hook returns and what next(e) and $.tool.call(input) resolve to: the tool's result ({ result, context? }) or { deny }.

    export type ToolCallResult = {export type ToolCallResult<Name extends string = string> = {    deny: string;    result?: undefined;    context?: undefined;…    text?: undefined;    isError?: undefined;} | {    result: unknown;    result: ToolResultOf<Name>;    context?: readonly string[];    ref?: number;    text?: string;    isError?: true;    isError?: undefined;    deny?: undefined;} | {    isError: true;    result: unknown;    text?: string;    ref?: number;    context?: readonly string[];    deny?: undefined;};
  • changed ToolGroupCall type extended

    One tool call of a ToolGroup, as ui.render sees it under calls.

    export type ToolGroupCall = {    tool_use_id?: string;    toolName: string;    input: unknown;    running: boolean;
  • changed ToolResultSummary type extended

    One tool_result block of a user message.

        id: string;    text: string;    isError: boolean;    result?: unknown;};
  • changed ToolUseSummary type extended

    One tool_use block of an assistant message, with its outcome once the transcript holds the call's tool_result (paired by id).

        id: string;    name: string;    input: Record<string, unknown>;    result?: unknown;    text?: string;    isError?: true;};
  • added AgentCallRecord type

    What an Agent call a plugin raised ($.tool.call({ tool: "Agent", ... })) answers as result once the agent settles; text is its final answer.

  • added BuiltinToolResults interface

    The structured result of each built-in tool by name, for declaration merging; empty until a declaration file adds entries, then after e.tool === "Bash" the result of next(e) is Bash's record.

  • added ButtonProps type

    The props of Button, every surface's pressable leaf: an address, a label, and the closure a press runs.

  • added Input const

    <Input key="reply" onSubmit={text => ...} />: a one-line text field; a change and Enter raise ui.input with e.element the key, e.kind which and e.value the text.

  • added InputProps type

    The props of Input, every surface's one-line text field: an address, optional texts, and the closures a change and a submit run. A leaf.

  • added Link const

    <Link href="https://...">label</Link>: a hyperlink; an OSC-8 span on the terminal, an anchor on the desktop.

  • added LinkProps type

    The props of Link, a hyperlink both surfaces draw: an OSC 8 span on the terminal (else its text then the URL in dim), an anchor on desktop.

  • added NextResultFor type

    What next(e) resolves to once e.tool is the literal T: on tool.call the result typed for that tool; on every other event, O as declared.

  • added ProcessRunInit type

    Options of $.process.run.

  • added ProcessRunResult type

    What $.process.run resolves with once the child has exited.

  • added Select const

    <Select key="peer" options={[...]} onSelect={value => ...} />: a one-of-several picker; a pick raises ui.select with e.element the key and e.value the option's value.

  • added SelectOption type

    One option of a Select: the value onSelect and ui.select carry, and the text drawn for it (the value when absent).

  • added SelectProps type

    The props of Select, every surface's one-of-several picker: an address, a label, the options, the one selected, the closure a pick runs. A leaf.

  • $.tool.call(input): resolves with result typed for the tool input names (ToolCallResult), or loosely for an input that names none literally.

  • added ToolNamed type

    An input that names its tool as the literal T: what next and $.tool.call read to type the call's result per tool (NextResultFor).

  • added ToolResultOf type

    The structured result of the tool named Name: its BuiltinToolResults entry for a built-in tool, else unknown.

  • added UiInputArgument type

    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.

  • added UiInputResult type

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

  • added UiSelectArgument type

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

  • added UiSelectResult type

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

11 docs only: reworded, same shape
  • Fetches url through the host (never the plugin's own network) and resolves { status, ok, headers, text } once the body is read.

  • Picks one of labels for text with one completion over $.model.complete and a fixed classifier prompt.

  • Returns the transcript so far, one entry per user or assistant message; progress rows, $.ui.log lines and notices are not messages.

  • Declares a tool the model can call from the next prompt on: the name, description and input schema of mcp__<plugin>__<name>.

  • Fires once per process for each loaded plugin, before the first prompt, and again for one that loads or reloads later; next(e) is { cwd }.

  • ui.render event

    Fires when the engine is about to draw a component: once per input value (props, viewport width), plugin load or $.ui.invalidate("ui.render").

  • The input of agent.spawn (agent-spawn/): what the Agent tool decided about the subagent it is about to start, before its model is resolved.

  • A plugin's options as register(on, options) receives them: the values of the fields its manifest's userConfig declares, defaults filled in.

  • Where a prompt.submit submission came from, as the engine knows it at the site it was queued from; a closed set, never a text prefix.

  • The input of prompt.submit (prompt-submit/): the prompt as typed, after the input became a user message and before the turn starts.

  • One message of the transcript as $.session.messages() returns it.

v2.1.259

The first published surface

The first surface the pipeline mined, so nothing here is a change: 44 verbs on 14 nouns, 31 events and 186 types. A symbol whose stamp says it was in the first published surface was already here.

Feedback