@fungi.computer/parakeet 0.5.0 → 0.6.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 (45) hide show
  1. package/README.md +17 -1
  2. package/dist/components/ChatComposer.js +66 -60
  3. package/dist/components/CodeBlock.js +3 -2
  4. package/dist/components/ComposerModelKey.d.ts +11 -0
  5. package/dist/components/ComposerModelKey.js +9 -0
  6. package/dist/components/ComposerShell.d.ts +47 -0
  7. package/dist/components/ComposerShell.js +29 -0
  8. package/dist/components/DecisionComposer.js +1 -2
  9. package/dist/components/TimelineItem.js +1 -1
  10. package/dist/components/ToolGroup.js +2 -2
  11. package/dist/conversation-opening.d.ts +1 -1
  12. package/dist/conversation-opening.js +2 -2
  13. package/dist/conversation.js +12 -9
  14. package/dist/core/build-timeline.js +5 -2
  15. package/dist/core/composer-model-name.d.ts +3 -0
  16. package/dist/core/composer-model-name.js +21 -0
  17. package/dist/core/display-text.d.ts +2 -0
  18. package/dist/core/display-text.js +7 -0
  19. package/dist/core/draft-storage.d.ts +2 -0
  20. package/dist/core/draft-storage.js +14 -1
  21. package/dist/core/session-projection.d.ts +1 -0
  22. package/dist/core/session-projection.js +3 -2
  23. package/dist/core/session-view-state.d.ts +2 -4
  24. package/dist/core/session-view-state.js +33 -13
  25. package/dist/core/tool-groups.d.ts +3 -0
  26. package/dist/core/tool-groups.js +37 -1
  27. package/dist/core/tool-view.d.ts +6 -0
  28. package/dist/core/tool-view.js +33 -0
  29. package/dist/core/use-timeline-item-key.d.ts +3 -4
  30. package/dist/core/use-timeline-item-key.js +8 -14
  31. package/dist/headless.d.ts +4 -3
  32. package/dist/headless.js +4 -3
  33. package/dist/index.d.ts +3 -0
  34. package/dist/index.js +3 -0
  35. package/dist/parakeet.js +9 -11
  36. package/dist/store/types.d.ts +9 -0
  37. package/dist/styles.css +581 -114
  38. package/docs/api/headless.md +124 -41
  39. package/docs/api/index.md +153 -1
  40. package/package.json +11 -8
  41. package/src/completion-menu.css +2 -1
  42. package/src/composer-shell.css +125 -0
  43. package/src/styles.css +5 -87
  44. package/dist/components/WaitingNotice.d.ts +0 -7
  45. package/dist/components/WaitingNotice.js +0 -8
@@ -2064,6 +2064,27 @@ Fixed positions and command anchors follow loaded history, never event time.
2064
2064
 
2065
2065
  ---
2066
2066
 
2067
+ ### sanitizeDisplayText()
2068
+
2069
+ ```ts
2070
+ function sanitizeDisplayText(value): string;
2071
+ ```
2072
+
2073
+ Display text keeps shaping characters, never terminal programs or bidi
2074
+ overrides.
2075
+
2076
+ #### Parameters
2077
+
2078
+ | Parameter | Type |
2079
+ | --------- | -------- |
2080
+ | `value` | `string` |
2081
+
2082
+ #### Returns
2083
+
2084
+ `string`
2085
+
2086
+ ---
2087
+
2067
2088
  ### formatWhen()
2068
2089
 
2069
2090
  ```ts
@@ -2139,11 +2160,32 @@ readonly `Readonly`\<\{ `commandId`: `string`; `outcome`: `"failed"` \|
2139
2160
 
2140
2161
  ---
2141
2162
 
2163
+ ### applySessionFrame()
2164
+
2165
+ ```ts
2166
+ function applySessionFrame(current, frame): SessionSnapshot;
2167
+ ```
2168
+
2169
+ Apply one already-decoded Shiitake frame to its authoritative projection.
2170
+
2171
+ #### Parameters
2172
+
2173
+ | Parameter | Type |
2174
+ | --------- | ----------------- |
2175
+ | `current` | `SessionSnapshot` |
2176
+ | `frame` | `SessionFrame` |
2177
+
2178
+ #### Returns
2179
+
2180
+ `SessionSnapshot`
2181
+
2182
+ ---
2183
+
2142
2184
  ### sessionQueryOptions()
2143
2185
 
2144
2186
  ```ts
2145
2187
  function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2146
