Skip to content
API reference

headless

Import
import * as api from "@fungi.computer/parakeet/headless";
Kind Export Description
type alias LoginMethodKind How a person proves they may use a provider: an API key or their subscription sign-in.
type alias LoginMethod One sign-in method a provider offers, labelled by its owner.
type alias LoginProvider One model provider in the registry. Names come from data, never code.
type alias LoginHost Where the credential will be used: the person’s machine or Fungi’s servers.
type alias LoginScope Whose credential it is: one person, or a Team.
type alias LoginPolicy The credential policy owner’s decision, the same shape as @fungi.computer/veil/model-credentials loginAllowed. Login offers only what it permits.
type alias ProviderAccess A configured provider reported by the credential owner, without secrets.
type alias AccountOwner The credential owner behind the account commands.
type alias AccountCommandOptions Contribution identity and the policy context for account commands.
type alias ModelAccountContext One account owner and its credential policy context for an interactive model picker.
type alias AdvertisedCatalogError Why one advertised catalog could not become commands.
type alias AdvertisedCommands Live commands for every catalog a Session’s extensions advertise.
type alias ParakeetBuiltinOptions The few commands every Parakeet client has, whatever the backend offers.
type alias KeyHint One key hint: the keys, what they do, and how much it matters (0 first).
type alias ComposerKeys The composer’s physical keys, which differ slightly between renderers.
type alias ComposerHintContext What the composer is doing right now.
type alias ParakeetOpenInteraction One interaction a renderer should draw as a dialog or panel.
type alias ParakeetNotice An attention item shown beside the composer until it is resolved: something failed or waits on the person. Everything else is a toast.
type alias ParakeetToast A transient message a renderer shows as a toast. A command’s confirmation of what the person just did is never one: it is an echo and is not announced.
type alias ParakeetAwaiting The decisions waiting on the person, which the composer takes over for.
type alias ParakeetInteractionState Everything a renderer draws for command conversations.
type alias ParakeetInteractions Parakeet’s command conversation store, shared by every renderer.
type alias SlashRuntime The Whistle surface a composer needs to run drafts.
type alias ParakeetCommandRuntime The Whistle runtime a Parakeet composer runs commands through.
type alias SlashCommandOptions Inputs for one composer’s command controller.
type alias SlashCommandController Everything a renderer needs to draw and drive slash commands.
type alias ParakeetSessionViewState Owner activity with the connection states shown while observation opens.
type alias ParakeetObservation Health of the current Session observation.
type alias ParakeetReconnectOutcome Result of retrying the shared Session observation.
type alias ApprovalFacts The ledger facts an approval card reads; the approvals ledger’s own view satisfies it.
type alias ApprovalReview What the host knows about a command the Agent asked to run outside the sandbox.
type alias ApprovalEntry One labelled value in a card’s facts or details.
type alias ApprovalContent The words an approval prompt carries above its choices.
type alias ApprovalCard Everything one approval shows, and what Always allow would confirm.
type alias ApprovalDecision What the person decided.
type alias ApprovalAnswerInput A decision, pinned to the revision the person saw.
type alias ApprovalAnswerResult How the owner took an answer; a refusal names its reason.
type alias ApprovalSource Where approvals come from and where answers go.
type alias ApprovalAnswered The answer was sent.
type alias ApprovalRefused The answer was refused, or could not be sent.
type alias ApprovalAbandoned The record changed or went away before an answer was sent.
type alias ApprovalOutcome How asking ended.
type alias AwaitingKind What the Agent needs from the person.
type alias AwaitingItem One decision waiting for the person. Its host is the renderer-neutral conversation that holds the current decision prompt and takes the answer.
type alias AwaitingQueue Which item the composer shows and where it stands among all of them.
type alias DecisionPrompt The decision prompt both renderers draw.
type alias DecisionPhase Where one decision is in its short life.
type alias DecisionState Everything the reducer remembers about one decision prompt.
type alias DecisionIntent What the person did, independent of which key or click did it.
type alias DecisionEffect What the owner of the decision must now do.
type alias DecisionOutcome The next state, and what the decision’s owner must do about the intent.
type alias DecisionRowView One drawn row of a decision.
type alias DecisionView What both renderers must draw for one decision.
type alias ClientContribution Decoded client data, still owned and ordered by its composition root.
type alias PlacedClientCell A committed cell retains its producer namespace in every renderer.
type alias SessionActivity Observed Session activity; header is only an attention item’s short heading.
type alias ParakeetOwnerViewState What a person’s readout of one Session says, decided from Shiitake’s raw activity facts. Shiitake publishes facts; this module owns their meaning.
type alias SessionViewFacts The facts a view state is decided from.
type alias SessionActivityStatus Coarse activity of a Session, for composer gating.
type alias SessionModelChoice A host’s maintained catalog projection; no credentials or provider execution.
type alias SessionModelCommandOptions Contribution identity, catalog and optional local model-picker presentation.
type alias ReloadSource One category a host can account for in /reload, described by the owner that already holds it. Nothing here caches, restarts or replaces anything: now re-reads through the owner’s own refresh, next_turn names a source the owner already re-reads at the start of every turn, and unsupported names a category with no safe re-read or replace lifecycle today.
type alias ReloadCommandOptions Where one /reload contribution comes from and what it can report.
type alias ParakeetSessionCommandOptions Shared Session actions with optional human presentation callbacks.
type alias DecisionController One decision being answered, ready for a renderer to draw and drive.
constant toolKindSigils Shared artwork identity for browser and native tool rows.
function loginRegistry() The providers and methods one surface may offer, in display order.
function accountCommandDefinitions() Provider-agnostic account commands. Every question and status update is a Whistle interaction, so any client that renders interactions renders login.
function contributeAccountCommands() Contribute the account commands as one lease.
function useClientActions() Ordinary advertised actions over the current admitted rows and observation.
function advertisedCommands() Turn each running extension’s advertised whistle.catalog/v1 catalog into Whistle commands that call that extension’s own door. The client names no command: a new extension’s catalog appears as new commands.
function parakeetBuiltinCommands() /help lists the live commands (built-in and advertised) and runs the one chosen; /keys does the same for key bindings; /clear empties the composer.
function composerHints() Hints for the current composer state, in display order.
function formatHints() One line of hints.
function fitHints() Keep the most important hints that fit width characters, in order.
function createParakeetInteractions() Own how commands talk to the human. An interaction opens only when it asks a question, hands off to a URL or shows progress; a command that just reports information emits a toast; ordinary success echoes are silent.
function isCancelledOutcome() Whether a handled command declined its input (for example a refused replacement).
function runSlashDraft() Run one composer draft: a prompt goes to send, a /command runs through Whistle. A grammar that asks for a request id keeps the same id across retries of the same draft until the command is handled. A slash projection can request draft consumption before dispatch, including while a dialog is open.
function useSlashCommands() The one slash-command controller behind every Parakeet composer. It owns the registry, completion, hints, execution and conversations; renderers only draw its state and forward keys.
function useParakeetSession() The Session this conversation observes.
function useExtensionSlots() Read the Session’s extension slots, including advertised command catalogs.
function useLastSessionReplyAt() Time of the last delivered watch snapshot or frame, not an SSE comment.
function useClientContributions() Presentation admitted once from the selected Session’s already observed slots.
function useParakeetInteractions() The selected Session’s ordinary command interaction owner.
function approvalCardCopy() The words of one approval. A connected tool gets its effect; a command the Agent wants to run outside the sandbox gets its folder, reason and rule. home shortens paths inside it to ~; now dates the expiry.
function approvalRefusal() What an answer was refused for, in words for the person.
function askApproval() Ask the person about one approval through a conversation’s decision prompts, then send the answer. Nothing is sent until Enter answers, Always allow and the family rule each need a second, separate confirmation whose default is Back, and an answer is only sent while the record is still the one that was shown.
function assistantMessageVisible() One rule for whether an assistant row has content either renderer shows.
function awaitingQueue() Order the items by arrival and pick the one the composer shows. A postponed item leaves the composer but stays counted: it is the footer row.
function awaitingTakeover() The item that owns the composer right now. An empty draft is taken over; a draft with text is never, unless the person asked for the decision.
function initialDecisionState() The state a decision starts in.
function reduceDecision() The one set of rules both renderers follow. Number keys only move the highlight, Enter is the only way to answer, and Esc steps back one level until it reaches the option list, where it postpones the decision.
function decisionView() Project a decision’s state into the view every renderer draws.
function decisionViewText() The plain strings a renderer must show for a view, in reading order. The lockstep tests hold every surface to this list.
function placeClientTimeline() Fixed positions and command anchors follow loaded history, never event time.
function formatWhen() When something happened, as a picker column: 14:02 for today, Yesterday, or 2026-10-24. Shared by every picker that lists past work.
function oneLine() text on one line, whitespace collapsed and cut at a word to limit.
function mergeTerminals() Preserve the first terminal for each command, in observed order.
function sessionQueryOptions() One shared TanStack observation keyed by Shiitake’s logical Session address.
function seedSessionQuery() Seed the shared observation with a bounded read before its watch mounts.
function subscribeSessionActivity() Borrow activity from the existing cache without starting another watch. An open attention item (such as an unanswered question) reports blocked ahead of working and idle; the header comes only from the question extension.
function sessionViewState() Decide a Session’s view state from its activity, terminals and progress.
function queuedSessionLabel() Explain a queued Session using its owner’s executor fact.
function sessionActivityStatus() Coarse activity for a view state: what the composer gates on.
function toolStatusTone() Shared tool status meaning, used by the browser and native presentations.
function toolCallView() Build the renderer-neutral view of one call.
function sessionModelCommandDefinitions() Describe and invoke the ordinary model-preference owner from any client.
function contributeModelCommands() Contribute one model action; owners may update its definitions through the lease.
function providerChoices() Group the existing registry or model providers without owning another catalog.
function reloadSources() Refresh what supports it and report every category honestly.
function reloadCommandDefinitions() The shared /reload definition over host-described reload sources.
function contributeReloadCommand() Contribute /reload to one Whistle host.
function contributeSessionCommands() Contribute the shared Session command vocabulary to one Whistle host.
function useApprovalAwaiting() Put one source’s pending approval in the composer’s queue. While the record is answerable and the person is present it asks through decision prompts; a changed revision replaces the item, so only the record on screen can be answered. Esc postpones it: the record stays pending in the ledger.
function useDecision() Own the answering of one waiting decision for any renderer: the reducer’s state per prompt, the answer sent to the item’s host, and the refusal that comes back. Renderers draw view and forward intents, nothing else.

