@fungi.computer/parakeet 0.1.0 → 0.2.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.
Files changed (59) hide show
  1. package/README.md +45 -6
  2. package/dist/account-commands.js +3 -11
  3. package/dist/commands/advertised.d.ts +3 -1
  4. package/dist/commands/advertised.js +89 -4
  5. package/dist/commands/interactions.d.ts +22 -7
  6. package/dist/commands/interactions.js +41 -17
  7. package/dist/commands/slash.js +3 -5
  8. package/dist/commands/use-slash-commands.js +2 -2
  9. package/dist/components/AgentHead.d.ts +2 -0
  10. package/dist/components/AgentHead.js +5 -4
  11. package/dist/components/ChatComposer.d.ts +3 -1
  12. package/dist/components/ChatComposer.js +79 -15
  13. package/dist/components/ChatMessage.d.ts +4 -0
  14. package/dist/components/ChatMessage.js +6 -2
  15. package/dist/components/ClientRows.js +2 -2
  16. package/dist/components/InteractionPanel.d.ts +2 -4
  17. package/dist/components/InteractionPanel.js +2 -2
  18. package/dist/components/TimelineItem.d.ts +2 -0
  19. package/dist/components/TimelineItem.js +31 -7
  20. package/dist/conversation-opening.d.ts +47 -0
  21. package/dist/conversation-opening.js +173 -0
  22. package/dist/conversation.d.ts +47 -3
  23. package/dist/conversation.js +584 -86
  24. package/dist/core/author-labels.d.ts +2 -0
  25. package/dist/core/build-timeline.d.ts +4 -2
  26. package/dist/core/build-timeline.js +46 -7
  27. package/dist/core/client-actions.js +6 -3
  28. package/dist/core/client-timeline.d.ts +9 -2
  29. package/dist/core/client-timeline.js +15 -4
  30. package/dist/core/draft-storage.d.ts +63 -0
  31. package/dist/core/draft-storage.js +50 -0
  32. package/dist/core/model-identity.d.ts +2 -0
  33. package/dist/core/model-identity.js +6 -0
  34. package/dist/core/queued-recall.d.ts +35 -0
  35. package/dist/core/queued-recall.js +138 -0
  36. package/dist/core/session-projection.js +17 -0
  37. package/dist/core/session-query.d.ts +54 -11
  38. package/dist/core/session-query.js +38 -12
  39. package/dist/core/tool-groups.d.ts +1 -1
  40. package/dist/core/tool-groups.js +3 -1
  41. package/dist/core/tool-view.js +2 -1
  42. package/dist/core/use-timeline-item-key.d.ts +8 -0
  43. package/dist/core/use-timeline-item-key.js +29 -0
  44. package/dist/headless.d.ts +6 -4
  45. package/dist/headless.js +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.js +1 -1
  48. package/dist/model-commands.js +64 -39
  49. package/dist/parakeet.js +17 -18
  50. package/dist/session-commands.d.ts +0 -9
  51. package/dist/session-commands.js +39 -68
  52. package/dist/session.d.ts +1 -1
  53. package/dist/store/types.d.ts +10 -4
  54. package/dist/styles.css +27 -12
  55. package/docs/api/commands/slash.md +24 -21
  56. package/docs/api/headless.md +375 -232
  57. package/docs/api/index.md +157 -45
  58. package/package.json +16 -10
  59. package/src/styles.css +0 -9
@@ -5,10 +5,7 @@ import { buildDurableTimeline } from "./core/build-timeline.js";
5
5
  import { sessionActivityStatus, sessionViewState, } from "./core/session-view-state.js";
6
6
  /** A choice prompt holds at most 256 options; the default read already bounds this. */
7
7
  const maxForkOptions = 200;
8
- const queueArguments = z.discriminatedUnion("action", [
9
- z.strictObject({ action: z.literal("list") }),
10
- z.strictObject({ action: z.literal("editLast") }),
11
- ]);
8
+ const queueArguments = z.strictObject({ action: z.literal("list") });
12
9
  const queueArgumentsSchema = z
13
10
  .record(z.string(), z.json())
14
11
  .parse(structuredClone(z.toJSONSchema(queueArguments)));