- observation: "connecting" | "live";
2188
+ observation: "live" | "connecting";
2147
2189
  snapshot: | Readonly<{
2148
2190
  sessionId: string;
2149
2191
  cursor: string | null;
@@ -2176,6 +2218,8 @@ function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2176
2218
  revision: ...;
2177
2219
  text: ...;
2178
2220
  thinking: ...;
2221
+ textOffset: ...;
2222
+ thinkingOffset: ...;
2179
2223
  textTruncated: ...;
2180
2224
  thinkingTruncated: ...;
2181
2225
  }>
@@ -2203,7 +2247,7 @@ function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2203
2247
  }>
2204
2248
  | undefined;
2205
2249
  }>, Error, Readonly<{
2206
- observation: "connecting" | "live";
2250
+ observation: "live" | "connecting";
2207
2251
  snapshot: | Readonly<{
2208
2252
  sessionId: string;
2209
2253
  cursor: string | null;
@@ -2236,6 +2280,8 @@ function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2236
2280
  revision: ...;
2237
2281
  text: ...;
2238
2282
  thinking: ...;
2283
+ textOffset: ...;
2284
+ thinkingOffset: ...;
2239
2285
  textTruncated: ...;
2240
2286
  thinkingTruncated: ...;
2241
2287
  }>
@@ -2263,7 +2309,7 @@ function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2263
2309
  }>
2264
2310
  | undefined;