LoginMethodKindtype alias

Section titled “LoginMethodKind”
Signature
type LoginMethodKind = "api_key" | "subscription";

How a person proves they may use a provider: an API key or their subscription sign-in.


LoginMethodtype alias

Section titled “LoginMethod”
Signature
type LoginMethod = Readonly<{
kind: LoginMethodKind;
label: string;
}>;

One sign-in method a provider offers, labelled by its owner.


LoginProvidertype alias

Section titled “LoginProvider”
Signature
type LoginProvider = Readonly<{
id: string;
name: string;
methods: readonly LoginMethod[];
}>;

One model provider in the registry. Names come from data, never code.


LoginHosttype alias

Section titled “LoginHost”
Signature
type LoginHost = "local" | "hosted";

Where the credential will be used: the person’s machine or Fungi’s servers.


LoginScopetype alias

Section titled “LoginScope”
Signature
type LoginScope = "user" | "team";

Whose credential it is: one person, or a Team.


LoginPolicytype alias

Section titled “LoginPolicy”
Signature
type LoginPolicy = Readonly<{
loginAllowed: (request) => boolean;
}>;

The credential policy owner’s decision, the same shape as @fungi.computer/veil/model-credentials loginAllowed. Login offers only what it permits.


ProviderAccesstype alias

Section titled “ProviderAccess”
Signature
type ProviderAccess = Readonly<{
providerId: string;
providerName: string;
type: "oauth" | "api_key";
}>;

A configured provider reported by the credential owner, without secrets.


AccountOwnertype alias

Section titled “AccountOwner”
Signature
type AccountOwner = Readonly<{
popularProviderIds: readonly string[];
access: (signal) => Promise<readonly ProviderAccess[]>;
providers: (signal) => Promise<readonly LoginProvider[]>;
login: (request, interaction) => Promise<void>;
logout: (providerId, interaction) => Promise<void>;
status: (signal) => Promise<string>;
}>;

The credential owner behind the account commands.


AccountCommandOptionstype alias

Section titled “AccountCommandOptions”
Signature
type AccountCommandOptions = Readonly<{
sourceId: string;
namespace: string;
host: LoginHost;
scope: LoginScope;
policy: LoginPolicy;
}>;

Contribution identity and the policy context for account commands.


ModelAccountContexttype alias

Section titled “ModelAccountContext”
Signature
type ModelAccountContext = Pick<
AccountCommandOptions,
"policy" | "host" | "scope"
> &
Readonly<{
owner: AccountOwner;
}>;

One account owner and its credential policy context for an interactive model picker.


AdvertisedCatalogErrortype alias

Section titled “AdvertisedCatalogError”
Signature
type AdvertisedCatalogError = Readonly<{
extensionId: string;
message: string;
}>;

Why one advertised catalog could not become commands.


AdvertisedCommandstype alias

Section titled “AdvertisedCommands”
Signature
type AdvertisedCommands = Readonly<{
update: (slots) => readonly AdvertisedCatalogError[];
dispose: () => void;
}>;

Live commands for every catalog a Session’s extensions advertise.


ParakeetBuiltinOptionstype alias

Section titled “ParakeetBuiltinOptions”
Signature
type ParakeetBuiltinOptions = Readonly<{
clear: () => void;
showCommands?: () => void | Promise<void>;
}>;

The few commands every Parakeet client has, whatever the backend offers.


Signature
type KeyHint = Readonly<{
keys: string;
label: string;
priority: number;
}>;

One key hint: the keys, what they do, and how much it matters (0 first).


ComposerKeystype alias

Section titled “ComposerKeys”
Signature
type ComposerKeys = Readonly<{
newline?: string;
scroll?: string;
queue?: string;
}>;

The composer’s physical keys, which differ slightly between renderers.


ComposerHintContexttype alias

Section titled “ComposerHintContext”
Signature
type ComposerHintContext = Readonly<{
completion: SlashCompletion;
busy: boolean;
bindings: readonly KeyBindingRow[];
keys: ComposerKeys;
}>;

What the composer is doing right now.


ParakeetOpenInteractiontype alias

Section titled “ParakeetOpenInteraction”
Signature
type ParakeetOpenInteraction = Readonly<{
key: number;
host: WhistleInteractionHost;
}>;

One interaction a renderer should draw as a dialog or panel.


ParakeetNoticetype alias

Section titled “ParakeetNotice”
Signature
type ParakeetNotice = Readonly<{
tone: "info" | "error";
message: string;
}>;

An attention item shown beside the composer until it is resolved: something failed or waits on the person. Everything else is a toast.


ParakeetToasttype alias

Section titled “ParakeetToast”
Signature
type ParakeetToast = Readonly<{
variant: "info" | "warning" | "error";
message: string;
}>;

A transient message a renderer shows as a toast. A command’s confirmation of what the person just did is never one: it is an echo and is not announced.


ParakeetAwaitingtype alias

Section titled “ParakeetAwaiting”
Signature
type ParakeetAwaiting = Readonly<{
items: readonly AwaitingItem[];
later: ReadonlySet<string>;
forced: boolean;
requests: number;
}>;

The decisions waiting on the person, which the composer takes over for.


ParakeetInteractionStatetype alias

Section titled “ParakeetInteractionState”
Signature
type ParakeetInteractionState = Readonly<{
awaiting: ParakeetAwaiting;
open?: ParakeetOpenInteraction;
inspection?: Readonly<{
entryId: string;
rowId: string;
}>;
notice?: ParakeetNotice;
}>;

Everything a renderer draws for command conversations.


ParakeetInteractionstype alias

Section titled “ParakeetInteractions”
Signature
type ParakeetInteractions = Readonly<{
snapshot: () => ParakeetInteractionState;
subscribe: (listener) => () => void;
close: () => void;
inspect: (inspection) => void;
report: (notice) => void;
toast: (toast) => void;
subscribeToasts: (listener) => () => void;
attach: (present) => () => void;
lastEnd: () => WhistleInteractionEnd["status"] | undefined;
awaiting: Readonly<{
add: (item) => () => void;
remove: (key) => void;
later: (key) => void;
focus: () => void;
}>;
}>;

Parakeet’s command conversation store, shared by every renderer.


SlashRuntimetype alias

Section titled “SlashRuntime”
Signature
type SlashRuntime = Pick<WhistleRuntime, "snapshot" | "execute">;

The Whistle surface a composer needs to run drafts.


ParakeetCommandRuntimetype alias

Section titled “ParakeetCommandRuntime”
Signature
type ParakeetCommandRuntime = Pick<
WhistleRuntime,
"contribute" | "snapshot" | "subscribe" | "execute" | "present"
>;

The Whistle runtime a Parakeet composer runs commands through.


SlashCommandOptionstype alias

Section titled “SlashCommandOptions”
Signature
type SlashCommandOptions = Readonly<{
enabled?: boolean;
commands: ParakeetCommandRuntime;
origin: WhistleExecutionOrigin;
keys: ComposerKeys;
busy: boolean;
interactionStore?: ParakeetInteractions;
showCommands?: () => void | Promise<void>;
}>;