@@ -63,18 +60,13 @@ export function contributeSessionCommands(commands, session, options) {
63
60
  aliases: ["queue"],
64
61
  order: 3,
65
62
  arguments: {
66
- hint: "list | edit-last",
63
+ hint: "list",
67
64
  words: [
68
65
  {
69
66
  word: "list",
70
67
  description: "List accepted queued prompts",
71
68
  arguments: { action: "list" },
72
69
  },
73
- {
74
- word: "edit-last",
75
- description: "Return the last queued prompt to the composer",
76
- arguments: { action: "editLast" },
77
- },
78
70
  ],
79
71
  },
80
72
  },
@@ -83,43 +75,19 @@ export function contributeSessionCommands(commands, session, options) {
83
75
  handler: async ({ arguments: rawArguments, interaction, }) => {
84
76
  const args = queueArguments.safeParse(rawArguments ?? { action: "list" });
85
77
  if (!args.success)
86
- throw new Error("/queue requires list or editLast.");
78
+ throw new Error("/queue requires list.");
87
79
  const snapshot = await session.read();
88
- if (args.data.action === "list") {
89
- const prompts = snapshot.pending.prompts;
90
- const settled = snapshot.terminals.map((terminal) => `${terminal.outcome} · ${terminal.commandId}`);
91
- tell(interaction, prompts.length === 0 && settled.length === 0
92
- ? "No queued prompts."
93
- : [
94
- ...prompts.map((prompt, index) => `${String(index + 1)}. queued · accepted: ${prompt.text}`),
95
- ...settled,
96
- ...(snapshot.pending.hasMore === true
97
- ? ["More accepted prompts are waiting outside this view."]
98
- : []),
99
- ].join("\n"));
100
- return;
101
- }
102
- if (snapshot.pending.hasMore === true)
103
- throw new Error("The queue view is incomplete; refresh it before editing the last prompt.");
104
- const prompt = [...snapshot.pending.prompts]
105
- .reverse()
106
- .find((candidate) => candidate.delivery === "followUp");
107
- if (prompt === undefined)
108
- throw new Error("There is no queued follow-up to edit.");
109
- if (session.cancel === undefined)
110
- throw new Error("Queue editing is unavailable in this host.");
111
- if (options.onEditQueued === undefined)
112
- throw new Error("Editing queued prompts is unavailable in this host.");
113
- if (options.canEditQueued?.() === false)
114
- throw new Error("Clear or submit the current draft before editing a queued prompt.");
115
- const withdrawn = await session.cancel({
116
- commandId: prompt.commandId,
117
- onlyIfPending: true,
118
- });
119
- if (withdrawn.status === "too_late")
120
- throw new Error("That queued prompt has already started; it can no longer be edited.");
121
- options.onEditQueued(prompt.text);
122
- tell(interaction, "Queued prompt returned to the composer for editing.");
80
+ const prompts = snapshot.pending.prompts;
81
+ const settled = snapshot.terminals.map((terminal) => `${terminal.outcome} · ${terminal.commandId}`);
82
+ tell(interaction, prompts.length === 0 && settled.length === 0
83
+ ? "No queued prompts."
84
+ : [
85
+ ...prompts.map((prompt, index) => `${String(index + 1)}. queued · accepted: ${prompt.text}`),
86
+ ...settled,
87
+ ...(snapshot.pending.hasMore === true
88
+ ? ["More accepted prompts are waiting outside this view."]
89
+ : []),
90
+ ].join("\n"));
123
91
  },
124
92
  },
125
93
  {
@@ -150,7 +118,8 @@ export function contributeSessionCommands(commands, session, options) {
150
118
  slash: { aliases: ["fork"], order: 7 },
151
119
  },
152
120
  handler: async ({ interaction }) => {
153
- if (!options.forkAvailable || options.onForked === undefined) {
121
+ const onForked = options.onForked;
122
+ if (!options.forkAvailable || onForked === undefined) {
154
123
  unavailable("/fork");
155
124
  return;
156
125
  }
@@ -171,23 +140,25 @@ export function contributeSessionCommands(commands, session, options) {
171
140
  label: item.text.slice(0, 100) || "(empty message)",
172
141
  })),
173
142
  });
