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 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.

Releases22 since 2.1.259
Newest2.1.283+0 added · 0 removed · 2 changed · 2 docs only
Machine readablechanges.jsonin pages: counts, and each release's items

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