Inputs for one composer’s command controller.


SlashCommandControllertype alias

Section titled “SlashCommandController”
Signature
type SlashCommandController = Readonly<{
completion: SlashCompletion;
open: boolean;
selected: number;
hints: readonly KeyHint[];
interactions: ParakeetInteractionState;
store: ParakeetInteractions;
awaiting: AwaitingQueue &
Readonly<{
forced: boolean;
}>;
move: (delta) => boolean;
highlight: (index) => void;
complete: () => boolean;
dismiss: () => boolean;
submit: (delivery?) => void;
choose: (index) => void;
available: (alias) => boolean;
runCommand: (alias) => void;
}>;

Everything a renderer needs to draw and drive slash commands.


ParakeetSessionViewStatetype alias

Section titled “ParakeetSessionViewState”
Signature
type ParakeetSessionViewState =
| ParakeetOwnerViewState
| Readonly<{
kind: "connecting";
}>
| Readonly<{
kind: "disconnected";
cause: string;
}>;

Owner activity with the connection states shown while observation opens.


ParakeetObservationtype alias

Section titled “ParakeetObservation”
Signature
type ParakeetObservation =
| Readonly<{
status: "connecting";
}>
| Readonly<{
status: "live";
}>
| Readonly<{
status: "unavailable";
reason: string;
}>;

Health of the current Session observation.


ParakeetReconnectOutcometype alias

Section titled “ParakeetReconnectOutcome”
Signature
type ParakeetReconnectOutcome =
| Readonly<{
kind: "nothing_to_reconnect";
state: "connected" | "connecting";
}>
| Readonly<{
kind: "reconnected";
}>
| Readonly<{
kind: "failed";
cause: string;
}>;

Result of retrying the shared Session observation.


ApprovalFactstype alias

Section titled “ApprovalFacts”
Signature
type ApprovalFacts = Readonly<{
record: Readonly<{
recordId: string;
revision: number;
requester: Readonly<{
displayName: string;
agentId: string | null;
sessionId: string | null;
principalId: string;
}>;
module: string;
operation: string;
access: string;
description: Readonly<{
inputBytes: number;
inputSha256: string;
}>;
reversibility: string;
expiresAt: number;
}>;
canAnswer: boolean;
}>;

The ledger facts an approval card reads; the approvals ledger’s own view satisfies it.


ApprovalReviewtype alias

Section titled “ApprovalReview”
Signature
type ApprovalReview = Readonly<{
command: string;
cwd: string;
justification: string;
form: "direct" | "shell";
kind: "exec" | "extension-install";
argv?: readonly string[];
prefix?: readonly string[];
warning?: string;
alwaysAllowCoverage?: string;
alwaysAllowUnavailableReason?: string;
risk?: Readonly<{
summary: string;
detail: string;
}>;
}>;

What the host knows about a command the Agent asked to run outside the sandbox.


ApprovalEntrytype alias

Section titled “ApprovalEntry”
Signature
type ApprovalEntry = Readonly<{
label: string;
value: string;
}>;

One labelled value in a card’s facts or details.


ApprovalContenttype alias

Section titled “ApprovalContent”
Signature
type ApprovalContent = Readonly<{
title: string;
summary?: string;
facts?: readonly ApprovalEntry[];
body?: string;
bodyLabel?: string;
details?: readonly ApprovalEntry[];
}>;

The words an approval prompt carries above its choices.


ApprovalCardtype alias

Section titled “ApprovalCard”
Signature
type ApprovalCard = Readonly<{
content: ApprovalContent;
always?: string;
confirmation?: ApprovalContent & object;
confirmWarning?: string;
confirmYes?: string;
}>;

Everything one approval shows, and what Always allow would confirm.


ApprovalDecisiontype alias

Section titled “ApprovalDecision”
Signature
type ApprovalDecision = "approve" | "deny" | "always-allow";

What the person decided.


ApprovalAnswerInputtype alias

Section titled “ApprovalAnswerInput”
Signature
type ApprovalAnswerInput = Readonly<{
recordId: string;
decision: ApprovalDecision;
expectedRevision: number;
denialNote?: string;
}>;

A decision, pinned to the revision the person saw.


ApprovalAnswerResulttype alias

Section titled “ApprovalAnswerResult”
Signature
type ApprovalAnswerResult = Readonly<{
kind: string;
reason?: string;
}>;

How the owner took an answer; a refusal names its reason.


ApprovalSourcetype alias

Section titled “ApprovalSource”
Signature
type ApprovalSource = Readonly<{
snapshot: () => ApprovalFacts | undefined;
subscribe: (listener) => () => void;
review?: ApprovalReview;
answer: (input) => Promise<ApprovalAnswerResult>;
family?: Readonly<{
label: string;
enable: () => Promise<boolean>;
}>;
}>;

Where approvals come from and where answers go.


ApprovalAnsweredtype alias

Section titled “ApprovalAnswered”
Signature
type ApprovalAnswered = Readonly<{
kind: "answered";
}>;

The answer was sent.


ApprovalRefusedtype alias

Section titled “ApprovalRefused”
Signature
type ApprovalRefused = Readonly<{
kind: "refused";
message: string;
}>;

The answer was refused, or could not be sent.


ApprovalAbandonedtype alias

Section titled “ApprovalAbandoned”
Signature
type ApprovalAbandoned = Readonly<{
kind: "abandoned";
}>;

The record changed or went away before an answer was sent.


ApprovalOutcometype alias

Section titled “ApprovalOutcome”
Signature
type ApprovalOutcome = ApprovalAnswered | ApprovalRefused | ApprovalAbandoned;

How asking ended.


AwaitingKindtype alias

Section titled “AwaitingKind”
Signature
type AwaitingKind = "question" | "approval";

What the Agent needs from the person.


AwaitingItemtype alias

Section titled “AwaitingItem”
Signature
type AwaitingItem = Readonly<{
key: string;
kind: AwaitingKind;
arrivedAt: number;
host: WhistleInteractionHost;
}>;

One decision waiting for the person. Its host is the renderer-neutral conversation that holds the current decision prompt and takes the answer.


AwaitingQueuetype alias

Section titled “AwaitingQueue”
Signature
type AwaitingQueue = Readonly<{
items: readonly AwaitingItem[];
current?: AwaitingItem;
position: number;
total: number;
}>;

Which item the composer shows and where it stands among all of them.


DecisionPrompttype alias

Section titled “DecisionPrompt”
Signature
type DecisionPrompt = WhistlePromptOf<"decision">;

The decision prompt both renderers draw.


DecisionPhasetype alias

Section titled “DecisionPhase”
Signature
type DecisionPhase = "choose" | "other" | "confirm" | "sending" | "refused";

Where one decision is in its short life.


DecisionStatetype alias

Section titled “DecisionState”
Signature
type DecisionState = Readonly<{
highlight: number;
toggled: ReadonlySet<string>;
other: string;
phase: DecisionPhase;
refusal?: string;
details: boolean;
}>;

Everything the reducer remembers about one decision prompt.


DecisionIntenttype alias

Section titled “DecisionIntent”
Signature
type DecisionIntent =
| Readonly<{
type: "move";
delta: -1 | 1;
}>
| Readonly<{
type: "pick";
number: number;
}>
| Readonly<{
type: "toggle";
}>
| Readonly<{
type: "type";
text: string;
}>
| Readonly<{
type: "append";
text: string;
}>
| Readonly<{
type: "enter";
}>
| Readonly<{
type: "escape";
}>
| Readonly<{
type: "details";
}>
| Readonly<{
type: "refused";
message: string;
}>;

What the person did, independent of which key or click did it.


DecisionEffecttype alias

Section titled “DecisionEffect”
Signature
type DecisionEffect =
| Readonly<{
type: "answer";
selected: string[];
text?: string;
}>
| Readonly<{
type: "later";
}>
| Readonly<{
type: "back";
}>;

What the owner of the decision must now do.


DecisionOutcometype alias

Section titled “DecisionOutcome”
Signature
type DecisionOutcome = Readonly<{
state: DecisionState;
effect?: DecisionEffect;
}>;

The next state, and what the decision’s owner must do about the intent.


DecisionRowViewtype alias

Section titled “DecisionRowView”
Signature
type DecisionRowView = Readonly<{
index: number;
kind: "option" | "other";
marker: string;
label: string;
description?: string;
recommended: boolean;
highlighted: boolean;
toggled: boolean;
destructive: boolean;
caption: string;
text: string;
}>;

One drawn row of a decision.


DecisionViewtype alias