174
- let forked;
175
- try {
176
- forked = await session.command({ type: "fork", entryId: answer });
177
- }
178
- catch (error) {
179
- if (error instanceof ShiitakeError) {
180
- if (error.boundary === "runtime" && error.cause === "conflict")
181
- throw new Error("Wait for the current run to finish, then fork.", { cause: error });
182
- if (error.boundary === "store" && error.cause === "unavailable")
183
- throw new Error("That message is no longer available to fork from.", { cause: error });
184
- if (error.boundary === "runtime" && error.cause === "rejected")
185
- throw new Error("This Session is bound to a channel and cannot be forked.", { cause: error });
143
+ const forked = await interaction.run(async () => {
144
+ try {
145
+ return await session.command({ type: "fork", entryId: answer });
186
146
  }
187
- throw error;
188
- }
189
- await options.onForked(forked.sessionId);
190
- tell(interaction, "Forked into a new Session.");
147
+ catch (error) {
148
+ if (error instanceof ShiitakeError) {
149
+ if (error.boundary === "runtime" && error.cause === "conflict")
150
+ throw new Error("Wait for the current run to finish, then fork.", { cause: error });
151
+ if (error.boundary === "store" && error.cause === "unavailable")
152
+ throw new Error("That message is no longer available to fork from.", { cause: error });
153
+ if (error.boundary === "runtime" && error.cause === "rejected")
154
+ throw new Error("This Session is bound to a channel and cannot be forked.", { cause: error });
155
+ }
156
+ throw error;
157
+ }
158
+ });
159
+ await interaction.run(async () => {
160
+ await onForked(forked.sessionId);
161
+ });
191
162
  },
192
163
  },
193
164
  {
@@ -207,7 +178,7 @@ export function contributeSessionCommands(commands, session, options) {
207
178
  },
208
179
  },
209
180
  },
210
- handler: async ({ arguments: input, interaction, }) => {
181
+ handler: async ({ arguments: input }) => {
211
182
  const parsed = compactArguments.safeParse(input);
212
183
  if (!parsed.success)
213
184
  throw new Error("Use /compact, or /compact <what to focus on>.");
@@ -218,7 +189,7 @@ export function contributeSessionCommands(commands, session, options) {
218
189
  await session.command(instructions.length === 0
219
190
  ? { type: "compact", requestId: nanoid() }
220
191
  : { type: "compact", requestId: nanoid(), instructions });
221
- return tell(interaction, "Compaction queued; it runs after any current work.");
192
+ return "Compaction queued; it runs after any current work.";
222
193
  },
223
194
  },
224
195
  {
@@ -238,7 +209,7 @@ export function contributeSessionCommands(commands, session, options) {
238
209
  },
239
210
  },
240
211
  },
241
- handler: async ({ arguments: input, interaction, }) => {
212
+ handler: async ({ arguments: input }) => {
242
213
  const parsed = nameArguments.safeParse(input);
243
214
  if (!parsed.success)
244
215
  throw new Error("Use /name <title>, or /name to clear it.");
@@ -248,9 +219,9 @@ export function contributeSessionCommands(commands, session, options) {
248
219
  const title = text.length === 0 ? null : text;
249
220
  await session.command({ type: "title", title });
250
221
  await options.onTitled?.(title);
251
- return tell(interaction, title === null
222
+ return title === null
252
223
  ? "Conversation title cleared; it follows the first prompt again."
253
- : `Conversation named "${title}".`);
224
+ : `Conversation named "${title}".`;
254
225
  },
255
226
  },
256
227
  ],
package/dist/session.d.ts CHANGED
@@ -18,7 +18,7 @@ export type ParakeetSessionCommand = {
18
18
  (input: SessionCommand): Promise<ParakeetPromptResult | CancelResult | ForkedSession | undefined>;
19
19
  };
20
20
  /** The exact Shiitake operations consumed by the retained conversation UI. */