2265
2311
  }>, readonly ["shiitake-session", string]>, "queryFn"> & object & QueryKeyWithDataTag<readonly ["shiitake-session", string], Readonly<{
2266
- observation: "connecting" | "live";
2312
+ observation: "live" | "connecting";
2267
2313
  snapshot: | Readonly<{
2268
2314
  sessionId: string;
2269
2315
  cursor: string | null;
@@ -2310,6 +2356,8 @@ function sessionQueryOptions(session): OmitKeyof<UseQueryOptions<Readonly<{
2310
2356
  revision: number;
2311
2357
  text: string;
2312
2358
  thinking: string;
2359
+ textOffset: number;
2360
+ thinkingOffset: number;
2313
2361
  textTruncated: boolean;
2314
2362
  thinkingTruncated: boolean;
2315
2363
  }>
@@ -2349,8 +2397,8 @@ One shared TanStack observation keyed by Shiitake's logical Session address.
2349
2397
 
2350
2398
  #### Returns
2351
2399
 
2352
- `OmitKeyof`\<`UseQueryOptions`\<`Readonly`\<\{ `observation`: `"connecting"` \|
2353
- `"live"`; `snapshot`: \| `Readonly`\<\{ `sessionId`: `string`; `cursor`:
2400
+ `OmitKeyof`\<`UseQueryOptions`\<`Readonly`\<\{ `observation`: `"live"` \|
2401
+ `"connecting"`; `snapshot`: \| `Readonly`\<\{ `sessionId`: `string`; `cursor`:
2354
2402
  `string` \| `null`; `hasMore`: `boolean`; `oldestCursor?`: `string` \| `null`;
2355
2403
  `messages`: readonly `Readonly`\<\{ `requestId?`: ...; `meta?`: ...; `data?`:
2356
2404
  ...; `origin?`: ...; `id`: ...; `sequence`: ...; `commandId`: ...; `value`: ...;
@@ -2360,35 +2408,36 @@ readonly `Readonly`\<...\>[]; `compactionNotices?`: readonly
2360
2408
  `Readonly`\<...\>[]; `sandboxFailures?`: readonly `object`[]; `pending`:
2361
2409
  `SessionPendingPrompts`; `activity`: `SessionActivity`; `progress`: \|
2362
2410
  `Readonly`\<\{ `messageId`: ...; `revision`: ...; `text`: ...; `thinking`: ...;
2363
- `textTruncated`: ...; `thinkingTruncated`: ...; \}\> \| `null`; `toolOutput`:
2364
- readonly `Readonly`\<\{ `toolCallId`: ...; `revision`: ...; `tail`: ...;
2365
- `droppedBytes`: ...; `totalBytes`: ...; \}\>[]; `extensions`:
2366
- `SessionExtensionSlots`; `attention`: readonly `object`[]; `context?`:
2367
- `Readonly`\<\{ `tokens`: ...; `window`: ...; \}\>; \}\> \| `undefined`;
2368
- `lastReplyAt`: `number` \| `undefined`; `latestPrompt`: \| `Readonly`\<\{
2369
- `commandId`: `string`; `text`: `string`; `images`: readonly `object`[] \|
2370
- `undefined`; \}\> \| `undefined`; \}\>, `Error`, `Readonly`\<\{ `observation`:
2371
- `"connecting"` \| `"live"`; `snapshot`: \| `Readonly`\<\{ `sessionId`: `string`;
2372
- `cursor`: `string` \| `null`; `hasMore`: `boolean`; `oldestCursor?`: `string` \|
2373
- `null`; `messages`: readonly `Readonly`\<\{ `requestId?`: ...; `meta?`: ...;
2374
- `data?`: ...; `origin?`: ...; `id`: ...; `sequence`: ...; `commandId`: ...;
2375
- `value`: ...; \}\>[]; `terminals`: readonly `Readonly`\<\{ `commandId`: ...;
2376
- `outcome`: ...; `sequence`: ...; `diagnostic`: ...; `meta?`: ...; \}\>[];
2377
- `compactions?`: readonly `Readonly`\<...\>[]; `compactionNotices?`: readonly
2378
- `Readonly`\<...\>[]; `sandboxFailures?`: readonly `object`[]; `pending`:
2379
- `SessionPendingPrompts`; `activity`: `SessionActivity`; `progress`: \|
2380
- `Readonly`\<\{ `messageId`: ...; `revision`: ...; `text`: ...; `thinking`: ...;
2381
- `textTruncated`: ...; `thinkingTruncated`: ...; \}\> \| `null`; `toolOutput`:
2382
- readonly `Readonly`\<\{ `toolCallId`: ...; `revision`: ...; `tail`: ...;
2383
- `droppedBytes`: ...; `totalBytes`: ...; \}\>[]; `extensions`:
2411
+ `textOffset`: ...; `thinkingOffset`: ...; `textTruncated`: ...;
2412
+ `thinkingTruncated`: ...; \}\> \| `null`; `toolOutput`: readonly `Readonly`\<\{
2413
+ `toolCallId`: ...; `revision`: ...; `tail`: ...; `droppedBytes`: ...;
2414
+ `totalBytes`: ...; \}\>[]; `extensions`: `SessionExtensionSlots`; `attention`:
2415
+ readonly `object`[]; `context?`: `Readonly`\<\{ `tokens`: ...; `window`: ...;
2416
+ \}\>; \}\> \| `undefined`; `lastReplyAt`: `number` \| `undefined`;
2417
+ `latestPrompt`: \| `Readonly`\<\{ `commandId`: `string`; `text`: `string`;
2418
+ `images`: readonly `object`[] \| `undefined`; \}\> \| `undefined`; \}\>,
2419
+ `Error`, `Readonly`\<\{ `observation`: `"live"` \| `"connecting"`; `snapshot`:
2420
+ \| `Readonly`\<\{ `sessionId`: `string`; `cursor`: `string` \| `null`;
2421
+ `hasMore`: `boolean`; `oldestCursor?`: `string` \| `null`; `messages`: readonly
2422
+ `Readonly`\<\{ `requestId?`: ...; `meta?`: ...; `data?`: ...; `origin?`: ...;
2423
+ `id`: ...; `sequence`: ...; `commandId`: ...; `value`: ...; \}\>[]; `terminals`:
2424
+ readonly `Readonly`\<\{ `commandId`: ...; `outcome`: ...; `sequence`: ...;
2425
+ `diagnostic`: ...; `meta?`: ...; \}\>[]; `compactions?`: readonly
2426
+ `Readonly`\<...\>[]; `compactionNotices?`: readonly `Readonly`\<...\>[];
2427
+ `sandboxFailures?`: readonly `object`[]; `pending`: `SessionPendingPrompts`;
2428
+ `activity`: `SessionActivity`; `progress`: \| `Readonly`\<\{ `messageId`: ...;
2429
+ `revision`: ...; `text`: ...; `thinking`: ...; `textOffset`: ...;
2430
+ `thinkingOffset`: ...; `textTruncated`: ...; `thinkingTruncated`: ...; \}\> \|
2431
+ `null`; `toolOutput`: readonly `Readonly`\<\{ `toolCallId`: ...; `revision`:
2432
+ ...; `tail`: ...; `droppedBytes`: ...; `totalBytes`: ...; \}\>[]; `extensions`:
2384
2433
  `SessionExtensionSlots`; `attention`: readonly `object`[]; `context?`:
2385
2434
  `Readonly`\<\{ `tokens`: ...; `window`: ...; \}\>; \}\> \| `undefined`;
2386
2435
  `lastReplyAt`: `number` \| `undefined`; `latestPrompt`: \| `Readonly`\<\{
2387
2436
  `commandId`: `string`; `text`: `string`; `images`: readonly `object`[] \|
2388
2437
  `undefined`; \}\> \| `undefined`; \}\>, readonly \[`"shiitake-session"`,
2389
2438
  `string`\]\>, `"queryFn"`\> & `object` & `QueryKeyWithDataTag`\<readonly
2390
- \[`"shiitake-session"`, `string`\], `Readonly`\<\{ `observation`: `"connecting"`
2391
- \| `"live"`; `snapshot`: \| `Readonly`\<\{ `sessionId`: `string`; `cursor`:
2439
+ \[`"shiitake-session"`, `string`\], `Readonly`\<\{ `observation`: `"live"` \|
2440
+ `"connecting"`; `snapshot`: \| `Readonly`\<\{ `sessionId`: `string`; `cursor`:
2392
2441
  `string` \| `null`; `hasMore`: `boolean`; `oldestCursor?`: `string` \| `null`;
2393
2442
  `messages`: readonly `Readonly`\<\{ `requestId?`: ... \| ...; `meta?`: ... \|
2394
2443
  ...; `data?`: ... \| ...; `origin?`: ... \| ...; `id`: `string`; `sequence`:
@@ -2402,12 +2451,13 @@ readonly `Readonly`\<\{ `commandId`: `string`; `outcome`: ... \| ... \| ... \|
2402
2451
  `sandboxFailures?`: readonly `object`[]; `pending`: `SessionPendingPrompts`;
2403
2452
  `activity`: `SessionActivity`; `progress`: \| `Readonly`\<\{ `messageId`:
2404
2453
  `string`; `revision`: `number`; `text`: `string`; `thinking`: `string`;
2405
- `textTruncated`: `boolean`; `thinkingTruncated`: `boolean`; \}\> \| `null`;
2406
- `toolOutput`: readonly `Readonly`\<\{ `toolCallId`: `string`; `revision`:
2407
- `number`; `tail`: `string`; `droppedBytes`: `number`; `totalBytes`: `number`;
2408
- \}\>[]; `extensions`: `SessionExtensionSlots`; `attention`: readonly `object`[];
2409
- `context?`: `Readonly`\<\{ `tokens`: `number`; `window`: ... \| ...; \}\>; \}\>
2410
- \| `undefined`; `lastReplyAt`: `number` \| `undefined`; `latestPrompt`: \|
2454
+ `textOffset`: `number`; `thinkingOffset`: `number`; `textTruncated`: `boolean`;
2455
+ `thinkingTruncated`: `boolean`; \}\> \| `null`; `toolOutput`: readonly
2456
+ `Readonly`\<\{ `toolCallId`: `string`; `revision`: `number`; `tail`: `string`;
2457
+ `droppedBytes`: `number`; `totalBytes`: `number`; \}\>[]; `extensions`:
2458
+ `SessionExtensionSlots`; `attention`: readonly `object`[]; `context?`:
2459
+ `Readonly`\<\{ `tokens`: `number`; `window`: ... \| ...; \}\>; \}\> \|
2460
+ `undefined`; `lastReplyAt`: `number` \| `undefined`; `latestPrompt`: \|
2411
2461
  `Readonly`\<\{ `commandId`: `string`; `text`: `string`; `images`: readonly
2412
2462
  `object`[] \| `undefined`; \}\> \| `undefined`; \}\>, `Error`\>
2413
2463
 
@@ -2485,23 +2535,35 @@ Decide a Session's view state from its activity, terminals and progress.
2485
2535
 
2486
2536
  ---
2487
2537
 
2488
- ### queuedSessionLabel()
2538
+ ### sessionStateLabel()
2489
2539
 
2490
2540
  ```ts
2491
- function queuedSessionLabel(state): string;
2541
+ function sessionStateLabel(
2542
+ state,
2543
+ waitingOnYou?,
2544
+ ):
2545
+ | "idle"
2546
+ | "thinking"
2547
+ | "failed"
2548
+ | "cancelling"
2549
+ | "streaming"
2550
+ | "running a tool"
2551
+ | "waiting on you";
2492
2552
  ```
2493
2553
 
2494
- Explain a queued Session using its owner's executor fact.
2554
+ Activity only: queued messages belong in the transcript, never in this label.
2495
2555
 
2496
2556
  #### Parameters
2497
2557
 
2498
- | Parameter | Type |
2499
- | --------- | ------------------------------------------------------------------------------------------- |
2500
- | `state` | `Extract`\<[`ParakeetOwnerViewState`](#parakeetownerviewstate), \{ `kind`: `"queued"`; \}\> |
2558
+ | Parameter | Type | Default value |
2559
+ | -------------- | --------------------------------------------------- | ------------- |
2560
+ | `state` | [`ParakeetOwnerViewState`](#parakeetownerviewstate) | `undefined` |
2561
+ | `waitingOnYou` | `boolean` | `false` |
2501
2562
 
2502
2563
  #### Returns
2503
2564
 
2504
- `string`
2565
+ \| `"idle"` \| `"thinking"` \| `"failed"` \| `"cancelling"` \| `"streaming"` \|
2566
+ `"running a tool"` \| `"waiting on you"`
2505
2567
 
2506
2568
  ---
2507
2569
 
@@ -2545,6 +2607,27 @@ Shared tool status meaning, used by the browser and native presentations.
2545
2607
 
2546
2608
  ---
2547
2609
 
2610
+ ### toolLiveLines()
2611
+
2612
+ ```ts
2613
+ function toolLiveLines(call, open): readonly string[];
2614
+ ```
2615
+
2616
+ Live output stays visible when folded, independent of result disclosure.
2617
+
2618
+ #### Parameters
2619
+
2620
+ | Parameter | Type |
2621
+ | --------- | ------------------------------------------------------- |
2622
+ | `call` | [`ParakeetToolCallView`](index.md#parakeettoolcallview) |
2623
+ | `open` | `boolean` |
2624
+
2625
+ #### Returns
2626
+
2627
+ readonly `string`[]
2628
+
2629
+ ---
2630
+
2548
2631
  ### toolCallView()
2549
2632
 
2550
2633
  ```ts
package/docs/api/index.md CHANGED
@@ -20,6 +20,64 @@ What the head is doing: at rest, working something out, or talking.
20
20
 
21
21
  ---
22
22
 
23
+ ### ComposerModelKeyProps
24
+
25
+ ```ts
26
+ type ComposerModelKeyProps = Omit<
27
+ KeycapButtonProps,
28
+ "icon" | "readout" | "label"
29
+ > &
30
+ object;
31
+ ```
32
+
33
+ A model label on the shared native key; callers own selection and menus.
34
+
35
+ #### Type Declaration
36
+
37
+ | Name | Type | Description |
38
+ | ------- | -------- | ------------------------------------------------------------------------ |
39
+ | `label` | `string` | Friendly catalog name, or the real model identity when no name is known. |
40
+
41
+ ---
42
+
43
+ ### ComposerShellRow
44
+
45
+ ```ts
46
+ type ComposerShellRow = Readonly<{
47
+ controls: ReactNode;
48
+ action: ReactNode;
49
+ status?: ReactNode;
50
+ readout?: ReactNode;
51
+ items: readonly StatusTrayItem[];
52
+ openId: string | null;
53
+ onOpenChange: (id) => void;
54
+ }>;
55
+ ```
56
+
57
+ App-owned controls and tray contents; Parakeet owns their single row.
58
+
59
+ ---
60
+
61
+ ### ComposerShellProps
62
+
63
+ ```ts
64
+ type ComposerShellProps = HTMLAttributes<HTMLDivElement> & object;
65
+ ```
66
+
67
+ Content slots for the shared chat and generation composer surface.
68
+
69
+ #### Type Declaration
70
+
71
+ | Name | Type | Description |
72
+ | -------------- | --------------------------------------- | ----------------------------------------------------------------- |
73
+ | `input` | `ReactNode` | Draft field or decision surface, using the shared input geometry. |
74
+ | `attachments?` | `ReactNode` | Optional draft attachments rendered by the Composer primitive. |
75
+ | `action?` | `ReactNode` | Retained field-and-Send mode without an internal control row. |
76
+ | `menu?` | `ReactNode` | Optional completion menu anchored to this shell. |
77
+ | `row?` | [`ComposerShellRow`](#composershellrow) | Omit while a decision owns the input and its own actions. |
78
+
79
+ ---
80
+
23
81
  ### InteractionPanelProps
24
82
 
25
83
  ```ts
@@ -232,6 +290,7 @@ Durable owner identity, independent of the current service endpoint.
232
290
  type ParakeetDraftStorage = Readonly<{
233
291
  getItem: (key) => string | null;
234
292
  setItem: (key, value) => void;
293
+ removeItem: (key) => void;
235
294
  }>;
236
295
  ```
237
296
 
@@ -464,6 +523,7 @@ type ParakeetToolCallView = Readonly<{
464
523
  exitCode?: number;
465
524
  error?: string;
466
525
  sections: readonly ParakeetToolCallSection[];
526
+ live?: ParakeetToolItem["live"];
467
527
  }>;
468
528
  ```
469
529
 
@@ -781,6 +841,11 @@ type ParakeetToolItem = Readonly<{
781
841
  data?: SessionMessage["data"];
782
842
  startedAt?: number;
783
843
  status: "completed" | "error" | "running" | "unknown";
844
+ live?: Readonly<{
845
+ lines: readonly string[];
846
+ droppedBytes: number;
847
+ revision: number;
848
+ }>;
784
849
  }>;
785
850
  ```
786
851
 
@@ -932,6 +997,20 @@ ready. The live canvas stays mounted and is paused unless `thinking` or
932
997
 
933
998
  ---
934
999
 
1000
+ ### ComposerModelKey
1001
+
1002
+ ```ts
1003
+ const ComposerModelKey: ForwardRefExoticComponent<
1004
+ Omit<KeycapButtonProps, "label" | "icon" | "readout"> &
1005
+ object &
1006
+ RefAttributes<HTMLButtonElement>
1007
+ >;
1008
+ ```
1009
+
1010
+ The same model face and chevron in chat and generation composers.
1011
+
1012
+ ---
1013
+
935
1014
  ### ShiitakeAvatar
936
1015
 
937
1016
  ```ts
@@ -977,6 +1056,72 @@ Defaults only, with no reader choices.
977
1056
 
978
1057
  ## Functions
979
1058
 
1059
+ ### composerSendState()
1060
+
1061
+ ```ts
1062
+ function composerSendState(__namedParameters): SendActionState;
1063
+ ```
1064
+
1065
+ One input-to-action rule for both Apps; Caps owns the resulting key's look.
1066
+
1067
+ #### Parameters
1068
+
1069
+ | Parameter | Type | Description |
1070
+ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
1071
+ | `__namedParameters` | \{ `draft`: `string`; `hasAttachments?`: `boolean`; `busy`: `boolean`; `queueWhileBusy?`: `boolean`; `blocked?`: `boolean`; \} | - |
1072
+ | `__namedParameters.draft` | `string` | - |
1073
+ | `__namedParameters.hasAttachments?` | `boolean` | - |
1074
+ | `__namedParameters.busy` | `boolean` | - |
1075
+ | `__namedParameters.queueWhileBusy?` | `boolean` | Chat can queue a follow-up; generation stays busy until it settles. |
1076
+ | `__namedParameters.blocked?` | `boolean` | An input owner can temporarily block submission, such as during recall. |
1077
+
1078
+ #### Returns
1079
+
1080
+ `SendActionState`
1081
+
1082
+ ---
1083
+
1084
+ ### ComposerShell()
1085
+
1086
+ ```ts
1087
+ function ComposerShell(__namedParameters): Element;
1088
+ ```
1089
+
1090
+ One field surface and one non-wrapping control row, with Send at its end.
1091
+
1092
+ #### Parameters
1093
+
1094
+ | Parameter | Type |
1095
+ | ------------------- | ------------------------------------------- |
1096
+ | `__namedParameters` | [`ComposerShellProps`](#composershellprops) |
1097
+
1098
+ #### Returns
1099
+
1100
+ `Element`
1101
+
1102
+ ---
1103
+
1104
+ ### useComposerTextareaSize()
1105
+
1106
+ ```ts
1107
+ function useComposerTextareaSize(ref, value): void;
1108
+ ```
1109
+
1110
+ Grow either App's field with its draft; shell CSS owns the height limits.
1111
+
1112
+ #### Parameters
1113
+
1114
+ | Parameter | Type |
1115
+ | --------- | ------------------------------------ |
1116
+ | `ref` | `RefObject`\<`HTMLTextAreaElement`\> |
1117
+ | `value` | `string` |
1118
+
1119
+ #### Returns
1120
+
1121
+ `void`
1122
+
1123
+ ---
1124
+
980
1125
  ### InteractionPanel()
981
1126
 
982
1127
  ```ts
@@ -1183,6 +1328,11 @@ function visibleToolCalls(
1183
1328
  exitCode?: number;
1184
1329
  error?: string;
1185
1330
  sections: readonly ParakeetToolCallSection[];
1331
+ live?: Readonly<{
1332
+ lines: readonly string[];
1333
+ droppedBytes: number;
1334
+ revision: number;
1335
+ }>;
1186
1336
  }>[];
1187
1337
  ```
1188
1338
 
@@ -1202,7 +1352,9 @@ readonly `Readonly`\<\{ `id`: `string`; `kind`:
1202
1352
  `activeVerb`: `string`; `label`: `string`; `paths`: readonly `string`[];
1203
1353
  `status`: `"error"` \| `"unknown"` \| `"running"` \| `"completed"`;
1204
1354
  `durationMs?`: `number`; `exitCode?`: `number`; `error?`: `string`; `sections`:
1205
- readonly [`ParakeetToolCallSection`](#parakeettoolcallsection)[]; \}\>[]
1355
+ readonly [`ParakeetToolCallSection`](#parakeettoolcallsection)[]; `live?`:
1356
+ `Readonly`\<\{ `lines`: readonly `string`[]; `droppedBytes`: `number`;
1357
+ `revision`: `number`; \}\>; \}\>[]
1206
1358
 
1207
1359
  ---
1208
1360
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/parakeet",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "author": "Levi <levi@technomancy.dev>",
5
5
  "private": false,
6
6
  "description": "Standalone React composer for a typed Shiitake Session",
@@ -36,6 +36,7 @@
36
36
  "import": "./dist/components/CompletionMenu.js"
37
37
  },
38
38
  "./completion-menu.css": "./src/completion-menu.css",
39
+ "./composer-shell.css": "./src/composer-shell.css",
39
40
  "./styles.css": "./dist/styles.css",
40
41
  "./tailwind.css": "./src/styles.css"
41
42
  },
@@ -45,6 +46,7 @@
45
46
  "LICENSE",
46
47
  "src/styles.css",
47
48
  "src/completion-menu.css",
49
+ "src/composer-shell.css",
48
50
  "docs/api"
49
51
  ],
50
52
  "peerDependencies": {
@@ -53,16 +55,17 @@
53
55
  "react-dom": "^18.2.0 || ^19.2.0"
54
56
  },
55
57
  "dependencies": {
56
- "@fungi.computer/agar": "0.5.0",
57
- "@fungi.computer/bird-dog": "0.3.0",
58
+ "@earendil-works/pi-ai": "1.3.0",
59
+ "@fungi.computer/agar": "0.6.1",
60
+ "@fungi.computer/bird-dog": "0.3.1",
58
61
  "@fungi.computer/cairn": "0.1.0",
59
- "@fungi.computer/caps": "0.4.0",
62
+ "@fungi.computer/caps": "0.6.0",
60
63
  "@fungi.computer/gills": "0.2.0",
61
- "@fungi.computer/knapsack": "0.4.0",
62
- "@fungi.computer/shiitake": "0.6.0",
63
- "@fungi.computer/sigils": "0.2.0",
64
+ "@fungi.computer/knapsack": "0.4.2",
65
+ "@fungi.computer/shiitake": "0.8.0",
66
+ "@fungi.computer/sigils": "0.2.1",
64
67
  "@fungi.computer/sprite": "0.2.0",
65
- "@fungi.computer/sprite-zdog": "0.2.0",
68
+ "@fungi.computer/sprite-zdog": "0.3.0",
66
69
  "@fungi.computer/whistle": "0.3.0",
67
70
  "@tanstack/markdown": "0.0.12",
68
71
  "@tanstack/react-virtual": "3.14.10",
@@ -5,7 +5,8 @@
5
5
  * same width and inset, flush on its top edge, and the surface's own top
6
6
  * border is the one line between them. --parakeet-completion-inset is the
7
7
  * distance from the menu's containing block to the surface's outer edge: an
8
- * anchor's padding (Grove) or minus a positioned card's border (Prints).
8
+ * anchor's padding or a field's own containing box. ComposerShell supplies
9
+ * zero inset; there is no Prints-specific negative card-border offset.
9
10
  * --parakeet-completion-face and --parakeet-completion-edge carry the
10
11
  * surface's own background and border colour, so the two read as one.
11
12
  */
@@ -0,0 +1,125 @@
1
+ /* Chat and generation share one surface, field inset and control-row grid.
2
+ Apps supply controls and content, never a second composer layout. */
3
+ .parakeet-composer-anchor {
4
+ --parakeet-completion-inset: 0px;
5
+ --parakeet-completion-face: var(--color-base-200);
6
+ --parakeet-completion-edge: var(--stipe-hairline);
7
+ display: block;
8
+ min-width: 0;
9
+ }
10
+
11
+ .parakeet-composer-anchor:has([data-parakeet-slash])
12
+ > .parakeet-composer-shell {
13
+ border-start-start-radius: 0;
14
+ border-start-end-radius: 0;
15
+ }
16
+
17
+ .parakeet-composer-shell {
18
+ padding: var(--spacing-sm);
19
+ container-type: inline-size;
20
+ }
21
+
22
+ .parakeet-composer-shell .caps-composer-input {
23
+ padding: var(--spacing-xs) var(--spacing-sm) 0;
24
+ }
25
+
26
+ .parakeet-composer-shell .caps-composer-input textarea {
27
+ min-height: 3rem;
28
+ max-height: 160px;
29
+ padding: var(--spacing-xs) 0;
30
+ resize: none;
31
+ overflow-x: hidden;
32
+ overflow-y: auto;
33
+ white-space: pre-wrap;
34
+ overflow-wrap: break-word;
35
+ font-family: var(--font-sans);
36
+ font-size: var(--text-base);
37
+ line-height: 1.6;
38
+ }
39
+
40
+ .parakeet-composer-shell .parakeet-composer-row {
41
+ --caps-status-tray-row-wrap: nowrap;
42
+ padding: var(--spacing-xs);
43
+ }
44
+
45
+ .parakeet-composer-row .caps-status-tray-row {
46
+ white-space: nowrap;
47
+ }
48
+
49
+ /* A menu trigger can carry Button's touch minimum as well as its Keycap face.
50
+ The shared row, not either App or the generic Button, owns key geometry. */
51
+ .parakeet-composer-row .caps-keycap-button {
52
+ height: var(--caps-status-tray-key-height);
53
+ min-height: var(--caps-status-tray-key-height);
54
+ }
55
+
56
+ /* Composer keys already disclose through their face and chevron. Keep native
57
+ expanded/pressed semantics without redundant decorative corner lamps. */
58
+ .parakeet-composer-row .caps-keycap-led {
59
+ display: none;
60
+ }
61
+
62
+ .parakeet-composer-row [data-status-tray-chip] {
63
+ min-width: 0;
64
+ }
65
+
66
+ .parakeet-composer-row .caps-status-tray-label,
67
+ .parakeet-composer-row .caps-keycap-button-label {
68
+ min-width: 0;
69
+ overflow: hidden;
70
+ text-overflow: ellipsis;
71
+ white-space: nowrap;
72
+ }
73
+
74
+ .parakeet-composer-row .parakeet-composer-model-key {
75
+ --caps-keycap-justify: space-between;
76
+ flex: 0 1 auto;
77
+ min-width: 4.5rem;
78
+ max-width: 220px;
79
+ font-size: var(--text-xs);
80
+ }
81
+
82
+ .parakeet-composer-trailing {
83
+ display: flex;
84
+ align-items: center;
85
+ flex: none;
86
+ gap: var(--spacing-xs);
87
+ margin-inline-start: auto;
88
+ }
89
+
90
+ .parakeet-composer-action {
91
+ display: flex;
92
+ flex: none;
93
+ }
94
+
95
+ .parakeet-composer-readout {
96
+ color: var(--stipe-fg-muted);
97
+ font-size: var(--text-xs);
98
+ line-height: 1;
99
+ font-variant-numeric: tabular-nums;
100
+ white-space: nowrap;
101
+ }
102
+
103
+ .parakeet-composer-row .composer-attention-label {
104
+ @apply sr-only;
105
+ }
106
+
107
+ .parakeet-composer-row .parakeet-composer-status {
108
+ gap: 0;
109
+ }
110
+
111
+ /* The status dot stays beside Send when usage yields to Settings; the model
112
+ label then yields to ellipsis.
113
+ Edge keys never shrink or change rows. The budget is the shell's width:
114
+ Grove's split pane can be narrower at 900px than at 640px. */
115
+ @container (max-width: 34rem) {
116
+ .parakeet-composer-readout {
117
+ display: none;
118
+ }
119
+ }
120
+
121
+ @container (max-width: 26rem) {
122
+ .parakeet-composer-row .parakeet-composer-model-key {
123
+ max-width: 7rem;
124
+ }
125
+ }