Section titled “DecisionView”
Signature
type DecisionView = Readonly<{
kind: AwaitingKind;
label: string;
title: string;
counter?: string;
summary?: string;
facts: readonly Readonly<{
label: string;
value: string;
}>[];
body?: string;
bodyLabel?: string;
details: readonly Readonly<{
label: string;
value: string;
}>[];
detailsOpen: boolean;
rows: readonly DecisionRowView[];
other?: Readonly<{
label: string;
placeholder?: string;
text: string;
focused: boolean;
maxLength: number;
}>;
multiple: boolean;
phase: DecisionPhase;
canSend: boolean;
status?: Readonly<{
tone: "info" | "error";
text: string;
}>;
hints: readonly KeyHint[];
}>;

What both renderers must draw for one decision.


ClientContributiontype alias

Section titled “ClientContribution”
Signature
type ClientContribution = Readonly<{
entryId: string;
value: ClientContributionV1;
}>;

Decoded client data, still owned and ordered by its composition root.


PlacedClientCelltype alias

Section titled “PlacedClientCell”
Signature
type PlacedClientCell = Readonly<{
entryId: string;
cell: ClientTimelineCellV1;
}>;

A committed cell retains its producer namespace in every renderer.


SessionActivitytype alias

Section titled “SessionActivity”
Signature
type SessionActivity = Readonly<{
state: "idle" | "working" | "blocked" | "unknown";
header?: string;
}>;

Observed Session activity; header is only an attention item’s short heading.


ParakeetOwnerViewStatetype alias

Section titled “ParakeetOwnerViewState”
Signature
type ParakeetOwnerViewState =
| Readonly<{
kind: "idle" | "waiting_for_you" | "thinking" | "responding";
}>
| Readonly<{
kind: "cancelling";
}>
| Readonly<{
kind: "compacting";
trigger: SessionCompactionTrigger;
}>
| Readonly<{
kind: "queued";
queuedCommandId: string;
runningWork: AgentRunningWork | null;
}>
| Readonly<{
kind: "retrying";
attempt: number;
maxAttempts: number;
cause: string;
nextRetryAt: number;
}>
| Readonly<{
kind: "running_tool";
tool: string;
}>
| Readonly<{
kind: "error";
cause: string;
}>;

What a person’s readout of one Session says, decided from Shiitake’s raw activity facts. Shiitake publishes facts; this module owns their meaning.


SessionViewFactstype alias

Section titled “SessionViewFacts”
Signature
type SessionViewFacts = Pick<
SessionSnapshot,
"activity" | "terminals" | "progress"
>;

The facts a view state is decided from.


SessionActivityStatustype alias

Section titled “SessionActivityStatus”
Signature
type SessionActivityStatus =
"cancelling" | "idle" | "queued" | "retrying" | "streaming" | "thinking";

Coarse activity of a Session, for composer gating.


SessionModelChoicetype alias

Section titled “SessionModelChoice”
Signature
type SessionModelChoice = Readonly<{
providerId: string;
providerName: string;
id: string;
name: string;
reasoning: readonly NonNullable<ModelPreference["reasoning"]>[];
}>;

A host’s maintained catalog projection; no credentials or provider execution.


SessionModelCommandOptionstype alias

Section titled “SessionModelCommandOptions”
Signature
type SessionModelCommandOptions = Readonly<{
account: ModelAccountContext;
sourceId: string;
namespace: string;
models: readonly SessionModelChoice[];
refreshModels: (signal) => Promise<readonly SessionModelChoice[]>;
availability?: () => WhistleAvailability;
}>;

Contribution identity, catalog and optional local model-picker presentation.


ReloadSourcetype alias

Section titled “ReloadSource”
Signature
type ReloadSource = Readonly<object &
| {
effect: "now";
reload: (signal) => Promise<void>;
}
| {
effect: "next_turn";
}
| {
effect: "unsupported";
reason: string;
}>;

One category a host can account for in /reload, described by the owner that already holds it. Nothing here caches, restarts or replaces anything: now re-reads through the owner’s own refresh, next_turn names a source the owner already re-reads at the start of every turn, and unsupported names a category with no safe re-read or replace lifecycle today.


ReloadCommandOptionstype alias

Section titled “ReloadCommandOptions”
Signature
type ReloadCommandOptions = Readonly<{
sourceId: string;
namespace: string;
sources: () => readonly ReloadSource[];
}>;

Where one /reload contribution comes from and what it can report.


ParakeetSessionCommandOptionstype alias

Section titled “ParakeetSessionCommandOptions”
Signature
type ParakeetSessionCommandOptions = Readonly<{
sourceId: string;
namespace: string;
sessionResume?: () => void | Promise<void>;
sessionResumeAvailable: boolean;
onForked?: (sessionId) => void | Promise<void>;
forkAvailable: boolean;
onTitled?: (title) => void | Promise<void>;
}>;

Shared Session actions with optional human presentation callbacks.


DecisionControllertype alias

Section titled “DecisionController”
Signature
type DecisionController = Readonly<{
view: DecisionView | undefined;
dispatch: (intent) => void;
later: () => void;
}>;

One decision being answered, ready for a renderer to draw and drive.

toolKindSigilsconstant

Section titled “toolKindSigils”
Signature
const toolKindSigils: object;

Shared artwork identity for browser and native tool rows.

Name Type Default value Description
code "computer" "computer" Artwork for code execution.
command "run" "run" Artwork for shell commands.
edit "write" "write" Artwork for file edits.
other "working" "working" Artwork for other tool calls.
read "read" "read" Artwork for file reads.
search "search" "search" Artwork for search results.

loginRegistry()function

Section titled “loginRegistry()”
Signature
function loginRegistry(
providers,
options,
): readonly Readonly<{
id: string;
name: string;
methods: readonly Readonly<{
kind: LoginMethodKind;
label: string;
}>[];
}>[];

The providers and methods one surface may offer, in display order.

Parameter Type
providers readonly Readonly<{ id: string; name: string; methods: readonly Readonly<{ kind: LoginMethodKind; label: string; }>[]; }>[]
options Readonly<{ policy: LoginPolicy; host: LoginHost; scope: LoginScope; }>

readonly Readonly<{ id: string; name: string; methods: readonly Readonly<{ kind: LoginMethodKind; label: string; }>[]; }>[]


accountCommandDefinitions()function

Section titled “accountCommandDefinitions()”
Signature
function accountCommandDefinitions(owner, options): readonly Readonly<{
id: string;
title: string;
category: string;
description?: string;
projections?: {
bindings?: {
order?: number;
values: readonly string[];
};
agent?: {
keybind?: string;
order?: number;
};
help?: {
order?: number;
};
menu?: {
order?: number;
};
palette?: {
order?: number;
};
slash?: {
aliases: readonly string[];
consumesDraft?: boolean;
order?: number;
arguments?: {
hint: string;
words?: readonly ...[];
text?: {
field: ...;
arguments: ...;
requestIdField?: ...;
};
};
};
};
action?: {
inputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
outputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
presentation?: | {
type: "action";
}
| {
type: "custom";
data: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
}
| {
type: "choice";
options: readonly object[];
}
| {
type: "form";
submitLabel?: string;
}
| {
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
};
};
availability?: () => WhistleAvailability;
handler: (input) => unknown;
}>[];

Provider-agnostic account commands. Every question and status update is a Whistle interaction, so any client that renders interactions renders login.

Parameter Type
owner AccountOwner
options AccountCommandOptions

readonly Readonly<{ id: string; title: string; category: string; description?: string; projections?: { bindings?: { order?: number; values: readonly string[]; }; agent?: { keybind?: string; order?: number; }; help?: { order?: number; }; menu?: { order?: number; }; palette?: { order?: number; }; slash?: { aliases: readonly string[]; consumesDraft?: boolean; order?: number; arguments?: { hint: string; words?: readonly …[]; text?: { field: …; arguments: …; requestIdField?: …; }; }; }; }; action?: { inputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; outputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; presentation?: | { type: "action"; } | { type: "custom"; data: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; } | { type: "choice"; options: readonly object[]; } | { type: "form"; submitLabel?: string; } | { type: "confirmation"; message: string; confirmLabel?: string; cancelLabel?: string; }; }; availability?: () => WhistleAvailability; handler: (input) => unknown; }>[]


contributeAccountCommands()function

Section titled “contributeAccountCommands()”
Signature
function contributeAccountCommands(
runtime,
owner,
options,
): WhistleContributionLease;

Contribute the account commands as one lease.

Parameter Type
runtime Pick<WhistleRuntime, "contribute">
owner AccountOwner
options AccountCommandOptions

WhistleContributionLease


useClientActions()function

Section titled “useClientActions()”
Signature
function useClientActions(commands): object;

Ordinary advertised actions over the current admitted rows and observation.

