Skip to content
API reference

catalog

Import
import * as api from "@fungi.computer/whistle/catalog";
Kind Export Description
type alias WhistleCatalogInvoke Call one advertised command at its backend; resolves to a raw step.
type alias WhistleCatalogV1 An advertised command catalog decoded by the maintained catalog schema.
type alias WhistleCatalogStepV1 A decoded catalog response step derived from its maintained schema.
constant whistleCatalogProtocol The one catalog protocol this Whistle understands.
constant WhistleCatalogSchema Validate one complete Whistle catalog and its unique command ids.
constant parseCatalog Parse an advertised catalog at the client boundary.
constant WhistleCatalogStepSchema Validate one response step before it reaches an interaction renderer.
constant parseCatalogStep Parse one backend reply before any of it reaches a renderer.
function catalogCommands() Turn an advertised catalog into Whistle commands. Each handler runs the backend’s step conversation through the caller’s interaction; an Agent, which has no interaction, can run only commands that finish in one step.

WhistleCatalogInvoketype alias

Section titled “WhistleCatalogInvoke”
Signature
type WhistleCatalogInvoke = (
commandId,
args,
signal,
) => Promise<WhistleJsonValue>;

Call one advertised command at its backend; resolves to a raw step.

Parameter Type
commandId string
args WhistleJsonObject
signal AbortSignal

Promise<WhistleJsonValue>


WhistleCatalogV1type alias

Section titled “WhistleCatalogV1”
Signature
type WhistleCatalogV1 = ReadonlySchemaValue<
z.output<typeof WhistleCatalogSchema>
>;

An advertised command catalog decoded by the maintained catalog schema.


WhistleCatalogStepV1type alias

Section titled “WhistleCatalogStepV1”
Signature
type WhistleCatalogStepV1 = ReadonlySchemaValue<
z.output<typeof WhistleCatalogStepSchema>
>;

A decoded catalog response step derived from its maintained schema.

whistleCatalogProtocolconstant

Section titled “whistleCatalogProtocol”
Signature
const whistleCatalogProtocol: "whistle.catalog/v1" = "whistle.catalog/v1";

The one catalog protocol this Whistle understands.


WhistleCatalogSchemaconstant

Section titled “WhistleCatalogSchema”
Signature
const WhistleCatalogSchema: ZodPipe<ZodObject<{
protocol: ZodLiteral<"whistle.catalog/v1">;
commands: ZodArray<ZodLazy<ZodObject<{
id: ZodLazy<ZodString>;
title: ZodLazy<ZodString>;
category: ZodLazy<ZodString>;
description: ZodOptional<ZodLazy<ZodString>>;
projections: ZodOptional<ZodLazy<ZodObject<{
bindings: ...;
agent: ...;
help: ...;
menu: ...;
palette: ...;
slash: ...;
}, $strict>>>;
action: ZodOptional<ZodLazy<ZodObject<{
inputSchema: ...;
outputSchema: ...;
presentation: ...;
}, $strict>>>;
availability: ZodOptional<ZodLazy<ZodDiscriminatedUnion<[..., ...], "status">>>;
}, $strict>>>;
}, $strict>, ZodTransform<Readonly<{
protocol: "whistle.catalog/v1";
commands: readonly object[];
}>, {
protocol: "whistle.catalog/v1";
commands: object[];
}>>;

Validate one complete Whistle catalog and its unique command ids.


parseCatalogconstant

Section titled “parseCatalog”
Signature
const parseCatalog: typeof WhistleCatalogSchema.parse;

Parse an advertised catalog at the client boundary.


WhistleCatalogStepSchemaconstant