21
- export type ParakeetSession = Readonly<Pick<ShiitakeSession, "address" | "extension" | "read" | "watch"> & {
21
+ export type ParakeetSession = Readonly<Pick<ShiitakeSession, "address" | "extension" | "read" | "watch" | "withdraw" | "latestPending"> & {
22
22
  /** Submit commands through this Session's admitted owner boundary. */
23
23
  command: ParakeetSessionCommand;
24
24
  }>;
@@ -1,5 +1,5 @@
1
1
  import type { ParakeetAuthor } from "../core/author-labels.js";
2
- import type { PromptDelivery, SessionCompactionTrigger, SessionMessage } from "@fungi.computer/shiitake/client";
2
+ import type { PromptDelivery, PromptCommand, SessionCompactionTrigger, SessionMessage } from "@fungi.computer/shiitake/client";
3
3
  import type { ToolArguments } from "../core/tool-contract.js";
4
4
  import type { ToolCallView } from "../core/tool-view.js";
5
5
  /** Exact Pi tool result joined to its tool call by the timeline projection. */
@@ -46,6 +46,8 @@ export type LocalPromptAdmission = Readonly<{
46
46
  commandId?: string;
47
47
  /** Prompt content sent to the Session. */
48
48
  content: string;
49
+ /** Full image payload retained with an optimistic or recalled prompt. */
50
+ images?: PromptCommand["images"];
49
51
  /** Existing Session delivery intent. */
50
52
  delivery: PromptDelivery;
51
53
  /** Current local admission result. */
@@ -91,6 +93,8 @@ export type ToolItem = Readonly<{
91
93
  name: string;
92
94
  /** Exact joined Pi tool result, when one has completed. */
93
95
  result?: ToolResultMessage;
96
+ /** Application display payload, separate from the model result. */
97
+ data?: SessionMessage["data"];
94
98
  /** Timestamp of the assistant message that issued the call. */
95
99
  startedAt?: number;
96
100
  /** Owner-confirmed activity or result; unknown when neither is available. */
@@ -152,9 +156,11 @@ export type CompactionNoticeItem = Readonly<{
152
156
  at: number;
153
157
  /** What started it: the user, the context threshold, or an overflow. */
154
158
  trigger: SessionCompactionTrigger;
155
- /** What the compaction did: nothing to summarize, or a failure. */
156
- result: "nothing_to_compact" | "failed";
157
- /** A failure's bounded reason; null for "nothing to compact". */
159
+ /** What the compaction did: nothing to summarize, a failure, or a summary
160
+ * dropped because its head no longer fit the context (stale) or because
161
+ * placing it would have left the context over the limit (insufficient). */
162
+ result: "nothing_to_compact" | "failed" | "stale" | "insufficient";
163
+ /** A failure's bounded reason; null otherwise. */
158
164
  diagnostic: string | null;
159
165
  }>;
160
166
  /** Stable row grammar rendered by Parakeet's timeline. */
package/dist/styles.css CHANGED
@@ -4476,6 +4476,9 @@
4476
4476
  }
4477
4477
  }
4478
4478
  }
4479
+ .isolate {
4480
+ isolation: isolate;
4481
+ }
4479
4482
  .stack {
4480
4483
  @layer daisyui.l1.l2.l3 {
4481
4484
  display: inline-grid;
@@ -6137,6 +6140,9 @@
6137
6140
  .w-0 {
6138
6141
  width: calc(var(--spacing) * 0);
6139
6142
  }
6143
+ .w-3 {
6144
+ width: calc(var(--spacing) * 3);
6145
+ }
6140
6146
  .w-8 {
6141
6147
  width: calc(var(--spacing) * 8);
6142
6148
  }
@@ -6197,6 +6203,9 @@
6197
6203
  .shrink-0 {
6198
6204
  flex-shrink: 0;
6199
6205
  }
6206
+ .grow {
6207
+ flex-grow: 1;
6208
+ }
6200
6209
  .border-collapse {
6201
6210
  border-collapse: collapse;
6202
6211
  }
@@ -6957,6 +6966,9 @@
6957
6966
  .opacity-55 {
6958
6967
  opacity: 55%;
6959
6968
  }
6969
+ .opacity-60 {
6970
+ opacity: 60%;
6971
+ }
6960
6972
  .opacity-70 {
6961
6973
  opacity: 70%;
6962
6974
  }
@@ -14079,8 +14091,8 @@
14079
14091
  min-height: 44px;
14080
14092
  }
14081
14093
  }