Parameter Type
commands ParakeetCommandRuntime
Name Type Description
state ReadonlyMap<{ id: string; label: string; input?: { [key: string]: Json; }; awaiting?: "question"; }, Readonly<{ pending: boolean; error?: string; }>> Current Session-owned state of admitted action intents.
enabled boolean Observation is live and this Session’s action owner is attached.
execute() (entryId, action, waiting) => Promise<void> Execute an admitted intent through its owning advertised command.

advertisedCommands()function

Section titled “advertisedCommands()”
Signature
function advertisedCommands(
runtime,
session,
contributions,
onInspect?,
): AdvertisedCommands;

Turn each running extension’s advertised whistle.catalog/v1 catalog into Whistle commands that call that extension’s own door. The client names no command: a new extension’s catalog appears as new commands.

Parameter Type Description
runtime Pick<WhistleRuntime, "contribute"> -
session Pick<ParakeetSession, "extension"> -
contributions () => readonly Readonly<{ entryId: string; value: { chips: readonly object[]; panel: readonly object[]; timeline: { cells: readonly object[]; omitted: number; }; waiting: | { summary: string; cancel: { id: string; label: string; input?: { [key: string]: Json; }; awaiting?: "question"; }; } | null; }; }>[] Current admitted panels that own unanswered prompts.
onInspect? (entryId, commandId) => void -

AdvertisedCommands


parakeetBuiltinCommands()function

Section titled “parakeetBuiltinCommands()”
Signature
function parakeetBuiltinCommands(runtime, options): readonly Readonly<{
id: string;
title: string;
category: string;
description?: string;
projections?: {
bindings?: {
order?: number;
values: readonly string[];
};
agent?: {
keybind?: string;
order?: number;
};
help?: {
order?: number;
};
menu?: {
order?: number;
};
palette?: {
order?: number;
};
slash?: {
aliases: readonly string[];
consumesDraft?: boolean;
order?: number;
arguments?: {
hint: string;
words?: readonly ...[];
text?: {
field: ...;
arguments: ...;
requestIdField?: ...;
};
};
};
};
action?: {
inputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
outputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
presentation?: | {
type: "action";
}
| {
type: "custom";
data: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
}
| {
type: "choice";
options: readonly object[];
}
| {
type: "form";
submitLabel?: string;
}
| {
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
};
};
availability?: () => WhistleAvailability;
handler: (input) => unknown;
}>[];

/help lists the live commands (built-in and advertised) and runs the one chosen; /keys does the same for key bindings; /clear empties the composer.

Parameter Type
runtime Pick<WhistleRuntime, "snapshot" | "execute">
options ParakeetBuiltinOptions

readonly Readonly<{ id: string; title: string; category: string; description?: string; projections?: { bindings?: { order?: number; values: readonly string[]; }; agent?: { keybind?: string; order?: number; }; help?: { order?: number; }; menu?: { order?: number; }; palette?: { order?: number; }; slash?: { aliases: readonly string[]; consumesDraft?: boolean; order?: number; arguments?: { hint: string; words?: readonly …[]; text?: { field: …; arguments: …; requestIdField?: …; }; }; }; }; action?: { inputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; outputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; presentation?: | { type: "action"; } | { type: "custom"; data: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; } | { type: "choice"; options: readonly object[]; } | { type: "form"; submitLabel?: string; } | { type: "confirmation"; message: string; confirmLabel?: string; cancelLabel?: string; }; }; availability?: () => WhistleAvailability; handler: (input) => unknown; }>[]


composerHints()function

Section titled “composerHints()”
Signature
function composerHints(context): readonly Readonly<{
keys: string;
label: string;
priority: number;
}>[];

Hints for the current composer state, in display order.

Parameter Type
context ComposerHintContext

readonly Readonly<{ keys: string; label: string; priority: number; }>[]


formatHints()function

Section titled “formatHints()”
Signature
function formatHints(hints): string;

One line of hints.

Parameter Type
hints readonly Readonly<{ keys: string; label: string; priority: number; }>[]

string


Signature
function fitHints(
hints,
width,
): readonly Readonly<{
keys: string;
label: string;
priority: number;
}>[];

Keep the most important hints that fit width characters, in order.

Parameter Type
hints readonly Readonly<{ keys: string; label: string; priority: number; }>[]
width number

readonly Readonly<{ keys: string; label: string; priority: number; }>[]


createParakeetInteractions()function

Section titled “createParakeetInteractions()”
Signature
function createParakeetInteractions(): ParakeetInteractions;

Own how commands talk to the human. An interaction opens only when it asks a question, hands off to a URL or shows progress; a command that just reports information emits a toast; ordinary success echoes are silent.

ParakeetInteractions


isCancelledOutcome()function

Section titled “isCancelledOutcome()”
Signature
function isCancelledOutcome(outcome): boolean;

Whether a handled command declined its input (for example a refused replacement).

Parameter Type
outcome WhistleExecutionOutcome

boolean


runSlashDraft()function

Section titled “runSlashDraft()”
Signature
function runSlashDraft(
draft,
commands,
send,
origin,
consumeDraft?,
): Promise<WhistleExecutionOutcome | undefined>;

Run one composer draft: a prompt goes to send, a /command runs through Whistle. A grammar that asks for a request id keeps the same id across retries of the same draft until the command is handled. A slash projection can request draft consumption before dispatch, including while a dialog is open.

Parameter Type
draft string
commands SlashRuntime
send () => void
origin WhistleExecutionOrigin
consumeDraft? () => void

Promise<WhistleExecutionOutcome | undefined>


useSlashCommands()function

Section titled “useSlashCommands()”
Signature
function useSlashCommands(options): SlashCommandController;

The one slash-command controller behind every Parakeet composer. It owns the registry, completion, hints, execution and conversations; renderers only draw its state and forward keys.

Parameter Type
options SlashCommandOptions

SlashCommandController


useParakeetSession()function

Section titled “useParakeetSession()”
Signature
function useParakeetSession(): ParakeetSession;

The Session this conversation observes.

ParakeetSession


useExtensionSlots()function

Section titled “useExtensionSlots()”
Signature
function useExtensionSlots(): SessionExtensionSlots;

Read the Session’s extension slots, including advertised command catalogs.

SessionExtensionSlots


useLastSessionReplyAt()function

Section titled “useLastSessionReplyAt()”
Signature
function useLastSessionReplyAt(): number | undefined;

Time of the last delivered watch snapshot or frame, not an SSE comment.

number | undefined


useClientContributions()function

Section titled “useClientContributions()”
Signature
function useClientContributions(): readonly Readonly<{
entryId: string;
value: {
chips: readonly object[];
panel: readonly object[];
timeline: {
cells: readonly object[];
omitted: number;
};
waiting: {
summary: string;
cancel: {
id: string;
label: string;
input?: {
[key: string]: Json;
};
awaiting?: "question";
};
} | null;
};
}>[];

Presentation admitted once from the selected Session’s already observed slots.

readonly Readonly<{ entryId: string; value: { chips: readonly object[]; panel: readonly object[]; timeline: { cells: readonly object[]; omitted: number; }; waiting: | { summary: string; cancel: { id: string; label: string; input?: { [key: string]: Json; }; awaiting?: "question"; }; } | null; }; }>[]


useParakeetInteractions()function

Section titled “useParakeetInteractions()”
Signature
function useParakeetInteractions(): ParakeetInteractions;

The selected Session’s ordinary command interaction owner.

ParakeetInteractions


approvalCardCopy()function

Section titled “approvalCardCopy()”
Signature
function approvalCardCopy(view, review, options): ApprovalCard;

The words of one approval. A connected tool gets its effect; a command the Agent wants to run outside the sandbox gets its folder, reason and rule. home shortens paths inside it to ~; now dates the expiry.

Parameter Type
view ApprovalFacts
review | Readonly<{ command: string; cwd: string; justification: string; form: "direct" | "shell"; kind: "exec" | "extension-install"; argv?: readonly string[]; prefix?: readonly string[]; warning?: string; alwaysAllowCoverage?: string; alwaysAllowUnavailableReason?: string; risk?: Readonly<{ summary: string; detail: string; }>; }> | undefined
options Readonly<{ width: number; home: string; now: number; }>

ApprovalCard


approvalRefusal()function

Section titled “approvalRefusal()”
Signature
function approvalRefusal(reason, decision): string;

What an answer was refused for, in words for the person.

Parameter Type
reason string
decision "approve" | "deny" | "always-allow"

string


askApproval()function

Section titled “askApproval()”
Signature
function askApproval(interaction, input): Promise<ApprovalOutcome>;

Ask the person about one approval through a conversation’s decision prompts, then send the answer. Nothing is sent until Enter answers, Always allow and the family rule each need a second, separate confirmation whose default is Back, and an answer is only sent while the record is still the one that was shown.