Section titled “WhistleCatalogStepSchema”
Signature
const WhistleCatalogStepSchema: ZodPipe<ZodDiscriminatedUnion<[ZodObject<{
type: ZodLiteral<"done">;
notice: ZodOptional<ZodLazy<ZodDiscriminatedUnion<[ZodObject<{
type: ...;
message: ...;
links: ...;
}, $strict>, ZodObject<{
type: ...;
message: ...;
}, $strict>, ZodObject<{
type: ...;
url: ...;
code: ...;
message: ...;
}, $strict>, ZodObject<{
type: ...;
message: ...;
}, $strict>], "type">>>;
result: ZodOptional<ZodJSONSchema>;
}, $strict>, ZodObject<{
type: ZodLiteral<"prompt">;
prompt: ZodDiscriminatedUnion<[ZodObject<{
summary: ZodOptional<ZodPipe<..., ...>>;
facts: ZodOptional<ZodArray<...>>;
body: ZodOptional<ZodPipe<..., ...>>;
bodyLabel: ZodOptional<ZodPipe<..., ...>>;
details: ZodOptional<ZodArray<...>>;
type: ZodLiteral<"choice">;
message: ZodPipe<ZodLazy<...>, ZodString>;
current: ZodOptional<ZodPipe<..., ...>>;
collapsedGroup: ZodOptional<ZodPipe<..., ...>>;
options: ZodArray<ZodObject<..., ...>>;
}, $strict>, ZodObject<{
summary: ZodOptional<ZodPipe<..., ...>>;
facts: ZodOptional<ZodArray<...>>;
body: ZodOptional<ZodPipe<..., ...>>;
bodyLabel: ZodOptional<ZodPipe<..., ...>>;
details: ZodOptional<ZodArray<...>>;
type: ZodLiteral<"text">;
message: ZodPipe<ZodLazy<...>, ZodString>;
placeholder: ZodOptional<ZodPipe<..., ...>>;
secret: ZodOptional<ZodBoolean>;
}, $strict>, ZodObject<{
summary: ZodOptional<ZodPipe<..., ...>>;
facts: ZodOptional<ZodArray<...>>;
body: ZodOptional<ZodPipe<..., ...>>;
bodyLabel: ZodOptional<ZodPipe<..., ...>>;
details: ZodOptional<ZodArray<...>>;
type: ZodLiteral<"confirmation">;
message: ZodPipe<ZodLazy<...>, ZodString>;
confirmLabel: ZodOptional<ZodPipe<..., ...>>;
cancelLabel: ZodOptional<ZodPipe<..., ...>>;
destructive: ZodOptional<ZodLiteral<...>>;
}, $strict>, ZodObject<{
summary: ZodOptional<ZodPipe<..., ...>>;
facts: ZodOptional<ZodArray<...>>;
body: ZodOptional<ZodPipe<..., ...>>;
bodyLabel: ZodOptional<ZodPipe<..., ...>>;
details: ZodOptional<ZodArray<...>>;
type: ZodLiteral<"decision">;
message: ZodPipe<ZodLazy<...>, ZodString>;
options: ZodArray<ZodObject<..., ...>>;
multiple: ZodOptional<ZodBoolean>;
other: ZodOptional<ZodObject<..., ...>>;
escape: ZodOptional<ZodPipe<..., ...>>;
}, $strict>], "type">;
notice: ZodOptional<ZodLazy<ZodDiscriminatedUnion<[ZodObject<{
type: ...;
message: ...;
links: ...;
}, $strict>, ZodObject<{
type: ...;
message: ...;
}, $strict>, ZodObject<{
type: ...;
url: ...;
code: ...;
message: ...;
}, $strict>, ZodObject<{
type: ...;
message: ...;
}, $strict>], "type">>>;
next: ZodObject<{
arguments: ZodLazy<ZodRecord<ZodString, ZodJSONSchema>>;
answer: ZodString;
}, $strict>;
}, $strict>], "type">, ZodTransform<
| Readonly<{
type: "done";
notice?: | {
type: "info";
message: string;
links?: object[];
}
| {
type: "progress";
message: string;
}
| {
type: "handoff";
url: string;
code?: string;
message?: string;
}
| {
type: "success";
message: string;
};
result?: JSONType;
}>
| Readonly<{
type: "prompt";
prompt: | {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "decision";
message: string;
options: object[];
multiple?: boolean;
other?: {
label: string;
placeholder?: string;
maxLength: number;
blank?: string;
};
escape?: string;
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "choice";
message: string;
current?: string;
collapsedGroup?: string;
options: object[];
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "text";
message: string;
placeholder?: string;
secret?: boolean;
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
destructive?: true;
};
notice?: | {
type: "info";
message: string;
links?: object[];
}
| {
type: "progress";
message: string;
}
| {
type: "handoff";
url: string;
code?: string;
message?: string;
}
| {
type: "success";
message: string;
};
next: {
arguments: Record<string, JSONType>;
answer: string;
};
}>,
| {
type: "done";
notice?: | {
type: "info";
message: string;
links?: object[];
}
| {
type: "progress";
message: string;
}
| {
type: "handoff";
url: string;
code?: string;
message?: string;
}
| {
type: "success";
message: string;
};
result?: JSONType;
}
| {
type: "prompt";
prompt: | {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "decision";
message: string;
options: object[];
multiple?: boolean;
other?: {
label: string;
placeholder?: string;
maxLength: number;
blank?: string;
};
escape?: string;
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "choice";
message: string;
current?: string;
collapsedGroup?: string;
options: object[];
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "text";
message: string;
placeholder?: string;
secret?: boolean;
}
| {
summary?: string;
facts?: object[];
body?: string;
bodyLabel?: string;
details?: object[];
type: "confirmation";
message: string;
confirmLabel?: string;
cancelLabel?: string;
destructive?: true;
};
notice?: | {
type: "info";
message: string;
links?: object[];
}
| {
type: "progress";
message: string;
}
| {
type: "handoff";
url: string;
code?: string;
message?: string;
}
| {
type: "success";
message: string;
};
next: {
arguments: Record<string, JSONType>;
answer: string;
};
}>>;

Validate one response step before it reaches an interaction renderer.


parseCatalogStepconstant

Section titled “parseCatalogStep”
Signature
const parseCatalogStep: typeof WhistleCatalogStepSchema.parse;

Parse one backend reply before any of it reaches a renderer.

catalogCommands()function

Section titled “catalogCommands()”
Signature
function catalogCommands(catalog, invoke): 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;
}>[];

Turn an advertised catalog into Whistle commands. Each handler runs the backend’s step conversation through the caller’s interaction; an Agent, which has no interaction, can run only commands that finish in one step.

Parameter Type
catalog { protocol: "whistle.catalog/v1"; commands: readonly object[]; }
catalog.protocol "whistle.catalog/v1"
catalog.commands readonly object[]
invoke WhistleCatalogInvoke

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; }>[]