14082
- .caps-window-header:has(> .caps-window-crumbs) {
14083
- min-height: 40px;
14094
+ .caps-window-header > .caps-window-icon {
14095
+ margin-inline: var(--spacing-md) calc(var(--spacing-sm) - var(--spacing-2xs));
14084
14096
  }
14085
14097
  .caps-window-crumbs {
14086
14098
  display: flex;
@@ -14088,7 +14100,7 @@
14088
14100
  min-width: 0;
14089
14101
  flex-shrink: 1;
14090
14102
  font-family: var(--caps-label-font, inherit);
14091
- font-size: var(--text-sm);
14103
+ font-size: 11px;
14092
14104
  font-weight: 500;
14093
14105
  }
14094
14106
  .caps-window-crumb-item[data-caps-crumb-position="current"] {
@@ -14129,7 +14141,7 @@
14129
14141
  gap: var(--spacing-sm);
14130
14142
  flex-shrink: 0;
14131
14143
  padding-inline-end: var(--spacing-sm);
14132
- font-size: var(--text-sm);
14144
+ font-size: 11px;
14133
14145
  color: currentColor;
14134
14146
  @supports (color: color-mix(in lab, red, red)) {
14135
14147
  color: color-mix(in srgb, currentColor 65%, transparent);
@@ -14142,6 +14154,16 @@
14142
14154
  flex-shrink: 0;
14143
14155
  }
14144
14156
  @media (max-width: 640px) {
14157
+ .caps-window-header:has(.caps-window-crumbs) {
14158
+ flex-wrap: wrap;
14159
+ }
14160
+ .caps-window-crumbs {
14161
+ min-width: min-content;
14162
+ flex-shrink: 0;
14163
+ }
14164
+ .caps-window-crumb-item {
14165
+ flex-shrink: 0;
14166
+ }
14145
14167
  .caps-window-statuses {
14146
14168
  gap: var(--spacing-2xs);
14147
14169
  padding-inline-end: var(--spacing-2xs);
@@ -14494,6 +14516,7 @@
14494
14516
  display: block;
14495
14517
  flex: none;
14496
14518
  overflow: visible;
14519
+ pointer-events: none;
14497
14520
  transition: color var(--stipe-motion-normal) ease;
14498
14521
  }
14499
14522
  .caps-status-mark {
@@ -18110,14 +18133,6 @@
18110
18133
  .chat-composer .parakeet-command-notice[data-tone="success"] {
18111
18134
  color: var(--color-success);
18112
18135
  }
18113
- .chat-composer .parakeet-key-hints {
18114
- margin: 0;
18115
- padding: 0 0.75rem 0.25rem;
18116
- background: var(--color-base-200);
18117
- font-family: var(--font-sans);
18118
- font-size: 0.6rem;
18119
- color: var(--stipe-fg-muted);
18120
- }
18121
18136
  .chat-composer .footer-divider {
18122
18137
  width: 3px;
18123
18138
  height: 3px;
@@ -16,6 +16,7 @@
16
16
  type SlashCommand = Readonly<{
17
17
  alias: string;
18
18
  commandId: string;
19
+ consumesDraft?: boolean;
19
20
  title: string;
20
21
  description?: string;
21
22
  category: string;
@@ -164,6 +165,7 @@ Human key labels from Whistle bindings, with the platform's modifier name.
164
165
  function slashRegistry(snapshot): readonly Readonly<{
165
166
  alias: string;
166
167
  commandId: string;
168
+ consumesDraft?: boolean;
167
169
  title: string;
168
170
  description?: string;
169
171
  category: string;
@@ -202,22 +204,23 @@ Every slash alias in the live graph, with the keys bound to its command.
202
204
 
203
205
  #### Returns
204
206
 
205
- readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`; `title`:
206
- `string`; `description?`: `string`; `category`: `string`; `order`: `number`;
207
- `grammar?`: \{ `hint`: `string`; `words?`: readonly `object`[]; `text?`: \{
208
- `field`: `string`; `arguments`: \{ \[`key`: `string`\]: \| `string` \| `number`
209
- \| `boolean` \| readonly string \| number \| boolean \| readonly (string \|
207
+ readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`;
208
+ `consumesDraft?`: `boolean`; `title`: `string`; `description?`: `string`;
209
+ `category`: `string`; `order`: `number`; `grammar?`: \{ `hint`: `string`;
210
+ `words?`: readonly `object`[]; `text?`: \{ `field`: `string`; `arguments`: \{
211
+ \[`key`: `string`\]: \| `string` \| `number` \| `boolean` \| readonly string \|
210
212
  number \| boolean \| readonly (string \| number \| boolean \| readonly (string
211
213
  \| number \| boolean \| readonly (string \| number \| boolean \| readonly
212
- (string \| number \| boolean \| readonly (string \| ... 4 more ... \| null)\[\]
213
- \| \{ ...; \} \| null)\[\] \| \{ ...; \} \| null)\[\] \| \{ ...; \} \| ...[] \|
214
- \{ \[`key`: `string`\]: string \| number \| boolean \| readonly (string \|
214
+ (string \| number \| boolean \| readonly (string \| number \| boolean \|
215
+ readonly (string \| ... 4 more ... \| null)\[\] \| \{ ...; \} \| null)\[\] \| \{
216
+ ...; \} \| null)\[\] \| \{ ...; \} \| ...[] \| \{ \[`key`: `string`\]: string \|
215
217
  number \| boolean \| readonly (string \| number \| boolean \| readonly (string
216
218
  \| number \| boolean \| readonly (string \| number \| boolean \| readonly
217
- (string \| number \| boolean \| readonly (string \| ... 4 more ... \| null)\[\]
218
- \| \{ ...; \} \| null)\[\] \| \{ ...; \} \| null)\[\] \| \{ ...; \} \| ...; \}
219
- \| `null`; \}; `requestIdField?`: `string`; \}; \}; `keys`: readonly `string`[];
220
- `availability`: `WhistleAvailability`; \}\>[]
219
+ (string \| number \| boolean \| readonly (string \| number \| boolean \|
220
+ readonly (string \| ... 4 more ... \| null)\[\] \| \{ ...; \} \| null)\[\] \| \{
221
+ ...; \} \| null)\[\] \| \{ ...; \} \| ...; \} \| `null`; \}; `requestIdField?`:
222
+ `string`; \}; \}; `keys`: readonly `string`[]; `availability`:
223
+ `WhistleAvailability`; \}\>[]
221
224
 
222
225
  ---
223
226
 
@@ -257,10 +260,10 @@ Parse one draft against the registry; only a leading `/` names a command.
257
260
 
258
261
  #### Parameters
259
262
 
260
- | Parameter | Type |
261
- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
262
- | `registry` | readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`; `title`: `string`; `description?`: `string`; `category`: `string`; `order`: `number`; `grammar?`: \{ `hint`: `string`; `words?`: readonly `object`[]; `text?`: \{ `field`: `string`; `arguments`: \{ \[`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`; \}; `requestIdField?`: `string`; \}; \}; `keys`: readonly `string`[]; `availability`: `WhistleAvailability`; \}\>[] |
263
- | `draft` | `string` |
263
+ | Parameter | Type |
264
+ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
265
+ | `registry` | readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`; `consumesDraft?`: `boolean`; `title`: `string`; `description?`: `string`; `category`: `string`; `order`: `number`; `grammar?`: \{ `hint`: `string`; `words?`: readonly `object`[]; `text?`: \{ `field`: `string`; `arguments`: \{ \[`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`; \}; `requestIdField?`: `string`; \}; \}; `keys`: readonly `string`[]; `availability`: `WhistleAvailability`; \}\>[] |
266
+ | `draft` | `string` |
264
267
 
265
268
  #### Returns
266
269
 
@@ -310,11 +313,11 @@ Rank completions for one draft; renderers draw exactly these rows.
310
313
 
311
314
  #### Parameters
312
315
 
313
- | Parameter | Type |
314
- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
315
- | `registry` | readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`; `title`: `string`; `description?`: `string`; `category`: `string`; `order`: `number`; `grammar?`: \{ `hint`: `string`; `words?`: readonly `object`[]; `text?`: \{ `field`: `string`; `arguments`: \{ \[`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`; \}; `requestIdField?`: `string`; \}; \}; `keys`: readonly `string`[]; `availability`: `WhistleAvailability`; \}\>[] |
316
- | `draft` | `string` |
317
- | `options` | `Readonly`\<\{ `idleCategory?`: `string`; \}\> |
316
+ | Parameter | Type |
317
+ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
318
+ | `registry` | readonly `Readonly`\<\{ `alias`: `string`; `commandId`: `string`; `consumesDraft?`: `boolean`; `title`: `string`; `description?`: `string`; `category`: `string`; `order`: `number`; `grammar?`: \{ `hint`: `string`; `words?`: readonly `object`[]; `text?`: \{ `field`: `string`; `arguments`: \{ \[`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`; \}; `requestIdField?`: `string`; \}; \}; `keys`: readonly `string`[]; `availability`: `WhistleAvailability`; \}\>[] |
319
+ | `draft` | `string` |
320
+ | `options` | `Readonly`\<\{ `idleCategory?`: `string`; \}\> |
318
321
 
319
322
  #### Returns
320
323