Parameter Type
interaction WhistleInteraction
input Readonly<{ view: ApprovalFacts; source: ApprovalSource; home: string; width: number; now: number; noteLimit: number; stillCurrent: () => boolean; onFailure: (cause) => void; }>

Promise<ApprovalOutcome>


assistantMessageVisible()function

Section titled “assistantMessageVisible()”
Signature
function assistantMessageVisible(item): boolean;

One rule for whether an assistant row has content either renderer shows.

Parameter Type
item ParakeetAssistantMessageItem

boolean


awaitingQueue()function

Section titled “awaitingQueue()”
Signature
function awaitingQueue(items, later): AwaitingQueue;

Order the items by arrival and pick the one the composer shows. A postponed item leaves the composer but stays counted: it is the footer row.

Parameter Type
items readonly Readonly<{ key: string; kind: AwaitingKind; arrivedAt: number; host: WhistleInteractionHost; }>[]
later ReadonlySet<string>

AwaitingQueue


awaitingTakeover()function

Section titled “awaitingTakeover()”
Signature
function awaitingTakeover(
awaiting,
draft,
):
| Readonly<{
key: string;
kind: AwaitingKind;
arrivedAt: number;
host: WhistleInteractionHost;
}>
| undefined;

The item that owns the composer right now. An empty draft is taken over; a draft with text is never, unless the person asked for the decision.

Parameter Type
awaiting Readonly<{ items: readonly Readonly<{ key: string; kind: AwaitingKind; arrivedAt: number; host: WhistleInteractionHost; }>[]; current?: Readonly<{ key: string; kind: AwaitingKind; arrivedAt: number; host: WhistleInteractionHost; }>; position: number; total: number; }> & Readonly<{ forced: boolean; }>
draft string

| Readonly<{ key: string; kind: AwaitingKind; arrivedAt: number; host: WhistleInteractionHost; }> | undefined


initialDecisionState()function

Section titled “initialDecisionState()”
Signature
function initialDecisionState(): DecisionState;

The state a decision starts in.

DecisionState


reduceDecision()function

Section titled “reduceDecision()”
Signature
function reduceDecision(state, intent, prompt): DecisionOutcome;

The one set of rules both renderers follow. Number keys only move the highlight, Enter is the only way to answer, and Esc steps back one level until it reaches the option list, where it postpones the decision.

Parameter Type
state DecisionState
intent DecisionIntent
prompt object & object

DecisionOutcome


decisionView()function

Section titled “decisionView()”
Signature
function decisionView(state, prompt, context): DecisionView;

Project a decision’s state into the view every renderer draws.

Parameter Type
state DecisionState
prompt object & object
context Readonly<{ kind: AwaitingKind; position: number; total: number; }>

DecisionView


decisionViewText()function

Section titled “decisionViewText()”
Signature
function decisionViewText(view): readonly string[];

The plain strings a renderer must show for a view, in reading order. The lockstep tests hold every surface to this list.

Parameter Type
view DecisionView

readonly string[]


placeClientTimeline()function

Section titled “placeClientTimeline()”
Signature
function placeClientTimeline(entries, anchors, positions?): object;

Fixed positions and command anchors follow loaded history, never event time.

Parameter Type
entries readonly Readonly<{ entryId: string; value: { chips: readonly object[]; panel: readonly object[]; timeline: { cells: readonly object[]; omitted: number; }; waiting: | { summary: string; cancel: { id: string; label: string; input?: { [key: string]: Json; }; awaiting?: "question"; }; } | null; }; }>[]
anchors ReadonlyMap<string, string>
positions ReadonlyMap<number, string | null>
Name Type Description
before Readonly<{ entryId: string; cell: { id: string; sequence: number; at: number; commandId: string | null; afterSequence?: number; rows: readonly object[]; }; }>[] Events before the first visible row of the root history page.
after Map<string, Readonly<{ entryId: string; cell: { id: string; sequence: number; at: number; commandId: string | null; afterSequence?: number; rows: readonly object[]; }; }>[]> Loaded durable row IDs mapped to their following committed events.
unanchored Readonly<{ entryId: string; cell: { id: string; sequence: number; at: number; commandId: string | null; afterSequence?: number; rows: readonly object[]; }; }>[] Null-anchor events for the separate Extension changes section.
omitted object[] Factual producer retention counts, independent of loaded message pages.

formatWhen()function

Section titled “formatWhen()”
Signature
function formatWhen(epochMillis, now): string;

When something happened, as a picker column: 14:02 for today, Yesterday, or 2026-10-24. Shared by every picker that lists past work.

Parameter Type
epochMillis number
now number

string


Signature
function oneLine(text, limit): string;

text on one line, whitespace collapsed and cut at a word to limit.

Parameter Type
text string
limit number

string


mergeTerminals()function

Section titled “mergeTerminals()”
Signature
function mergeTerminals(
current,
incoming,
): readonly Readonly<{
commandId: string;
outcome: "failed" | "cancelled" | "completed" | "interrupted";
sequence: number;
diagnostic: string | null;
meta?: Json;
}>[];

Preserve the first terminal for each command, in observed order.

Parameter Type
current readonly Readonly<{ commandId: string; outcome: "failed" | "cancelled" | "completed" | "interrupted"; sequence: number; diagnostic: string | null; meta?: Json; }>[]
incoming readonly Readonly<{ commandId: string; outcome: "failed" | "cancelled" | "completed" | "interrupted"; sequence: number; diagnostic: string | null; meta?: Json; }>[]

readonly Readonly<{ commandId: string; outcome: "failed" | "cancelled" | "completed" | "interrupted"; sequence: number; diagnostic: string | null; meta?: Json; }>[]


sessionQueryOptions()function

Section titled “sessionQueryOptions()”
Signature
function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
observation: "connecting" | "live";
snapshot: | Readonly<{
sessionId: string;
cursor: string | null;
hasMore: boolean;
oldestCursor?: string | null;
messages: readonly Readonly<{
requestId?: ...;
meta?: ...;
data?: ...;
origin?: ...;
id: ...;
sequence: ...;
commandId: ...;
value: ...;
}>[];
terminals: readonly Readonly<{
commandId: ...;
outcome: ...;
sequence: ...;
diagnostic: ...;
meta?: ...;
}>[];
compactions?: readonly Readonly<...>[];
compactionNotices?: readonly Readonly<...>[];
sandboxFailures?: readonly object[];
pending: SessionPendingPrompts;
activity: SessionActivity;
progress: | Readonly<{
messageId: ...;
revision: ...;
text: ...;
thinking: ...;
textTruncated: ...;
thinkingTruncated: ...;
}>
| null;
toolOutput: readonly Readonly<{
toolCallId: ...;
revision: ...;
tail: ...;
droppedBytes: ...;
totalBytes: ...;
}>[];
extensions: SessionExtensionSlots;
attention: readonly object[];
context?: Readonly<{
tokens: ...;
window: ...;
}>;
}>
| undefined;
lastReplyAt: number | undefined;
latestPrompt: | Readonly<{
commandId: string;
text: string;
images: readonly object[] | undefined;
}>
| undefined;
}>, Error, Readonly<{
observation: "connecting" | "live";
snapshot: | Readonly<{
sessionId: string;
cursor: string | null;
hasMore: boolean;
oldestCursor?: string | null;
messages: readonly Readonly<{
requestId?: ...;
meta?: ...;
data?: ...;
origin?: ...;
id: ...;
sequence: ...;
commandId: ...;
value: ...;
}>[];
terminals: readonly Readonly<{
commandId: ...;
outcome: ...;
sequence: ...;
diagnostic: ...;
meta?: ...;
}>[];
compactions?: readonly Readonly<...>[];
compactionNotices?: readonly Readonly<...>[];
sandboxFailures?: readonly object[];
pending: SessionPendingPrompts;
activity: SessionActivity;
progress: | Readonly<{
messageId: ...;
revision: ...;
text: ...;
thinking: ...;
textTruncated: ...;
thinkingTruncated: ...;
}>
| null;
toolOutput: readonly Readonly<{
toolCallId: ...;
revision: ...;
tail: ...;
droppedBytes: ...;
totalBytes: ...;
}>[];
extensions: SessionExtensionSlots;
attention: readonly object[];
context?: Readonly<{
tokens: ...;
window: ...;
}>;
}>
| undefined;
lastReplyAt: number | undefined;
latestPrompt: | Readonly<{
commandId: string;
text: string;
images: readonly object[] | undefined;
}>
| undefined;
}>, readonly ["shiitake-session", string]>, "queryFn"> & object & QueryKeyWithDataTag<readonly ["shiitake-session", string], Readonly<{
observation: "connecting" | "live";
snapshot: | Readonly<{
sessionId: string;
cursor: string | null;
hasMore: boolean;
oldestCursor?: string | null;
messages: readonly Readonly<{
requestId?: ... | ...;
meta?: ... | ...;
data?: ... | ...;
origin?: ... | ...;
id: string;
sequence: number;
commandId: ... | ...;
value: ModelMessage;
}>[];
terminals: readonly Readonly<{
commandId: string;
outcome: ... | ... | ... | ...;
sequence: number;
diagnostic: ... | ...;
meta?: ... | ...;
}>[];
compactions?: readonly Readonly<{
id: ...;
sequence: ...;
at: ...;
tokensBefore: ...;
tokensAfter: ...;
trigger: ...;
}>[];
compactionNotices?: readonly Readonly<{
id: ...;
sequence: ...;
at: ...;
trigger: ...;
result: ...;
diagnostic: ...;
}>[];
sandboxFailures?: readonly object[];
pending: SessionPendingPrompts;
activity: SessionActivity;
progress: | Readonly<{
messageId: string;
revision: number;
text: string;
thinking: string;
textTruncated: boolean;
thinkingTruncated: boolean;
}>
| null;
toolOutput: readonly Readonly<{
toolCallId: string;
revision: number;
tail: string;
droppedBytes: number;
totalBytes: number;
}>[];
extensions: SessionExtensionSlots;
attention: readonly object[];
context?: Readonly<{
tokens: number;
window: ... | ...;
}>;
}>
| undefined;
lastReplyAt: number | undefined;
latestPrompt: | Readonly<{
commandId: string;
text: string;
images: readonly object[] | undefined;
}>
| undefined;
}>, Error>;

