@fungi.computer/whistle 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +373 -2
- package/dist/catalog.d.ts +459 -0
- package/dist/catalog.js +147 -0
- package/dist/html.d.ts +14 -0
- package/dist/html.js +11 -0
- package/dist/index.d.ts +253 -0
- package/dist/index.js +694 -0
- package/dist/interaction.d.ts +59 -0
- package/dist/interaction.js +131 -0
- package/dist/keymap.d.ts +34 -0
- package/dist/keymap.js +36 -0
- package/dist/wire.d.ts +380 -0
- package/dist/wire.js +299 -0
- package/docs/api/README.md +17 -0
- package/docs/api/catalog.md +498 -0
- package/docs/api/html.md +45 -0
- package/docs/api/index.md +675 -0
- package/docs/api/interaction.md +124 -0
- package/docs/api/wire.md +1033 -0
- package/package.json +87 -3
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { WhistleInteractionEnd, WhistleInteractionSession, WhistleNotice, WhistleNoticeLink, WhistlePrompt } from "./index.js";
|
|
2
|
+
/** Where one interaction is in its life. */
|
|
3
|
+
export type WhistleInteractionStatus = "working" | "prompting" | "failed" | "done" | "cancelled";
|
|
4
|
+
/** The one pending question, with the sequence its answer must name. */
|
|
5
|
+
export type WhistlePendingPrompt = Readonly<{
|
|
6
|
+
/** Identity the answer must name; a stale answer is ignored. */
|
|
7
|
+
sequence: number;
|
|
8
|
+
/** The parsed question. */
|
|
9
|
+
request: WhistlePrompt;
|
|
10
|
+
}>;
|
|
11
|
+
/** A notice that carries a message line. */
|
|
12
|
+
export type WhistleMessageNotice = Extract<WhistleNotice, Readonly<{
|
|
13
|
+
/** Notice kinds that carry a message line. */
|
|
14
|
+
type: "info" | "progress" | "success";
|
|
15
|
+
}>>;
|
|
16
|
+
/** A "continue elsewhere" notice. */
|
|
17
|
+
export type WhistleHandoffNotice = Extract<WhistleNotice, Readonly<{
|
|
18
|
+
/** The handoff notice kind. */
|
|
19
|
+
type: "handoff";
|
|
20
|
+
}>>;
|
|
21
|
+
/** Everything a renderer needs to draw one interaction. */
|
|
22
|
+
export type WhistleInteractionSnapshot = Readonly<{
|
|
23
|
+
/** The command title. */
|
|
24
|
+
title: string;
|
|
25
|
+
/** Where the interaction is in its life. */
|
|
26
|
+
status: WhistleInteractionStatus;
|
|
27
|
+
/** Latest info, progress or success message. */
|
|
28
|
+
message?: WhistleMessageNotice | undefined;
|
|
29
|
+
/** Latest "continue elsewhere" step, kept until the interaction ends. */
|
|
30
|
+
handoff?: WhistleHandoffNotice | undefined;
|
|
31
|
+
/** Links from the latest info notice. */
|
|
32
|
+
links: readonly WhistleNoticeLink[];
|
|
33
|
+
/** The question waiting for an answer. */
|
|
34
|
+
prompt?: WhistlePendingPrompt | undefined;
|
|
35
|
+
/** Failure message while status is "failed". */
|
|
36
|
+
failure?: string | undefined;
|
|
37
|
+
}>;
|
|
38
|
+
/** A renderer-neutral store behind one interaction dialog or panel. */
|
|
39
|
+
export type WhistleInteractionHost = Readonly<{
|
|
40
|
+
/** The current immutable snapshot. */
|
|
41
|
+
snapshot: () => WhistleInteractionSnapshot;
|
|
42
|
+
/** Observe snapshot changes. */
|
|
43
|
+
subscribe: (listener: () => void) => () => void;
|
|
44
|
+
/** Start one attempt; a retry calls this again. */
|
|
45
|
+
begin: () => WhistleInteractionSession;
|
|
46
|
+
/** Answer the pending prompt; a stale sequence or invalid value is ignored. */
|
|
47
|
+
answer: (sequence: number, value: string | boolean) => boolean;
|
|
48
|
+
/** Dismiss: abort the attempt, or close a settled failure. */
|
|
49
|
+
cancel: () => void;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Own one interaction's state for any renderer. Prompts and notices are
|
|
53
|
+
* parsed here, at the boundary where command-supplied data becomes UI.
|
|
54
|
+
*/
|
|
55
|
+
export declare function createWhistleInteractionHost(options: Readonly<{
|
|
56
|
+
title: string;
|
|
57
|
+
onEnd?: (end: WhistleInteractionEnd) => void;
|
|
58
|
+
}>): WhistleInteractionHost;
|
|
59
|
+
export { interactionTextLimit } from "./wire.js";
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { parseNotice, parsePrompt, createPromptAnswerDecoder, } from "./wire.js";
|
|
2
|
+
/**
|
|
3
|
+
* Own one interaction's state for any renderer. Prompts and notices are
|
|
4
|
+
* parsed here, at the boundary where command-supplied data becomes UI.
|
|
5
|
+
*/
|
|
6
|
+
export function createWhistleInteractionHost(options) {
|
|
7
|
+
const listeners = new Set();
|
|
8
|
+
let state = {
|
|
9
|
+
title: options.title,
|
|
10
|
+
status: "working",
|
|
11
|
+
links: [],
|
|
12
|
+
};
|
|
13
|
+
let attempt;
|
|
14
|
+
let waiting;
|
|
15
|
+
let sequence = 0;
|
|
16
|
+
const publish = (next) => {
|
|
17
|
+
state = { ...state, ...next };
|
|
18
|
+
for (const listener of listeners)
|
|
19
|
+
listener();
|
|
20
|
+
};
|
|
21
|
+
const end = (result) => {
|
|
22
|
+
waiting = undefined;
|
|
23
|
+
if (result.status === "failed")
|
|
24
|
+
publish({ status: "failed", failure: result.message, prompt: undefined });
|
|
25
|
+
else
|
|
26
|
+
publish({
|
|
27
|
+
status: result.status === "handled" ? "done" : "cancelled",
|
|
28
|
+
prompt: undefined,
|
|
29
|
+
});
|
|
30
|
+
options.onEnd?.(result);
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
snapshot: () => state,
|
|
34
|
+
subscribe: (listener) => {
|
|
35
|
+
listeners.add(listener);
|
|
36
|
+
return () => {
|
|
37
|
+
listeners.delete(listener);
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
begin: () => {
|
|
41
|
+
attempt?.abort();
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
attempt = controller;
|
|
44
|
+
const signal = controller.signal;
|
|
45
|
+
waiting = undefined;
|
|
46
|
+
state = { title: options.title, status: "working", links: [] };
|
|
47
|
+
publish({});
|
|
48
|
+
const current = () => attempt === controller && !signal.aborted;
|
|
49
|
+
const interaction = {
|
|
50
|
+
signal,
|
|
51
|
+
prompt: (raw, promptOptions) => {
|
|
52
|
+
const promptSignal = promptOptions?.signal === undefined
|
|
53
|
+
? signal
|
|
54
|
+
: AbortSignal.any([signal, promptOptions.signal]);
|
|
55
|
+
promptSignal.throwIfAborted();
|
|
56
|
+
const request = parsePrompt(raw);
|
|
57
|
+
const decodeAnswer = createPromptAnswerDecoder(raw);
|
|
58
|
+
const answer = Promise.withResolvers();
|
|
59
|
+
const own = ++sequence;
|
|
60
|
+
const abort = () => {
|
|
61
|
+
if (waiting?.sequence === own) {
|
|
62
|
+
waiting = undefined;
|
|
63
|
+
if (current())
|
|
64
|
+
publish({ status: "working", prompt: undefined });
|
|
65
|
+
}
|
|
66
|
+
answer.reject(promptSignal.reason);
|
|
67
|
+
};
|
|
68
|
+
promptSignal.addEventListener("abort", abort, { once: true });
|
|
69
|
+
waiting = {
|
|
70
|
+
sequence: own,
|
|
71
|
+
request,
|
|
72
|
+
resolve: (value) => {
|
|
73
|
+
const outcome = decodeAnswer(value);
|
|
74
|
+
if (outcome.kind === "invalid")
|
|
75
|
+
return false;
|
|
76
|
+
promptSignal.removeEventListener("abort", abort);
|
|
77
|
+
answer.resolve(outcome.value);
|
|
78
|
+
return true;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
publish({
|
|
82
|
+
status: "prompting",
|
|
83
|
+
prompt: { sequence: own, request },
|
|
84
|
+
});
|
|
85
|
+
return answer.promise;
|
|
86
|
+
},
|
|
87
|
+
notify: (raw) => {
|
|
88
|
+
if (!current())
|
|
89
|
+
return;
|
|
90
|
+
const notice = parseNotice(raw);
|
|
91
|
+
if (notice.type === "handoff")
|
|
92
|
+
publish({ handoff: notice });
|
|
93
|
+
else
|
|
94
|
+
publish({
|
|
95
|
+
message: notice,
|
|
96
|
+
links: notice.type === "info" ? (notice.links ?? []) : state.links,
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
interaction,
|
|
102
|
+
settle: (result) => {
|
|
103
|
+
if (attempt !== controller)
|
|
104
|
+
return;
|
|
105
|
+
attempt = undefined;
|
|
106
|
+
end(signal.aborted ? { status: "cancelled" } : result);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
answer: (own, value) => {
|
|
111
|
+
const pending = waiting;
|
|
112
|
+
if (pending?.sequence !== own)
|
|
113
|
+
return false;
|
|
114
|
+
if (!pending.resolve(value))
|
|
115
|
+
return false;
|
|
116
|
+
waiting = undefined;
|
|
117
|
+
publish({ status: "working", prompt: undefined });
|
|
118
|
+
return true;
|
|
119
|
+
},
|
|
120
|
+
cancel: () => {
|
|
121
|
+
if (attempt !== undefined) {
|
|
122
|
+
publish({ prompt: undefined });
|
|
123
|
+
attempt.abort(new Error("Interaction cancelled"));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (state.status === "failed")
|
|
127
|
+
end({ status: "cancelled" });
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export { interactionTextLimit } from "./wire.js";
|
package/dist/keymap.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { WhistleExecutionOrigin, WhistleRuntime } from "./index.js";
|
|
2
|
+
/** Lifecycle operations for a projection into a maintained host keymap. */
|
|
3
|
+
export type WhistleKeymapAdapter = Readonly<{
|
|
4
|
+
/** Remove the projected layer from the host. */
|
|
5
|
+
cleanup: () => void;
|
|
6
|
+
}>;
|
|
7
|
+
/** One physical key string mapped to a Whistle command identifier. */
|
|
8
|
+
export type WhistleKeymapBinding = Readonly<{
|
|
9
|
+
/** Whistle command identifier. */
|
|
10
|
+
cmd: string;
|
|
11
|
+
/** Host key notation. */
|
|
12
|
+
key: string;
|
|
13
|
+
}>;
|
|
14
|
+
/** Host callback that executes one semantic Whistle command. */
|
|
15
|
+
export type WhistleKeymapCommand = Readonly<{
|
|
16
|
+
/** Whistle command identifier. */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Execute the command and report whether the host handled it. */
|
|
19
|
+
run: () => Promise<boolean>;
|
|
20
|
+
}>;
|
|
21
|
+
/** Binding and command records accepted by a maintained keymap host. */
|
|
22
|
+
export type WhistleKeymapLayer = Readonly<{
|
|
23
|
+
/** Physical bindings mapped to Whistle command identifiers. */
|
|
24
|
+
bindings: readonly WhistleKeymapBinding[];
|
|
25
|
+
/** Host callbacks that execute the semantic commands. */
|
|
26
|
+
commands: readonly WhistleKeymapCommand[];
|
|
27
|
+
}>;
|
|
28
|
+
/** Minimal registration surface implemented by a maintained host keymap. */
|
|
29
|
+
export type WhistleKeymapHost = Readonly<{
|
|
30
|
+
/** Register one projected layer and return its disposal function. */
|
|
31
|
+
registerLayer: (layer: WhistleKeymapLayer) => () => void;
|
|
32
|
+
}>;
|
|
33
|
+
/** Project Whistle bindings into a host-created maintained OpenTUI keymap. */
|
|
34
|
+
export declare function createWhistleKeymapAdapter(keymap: WhistleKeymapHost, whistle: Pick<WhistleRuntime, "snapshot" | "subscribe" | "execute">, origin: WhistleExecutionOrigin): WhistleKeymapAdapter;
|
package/dist/keymap.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Project Whistle bindings into a host-created maintained OpenTUI keymap. */
|
|
2
|
+
export function createWhistleKeymapAdapter(keymap, whistle, origin) {
|
|
3
|
+
const hostKeymap = keymap;
|
|
4
|
+
let dispose = () => undefined;
|
|
5
|
+
let cleaned = false;
|
|
6
|
+
const update = () => {
|
|
7
|
+
if (cleaned)
|
|
8
|
+
return;
|
|
9
|
+
dispose();
|
|
10
|
+
const snapshot = whistle.snapshot();
|
|
11
|
+
const commandIds = new Set(snapshot.bindings.map((row) => row.commandId));
|
|
12
|
+
const bindings = snapshot.bindings.map((row) => ({
|
|
13
|
+
cmd: row.commandId,
|
|
14
|
+
key: row.binding,
|
|
15
|
+
}));
|
|
16
|
+
const commands = [...commandIds].map((commandId) => ({
|
|
17
|
+
name: commandId,
|
|
18
|
+
run: () => whistle.execute(commandId, { origin }).then(executionResult),
|
|
19
|
+
}));
|
|
20
|
+
dispose = hostKeymap.registerLayer({ bindings, commands });
|
|
21
|
+
};
|
|
22
|
+
update();
|
|
23
|
+
const unsubscribe = whistle.subscribe(update);
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
cleanup: () => {
|
|
26
|
+
if (cleaned)
|
|
27
|
+
return;
|
|
28
|
+
cleaned = true;
|
|
29
|
+
unsubscribe();
|
|
30
|
+
dispose();
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function executionResult(outcome) {
|
|
35
|
+
return outcome.status === "handled";
|
|
36
|
+
}
|
package/dist/wire.d.ts
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/** Preserve readonly domain collections while deriving contracts from schemas. */
|
|
3
|
+
export type ReadonlySchemaValue<T> = T extends (infer Item)[] ? readonly ReadonlySchemaValue<Item>[] : T extends object ? {
|
|
4
|
+
readonly [Key in keyof T]: ReadonlySchemaValue<T[Key]>;
|
|
5
|
+
} : T;
|
|
6
|
+
/** Host-owned availability carried by every discovered agent row. */
|
|
7
|
+
export declare const WhistleAvailabilitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
8
|
+
status: z.ZodLiteral<"available">;
|
|
9
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
10
|
+
status: z.ZodLiteral<"unavailable">;
|
|
11
|
+
reason: z.ZodString;
|
|
12
|
+
}, z.core.$strict>], "status">;
|
|
13
|
+
/** The JSON value grammar shared by Whistle transports and App adapters. */
|
|
14
|
+
export declare const WhistleJsonValueSchema: z.ZodJSONSchema;
|
|
15
|
+
/** JSON values accepted at Whistle transport boundaries. */
|
|
16
|
+
export type WhistleJsonValue = ReadonlySchemaValue<z.output<typeof WhistleJsonValueSchema>>;
|
|
17
|
+
/** One JSON object, used for action schemas and custom presentation data. */
|
|
18
|
+
export declare const WhistleJsonObjectSchema: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
19
|
+
/** A JSON object accepted at Whistle transport boundaries. */
|
|
20
|
+
export type WhistleJsonObject = ReadonlySchemaValue<z.output<typeof WhistleJsonObjectSchema>>;
|
|
21
|
+
/** Parse copied JSON data at an untrusted transport boundary. */
|
|
22
|
+
export declare const parseJsonValue: typeof WhistleJsonValueSchema.parse;
|
|
23
|
+
/** Parse a copied JSON object at an untrusted transport boundary. */
|
|
24
|
+
export declare const parseJsonObject: typeof WhistleJsonObjectSchema.parse;
|
|
25
|
+
/** General portable failure data for adapters that cross a transport. */
|
|
26
|
+
export declare const WhistleFailureSchema: z.ZodObject<{
|
|
27
|
+
code: z.ZodString;
|
|
28
|
+
message: z.ZodString;
|
|
29
|
+
details: z.ZodOptional<z.ZodJSONSchema>;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
/** Portable failure data that crosses Whistle transports. */
|
|
32
|
+
export type WhistleFailure = ReadonlySchemaValue<z.output<typeof WhistleFailureSchema>>;
|
|
33
|
+
/** Parse failure data without carrying an Error or stack across the wire. */
|
|
34
|
+
export declare const parseFailure: typeof WhistleFailureSchema.parse;
|
|
35
|
+
/** The JSON object shape used by Whistle action schemas. */
|
|
36
|
+
export declare const WhistleActionSchemaSchema: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
37
|
+
/** JSON Schema document used as an action input or output contract. */
|
|
38
|
+
export type WhistleActionSchema = ReadonlySchemaValue<z.output<typeof WhistleActionSchemaSchema>>;
|
|
39
|
+
declare const availabilitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
40
|
+
status: z.ZodLiteral<"available">;
|
|
41
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
42
|
+
status: z.ZodLiteral<"unavailable">;
|
|
43
|
+
reason: z.ZodString;
|
|
44
|
+
}, z.core.$strict>], "status">;
|
|
45
|
+
/** Host-owned availability fact carried in agent snapshots. */
|
|
46
|
+
export type WhistleAvailability = ReadonlySchemaValue<z.output<typeof WhistleAvailabilitySchema>>;
|
|
47
|
+
/** Validate renderer-neutral presentation data attached to an action. */
|
|
48
|
+
export declare const WhistleActionPresentationSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
49
|
+
type: z.ZodLiteral<"action">;
|
|
50
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
51
|
+
type: z.ZodLiteral<"custom">;
|
|
52
|
+
data: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
53
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
54
|
+
type: z.ZodLiteral<"choice">;
|
|
55
|
+
options: z.ZodArray<z.ZodObject<{
|
|
56
|
+
value: z.ZodJSONSchema;
|
|
57
|
+
label: z.ZodString;
|
|
58
|
+
description: z.ZodOptional<z.ZodString>;
|
|
59
|
+
}, z.core.$strip>>;
|
|
60
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
61
|
+
type: z.ZodLiteral<"form">;
|
|
62
|
+
submitLabel: z.ZodOptional<z.ZodString>;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
type: z.ZodLiteral<"confirmation">;
|
|
65
|
+
message: z.ZodString;
|
|
66
|
+
confirmLabel: z.ZodOptional<z.ZodString>;
|
|
67
|
+
cancelLabel: z.ZodOptional<z.ZodString>;
|
|
68
|
+
}, z.core.$strict>]>;
|
|
69
|
+
/** Renderer-neutral presentation data attached to an action. */
|
|
70
|
+
export type WhistleActionPresentation = ReadonlySchemaValue<z.output<typeof WhistleActionPresentationSchema>>;
|
|
71
|
+
/** Validate the serializable action contract carried by a command. */
|
|
72
|
+
export declare const WhistleActionDataSchema: z.ZodObject<{
|
|
73
|
+
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
74
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
75
|
+
presentation: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
76
|
+
type: z.ZodLiteral<"action">;
|
|
77
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
78
|
+
type: z.ZodLiteral<"custom">;
|
|
79
|
+
data: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
80
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
81
|
+
type: z.ZodLiteral<"choice">;
|
|
82
|
+
options: z.ZodArray<z.ZodObject<{
|
|
83
|
+
value: z.ZodJSONSchema;
|
|
84
|
+
label: z.ZodString;
|
|
85
|
+
description: z.ZodOptional<z.ZodString>;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
88
|
+
type: z.ZodLiteral<"form">;
|
|
89
|
+
submitLabel: z.ZodOptional<z.ZodString>;
|
|
90
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
91
|
+
type: z.ZodLiteral<"confirmation">;
|
|
92
|
+
message: z.ZodString;
|
|
93
|
+
confirmLabel: z.ZodOptional<z.ZodString>;
|
|
94
|
+
cancelLabel: z.ZodOptional<z.ZodString>;
|
|
95
|
+
}, z.core.$strict>]>>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
/** Serializable action data accepted by Whistle. */
|
|
98
|
+
export type WhistleAction = ReadonlySchemaValue<z.output<typeof WhistleActionDataSchema>>;
|
|
99
|
+
/** Validate aliases and argument mapping metadata for slash commands. */
|
|
100
|
+
export declare const WhistleSlashArgumentsSchema: z.ZodObject<{
|
|
101
|
+
hint: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
102
|
+
words: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
103
|
+
word: z.ZodString;
|
|
104
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
105
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
106
|
+
}, z.core.$strict>>>;
|
|
107
|
+
text: z.ZodOptional<z.ZodObject<{
|
|
108
|
+
field: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
109
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
110
|
+
requestIdField: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
111
|
+
}, z.core.$strict>>;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
/** Slash command parsing metadata accepted from transport owners. */
|
|
114
|
+
export type WhistleSlashArguments = ReadonlySchemaValue<z.output<typeof WhistleSlashArgumentsSchema>>;
|
|
115
|
+
/** A fixed word and its action arguments within a slash command. */
|
|
116
|
+
export type WhistleSlashWord = ReadonlySchemaValue<NonNullable<z.output<typeof WhistleSlashArgumentsSchema>["words"]>[number]>;
|
|
117
|
+
/** Validate explicit membership and ordering across Whistle surfaces. */
|
|
118
|
+
export declare const WhistleCommandProjectionsSchema: z.ZodObject<{
|
|
119
|
+
bindings: z.ZodOptional<z.ZodObject<{
|
|
120
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
values: z.ZodArray<z.ZodString>;
|
|
122
|
+
}, z.core.$strict>>;
|
|
123
|
+
agent: z.ZodOptional<z.ZodObject<{
|
|
124
|
+
keybind: z.ZodOptional<z.ZodString>;
|
|
125
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
126
|
+
}, z.core.$strict>>;
|
|
127
|
+
help: z.ZodOptional<z.ZodObject<{
|
|
128
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
129
|
+
}, z.core.$strict>>;
|
|
130
|
+
menu: z.ZodOptional<z.ZodObject<{
|
|
131
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
132
|
+
}, z.core.$strict>>;
|
|
133
|
+
palette: z.ZodOptional<z.ZodObject<{
|
|
134
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
135
|
+
}, z.core.$strict>>;
|
|
136
|
+
slash: z.ZodOptional<z.ZodObject<{
|
|
137
|
+
aliases: z.ZodArray<z.ZodString>;
|
|
138
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
139
|
+
arguments: z.ZodOptional<z.ZodObject<{
|
|
140
|
+
hint: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
141
|
+
words: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
142
|
+
word: z.ZodString;
|
|
143
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
144
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
145
|
+
}, z.core.$strict>>>;
|
|
146
|
+
text: z.ZodOptional<z.ZodObject<{
|
|
147
|
+
field: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
148
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
149
|
+
requestIdField: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
150
|
+
}, z.core.$strict>>;
|
|
151
|
+
}, z.core.$strict>>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
153
|
+
}, z.core.$strict>;
|
|
154
|
+
/** Projection membership selected by a semantic command owner. */
|
|
155
|
+
export type WhistleCommandProjections = ReadonlySchemaValue<z.output<typeof WhistleCommandProjectionsSchema>>;
|
|
156
|
+
/** Validate data-only command definitions supplied by an adapter. */
|
|
157
|
+
export declare const WhistleCommandDefinitionSchema: z.ZodObject<{
|
|
158
|
+
id: z.ZodString;
|
|
159
|
+
title: z.ZodString;
|
|
160
|
+
category: z.ZodString;
|
|
161
|
+
description: z.ZodOptional<z.ZodString>;
|
|
162
|
+
projections: z.ZodOptional<z.ZodObject<{
|
|
163
|
+
bindings: z.ZodOptional<z.ZodObject<{
|
|
164
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
165
|
+
values: z.ZodArray<z.ZodString>;
|
|
166
|
+
}, z.core.$strict>>;
|
|
167
|
+
agent: z.ZodOptional<z.ZodObject<{
|
|
168
|
+
keybind: z.ZodOptional<z.ZodString>;
|
|
169
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
170
|
+
}, z.core.$strict>>;
|
|
171
|
+
help: z.ZodOptional<z.ZodObject<{
|
|
172
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
173
|
+
}, z.core.$strict>>;
|
|
174
|
+
menu: z.ZodOptional<z.ZodObject<{
|
|
175
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
176
|
+
}, z.core.$strict>>;
|
|
177
|
+
palette: z.ZodOptional<z.ZodObject<{
|
|
178
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
179
|
+
}, z.core.$strict>>;
|
|
180
|
+
slash: z.ZodOptional<z.ZodObject<{
|
|
181
|
+
aliases: z.ZodArray<z.ZodString>;
|
|
182
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
183
|
+
arguments: z.ZodOptional<z.ZodObject<{
|
|
184
|
+
hint: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
185
|
+
words: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
186
|
+
word: z.ZodString;
|
|
187
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
188
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
189
|
+
}, z.core.$strict>>>;
|
|
190
|
+
text: z.ZodOptional<z.ZodObject<{
|
|
191
|
+
field: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
192
|
+
arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
193
|
+
requestIdField: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
194
|
+
}, z.core.$strict>>;
|
|
195
|
+
}, z.core.$strict>>;
|
|
196
|
+
}, z.core.$strict>>;
|
|
197
|
+
}, z.core.$strict>>;
|
|
198
|
+
action: z.ZodOptional<z.ZodObject<{
|
|
199
|
+
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
200
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
201
|
+
presentation: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
202
|
+
type: z.ZodLiteral<"action">;
|
|
203
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
204
|
+
type: z.ZodLiteral<"custom">;
|
|
205
|
+
data: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
206
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
207
|
+
type: z.ZodLiteral<"choice">;
|
|
208
|
+
options: z.ZodArray<z.ZodObject<{
|
|
209
|
+
value: z.ZodJSONSchema;
|
|
210
|
+
label: z.ZodString;
|
|
211
|
+
description: z.ZodOptional<z.ZodString>;
|
|
212
|
+
}, z.core.$strip>>;
|
|
213
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
214
|
+
type: z.ZodLiteral<"form">;
|
|
215
|
+
submitLabel: z.ZodOptional<z.ZodString>;
|
|
216
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
217
|
+
type: z.ZodLiteral<"confirmation">;
|
|
218
|
+
message: z.ZodString;
|
|
219
|
+
confirmLabel: z.ZodOptional<z.ZodString>;
|
|
220
|
+
cancelLabel: z.ZodOptional<z.ZodString>;
|
|
221
|
+
}, z.core.$strict>]>>;
|
|
222
|
+
}, z.core.$strict>>;
|
|
223
|
+
availability: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
224
|
+
status: z.ZodLiteral<"available">;
|
|
225
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
226
|
+
status: z.ZodLiteral<"unavailable">;
|
|
227
|
+
reason: z.ZodString;
|
|
228
|
+
}, z.core.$strict>], "status">>;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
/** Data-only command definition accepted at adapter boundaries. */
|
|
231
|
+
export type WhistleCommandDefinition = ReadonlySchemaValue<z.output<typeof WhistleCommandDefinitionSchema>>;
|
|
232
|
+
/** Parse action metadata once before an adapter constructs a Whistle command. */
|
|
233
|
+
export declare const parseAction: typeof WhistleActionDataSchema.parse;
|
|
234
|
+
/** Parse the Whistle-owned projection metadata supplied by an App. */
|
|
235
|
+
export declare const parseProjections: typeof WhistleCommandProjectionsSchema.parse;
|
|
236
|
+
/** Parse an availability fact while preserving its reason. */
|
|
237
|
+
export declare const parseAvailability: typeof availabilitySchema.parse;
|
|
238
|
+
/** Parse one data-only command definition before an adapter creates a command. */
|
|
239
|
+
export declare const parseCommandDefinition: typeof WhistleCommandDefinitionSchema.parse;
|
|
240
|
+
/** One neutral agent row emitted by Whistle's `snapshot.agent` projection. */
|
|
241
|
+
export declare const WhistleAgentProjectionSchema: z.ZodObject<{
|
|
242
|
+
commandId: z.ZodString;
|
|
243
|
+
sourceId: z.ZodString;
|
|
244
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
245
|
+
title: z.ZodString;
|
|
246
|
+
category: z.ZodString;
|
|
247
|
+
description: z.ZodOptional<z.ZodString>;
|
|
248
|
+
order: z.ZodNumber;
|
|
249
|
+
availability: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
250
|
+
status: z.ZodLiteral<"available">;
|
|
251
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
252
|
+
status: z.ZodLiteral<"unavailable">;
|
|
253
|
+
reason: z.ZodString;
|
|
254
|
+
}, z.core.$strict>], "status">;
|
|
255
|
+
action: z.ZodOptional<z.ZodObject<{
|
|
256
|
+
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
257
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
258
|
+
}, z.core.$strict>>;
|
|
259
|
+
keybind: z.ZodOptional<z.ZodString>;
|
|
260
|
+
}, z.core.$strict>;
|
|
261
|
+
/** Decoded agent projection data as received across the wire. */
|
|
262
|
+
export type WhistleAgentProjectionData = z.output<typeof WhistleAgentProjectionSchema>;
|
|
263
|
+
/** A neutral Whistle agent projection collection. */
|
|
264
|
+
export declare const WhistleAgentProjectionsSchema: z.ZodArray<z.ZodObject<{
|
|
265
|
+
commandId: z.ZodString;
|
|
266
|
+
sourceId: z.ZodString;
|
|
267
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
268
|
+
title: z.ZodString;
|
|
269
|
+
category: z.ZodString;
|
|
270
|
+
description: z.ZodOptional<z.ZodString>;
|
|
271
|
+
order: z.ZodNumber;
|
|
272
|
+
availability: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
273
|
+
status: z.ZodLiteral<"available">;
|
|
274
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
275
|
+
status: z.ZodLiteral<"unavailable">;
|
|
276
|
+
reason: z.ZodString;
|
|
277
|
+
}, z.core.$strict>], "status">;
|
|
278
|
+
action: z.ZodOptional<z.ZodObject<{
|
|
279
|
+
inputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
280
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
281
|
+
}, z.core.$strict>>;
|
|
282
|
+
keybind: z.ZodOptional<z.ZodString>;
|
|
283
|
+
}, z.core.$strict>>;
|
|
284
|
+
/** Decode an untrusted agent projection collection at the wire boundary. */
|
|
285
|
+
export declare const parse: typeof WhistleAgentProjectionsSchema.parse;
|
|
286
|
+
/** Longest prompt answer or message an interaction carries. */
|
|
287
|
+
export declare const interactionTextLimit = 8192;
|
|
288
|
+
/** Validate renderer-neutral interaction prompts received from a host. */
|
|
289
|
+
export declare const WhistlePromptSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
290
|
+
type: z.ZodLiteral<"choice">;
|
|
291
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
292
|
+
collapsedGroup: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
293
|
+
options: z.ZodArray<z.ZodObject<{
|
|
294
|
+
value: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
295
|
+
label: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
296
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
297
|
+
group: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
298
|
+
}, z.core.$strict>>;
|
|
299
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
300
|
+
type: z.ZodLiteral<"text">;
|
|
301
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
302
|
+
placeholder: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
303
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
304
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
305
|
+
type: z.ZodLiteral<"confirmation">;
|
|
306
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
307
|
+
confirmLabel: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
308
|
+
cancelLabel: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
309
|
+
}, z.core.$strict>], "type">;
|
|
310
|
+
/** A renderer-neutral interaction prompt. */
|
|
311
|
+
export type WhistlePrompt = ReadonlySchemaValue<z.output<typeof WhistlePromptSchema>>;
|
|
312
|
+
/** One selectable value in a parsed interaction prompt. */
|
|
313
|
+
export type WhistlePromptOption = NonNullable<Extract<WhistlePrompt, {
|
|
314
|
+
type: "choice";
|
|
315
|
+
}>["options"][number]>;
|
|
316
|
+
/** Validate interaction notices received from a host. */
|
|
317
|
+
export declare const WhistleNoticeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
318
|
+
type: z.ZodLiteral<"info">;
|
|
319
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
320
|
+
links: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
321
|
+
url: z.ZodURL;
|
|
322
|
+
label: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
323
|
+
}, z.core.$strict>>>;
|
|
324
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
325
|
+
type: z.ZodLiteral<"progress">;
|
|
326
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
327
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
328
|
+
type: z.ZodLiteral<"handoff">;
|
|
329
|
+
url: z.ZodURL;
|
|
330
|
+
code: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
331
|
+
message: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
332
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
333
|
+
type: z.ZodLiteral<"success">;
|
|
334
|
+
message: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
335
|
+
}, z.core.$strict>], "type">;
|
|
336
|
+
/** A renderer-neutral interaction notice. */
|
|
337
|
+
export type WhistleNotice = ReadonlySchemaValue<z.output<typeof WhistleNoticeSchema>>;
|
|
338
|
+
/** One link included in a parsed informational notice. */
|
|
339
|
+
export type WhistleNoticeLink = ReadonlySchemaValue<NonNullable<Extract<z.output<typeof WhistleNoticeSchema>, {
|
|
340
|
+
type: "info";
|
|
341
|
+
}>["links"]>[number]>;
|
|
342
|
+
/** Parse one interaction prompt at the boundary where a client renders it. */
|
|
343
|
+
export declare const parsePrompt: typeof WhistlePromptSchema.parse;
|
|
344
|
+
/** Parse one interaction notice at the boundary where a client renders it. */
|
|
345
|
+
export declare const parseNotice: typeof WhistleNoticeSchema.parse;
|
|
346
|
+
/** Answer types owned by the closed prompt vocabulary. */
|
|
347
|
+
export type WhistlePromptAnswers = {
|
|
348
|
+
confirmation: boolean;
|
|
349
|
+
text: string;
|
|
350
|
+
choice: string;
|
|
351
|
+
};
|
|
352
|
+
/** A prompt and its discriminator remain correlated through generic dispatch. */
|
|
353
|
+
export type WhistlePromptOf<Kind extends WhistlePrompt["type"]> = {
|
|
354
|
+
[K in Kind]: Extract<WhistlePrompt, {
|
|
355
|
+
type: K;
|
|
356
|
+
}> & {
|
|
357
|
+
readonly type: K;
|
|
358
|
+
};
|
|
359
|
+
}[Kind];
|
|
360
|
+
/** Capture a prompt's parsed answer contract before handing it to a renderer. */
|
|
361
|
+
export declare function createPromptAnswerParser<Kind extends WhistlePrompt["type"]>(prompt: WhistlePromptOf<Kind>): (value: string | boolean) => WhistlePromptAnswers[Kind];
|
|
362
|
+
/** Parse the answer a human gave to one prompt before the command sees it. */
|
|
363
|
+
export declare function parsePromptAnswer<Kind extends WhistlePrompt["type"]>(prompt: WhistlePromptOf<Kind>, value: string | boolean): WhistlePromptAnswers[Kind];
|
|
364
|
+
/** Capture a typed answer decoder; invalid input stays an explicit outcome. */
|
|
365
|
+
export declare function createPromptAnswerDecoder<Kind extends WhistlePrompt["type"]>(prompt: WhistlePromptOf<Kind>): (value: string | boolean) => Readonly<{
|
|
366
|
+
kind: "accepted";
|
|
367
|
+
value: WhistlePromptAnswers[Kind];
|
|
368
|
+
}> | Readonly<{
|
|
369
|
+
kind: "invalid";
|
|
370
|
+
cause: z.ZodError;
|
|
371
|
+
}>;
|
|
372
|
+
/** Decode a human answer without throwing so renderers can handle invalid input. */
|
|
373
|
+
export declare function decodePromptAnswer<Kind extends WhistlePrompt["type"]>(prompt: WhistlePromptOf<Kind>, value: string | boolean): Readonly<{
|
|
374
|
+
kind: "invalid";
|
|
375
|
+
cause: z.ZodError;
|
|
376
|
+
}> | Readonly<{
|
|
377
|
+
kind: "accepted";
|
|
378
|
+
value: WhistlePromptAnswers[Kind];
|
|
379
|
+
}>;
|
|
380
|
+
export {};
|