One shared TanStack observation keyed by Shiitake’s logical Session address.

Parameter Type
session ParakeetSession

OmitKeyof<UseQueryOptions<Readonly<{ observation: "connecting" | "live"; snapshot: | Readonly<{ sessionId: string; cursor: string | null; hasMore: boolean; oldestCursor?: string | null; messages: readonly Readonly<{ requestId?: …; meta?: …; data?: …; origin?: …; id: …; sequence: …; commandId: …; value: …; }>[]; terminals: readonly Readonly<{ commandId: …; outcome: …; sequence: …; diagnostic: …; meta?: …; }>[]; compactions?: readonly Readonly<…>[]; compactionNotices?: readonly Readonly<…>[]; sandboxFailures?: readonly object[]; pending: SessionPendingPrompts; activity: SessionActivity; progress: | Readonly<{ messageId: …; revision: …; text: …; thinking: …; textTruncated: …; thinkingTruncated: …; }> | null; toolOutput: readonly Readonly<{ toolCallId: …; revision: …; tail: …; droppedBytes: …; totalBytes: …; }>[]; extensions: SessionExtensionSlots; attention: readonly object[]; context?: Readonly<{ tokens: …; window: …; }>; }> | undefined; lastReplyAt: number | undefined; latestPrompt: | Readonly<{ commandId: string; text: string; images: readonly object[] | undefined; }> | undefined; }>, Error, Readonly<{ observation: "connecting" | "live"; snapshot: | Readonly<{ sessionId: string; cursor: string | null; hasMore: boolean; oldestCursor?: string | null; messages: readonly Readonly<{ requestId?: …; meta?: …; data?: …; origin?: …; id: …; sequence: …; commandId: …; value: …; }>[]; terminals: readonly Readonly<{ commandId: …; outcome: …; sequence: …; diagnostic: …; meta?: …; }>[]; compactions?: readonly Readonly<…>[]; compactionNotices?: readonly Readonly<…>[]; sandboxFailures?: readonly object[]; pending: SessionPendingPrompts; activity: SessionActivity; progress: | Readonly<{ messageId: …; revision: …; text: …; thinking: …; textTruncated: …; thinkingTruncated: …; }> | null; toolOutput: readonly Readonly<{ toolCallId: …; revision: …; tail: …; droppedBytes: …; totalBytes: …; }>[]; extensions: SessionExtensionSlots; attention: readonly object[]; context?: Readonly<{ tokens: …; window: …; }>; }> | undefined; lastReplyAt: number | undefined; latestPrompt: | Readonly<{ commandId: string; text: string; images: readonly object[] | undefined; }> | undefined; }>, readonly ["shiitake-session", string]>, "queryFn"> & object & QueryKeyWithDataTag<readonly ["shiitake-session", string], Readonly<{ observation: "connecting" | "live"; snapshot: | Readonly<{ sessionId: string; cursor: string | null; hasMore: boolean; oldestCursor?: string | null; messages: readonly Readonly<{ requestId?: … | …; meta?: … | …; data?: … | …; origin?: … | …; id: string; sequence: number; commandId: … | …; value: ModelMessage; }>[]; terminals: readonly Readonly<{ commandId: string; outcome: … | … | … | …; sequence: number; diagnostic: … | …; meta?: … | …; }>[]; compactions?: readonly Readonly<{ id: …; sequence: …; at: …; tokensBefore: …; tokensAfter: …; trigger: …; }>[]; compactionNotices?: readonly Readonly<{ id: …; sequence: …; at: …; trigger: …; result: …; diagnostic: …; }>[]; sandboxFailures?: readonly object[]; pending: SessionPendingPrompts; activity: SessionActivity; progress: | Readonly<{ messageId: string; revision: number; text: string; thinking: string; textTruncated: boolean; thinkingTruncated: boolean; }> | null; toolOutput: readonly Readonly<{ toolCallId: string; revision: number; tail: string; droppedBytes: number; totalBytes: number; }>[]; extensions: SessionExtensionSlots; attention: readonly object[]; context?: Readonly<{ tokens: number; window: … | …; }>; }> | undefined; lastReplyAt: number | undefined; latestPrompt: | Readonly<{ commandId: string; text: string; images: readonly object[] | undefined; }> | undefined; }>, Error>


seedSessionQuery()function

Section titled “seedSessionQuery()”
Signature
function seedSessionQuery(queryClient, session, snapshot): void;

Seed the shared observation with a bounded read before its watch mounts.

Parameter Type
queryClient QueryClient
session ParakeetSession
snapshot SessionSnapshot

void


subscribeSessionActivity()function

Section titled “subscribeSessionActivity()”
Signature
function subscribeSessionActivity(
queryClient,
session,
listener,
questionExtensionId,
): () => void;

Borrow activity from the existing cache without starting another watch. An open attention item (such as an unanswered question) reports blocked ahead of working and idle; the header comes only from the question extension.

Parameter Type
queryClient QueryClient
session ParakeetSession
listener (activity) => void
questionExtensionId string | undefined

() => void


sessionViewState()function

Section titled “sessionViewState()”
Signature
function sessionViewState(facts): ParakeetOwnerViewState;

Decide a Session’s view state from its activity, terminals and progress.

Parameter Type
facts SessionViewFacts

ParakeetOwnerViewState


queuedSessionLabel()function

Section titled “queuedSessionLabel()”
Signature
function queuedSessionLabel(state): string;

Explain a queued Session using its owner’s executor fact.

Parameter Type
state Extract<ParakeetOwnerViewState, { kind: "queued"; }>

string


sessionActivityStatus()function

Section titled “sessionActivityStatus()”
Signature
function sessionActivityStatus(view): SessionActivityStatus;

Coarse activity for a view state: what the composer gates on.

Parameter Type
view ParakeetOwnerViewState

SessionActivityStatus


toolStatusTone()function

Section titled “toolStatusTone()”
Signature
function toolStatusTone(status): "error" | "success" | "info" | "neutral";

Shared tool status meaning, used by the browser and native presentations.

Parameter Type
status "error" | "unknown" | "running" | "completed"

"error" | "success" | "info" | "neutral"


toolCallView()function

Section titled “toolCallView()”
Signature
function toolCallView(item): ParakeetToolCallView;

Build the renderer-neutral view of one call.

Parameter Type
item ParakeetToolItem

ParakeetToolCallView


sessionModelCommandDefinitions()function

Section titled “sessionModelCommandDefinitions()”
Signature
function sessionModelCommandDefinitions(session, options): readonly Readonly<{
id: string;
title: string;
category: string;
description?: string;
projections?: {
bindings?: {
order?: number;
values: readonly string[];
};
agent?: {
keybind?: string;
order?: number;
};
help?: {
order?: number;
};
menu?: {
order?: number;
};
palette?: {
order?: number;
};
slash?: {
aliases: readonly string[];
consumesDraft?: boolean;
order?: number;
arguments?: {
hint: string;
words?: readonly ...[];
text?: {
field: ...;
arguments: ...;
requestIdField?: ...;
};
};
};
};
action?: {
inputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
outputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
presentation?: | {
type: "action";
}
| {
type: "custom";
data: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
}
| {
type: "choice";
options: readonly object[];
}
| {
type: "form";
submitLabel?: string;
}
| {
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
};
};
availability?: () => WhistleAvailability;
handler: (input) => unknown;
}>[];

Describe and invoke the ordinary model-preference owner from any client.

Parameter Type
session ModelPreferenceOwner
options SessionModelCommandOptions

readonly Readonly<{ id: string; title: string; category: string; description?: string; projections?: { bindings?: { order?: number; values: readonly string[]; }; agent?: { keybind?: string; order?: number; }; help?: { order?: number; }; menu?: { order?: number; }; palette?: { order?: number; }; slash?: { aliases: readonly string[]; consumesDraft?: boolean; order?: number; arguments?: { hint: string; words?: readonly …[]; text?: { field: …; arguments: …; requestIdField?: …; }; }; }; }; action?: { inputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; outputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; presentation?: | { type: "action"; } | { type: "custom"; data: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; } | { type: "choice"; options: readonly object[]; } | { type: "form"; submitLabel?: string; } | { type: "confirmation"; message: string; confirmLabel?: string; cancelLabel?: string; }; }; availability?: () => WhistleAvailability; handler: (input) => unknown; }>[]


contributeModelCommands()function

Section titled “contributeModelCommands()”
Signature
function contributeModelCommands(
commands,
session,
options,
): Readonly<{
update: (commands) => void;
dispose: () => void;
}>;

Contribute one model action; owners may update its definitions through the lease.

Parameter Type
commands Pick<WhistleRuntime, "contribute">
session ModelPreferenceOwner
options SessionModelCommandOptions

Readonly<{ update: (commands) => void; dispose: () => void; }>


providerChoices()function

Section titled “providerChoices()”
Signature
function providerChoices(
providers,
access,
popularProviderIds,
screen,
): readonly object[];

Group the existing registry or model providers without owning another catalog.

Parameter Type
providers readonly Readonly<{ id: string; name: string; methods: readonly Readonly<{ kind: LoginMethodKind; label: string; }>[]; }>[]
access readonly Readonly<{ providerId: string; providerName: string; type: "oauth" | "api_key"; }>[]
popularProviderIds readonly string[]
screen "login" | "model"

readonly object[]


reloadSources()function

Section titled “reloadSources()”
Signature
function reloadSources(sources, signal): Promise<string>;

Refresh what supports it and report every category honestly.

Parameter Type
sources readonly ReloadSource[]
signal AbortSignal

Promise<string>


reloadCommandDefinitions()function

Section titled “reloadCommandDefinitions()”
Signature
function reloadCommandDefinitions(options): readonly Readonly<{
id: string;
title: string;
category: string;
description?: string;
projections?: {
bindings?: {
order?: number;
values: readonly string[];
};
agent?: {
keybind?: string;
order?: number;
};
help?: {
order?: number;
};
menu?: {
order?: number;
};
palette?: {
order?: number;
};
slash?: {
aliases: readonly string[];
consumesDraft?: boolean;
order?: number;
arguments?: {
hint: string;
words?: readonly ...[];
text?: {
field: ...;
arguments: ...;
requestIdField?: ...;
};
};
};
};
action?: {
inputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
outputSchema?: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
presentation?: | {
type: "action";
}
| {
type: "custom";
data: {
[key: string]:
| string
| number
| boolean
| readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...[]
| {
[key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | ... 4 more ... | null)[] | { ...; } | null)[] | { ...; } | null)[] | { ...; } | ...;
}
| null;
};
}
| {
type: "choice";
options: readonly object[];
}
| {
type: "form";
submitLabel?: string;
}
| {
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
};
};
availability?: () => WhistleAvailability;
handler: (input) => unknown;
}>[];

The shared /reload definition over host-described reload sources.

Parameter Type
options Pick<ReloadCommandOptions, "sources">

readonly Readonly<{ id: string; title: string; category: string; description?: string; projections?: { bindings?: { order?: number; values: readonly string[]; }; agent?: { keybind?: string; order?: number; }; help?: { order?: number; }; menu?: { order?: number; }; palette?: { order?: number; }; slash?: { aliases: readonly string[]; consumesDraft?: boolean; order?: number; arguments?: { hint: string; words?: readonly …[]; text?: { field: …; arguments: …; requestIdField?: …; }; }; }; }; action?: { inputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; outputSchema?: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; presentation?: | { type: "action"; } | { type: "custom"; data: { [key: string]: | string | number | boolean | readonly string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …[] | { [key: string]: string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | … 4 more … | null)[] | { …; } | null)[] | { …; } | null)[] | { …; } | …; } | null; }; } | { type: "choice"; options: readonly object[]; } | { type: "form"; submitLabel?: string; } | { type: "confirmation"; message: string; confirmLabel?: string; cancelLabel?: string; }; }; availability?: () => WhistleAvailability; handler: (input) => unknown; }>[]


contributeReloadCommand()function

Section titled “contributeReloadCommand()”
Signature
function contributeReloadCommand(
commands,
options,
): Readonly<{
update: (commands) => void;
dispose: () => void;
}>;

Contribute /reload to one Whistle host.

Parameter Type
commands Pick<WhistleRuntime, "contribute">
options ReloadCommandOptions

Readonly<{ update: (commands) => void; dispose: () => void; }>


contributeSessionCommands()function

Section titled “contributeSessionCommands()”
Signature
function contributeSessionCommands(
commands,
session,
options,
): Readonly<{
update: (commands) => void;
dispose: () => void;
}>;

Contribute the shared Session command vocabulary to one Whistle host.

Parameter Type
commands Pick<SessionCommandRuntime, "contribute">
session SessionCommandSession
options ParakeetSessionCommandOptions

Readonly<{ update: (commands) => void; dispose: () => void; }>


useApprovalAwaiting()function

Section titled “useApprovalAwaiting()”
Signature
function useApprovalAwaiting(options): void;

Put one source’s pending approval in the composer’s queue. While the record is answerable and the person is present it asks through decision prompts; a changed revision replaces the item, so only the record on screen can be answered. Esc postpones it: the record stays pending in the ledger.

Parameter Type
options Readonly<{ source: ApprovalSource | undefined; store: ParakeetInteractions; enabled: boolean; home: string; width: number; noteLimit: number; onFailure: (cause) => void; }>

void


useDecision()function

Section titled “useDecision()”
Signature
function useDecision(item, context): DecisionController;

Own the answering of one waiting decision for any renderer: the reducer’s state per prompt, the answer sent to the item’s host, and the refusal that comes back. Renderers draw view and forward intents, nothing else.

Parameter Type
item AwaitingItem
context Readonly<{ position: number; total: number; later: () => void; }>

DecisionController

Re-exports formatModelIdentity


Re-exports formatModelWithLevel


Re-exports QueuedRecallState


Re-exports QueuedRecallOutcome


Re-exports ParakeetDraftIdentity


Re-exports ParakeetDraftStorage


Re-exports formatContextUsage


Re-exports formatTokenCount


Re-exports ParakeetProvider


Re-exports useComposer


Re-exports useStatus


Re-exports useTimeline


Re-exports ComposerController


Re-exports ParakeetDraftCheckpoint


Re-exports ParakeetModel


Re-exports ParakeetStatus


Re-exports ParakeetUsage


Re-exports StatusController


Re-exports TimelineController


Re-exports completeSlash


Re-exports fuzzyMatch


Re-exports keyBindings


Re-exports keyLabel


Re-exports parseSlashDraft


Re-exports slashRegistry


Re-exports FuzzyMatch


Re-exports KeyBindingRow


Re-exports SlashCommand


Re-exports SlashCommandItem


Re-exports SlashCompletion


Re-exports SlashParse


Re-exports SlashWordItem


Re-exports ParakeetSession


Re-exports ParakeetSessionCommand


Re-exports ParakeetPromptResult


Re-exports ParakeetAssistantMessageItem


Re-exports ParakeetTimelineItem


Re-exports ParakeetToolGroupItem


Re-exports ParakeetToolItem


Re-exports ParakeetUserMessageItem


Re-exports ParakeetToolArguments


Re-exports useMarkdown


Re-exports formatToolDuration


Re-exports ParakeetToolCallSection


Re-exports ParakeetToolCallView


Re-exports ParakeetToolDiffFile


Re-exports ParakeetToolDiffHunk


Re-exports ParakeetToolDiffLine


Re-exports ParakeetToolDiffRow


Re-exports ParakeetToolExcerptLine


Re-exports ParakeetToolKind


Re-exports ParakeetToolMatch


Re-exports ParakeetToolOutputLine


Re-exports disclosureOpen


Re-exports initialToolDisclosure


Re-exports toggleAllDisclosure


Re-exports toggleDisclosure


Re-exports toolCallDefaultOpen


Re-exports toolGroupDefaultOpen


Re-exports visibleToolCalls


Re-exports ToolDisclosureState