@workerdeck/ui 0.23.0 → 1.0.0
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/build/{SessionPanel-DUt2VzXG.mjs → SessionPanel-DDgBkHsi.mjs} +2151 -3357
- package/build/SessionPanel-DDgBkHsi.mjs.map +1 -0
- package/build/SessionPanel-E_L_ldQ5.d.mts +207 -0
- package/build/format-B8ZM9LPy.d.mts +16 -0
- package/build/format.d.mts +8 -75
- package/build/format.mjs +2 -2
- package/build/index.d.mts +63 -1138
- package/build/index.mjs +4 -300
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +15 -23
- package/build/{status-BE-zg88x.mjs → status-C0HSLZas.mjs} +14 -85
- package/build/status-C0HSLZas.mjs.map +1 -0
- package/build/workspace.d.mts +5 -126
- package/build/workspace.mjs +11 -143
- package/build/workspace.mjs.map +1 -1
- package/package.json +4 -4
- package/src/components/agent/CodeEditor.tsx +31 -103
- package/src/components/agent/Composer.tsx +114 -333
- package/src/components/agent/ContextDialog.tsx +20 -41
- package/src/components/agent/ContextRing.tsx +6 -28
- package/src/components/agent/Conversation.tsx +21 -33
- package/src/components/agent/EditorTabs.tsx +39 -67
- package/src/components/agent/EngineIcon.tsx +29 -72
- package/src/components/agent/EntryIcon.tsx +16 -0
- package/src/components/agent/FileCard.tsx +10 -16
- package/src/components/agent/FileTree.tsx +52 -125
- package/src/components/agent/FileViewer.tsx +30 -60
- package/src/components/agent/HostFilesDialog.tsx +40 -69
- package/src/components/agent/Loader.tsx +3 -24
- package/src/components/agent/McpDialog.tsx +64 -137
- package/src/components/agent/Message.tsx +2 -21
- package/src/components/agent/ModelSelect.tsx +33 -62
- package/src/components/agent/PermissionModeSelect.tsx +21 -79
- package/src/components/agent/PermissionPrompt.tsx +59 -63
- package/src/components/agent/ProjectIcon.tsx +228 -93
- package/src/components/agent/PromptTokenText.tsx +10 -16
- package/src/components/agent/QuestionPrompt.tsx +43 -64
- package/src/components/agent/Reasoning.tsx +13 -16
- package/src/components/agent/Response.tsx +3 -9
- package/src/components/agent/Scrubber.tsx +31 -80
- package/src/components/agent/SessionBrowser.tsx +64 -243
- package/src/components/agent/SessionEmptyState.tsx +10 -40
- package/src/components/agent/SessionInfoDialog.tsx +46 -78
- package/src/components/agent/SessionItem.tsx +53 -320
- package/src/components/agent/SessionList.tsx +23 -39
- package/src/components/agent/SessionPanel.tsx +315 -996
- package/src/components/agent/SessionStatusIcon.tsx +14 -28
- package/src/components/agent/SessionSteps.tsx +34 -187
- package/src/components/agent/SessionWorkspace.tsx +104 -219
- package/src/components/agent/SkillsDialog.tsx +35 -80
- package/src/components/agent/StatusBar.tsx +51 -136
- package/src/components/agent/SubagentStrip.tsx +12 -77
- package/src/components/agent/ToolCallCard.tsx +94 -135
- package/src/components/agent/Transcript.tsx +103 -1288
- package/src/components/agent/TranscriptItemView.tsx +155 -0
- package/src/components/agent/TranscriptRows.tsx +418 -0
- package/src/components/agent/UsageDialog.tsx +7 -29
- package/src/components/agent/UsageMeters.tsx +18 -73
- package/src/components/agent/pulse.tsx +9 -32
- package/src/components/agent/scrubber-marks.ts +33 -103
- package/src/components/agent/status.ts +1 -5
- package/src/components/agent/tool-result-fetch.tsx +3 -25
- package/src/components/agent/tool-result-image.tsx +32 -111
- package/src/components/agent/transcript-rows.ts +41 -118
- package/src/components/agent/transcript-variant.tsx +3 -80
- package/src/components/agent/use-height-epoch.ts +10 -24
- package/src/components/agent/use-path-links.ts +45 -63
- package/src/components/agent/use-subagent-frame.ts +106 -0
- package/src/components/agent/use-transcript-jumps.ts +49 -107
- package/src/components/prompt-area/animated-placeholder.tsx +6 -5
- package/src/components/prompt-area/clipboard-helpers.ts +26 -21
- package/src/components/prompt-area/cursor-helpers.ts +79 -37
- package/src/components/prompt-area/dom-helpers.ts +97 -69
- package/src/components/prompt-area/file-strip.tsx +90 -80
- package/src/components/prompt-area/html-to-markdown.ts +67 -46
- package/src/components/prompt-area/image-strip.tsx +8 -18
- package/src/components/prompt-area/index.ts +2 -15
- package/src/components/prompt-area/prompt-area-engine.ts +100 -115
- package/src/components/prompt-area/prompt-area-list-ops.ts +66 -59
- package/src/components/prompt-area/prompt-area.tsx +31 -38
- package/src/components/prompt-area/remove-button.tsx +3 -9
- package/src/components/prompt-area/segment-helpers.ts +4 -12
- package/src/components/prompt-area/trigger-popover.tsx +15 -27
- package/src/components/prompt-area/trigger-presets.ts +0 -10
- package/src/components/prompt-area/types.ts +3 -8
- package/src/components/prompt-area/use-chip-editing.ts +305 -0
- package/src/components/prompt-area/use-markdown-mode.ts +7 -17
- package/src/components/prompt-area/use-prompt-area-events.ts +80 -86
- package/src/components/prompt-area/use-prompt-area-keydown.ts +598 -0
- package/src/components/prompt-area/use-prompt-area-state.ts +5 -23
- package/src/components/prompt-area/use-prompt-area.ts +170 -896
- package/src/components/prompt-area/use-trigger-search.ts +21 -19
- package/src/components/terminal/PermissionPrompt.tsx +56 -59
- package/src/components/terminal/QuestionPrompt.tsx +28 -79
- package/src/components/terminal/StatusLine.tsx +13 -63
- package/src/components/terminal/TerminalTranscript.tsx +44 -160
- package/src/components/terminal/affordances.tsx +68 -98
- package/src/components/terminal/blocks.ts +20 -156
- package/src/components/terminal/diff.tsx +19 -67
- package/src/components/terminal/height.ts +163 -313
- package/src/components/terminal/image-box.ts +0 -44
- package/src/components/terminal/items.tsx +150 -305
- package/src/components/terminal/markdown.tsx +36 -95
- package/src/components/terminal/press.tsx +26 -53
- package/src/components/terminal/prompt.tsx +40 -170
- package/src/components/terminal/result-preview.ts +8 -56
- package/src/components/terminal/row.tsx +11 -98
- package/src/components/terminal/scrubber.tsx +108 -401
- package/src/components/terminal/surface.tsx +6 -54
- package/src/components/terminal/todos.ts +66 -0
- package/src/components/terminal/tool-run.ts +21 -192
- package/src/components/ui/AlertDialog.tsx +8 -23
- package/src/components/ui/Badge.tsx +18 -29
- package/src/components/ui/Button.tsx +7 -15
- package/src/components/ui/Card.tsx +2 -13
- package/src/components/ui/CodeBlock.tsx +10 -37
- package/src/components/ui/CopyButton.tsx +10 -23
- package/src/components/ui/Dialog.tsx +23 -36
- package/src/components/ui/Empty.tsx +6 -29
- package/src/components/ui/Input.tsx +14 -16
- package/src/components/ui/Menu.tsx +6 -18
- package/src/components/ui/PortalScope.tsx +1 -21
- package/src/components/ui/ProgressRing.tsx +8 -19
- package/src/components/ui/Select.tsx +18 -31
- package/src/components/ui/Sonner.tsx +1 -2
- package/src/components/ui/Spinner.tsx +1 -1
- package/src/components/ui/Splitter.tsx +30 -64
- package/src/components/ui/Textarea.tsx +2 -5
- package/src/components/ui/Tooltip.tsx +3 -13
- package/src/format.ts +0 -9
- package/src/index.ts +16 -113
- package/src/lib/clipboard.ts +8 -28
- package/src/lib/css.ts +8 -0
- package/src/lib/format.ts +101 -86
- package/src/lib/plan-request.ts +16 -0
- package/src/lib/status.ts +45 -95
- package/src/lib/tool-icon.ts +39 -47
- package/src/lib/utils.ts +1 -3
- package/src/styles/terminal.css +81 -49
- package/src/styles/theme.css +96 -32
- package/src/workspace.ts +1 -24
- package/build/SessionPanel-BobynUo4.d.mts +0 -669
- package/build/SessionPanel-DUt2VzXG.mjs.map +0 -1
- package/build/format-ljc3lKpA.d.mts +0 -59
- package/build/status-BE-zg88x.mjs.map +0 -1
package/build/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as formatDuration, c as formatRelativeTime, d as rateLimitWindowSeconds, f as toolInputPreview, i as formatCountdown, l as formatTokens, n as formatBytes, o as formatRateLimitWindow, r as formatCost, s as formatRateLimitWindowLong, t as formatAgoPrecise, u as friendlyModel } from "./format-
|
|
2
|
-
import { C as permissionModeChoices, S as PermissionModeSelectProps, _ as useAffordances, a as SessionVitals, b as PermissionModeMeta, c as TranscriptDensityProvider, d as TranscriptVariantProvider, f as useTranscriptDensity, g as WithActions, h as TerminalAffordances, i as SessionSurfacePanel, l as TranscriptFont, m as CopyAction, n as SessionPanel, o as TerminalMetrics, p as useTranscriptVariant, r as SessionPanelProps, s as TranscriptDensity, t as SessionControls, u as TranscriptVariant, v as PERMISSION_MODES, w as permissionModeMeta, x as PermissionModeSelect, y as PermissionModeChoice } from "./SessionPanel-
|
|
1
|
+
import { a as formatDuration, c as formatRelativeTime, d as rateLimitWindowSeconds, f as toolInputPreview, i as formatCountdown, l as formatTokens, n as formatBytes, o as formatRateLimitWindow, r as formatCost, s as formatRateLimitWindowLong, t as formatAgoPrecise, u as friendlyModel } from "./format-B8ZM9LPy.mjs";
|
|
2
|
+
import { C as permissionModeChoices, S as PermissionModeSelectProps, _ as useAffordances, a as SessionVitals, b as PermissionModeMeta, c as TranscriptDensityProvider, d as TranscriptVariantProvider, f as useTranscriptDensity, g as WithActions, h as TerminalAffordances, i as SessionSurfacePanel, l as TranscriptFont, m as CopyAction, n as SessionPanel, o as TerminalMetrics, p as useTranscriptVariant, r as SessionPanelProps, s as TranscriptDensity, t as SessionControls, u as TranscriptVariant, v as PERMISSION_MODES, w as permissionModeMeta, x as PermissionModeSelect, y as PermissionModeChoice } from "./SessionPanel-E_L_ldQ5.mjs";
|
|
3
3
|
import * as _$react from "react";
|
|
4
4
|
import { ButtonHTMLAttributes, FunctionComponent, HTMLAttributes, InputHTMLAttributes, ReactElement, ReactNode, Ref, RefObject, TextareaHTMLAttributes } from "react";
|
|
5
5
|
import { VariantProps } from "class-variance-authority";
|
|
@@ -34,7 +34,6 @@ declare const badgeVariants: (props?: ({
|
|
|
34
34
|
mono?: boolean | null | undefined;
|
|
35
35
|
} & _$class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
36
36
|
interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
|
|
37
|
-
/** Render a leading status dot in the variant's color. */
|
|
38
37
|
dot?: boolean;
|
|
39
38
|
}
|
|
40
39
|
declare function Badge({
|
|
@@ -99,25 +98,15 @@ declare const MenuSeparator: FunctionComponent<Menu$1.Separator.Props>;
|
|
|
99
98
|
declare const Dialog: typeof Dialog$1.Root;
|
|
100
99
|
declare const DialogTrigger: Dialog$1.Trigger;
|
|
101
100
|
declare const DialogClose: _$react.ForwardRefExoticComponent<Omit<_$_base_ui_react_dialog0.DialogCloseProps, "ref"> & _$react.RefAttributes<HTMLButtonElement>>;
|
|
102
|
-
/**
|
|
103
|
-
* A dismissible panel, sized for reading rather than confirming — the web
|
|
104
|
-
* counterpart of the iOS app's detail sheets (context, usage, session info, MCP).
|
|
105
|
-
*
|
|
106
|
-
* Taller than {@link AlertDialogContent} and scrollable inside, because these
|
|
107
|
-
* carry lists whose length is the engine's business, not the layout's.
|
|
108
|
-
*/
|
|
109
101
|
declare const DialogContent: FunctionComponent<Dialog$1.Popup.Props & {
|
|
110
102
|
size?: 'sm' | 'md' | 'lg';
|
|
111
103
|
}>;
|
|
112
|
-
/** Title row with the close button, pinned above the scrolling body. */
|
|
113
104
|
declare const DialogHeader: FunctionComponent<{
|
|
114
105
|
title: string;
|
|
115
|
-
description?: string;
|
|
106
|
+
description?: string;
|
|
116
107
|
actions?: React.ReactNode;
|
|
117
108
|
}>;
|
|
118
|
-
/** The scrolling region under the header. */
|
|
119
109
|
declare const DialogBody: FunctionComponent<React.HTMLAttributes<HTMLDivElement>>;
|
|
120
|
-
/** A label/value row — the shape every one of these panels is mostly made of. */
|
|
121
110
|
declare const DialogRow: FunctionComponent<{
|
|
122
111
|
label: string;
|
|
123
112
|
children: React.ReactNode;
|
|
@@ -127,14 +116,6 @@ declare const DialogRow: FunctionComponent<{
|
|
|
127
116
|
//#region src/components/ui/Tooltip.d.ts
|
|
128
117
|
declare const TooltipProvider: _$react.FC<_$_base_ui_react_tooltip0.TooltipProviderProps>;
|
|
129
118
|
declare const TooltipContent: FunctionComponent<Tooltip.Popup.Props & Pick<Tooltip.Positioner.Props, 'side' | 'sideOffset'>>;
|
|
130
|
-
/**
|
|
131
|
-
* Convenience wrapper: `<Tip content="..."><Button/></Tip>`.
|
|
132
|
-
*
|
|
133
|
-
* Pass `render` when the trigger must *be* an element you already have — a tab, a
|
|
134
|
-
* row — rather than something wrapped in a span. The default span is fine beside
|
|
135
|
-
* a button but would break any layout that styles its own children (a flex tab
|
|
136
|
-
* strip gets an extra box between the container and its items).
|
|
137
|
-
*/
|
|
138
119
|
declare function Tip({
|
|
139
120
|
content,
|
|
140
121
|
render,
|
|
@@ -148,14 +129,11 @@ declare function Tip({
|
|
|
148
129
|
}): _$react.JSX.Element;
|
|
149
130
|
//#endregion
|
|
150
131
|
//#region src/components/ui/Sonner.d.ts
|
|
151
|
-
/** Token-themed toaster; relies on the [data-theme] swap, so no `theme` prop needed. */
|
|
152
132
|
declare function Toaster(): _$react.JSX.Element;
|
|
153
133
|
//#endregion
|
|
154
134
|
//#region src/components/ui/CopyButton.d.ts
|
|
155
135
|
interface CopyButtonProps extends Omit<ButtonProps, 'onClick' | 'children'> {
|
|
156
136
|
value: string;
|
|
157
|
-
/** Draw the state as characters (`⧉` / `✓`) rather than line-art icons — for
|
|
158
|
-
* terminal-styled surfaces, where an SVG reads as another app's button. */
|
|
159
137
|
glyph?: boolean;
|
|
160
138
|
}
|
|
161
139
|
declare function CopyButton({
|
|
@@ -177,24 +155,11 @@ declare function Spinner({
|
|
|
177
155
|
//#region src/components/ui/CodeBlock.d.ts
|
|
178
156
|
interface CodeBlockProps {
|
|
179
157
|
code: string;
|
|
180
|
-
/** Header label, e.g. a language or "Parameters". */
|
|
181
158
|
label?: ReactNode;
|
|
182
159
|
copyable?: boolean;
|
|
183
|
-
/**
|
|
184
|
-
* `'panel'` (default) is the framed card: border, header strip, rounded.
|
|
185
|
-
* `'plain'` is the terminal treatment — the label is a dim line, the code a
|
|
186
|
-
* flat band, and copy is a character. For surfaces where a box around every
|
|
187
|
-
* payload is more chrome than content (the transcript's `lines` variant).
|
|
188
|
-
*
|
|
189
|
-
* A prop rather than a read of the transcript's variant context: this is a
|
|
190
|
-
* `ui/` primitive and has no business knowing what a transcript is. The agent
|
|
191
|
-
* component that renders it does.
|
|
192
|
-
*/
|
|
193
160
|
variant?: 'panel' | 'plain';
|
|
194
161
|
className?: string;
|
|
195
162
|
}
|
|
196
|
-
/** Plain (unhighlighted) code panel for structured data like tool inputs. Markdown code
|
|
197
|
-
* inside assistant responses is highlighted by <Response> instead. */
|
|
198
163
|
declare function CodeBlock({
|
|
199
164
|
code,
|
|
200
165
|
label,
|
|
@@ -205,49 +170,17 @@ declare function CodeBlock({
|
|
|
205
170
|
//#endregion
|
|
206
171
|
//#region src/components/ui/Splitter.d.ts
|
|
207
172
|
interface SplitterProps {
|
|
208
|
-
/**
|
|
209
|
-
* ARIA's sense of the word: a `vertical` splitter is a vertical bar between
|
|
210
|
-
* two side-by-side panes, and it resizes a **width**. A `horizontal` one sits
|
|
211
|
-
* between stacked panes and resizes a **height**.
|
|
212
|
-
*/
|
|
213
173
|
orientation: 'vertical' | 'horizontal';
|
|
214
|
-
/** Current size of the pane this splitter controls, in pixels. */
|
|
215
174
|
value: number;
|
|
216
175
|
onValueChange: (value: number) => void;
|
|
217
176
|
min: number;
|
|
218
177
|
max: number;
|
|
219
|
-
/** Keyboard step. */
|
|
220
178
|
step?: number;
|
|
221
|
-
/**
|
|
222
|
-
* Size to snap back to on a double-click — the convention every pane divider
|
|
223
|
-
* that can be dragged is expected to honour. Omit and a double-click does
|
|
224
|
-
* nothing, which is the honest behaviour when there is no default to mean.
|
|
225
|
-
*/
|
|
226
179
|
defaultValue?: number;
|
|
227
|
-
/** Set when dragging the splitter *away* from the origin should shrink the
|
|
228
|
-
* controlled pane — i.e. the pane is on the right or the bottom. */
|
|
229
180
|
inverted?: boolean;
|
|
230
|
-
/** Required: "Resize" alone does not say which of two splitters this is. */
|
|
231
181
|
'aria-label': string;
|
|
232
182
|
className?: string;
|
|
233
183
|
}
|
|
234
|
-
/**
|
|
235
|
-
* A draggable pane divider.
|
|
236
|
-
*
|
|
237
|
-
* Hand-rolled rather than depended on: `@base-ui/react` ships no splitter, the
|
|
238
|
-
* behaviour is a hundred lines of pointer events, and this repo's instinct at
|
|
239
|
-
* this layer is to own it (the composer is vendored for the same reason).
|
|
240
|
-
*
|
|
241
|
-
* Pointer capture is what makes it survive a fast drag — without it the pointer
|
|
242
|
-
* leaves the 5px bar within a frame and the moves go to whatever is underneath,
|
|
243
|
-
* which for this layout is an iframe-free but still selection-happy code pane.
|
|
244
|
-
* The drag origin is captured on pointerdown and every move is measured against
|
|
245
|
-
* it, so the pane cannot drift relative to the cursor over a long drag the way
|
|
246
|
-
* per-move deltas do once clamping is involved.
|
|
247
|
-
*
|
|
248
|
-
* Keyboard-operable and announced as a separator, because a pane you can only
|
|
249
|
-
* size by dragging is a pane some people cannot size.
|
|
250
|
-
*/
|
|
251
184
|
declare function Splitter({
|
|
252
185
|
orientation,
|
|
253
186
|
value,
|
|
@@ -262,22 +195,6 @@ declare function Splitter({
|
|
|
262
195
|
}: SplitterProps): _$react.JSX.Element;
|
|
263
196
|
//#endregion
|
|
264
197
|
//#region src/components/ui/Empty.d.ts
|
|
265
|
-
/**
|
|
266
|
-
* A view with nothing in it: icon, title, description, and at most one action.
|
|
267
|
-
*
|
|
268
|
-
* Centered and given room, because an empty view is the first thing a new
|
|
269
|
-
* install shows and a flush-left sentence in the top corner reads like a bug
|
|
270
|
-
* report. It lives here rather than in one client because every panel that can
|
|
271
|
-
* be empty should be empty the same way — the extension's views and the
|
|
272
|
-
* dashboard's four sidebars are the same shape of thing.
|
|
273
|
-
*
|
|
274
|
-
* **At most one action, and never one the view header already offers.** Creating
|
|
275
|
-
* a session and adding a gateway are the `+` in the native title bar, exclusively
|
|
276
|
-
* — so those empty states point at it in words rather than growing a second
|
|
277
|
-
* button that does the same thing two inches lower. A button here is for the way
|
|
278
|
-
* out of a state the header has no answer to: clearing a filter, widening a
|
|
279
|
-
* scope.
|
|
280
|
-
*/
|
|
281
198
|
declare function Empty({
|
|
282
199
|
icon,
|
|
283
200
|
title,
|
|
@@ -291,7 +208,6 @@ declare function Empty({
|
|
|
291
208
|
action?: string;
|
|
292
209
|
onAction?: () => void;
|
|
293
210
|
}): _$react.JSX.Element;
|
|
294
|
-
/** A key or icon named inline in an empty state's description — "use the + above". */
|
|
295
211
|
declare function EmptyKey({
|
|
296
212
|
children
|
|
297
213
|
}: {
|
|
@@ -300,15 +216,11 @@ declare function EmptyKey({
|
|
|
300
216
|
//#endregion
|
|
301
217
|
//#region src/components/ui/ProgressRing.d.ts
|
|
302
218
|
interface ProgressRingProps {
|
|
303
|
-
/** Filled share, 0–100 (clamped). */
|
|
304
219
|
value: number;
|
|
305
|
-
/** Outer diameter in px. */
|
|
306
220
|
size?: number;
|
|
307
221
|
strokeWidth?: number;
|
|
308
222
|
className?: string;
|
|
309
223
|
}
|
|
310
|
-
/** Tiny SVG progress circle; stroke color comes from `currentColor` so callers set it
|
|
311
|
-
* via text color classes (e.g. warning/danger past thresholds). */
|
|
312
224
|
declare function ProgressRing({
|
|
313
225
|
value,
|
|
314
226
|
size,
|
|
@@ -325,10 +237,8 @@ declare function ProgressRing({
|
|
|
325
237
|
* - Immutable chips for resolved mentions/commands
|
|
326
238
|
* - Configurable trigger behavior (dropdown vs callback)
|
|
327
239
|
* - Simple inline markdown rendering
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
* A segment of content within the editable text.
|
|
331
|
-
* The document model is an ordered array of these segments.
|
|
240
|
+
*
|
|
241
|
+
* The document model is an ordered array of {@link TextSegment}/{@link ChipSegment}.
|
|
332
242
|
*/
|
|
333
243
|
type TextSegment = {
|
|
334
244
|
type: 'text';
|
|
@@ -763,241 +673,36 @@ type ToolCallItem$1 = Extract<TranscriptItem, {
|
|
|
763
673
|
kind: 'tool_call';
|
|
764
674
|
}>;
|
|
765
675
|
//#endregion
|
|
766
|
-
//#region src/components/terminal/row.d.ts
|
|
767
|
-
/**
|
|
768
|
-
* The primitives every terminal row is built from.
|
|
769
|
-
*
|
|
770
|
-
* There are three, and that is the whole vocabulary: a {@link Row} (a gutter
|
|
771
|
-
* cell and a body cell), a {@link Blank} (one empty line), and a {@link Band} (a
|
|
772
|
-
* run of rows carrying a full-bleed background). Anything the theme draws — a
|
|
773
|
-
* message, a tool call, a diff hunk, an approval prompt — is some arrangement of
|
|
774
|
-
* those, which is what keeps the grid a property of the renderer rather than a
|
|
775
|
-
* thing each component re-derives.
|
|
776
|
-
*
|
|
777
|
-
* Geometry is in `styles/terminal.css`. These components choose a class, a
|
|
778
|
-
* marker and a tone; they never carry a measurement.
|
|
779
|
-
*/
|
|
780
|
-
/** The palette, as a name. See the `[data-tone]` rules in `terminal.css`. */
|
|
781
|
-
type Tone = 'fg' | 'bright' | 'dim' | 'faint' | 'mark' | 'blue' | 'green' | 'red' | 'yellow' | 'magenta';
|
|
782
|
-
interface RowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
783
|
-
/**
|
|
784
|
-
* What sits in the gutter — `●`, `⎿`, `>`, a list bullet, or nothing. Kept to
|
|
785
|
-
* the width of the gutter (`--term-cell`, two columns by default): a wider
|
|
786
|
-
* marker would push its own body off the column every other row starts on.
|
|
787
|
-
* Omitted, the gutter is still drawn as empty space, so an unmarked row's
|
|
788
|
-
* text lines up with a marked one's.
|
|
789
|
-
*/
|
|
790
|
-
glyph?: ReactNode;
|
|
791
|
-
/** The marker's colour. Defaults to dim — the marker is structure, not content. */
|
|
792
|
-
glyphTone?: Tone;
|
|
793
|
-
/** The body's colour. */
|
|
794
|
-
tone?: Tone;
|
|
795
|
-
bold?: boolean;
|
|
796
|
-
/** Indent levels, one character cell each. A child row's marker then sits
|
|
797
|
-
* exactly under its parent row's first letter. */
|
|
798
|
-
indent?: 0 | 1 | 2 | 3;
|
|
799
|
-
/**
|
|
800
|
-
* Gutter width in columns, when the marker needs other than two — an ordered
|
|
801
|
-
* list's `10.` is four, a prompt's `❯ 1.` is five, and a framed payload wants
|
|
802
|
-
* `0`. Changes only this row's split, so the body still starts on a whole
|
|
803
|
-
* column.
|
|
804
|
-
*/
|
|
805
|
-
columns?: number;
|
|
806
|
-
children?: ReactNode;
|
|
807
|
-
}
|
|
808
|
-
declare function Row({
|
|
809
|
-
glyph,
|
|
810
|
-
glyphTone,
|
|
811
|
-
tone,
|
|
812
|
-
bold,
|
|
813
|
-
indent,
|
|
814
|
-
columns,
|
|
815
|
-
className,
|
|
816
|
-
children,
|
|
817
|
-
style,
|
|
818
|
-
...props
|
|
819
|
-
}: RowProps): _$react.JSX.Element;
|
|
820
|
-
/**
|
|
821
|
-
* One empty line — the theme's only vertical spacing.
|
|
822
|
-
*
|
|
823
|
-
* A terminal separates blocks with a blank line, not with padding, and saying it
|
|
824
|
-
* that way has a practical payoff: spacing is part of the row list, so it can be
|
|
825
|
-
* decided by whoever knows whether two blocks belong together (a tool call and
|
|
826
|
-
* its output do not get one; two assistant turns do), instead of by a margin
|
|
827
|
-
* rule that cannot tell them apart.
|
|
828
|
-
*/
|
|
829
|
-
declare function Blank(): _$react.JSX.Element;
|
|
830
|
-
/**
|
|
831
|
-
* A run of rows under a background: a code block, a command's output, a diff
|
|
832
|
-
* hunk. Full-bleed — the wash reaches the scroller's edges, because in a
|
|
833
|
-
* terminal the line is the full width of the screen. See `--term-bleed` on
|
|
834
|
-
* {@link TerminalSurface}.
|
|
835
|
-
*/
|
|
836
|
-
declare function Band({
|
|
837
|
-
className,
|
|
838
|
-
...props
|
|
839
|
-
}: HTMLAttributes<HTMLDivElement>): _$react.JSX.Element;
|
|
840
|
-
/** Inline colour/weight inside a row's body. */
|
|
841
|
-
declare function Ink({
|
|
842
|
-
tone,
|
|
843
|
-
bold,
|
|
844
|
-
className,
|
|
845
|
-
...props
|
|
846
|
-
}: HTMLAttributes<HTMLSpanElement> & {
|
|
847
|
-
tone?: Tone;
|
|
848
|
-
bold?: boolean;
|
|
849
|
-
}): _$react.JSX.Element;
|
|
850
|
-
//#endregion
|
|
851
676
|
//#region src/components/agent/Transcript.d.ts
|
|
852
677
|
interface TranscriptProps {
|
|
853
678
|
state: TranscriptState;
|
|
854
|
-
/** Builds the download URL for a delivered file (see FileCard). Typically
|
|
855
|
-
* `(path) => client.sessionFileUrl(sessionId, path)`. */
|
|
856
679
|
fileUrl?: (path: string) => string;
|
|
857
|
-
/** Builds the URL for an uploaded attachment. Typically
|
|
858
|
-
* `(id) => client.attachmentUrl(sessionId, id)`. Same-origin and
|
|
859
|
-
* cookie-authenticated, which is what lets an `<img src>` render one. */
|
|
860
680
|
attachmentUrl?: (attachmentId: string) => string;
|
|
861
|
-
/** Whether this gateway serves `@file` search here — the empty state must not
|
|
862
|
-
* advertise an affordance the composer doesn't have. */
|
|
863
681
|
canBrowseFiles?: boolean;
|
|
864
|
-
/** Reads a host file as a data URL, for tool calls whose output is a picture
|
|
865
|
-
* on the host (codex's `image_gen`). Omit and those cards name the path. */
|
|
866
682
|
hostImage?: (path: string) => Promise<string | undefined>;
|
|
867
|
-
/**
|
|
868
|
-
* How a turn is drawn: `cards` (default, the chat convention) or `terminal`,
|
|
869
|
-
* which is not a set of branches in these components but its own renderer.
|
|
870
|
-
* See {@link TranscriptVariant}.
|
|
871
|
-
*/
|
|
872
683
|
variant?: TranscriptVariant;
|
|
873
|
-
/**
|
|
874
|
-
* How much air each row gets: `comfortable` (default — a blank line between
|
|
875
|
-
* messages, as the Claude Code CLI does) or `compact`. Independent of
|
|
876
|
-
* {@link TranscriptVariant}. See {@link TranscriptDensity}.
|
|
877
|
-
*/
|
|
878
684
|
density?: TranscriptDensity;
|
|
879
|
-
/** Terminal theme only: the character cell, in whole pixels. See
|
|
880
|
-
* {@link TerminalSurface}. */
|
|
881
685
|
fontSize?: number;
|
|
882
686
|
lineHeight?: number;
|
|
883
|
-
/** Terminal theme only: the pointer affordances a real terminal cannot offer.
|
|
884
|
-
* `false` for none. See {@link TerminalAffordances}. */
|
|
885
687
|
affordances?: TerminalAffordances | boolean;
|
|
886
|
-
/** Hold the prompt of the turn being read at the top of the scroller. Works
|
|
887
|
-
* in both variants: the terminal clips to one line, cards shows a frosted
|
|
888
|
-
* bar. The *real* row is pinned, not a copy — see `TranscriptRows`. */
|
|
889
688
|
stickyPrompt?: boolean;
|
|
890
|
-
/**
|
|
891
|
-
* Mount the overview scrubber — a 12px rail of marks (your prompts, each
|
|
892
|
-
* turn's response and result as one mark, errors, the pending approval, the
|
|
893
|
-
* catch-up boundary) over the scroller's right edge. Two rails behind one
|
|
894
|
-
* prop: under `terminal` it is the pixel-exact ruler that replaces the
|
|
895
|
-
* native scrollbar (positions ride the height calculator; drag scrubs), and
|
|
896
|
-
* under `cards` it is the **proportional annotation rail** — positioned by
|
|
897
|
-
* `itemIndex / items.length`, because proportional text gives the
|
|
898
|
-
* calculator no claim there — where the native scrollbar stays and the rail
|
|
899
|
-
* only peeks and jumps. With `affordances={false}` either rail degrades to
|
|
900
|
-
* passive paint — no drag, peek or click.
|
|
901
|
-
*/
|
|
902
689
|
scrubber?: boolean;
|
|
903
|
-
|
|
904
|
-
* Bookmarked item indices, painted as full-width marks on the rail. Paint
|
|
905
|
-
* only, deliberately: the store — and the affordance that writes it — is
|
|
906
|
-
* the client's, the way the unread watermarks are, not the panel's.
|
|
907
|
-
*/
|
|
908
|
-
scrubberMarks?: readonly number[];
|
|
909
|
-
/**
|
|
910
|
-
* The attach replay is still landing (`useClaudeSession().replaying`): rows
|
|
911
|
-
* render, measure and pin exactly as normal but nothing paints, and a loading
|
|
912
|
-
* line shows in their place; when it flips false the settled tail appears in
|
|
913
|
-
* one frame. Hiding is by *visibility*, never by not mounting — see the
|
|
914
|
-
* comment at the render site. Optional: an embedder that never passes it
|
|
915
|
-
* gets today's behaviour, and a short or empty session holds for no visible
|
|
916
|
-
* time at all (the frame between attach and replay-complete).
|
|
917
|
-
*/
|
|
690
|
+
bookmarks?: readonly string[];
|
|
918
691
|
replaying?: boolean;
|
|
919
|
-
/**
|
|
920
|
-
* Catch-up: `from` is how many items had been seen last time, `since` when
|
|
921
|
-
* that was. A recap row is drawn at that boundary and everything above it is
|
|
922
|
-
* dimmed. Omit (or pass a boundary at/after the end) and the transcript
|
|
923
|
-
* renders exactly as before.
|
|
924
|
-
*/
|
|
925
692
|
catchUp?: {
|
|
926
693
|
from: number;
|
|
927
694
|
since?: number;
|
|
928
695
|
};
|
|
929
|
-
/**
|
|
930
|
-
* Filled with a closure that scrolls the recap row into view — the seam the
|
|
931
|
-
* panel's catch-up strip presses. A ref rather than a DOM query because the
|
|
932
|
-
* rows are virtualized: when the recap row isn't mounted, only the
|
|
933
|
-
* virtualizer knows where it would be. Optional; embedders without a
|
|
934
|
-
* catch-up strip never touch it. `null` while no transcript is mounted.
|
|
935
|
-
*/
|
|
936
696
|
jumpToRecapRef?: RefObject<(() => void) | null>;
|
|
937
|
-
/**
|
|
938
|
-
* Filled with a closure that re-pins the transcript to the bottom, so a host
|
|
939
|
-
* can resume following after the reader has scrolled away. The panel presses
|
|
940
|
-
* it on send: choosing to say something is choosing to watch what happens
|
|
941
|
-
* next, and a transcript left parked where you were reading makes a sent
|
|
942
|
-
* message look like it did nothing at all.
|
|
943
|
-
*/
|
|
944
697
|
repinRef?: RefObject<(() => void) | null>;
|
|
945
|
-
/**
|
|
946
|
-
* Scroll a tool call into view — bump `nonce` to ask again for the same one.
|
|
947
|
-
*
|
|
948
|
-
* The seam a *list* needs: sub-agent work is nested inside the `Task` call
|
|
949
|
-
* that spawned it, so "open that sub-agent" can only ever mean "take me to its
|
|
950
|
-
* row". A `parentToolUseId` works here as well as the Task's own id, since the
|
|
951
|
-
* lookup resolves an absorbed child to the row that folded it.
|
|
952
|
-
*
|
|
953
|
-
* A prop rather than a ref (the shape `jumpToRecapRef` uses) because the asker
|
|
954
|
-
* is outside this webview entirely and the request travels as data; a ref
|
|
955
|
-
* would need a live closure at the other end of a postMessage bridge.
|
|
956
|
-
*/
|
|
957
698
|
reveal?: {
|
|
958
699
|
toolUseId: string;
|
|
959
700
|
nonce: number;
|
|
960
701
|
};
|
|
961
|
-
/**
|
|
962
|
-
* Render **only** the work one sub-agent did, rather than the conversation —
|
|
963
|
-
* the sub-agent takeover's frame.
|
|
964
|
-
*
|
|
965
|
-
* Membership is `subagentItems` (`terminal/blocks.ts`), which is also the rule
|
|
966
|
-
* iOS will mirror: everything the agent produced, and not the spawning `Task`
|
|
967
|
-
* call itself, which *is* the frame rather than a row in it.
|
|
968
|
-
*
|
|
969
|
-
* Features are switched off internally whenever it is set, and the gate lives
|
|
970
|
-
* here rather than at the call site on purpose: each is keyed to a
|
|
971
|
-
* **full-transcript item index**, so a host that passed a frame and a catch-up
|
|
972
|
-
* boundary together would not be making a strange choice, it would be making
|
|
973
|
-
* an incoherent one. Those are the catch-up boundary and its recap row, the
|
|
974
|
-
* sticky prompt, `reveal`, and the scrubber's **bookmarks** (host indices in
|
|
975
|
-
* full-transcript space).
|
|
976
|
-
*
|
|
977
|
-
* The **scrubber itself stays**, and the distinction is the point: the rail
|
|
978
|
-
* derives every one of its inputs from the rows it is given, and inside a
|
|
979
|
-
* frame those are the sub-agent's own — so it marks that agent's prompts,
|
|
980
|
-
* answers and failures at that agent's offsets. It was originally gated with
|
|
981
|
-
* the marks, on the reasonable-looking argument that they are one feature;
|
|
982
|
-
* they are two, and a fifty-tool agent run is exactly where a rail earns its
|
|
983
|
-
* keep. What stays besides is everything that makes a long stream readable —
|
|
984
|
-
* virtualization, the height epoch, the follow spring, the replay hold.
|
|
985
|
-
*/
|
|
986
702
|
frame?: {
|
|
987
703
|
parentToolUseId: string;
|
|
988
704
|
};
|
|
989
|
-
/**
|
|
990
|
-
* Raise the takeover from a `Task` row. Absent draws no affordance, which is
|
|
991
|
-
* what the plain renderer and the cards variant get: cards folds nothing, so
|
|
992
|
-
* it has no task blocks to hang this on, and reaches the takeover from the
|
|
993
|
-
* sessions list instead.
|
|
994
|
-
*/
|
|
995
705
|
onOpenSubagent?: (toolUseId: string) => void;
|
|
996
|
-
/**
|
|
997
|
-
* Replaces the default empty state when the transcript has no items. Pass a
|
|
998
|
-
* `ReactNode` to show your product's own onboarding instead of WorkerDeck's
|
|
999
|
-
* generic "`>_` Tell the agent what to do." placeholder.
|
|
1000
|
-
*/
|
|
1001
706
|
emptyState?: ReactNode;
|
|
1002
707
|
className?: string;
|
|
1003
708
|
}
|
|
@@ -1014,7 +719,7 @@ declare function Transcript({
|
|
|
1014
719
|
affordances,
|
|
1015
720
|
stickyPrompt,
|
|
1016
721
|
scrubber,
|
|
1017
|
-
|
|
722
|
+
bookmarks,
|
|
1018
723
|
replaying,
|
|
1019
724
|
catchUp,
|
|
1020
725
|
jumpToRecapRef,
|
|
@@ -1027,40 +732,10 @@ declare function Transcript({
|
|
|
1027
732
|
}: TranscriptProps): _$react.JSX.Element;
|
|
1028
733
|
//#endregion
|
|
1029
734
|
//#region src/components/terminal/surface.d.ts
|
|
1030
|
-
/**
|
|
1031
|
-
* The root of the terminal theme: the element that establishes the character
|
|
1032
|
-
* cell every row inside it lands on.
|
|
1033
|
-
*
|
|
1034
|
-
* It exists as a component rather than a class because the cell has to be *set*
|
|
1035
|
-
* somewhere — the font, the size and the line height together are what make
|
|
1036
|
-
* `1ch` mean one column and `--term-line` mean one row — and because that is the
|
|
1037
|
-
* one place a host is allowed to change the metrics. Everything below this
|
|
1038
|
-
* element measures itself in those two units and never in pixels.
|
|
1039
|
-
*
|
|
1040
|
-
* The geometry and the palette live in `styles/terminal.css`; this only names
|
|
1041
|
-
* the element and hands down the two numbers.
|
|
1042
|
-
*/
|
|
1043
735
|
interface TerminalSurfaceProps extends HTMLAttributes<HTMLDivElement> {
|
|
1044
|
-
/**
|
|
1045
|
-
* Cell size in **whole pixels**. Fractional values put every other row on a
|
|
1046
|
-
* half-pixel: text softens and the diff bands show a seam, which is exactly
|
|
1047
|
-
* what a grid renderer must not do. Defaults (13/18) are the CLI's own.
|
|
1048
|
-
*/
|
|
1049
736
|
fontSize?: number;
|
|
1050
737
|
lineHeight?: number;
|
|
1051
|
-
/**
|
|
1052
|
-
* How far a full-bleed band reaches past the content edge — normally the
|
|
1053
|
-
* scroller's own horizontal padding. A band cancels it with matched negative
|
|
1054
|
-
* margin and padding, so a diff hunk's wash runs to the viewport edge the way
|
|
1055
|
-
* a terminal's line does, instead of stopping at a gutter.
|
|
1056
|
-
*/
|
|
1057
738
|
bleed?: string;
|
|
1058
|
-
/**
|
|
1059
|
-
* The things a real terminal cannot do — the pointer hover fill, the
|
|
1060
|
-
* hover-revealed copy actions. `false` turns them all off, an object picks.
|
|
1061
|
-
* Default: all on. See {@link TerminalAffordances}; none of them costs layout,
|
|
1062
|
-
* so switching them off changes no glyph's position.
|
|
1063
|
-
*/
|
|
1064
739
|
affordances?: TerminalAffordances | boolean;
|
|
1065
740
|
}
|
|
1066
741
|
declare function TerminalSurface({
|
|
@@ -1075,39 +750,14 @@ declare function TerminalSurface({
|
|
|
1075
750
|
}: TerminalSurfaceProps): _$react.JSX.Element;
|
|
1076
751
|
//#endregion
|
|
1077
752
|
//#region src/components/terminal/TerminalTranscript.d.ts
|
|
1078
|
-
/**
|
|
1079
|
-
* The transcript, drawn as a terminal.
|
|
1080
|
-
*
|
|
1081
|
-
* The whole of the layout is here and it is four lines long, which is the point:
|
|
1082
|
-
* items become row blocks, a blank line goes between blocks that do not belong
|
|
1083
|
-
* together, and the working line is one more row at the end. There is no gap
|
|
1084
|
-
* scale, no density knob and no variant branch — a terminal has one line height
|
|
1085
|
-
* and one type size, and everything the theme can express is expressed in which
|
|
1086
|
-
* rows exist and what marker each carries.
|
|
1087
|
-
*
|
|
1088
|
-
* Not virtualized yet: the row blocks are the part that has to be right first,
|
|
1089
|
-
* and the existing `Transcript` already owns a hard-won virtualizer plus the
|
|
1090
|
-
* scroll-regime rules it needs. This renders into that shell when the rows are
|
|
1091
|
-
* settled, rather than growing a second copy of that logic.
|
|
1092
|
-
*/
|
|
1093
753
|
interface TerminalTranscriptProps {
|
|
1094
754
|
state: TranscriptState;
|
|
1095
|
-
/** Builds the download URL for a delivered file. */
|
|
1096
755
|
fileUrl?: (path: string) => string;
|
|
1097
|
-
/** Cell metrics, in whole pixels. See {@link TerminalSurface}. */
|
|
1098
756
|
fontSize?: number;
|
|
1099
757
|
lineHeight?: number;
|
|
1100
|
-
/** The pointer affordances a real terminal has no way to offer — hover fill,
|
|
1101
|
-
* hover-revealed copy. `false` for none. See {@link TerminalAffordances}. */
|
|
1102
758
|
affordances?: TerminalAffordances | boolean;
|
|
1103
759
|
className?: string;
|
|
1104
760
|
}
|
|
1105
|
-
/**
|
|
1106
|
-
* One transcript item as terminal rows. Exported because the virtualized shell
|
|
1107
|
-
* in `agent/Transcript.tsx` renders rows through it: the theme owns how a row
|
|
1108
|
-
* looks, that component owns which rows are mounted, and neither needs a copy
|
|
1109
|
-
* of the other.
|
|
1110
|
-
*/
|
|
1111
761
|
declare function TerminalItemView({
|
|
1112
762
|
item,
|
|
1113
763
|
fileUrl
|
|
@@ -1128,15 +778,8 @@ declare function TerminalTranscript({
|
|
|
1128
778
|
interface TerminalStatusLineProps {
|
|
1129
779
|
className?: string;
|
|
1130
780
|
state: TranscriptState;
|
|
1131
|
-
/** Plan windows to read from, when they should not be the session's own — the
|
|
1132
|
-
* gateway's per-profile state merged over this transcript's. See
|
|
1133
|
-
* {@link StatusBarProps.rateLimits}. Absent = `state.rateLimits`. */
|
|
1134
781
|
rateLimits?: Record<string, RateLimitInfo>;
|
|
1135
|
-
/** How the client is doing at reaching the gateway. Wins the status slot when
|
|
1136
|
-
* the socket is down — see above. */
|
|
1137
782
|
connection?: ConnectionState;
|
|
1138
|
-
/** Opens the panel that answers each reading's own question. Omit and the
|
|
1139
|
-
* reading is text rather than something to press. */
|
|
1140
783
|
onOpenStatus?: () => void;
|
|
1141
784
|
onOpenContext?: () => void;
|
|
1142
785
|
onOpenUsage?: () => void;
|
|
@@ -1152,27 +795,9 @@ declare function TerminalStatusLine({
|
|
|
1152
795
|
}: TerminalStatusLineProps): _$react.JSX.Element;
|
|
1153
796
|
//#endregion
|
|
1154
797
|
//#region src/components/terminal/PermissionPrompt.d.ts
|
|
1155
|
-
/**
|
|
1156
|
-
* The approval, as the CLI draws it: a rule, what is being asked and about what,
|
|
1157
|
-
* the change itself, a dashed rule, the question, numbered answers, and the keys.
|
|
1158
|
-
*
|
|
1159
|
-
* Two things it does that the card version does not, both taken from the CLI:
|
|
1160
|
-
*
|
|
1161
|
-
* - **It shows the change, not the payload.** For a file edit, `old_string` and
|
|
1162
|
-
* `new_string` are a diff — so it renders one, rather than the JSON input a
|
|
1163
|
-
* reader would have to diff in their head. Without line numbers, necessarily:
|
|
1164
|
-
* the edit has not happened and this client has never read the file (see
|
|
1165
|
-
* {@link previewPatch}). Everything else falls back to the input.
|
|
1166
|
-
* - **The heading is the engine's own sentence.** `displayName` ("Edit file")
|
|
1167
|
-
* over `title`, never "wants to use {tool}" composed here — for codex an
|
|
1168
|
-
* approval is an *escalation after a sandbox refusal*, and the runner has
|
|
1169
|
-
* already written the sentence that says so.
|
|
1170
|
-
*/
|
|
1171
798
|
interface TerminalPermissionPromptProps {
|
|
1172
799
|
request: PermissionRequest;
|
|
1173
800
|
onApprove: (requestId: string) => void;
|
|
1174
|
-
/** `message` is fed back to the agent, which can then try something else;
|
|
1175
|
-
* `interrupt` also stops the turn. */
|
|
1176
801
|
onDeny: (requestId: string, message?: string, interrupt?: boolean) => void;
|
|
1177
802
|
className?: string;
|
|
1178
803
|
}
|
|
@@ -1185,11 +810,8 @@ declare function TerminalPermissionPrompt({
|
|
|
1185
810
|
//#endregion
|
|
1186
811
|
//#region src/components/terminal/QuestionPrompt.d.ts
|
|
1187
812
|
interface TerminalQuestionPromptProps {
|
|
1188
|
-
/** A pending permission whose toolName is 'AskUserQuestion'. */
|
|
1189
813
|
request: PermissionRequest;
|
|
1190
|
-
/** Allow the tool with `updatedInput` (the original input plus `answers`). */
|
|
1191
814
|
onAnswer: (requestId: string, updatedInput: Record<string, unknown>) => void;
|
|
1192
|
-
/** Deny the tool — the model proceeds without an answer. */
|
|
1193
815
|
onDismiss: (requestId: string, message?: string) => void;
|
|
1194
816
|
className?: string;
|
|
1195
817
|
}
|
|
@@ -1201,15 +823,6 @@ declare function TerminalQuestionPrompt({
|
|
|
1201
823
|
}: TerminalQuestionPromptProps): _$react.JSX.Element;
|
|
1202
824
|
//#endregion
|
|
1203
825
|
//#region src/components/terminal/diff.d.ts
|
|
1204
|
-
/**
|
|
1205
|
-
* A patch for a change that has **not happened yet** — an approval prompt's
|
|
1206
|
-
* `Edit`, where the input names the old and new text but no line numbers exist
|
|
1207
|
-
* because the edit has not been applied and this client has never read the file.
|
|
1208
|
-
*
|
|
1209
|
-
* `newStart: 0` is how it says so, and {@link TerminalDiff} reads that back: a
|
|
1210
|
-
* diff whose hunks all start at zero renders without a number column rather than
|
|
1211
|
-
* printing a column of zeroes or inventing an offset.
|
|
1212
|
-
*/
|
|
1213
826
|
declare function previewPatch(input: unknown): FilePatch | undefined;
|
|
1214
827
|
declare function TerminalDiff({
|
|
1215
828
|
patch
|
|
@@ -1220,7 +833,6 @@ declare function TerminalDiff({
|
|
|
1220
833
|
//#region src/components/terminal/markdown.d.ts
|
|
1221
834
|
interface TerminalMarkdownProps {
|
|
1222
835
|
children: string;
|
|
1223
|
-
/** Streaming text: tolerate half-written markdown (unclosed fences, half links). */
|
|
1224
836
|
streaming?: boolean;
|
|
1225
837
|
className?: string;
|
|
1226
838
|
}
|
|
@@ -1230,20 +842,48 @@ declare const TerminalMarkdown: _$react.MemoExoticComponent<({
|
|
|
1230
842
|
className
|
|
1231
843
|
}: TerminalMarkdownProps) => _$react.JSX.Element>;
|
|
1232
844
|
//#endregion
|
|
845
|
+
//#region src/components/terminal/row.d.ts
|
|
846
|
+
type Tone = 'fg' | 'bright' | 'dim' | 'faint' | 'mark' | 'blue' | 'green' | 'red' | 'yellow' | 'magenta';
|
|
847
|
+
interface RowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
848
|
+
glyph?: ReactNode;
|
|
849
|
+
glyphTone?: Tone;
|
|
850
|
+
tone?: Tone;
|
|
851
|
+
bold?: boolean;
|
|
852
|
+
indent?: 0 | 1 | 2 | 3;
|
|
853
|
+
columns?: number;
|
|
854
|
+
children?: ReactNode;
|
|
855
|
+
}
|
|
856
|
+
declare function Row({
|
|
857
|
+
glyph,
|
|
858
|
+
glyphTone,
|
|
859
|
+
tone,
|
|
860
|
+
bold,
|
|
861
|
+
indent,
|
|
862
|
+
columns,
|
|
863
|
+
className,
|
|
864
|
+
children,
|
|
865
|
+
style,
|
|
866
|
+
...props
|
|
867
|
+
}: RowProps): _$react.JSX.Element;
|
|
868
|
+
declare function Blank(): _$react.JSX.Element;
|
|
869
|
+
declare function Band({
|
|
870
|
+
className,
|
|
871
|
+
...props
|
|
872
|
+
}: HTMLAttributes<HTMLDivElement>): _$react.JSX.Element;
|
|
873
|
+
declare function Ink({
|
|
874
|
+
tone,
|
|
875
|
+
bold,
|
|
876
|
+
className,
|
|
877
|
+
...props
|
|
878
|
+
}: HTMLAttributes<HTMLSpanElement> & {
|
|
879
|
+
tone?: Tone;
|
|
880
|
+
bold?: boolean;
|
|
881
|
+
}): _$react.JSX.Element;
|
|
882
|
+
//#endregion
|
|
1233
883
|
//#region src/components/agent/Conversation.d.ts
|
|
1234
884
|
interface ConversationProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
1235
885
|
children: ReactNode;
|
|
1236
886
|
}
|
|
1237
|
-
/** Scroll container that stays pinned to the bottom while streaming, unless the user
|
|
1238
|
-
* scrolls up — plus a floating scroll-to-bottom button.
|
|
1239
|
-
*
|
|
1240
|
-
* **Nothing here animates its scroll position.** `initial` and `resize` are both
|
|
1241
|
-
* `'instant'` and are no longer configurable: the follow spring's job is to
|
|
1242
|
-
* *stay* at the bottom, not to travel there, and every travel a reader has ever
|
|
1243
|
-
* complained about on this surface was an animation we asked for. The `resize`
|
|
1244
|
-
* prop used to exist so a caller could pick, which required the caller to know
|
|
1245
|
-
* whether the transcript was streaming or replaying — a latch's worth of
|
|
1246
|
-
* machinery to decide something that has one right answer. */
|
|
1247
887
|
declare function Conversation({
|
|
1248
888
|
className,
|
|
1249
889
|
children,
|
|
@@ -1266,19 +906,6 @@ declare function ConversationScrollButton({
|
|
|
1266
906
|
interface MessageProps extends HTMLAttributes<HTMLDivElement> {
|
|
1267
907
|
from: 'user' | 'assistant';
|
|
1268
908
|
}
|
|
1269
|
-
/**
|
|
1270
|
-
* One chat turn row.
|
|
1271
|
-
*
|
|
1272
|
-
* `cards`: user messages sit in a bubble, assistant content is flat and
|
|
1273
|
-
* full-width. Both are **left-aligned**: the transcript is a log read top to
|
|
1274
|
-
* bottom, and an editor-shaped host (a full-width session view beside a sessions
|
|
1275
|
-
* rail) has no right edge to anchor to — a bubble drifting right in a 1600px
|
|
1276
|
-
* column separates a prompt from the reply it produced. The bubble alone is
|
|
1277
|
-
* enough to say who spoke.
|
|
1278
|
-
*
|
|
1279
|
-
* The terminal theme draws none of this: it is its own renderer
|
|
1280
|
-
* (`components/terminal/`) and mounts instead of these rows.
|
|
1281
|
-
*/
|
|
1282
909
|
declare function Message({
|
|
1283
910
|
from,
|
|
1284
911
|
className,
|
|
@@ -1293,12 +920,9 @@ declare function MessageContent({
|
|
|
1293
920
|
//#region src/components/agent/Response.d.ts
|
|
1294
921
|
interface ResponseProps {
|
|
1295
922
|
children: string;
|
|
1296
|
-
/** Streaming text: tolerate incomplete markdown (unclosed fences, half links). */
|
|
1297
923
|
streaming?: boolean;
|
|
1298
924
|
className?: string;
|
|
1299
925
|
}
|
|
1300
|
-
/** Markdown renderer for assistant output — streaming-safe via streamdown, code
|
|
1301
|
-
* highlighted with shiki (dual theme follows [data-theme] through the dark: variant). */
|
|
1302
926
|
declare const Response: _$react.MemoExoticComponent<({
|
|
1303
927
|
children,
|
|
1304
928
|
streaming,
|
|
@@ -1308,13 +932,10 @@ declare const Response: _$react.MemoExoticComponent<({
|
|
|
1308
932
|
//#region src/components/agent/Reasoning.d.ts
|
|
1309
933
|
interface ReasoningProps {
|
|
1310
934
|
children: string;
|
|
1311
|
-
/** Auto-opens while true, auto-closes shortly after it flips false. */
|
|
1312
935
|
isStreaming?: boolean;
|
|
1313
936
|
defaultOpen?: boolean;
|
|
1314
937
|
className?: string;
|
|
1315
938
|
}
|
|
1316
|
-
/** Collapsible extended-thinking block: open while the model is thinking, tucks itself
|
|
1317
|
-
* away once the thought is finished (unless the user toggled it manually). */
|
|
1318
939
|
declare function Reasoning({
|
|
1319
940
|
children,
|
|
1320
941
|
isStreaming,
|
|
@@ -1324,26 +945,11 @@ declare function Reasoning({
|
|
|
1324
945
|
//#endregion
|
|
1325
946
|
//#region src/components/agent/Loader.d.ts
|
|
1326
947
|
interface LoaderProps {
|
|
1327
|
-
/** Overrides the cycling verb — for a state that has one true name
|
|
1328
|
-
* ("Starting session…"). */
|
|
1329
948
|
label?: string;
|
|
1330
|
-
/** When the current run began, for the elapsed clock. Absent = no clock.
|
|
1331
|
-
* Unused by the card treatment; kept so the `cards` and `terminal` loaders
|
|
1332
|
-
* take the same call site in `Transcript`. */
|
|
1333
949
|
startedAt?: number;
|
|
1334
|
-
/** Context tokens in play. Same story as `startedAt`. */
|
|
1335
950
|
tokens?: number;
|
|
1336
951
|
className?: string;
|
|
1337
952
|
}
|
|
1338
|
-
/**
|
|
1339
|
-
* "The agent is working and hasn't produced output yet."
|
|
1340
|
-
*
|
|
1341
|
-
* Three dots pulsing in CSS — the chat convention, for the `cards` variant. The
|
|
1342
|
-
* terminal theme has its own working line (`terminal/items.tsx`'s `WorkingRow`,
|
|
1343
|
-
* with the mark's pulse in the gutter and the run's readings beside the verb),
|
|
1344
|
-
* because there it is a *row of the transcript* rather than a spinner floating
|
|
1345
|
-
* over one.
|
|
1346
|
-
*/
|
|
1347
953
|
declare function Loader({
|
|
1348
954
|
label,
|
|
1349
955
|
className
|
|
@@ -1355,13 +961,6 @@ type ToolCallItem = Extract<TranscriptItem, {
|
|
|
1355
961
|
}>;
|
|
1356
962
|
interface ToolCallCardProps {
|
|
1357
963
|
item: ToolCallItem;
|
|
1358
|
-
/**
|
|
1359
|
-
* Reads a host file as a data URL, for tools whose output is a picture on the
|
|
1360
|
-
* host. Resolves `undefined` when the gateway won't serve that path — a
|
|
1361
|
-
* generated image saved outside the allowed roots (codex's default
|
|
1362
|
-
* `$CODEX_HOME/generated_images/`) is one, and the card then names the path
|
|
1363
|
-
* instead of showing it.
|
|
1364
|
-
*/
|
|
1365
964
|
hostImage?: (path: string) => Promise<string | undefined>;
|
|
1366
965
|
className?: string;
|
|
1367
966
|
}
|
|
@@ -1377,14 +976,9 @@ type FileDeliveredItem = Extract<TranscriptItem, {
|
|
|
1377
976
|
}>;
|
|
1378
977
|
interface FileCardProps {
|
|
1379
978
|
item: FileDeliveredItem;
|
|
1380
|
-
/** Download URL for the delivered path (the server's session file route).
|
|
1381
|
-
* Without it the card renders informational only. */
|
|
1382
979
|
href?: string;
|
|
1383
980
|
className?: string;
|
|
1384
981
|
}
|
|
1385
|
-
/** A file the agent handed over (`file_delivered`): name, size, download link.
|
|
1386
|
-
* The file lives in the session's in-memory VFS — the link works while the
|
|
1387
|
-
* session lives. */
|
|
1388
982
|
declare function FileCard({
|
|
1389
983
|
item,
|
|
1390
984
|
href,
|
|
@@ -1395,23 +989,9 @@ declare function FileCard({
|
|
|
1395
989
|
interface PermissionPromptProps {
|
|
1396
990
|
request: PermissionRequest;
|
|
1397
991
|
onApprove: (requestId: string) => void;
|
|
1398
|
-
/** `message` is fed back to the agent, which can then try something else;
|
|
1399
|
-
* `interrupt` also stops the turn. */
|
|
1400
992
|
onDeny: (requestId: string, message?: string, interrupt?: boolean) => void;
|
|
1401
993
|
className?: string;
|
|
1402
994
|
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Generic allow/deny prompt for a pending permission request.
|
|
1405
|
-
*
|
|
1406
|
-
* Three outcomes, not two: denying usually means "not that, try something else",
|
|
1407
|
-
* so plain Deny lets the turn continue (with an optional reason the agent reads)
|
|
1408
|
-
* while "Deny & stop" also interrupts.
|
|
1409
|
-
*
|
|
1410
|
-
* The heading is whatever the engine authored — `title`, else `displayName`.
|
|
1411
|
-
* Composing "wants to use {tool}" instead would be wrong for codex, where an
|
|
1412
|
-
* approval is usually an *escalation after a sandbox refusal* and the runner has
|
|
1413
|
-
* already written the sentence that says so.
|
|
1414
|
-
*/
|
|
1415
995
|
declare function PermissionPrompt({
|
|
1416
996
|
request,
|
|
1417
997
|
onApprove,
|
|
@@ -1425,23 +1005,14 @@ type QuestionBehaviorMeta = {
|
|
|
1425
1005
|
label: string;
|
|
1426
1006
|
description: string;
|
|
1427
1007
|
};
|
|
1428
|
-
/** The AskUserQuestion policies surfaced on job/session creation forms. */
|
|
1429
1008
|
declare const QUESTION_BEHAVIORS: QuestionBehaviorMeta[];
|
|
1430
|
-
/** Extract well-formed questions from an AskUserQuestion permission request's input. */
|
|
1431
1009
|
declare function parseUserQuestions(input: Record<string, unknown>): UserQuestion[];
|
|
1432
1010
|
interface QuestionPromptProps {
|
|
1433
|
-
/** A pending permission whose toolName is 'AskUserQuestion'. */
|
|
1434
1011
|
request: PermissionRequest;
|
|
1435
|
-
/** Allow the tool with `updatedInput` (the original input plus `answers`). */
|
|
1436
1012
|
onAnswer: (requestId: string, updatedInput: Record<string, unknown>) => void;
|
|
1437
|
-
/** Deny the tool — the model proceeds without an answer. */
|
|
1438
1013
|
onDismiss: (requestId: string, message?: string) => void;
|
|
1439
1014
|
className?: string;
|
|
1440
1015
|
}
|
|
1441
|
-
/** Interactive form for the AskUserQuestion tool: option buttons per question
|
|
1442
|
-
* (multi-select where the question allows it), a free-text "Other" escape hatch,
|
|
1443
|
-
* and the focused option's preview. Falls back to nothing renderable → the caller
|
|
1444
|
-
* should show a generic PermissionPrompt if `parseUserQuestions` finds no questions. */
|
|
1445
1016
|
declare function QuestionPrompt({
|
|
1446
1017
|
request,
|
|
1447
1018
|
onAnswer,
|
|
@@ -1450,107 +1021,44 @@ declare function QuestionPrompt({
|
|
|
1450
1021
|
}: QuestionPromptProps): _$react.JSX.Element;
|
|
1451
1022
|
//#endregion
|
|
1452
1023
|
//#region src/components/agent/Composer.d.ts
|
|
1453
|
-
/** Files matching an `@` query, for the composer's file trigger. Structural so
|
|
1454
|
-
* the ui package doesn't have to reach for the protocol's `HostFileMatch`. */
|
|
1455
1024
|
type ComposerFileMatch = {
|
|
1456
1025
|
path: string;
|
|
1457
1026
|
relative: string;
|
|
1458
1027
|
};
|
|
1459
|
-
/** Imperative surface for panels that draft a message the user then finishes —
|
|
1460
|
-
* the skills dialog's "Use this skill". Nothing here sends. */
|
|
1461
1028
|
type ComposerHandle = {
|
|
1462
|
-
|
|
1463
|
-
* whatever is already there. */
|
|
1464
|
-
insertText: (text: string) => void; /** Put the caret in the field, changing nothing. */
|
|
1029
|
+
insertText: (text: string) => void;
|
|
1465
1030
|
focus: () => void;
|
|
1466
1031
|
};
|
|
1467
1032
|
interface ComposerProps {
|
|
1468
|
-
/** `attachmentIds` are the staged uploads, in the order they were picked. */
|
|
1469
1033
|
onSend: (text: string, attachmentIds: string[]) => void;
|
|
1470
1034
|
onInterrupt: () => void;
|
|
1471
1035
|
busy: boolean;
|
|
1472
|
-
/** Disable input entirely (session failed/closed). */
|
|
1473
1036
|
disabled?: boolean;
|
|
1474
1037
|
placeholder?: string;
|
|
1475
|
-
/** Slash commands offered as autocomplete; picked ones render as chips. */
|
|
1476
1038
|
commands?: SlashCommandInfo[];
|
|
1477
|
-
/**
|
|
1478
|
-
* Skills offered under a **`$`** popover of their own — codex's sigil, kept
|
|
1479
|
-
* separate from `/` because the two behave differently. A skill is a typing
|
|
1480
|
-
* aid, not a command: picking one inserts editable text (the skill's own
|
|
1481
|
-
* `defaultPrompt` where it has one, else `$name`) and nothing is sent. No
|
|
1482
|
-
* engine parses `$skillname` as syntax, which is exactly why these can never
|
|
1483
|
-
* resolve to a chip the way `commands` do.
|
|
1484
|
-
*/
|
|
1485
1039
|
skills?: SkillInfo[];
|
|
1486
|
-
/** Host-file search behind the `@` trigger. Omit to leave `@` inert — a
|
|
1487
|
-
* gateway without host files has nothing to complete. */
|
|
1488
1040
|
onSearchFiles?: (query: string, options: {
|
|
1489
1041
|
signal: AbortSignal;
|
|
1490
1042
|
}) => Promise<ComposerFileMatch[]>;
|
|
1491
|
-
/** Attachment staging (see `useAttachments`). Omit for a text-only composer. */
|
|
1492
1043
|
attachments?: UseAttachmentsResult;
|
|
1493
|
-
/** Left side of the toolbar row (mode selects, …). */
|
|
1494
1044
|
toolbar?: ReactNode;
|
|
1495
|
-
/**
|
|
1496
|
-
* `'stacked'` (default) gives the buttons a row of their own under the field —
|
|
1497
|
-
* right where a toolbar belongs. `'inline'` puts the field and the buttons on
|
|
1498
|
-
* ONE line, growing from a single row as the message does: for a host whose
|
|
1499
|
-
* session controls live in its own chrome (VS Code's status bar), where the
|
|
1500
|
-
* empty composer would otherwise spend two rows saying nothing.
|
|
1501
|
-
*/
|
|
1502
1045
|
layout?: 'stacked' | 'inline';
|
|
1503
|
-
/**
|
|
1504
|
-
* Terminal theme only: the cell the composer draws on. Passed straight
|
|
1505
|
-
* through to its own {@link TerminalSurface}, and it has to be passed — the
|
|
1506
|
-
* composer sits outside the transcript's scroller, so it establishes a second
|
|
1507
|
-
* surface, and a surface handed no metrics falls back to the 13/18 default. A
|
|
1508
|
-
* host running the transcript at its editor's size and the composer at the
|
|
1509
|
-
* default would have the caret land on a different column from the text above
|
|
1510
|
-
* it, which is the one thing this theme exists to prevent.
|
|
1511
|
-
*/
|
|
1512
1046
|
fontSize?: number;
|
|
1513
1047
|
lineHeight?: number;
|
|
1514
|
-
/** Terminal theme only; see {@link TerminalAffordances}. */
|
|
1515
1048
|
affordances?: TerminalAffordances | boolean;
|
|
1049
|
+
/**
|
|
1050
|
+
* Where unsent text is remembered between mounts. The composer is remounted on every session switch, so without
|
|
1051
|
+
* this a half-written prompt dies with the switch. Omit to keep the composer stateless across mounts.
|
|
1052
|
+
*/
|
|
1053
|
+
draft?: {
|
|
1054
|
+
initialText: string;
|
|
1055
|
+
save: (text: string) => void;
|
|
1056
|
+
clear: () => void;
|
|
1057
|
+
};
|
|
1516
1058
|
className?: string;
|
|
1517
1059
|
ref?: Ref<ComposerHandle>;
|
|
1518
1060
|
}
|
|
1519
|
-
/**
|
|
1520
|
-
* What a picked skill types into the composer.
|
|
1521
|
-
*
|
|
1522
|
-
* The engine's own `defaultPrompt` when it declared one — it knows what its
|
|
1523
|
-
* skill wants to be asked — and otherwise `$name`, which is codex's native way
|
|
1524
|
-
* of referring to a skill in prompt text: its `skill-creator` documents the form
|
|
1525
|
-
* (`Use $skill-x at /path/to/skill-x to solve problem y`) and its own bundled
|
|
1526
|
-
* prompts are written that way ("Use $pdf to …"). Spelling it the way the engine
|
|
1527
|
-
* spells it beats paraphrasing into "Use the X skill to".
|
|
1528
|
-
*
|
|
1529
|
-
* Either way it ends in a space so the caret lands ready for the rest of the
|
|
1530
|
-
* sentence, and either way it is ordinary text: nothing here is submitted, and
|
|
1531
|
-
* nothing is parsed back out.
|
|
1532
|
-
*/
|
|
1533
1061
|
declare function skillPrompt(skill: SkillInfo): string;
|
|
1534
|
-
/**
|
|
1535
|
-
* Framed prompt input built on prompt-area's contentEditable.
|
|
1536
|
-
*
|
|
1537
|
-
* Three completions ride the same field and behave nothing alike. `/` is the
|
|
1538
|
-
* CLI's command list and `$` is the engine's skill list — both local, so they
|
|
1539
|
-
* filter completely and instantly; `@` is a search against the host filesystem,
|
|
1540
|
-
* debounced and abortable so a fast typist makes one request rather than eight.
|
|
1541
|
-
*
|
|
1542
|
-
* `/` and `$` are separate keys rather than one merged menu, and that mirrors
|
|
1543
|
-
* the engines themselves: codex completes skills on `$` and reserves `/` for
|
|
1544
|
-
* commands. The behaviours differ too — a command resolves to a **chip**,
|
|
1545
|
-
* because the CLI really does parse `/name` out of the message, while a skill
|
|
1546
|
-
* resolves to plain editable **text**, because no engine parses `$name` as
|
|
1547
|
-
* syntax; it is prose the model reads. Rendering them alike would promise
|
|
1548
|
-
* something that does not happen.
|
|
1549
|
-
*
|
|
1550
|
-
* Files can arrive three ways — the paperclip, a drop, or a paste — because on a
|
|
1551
|
-
* desktop all three are things people already do, and the upload starts the
|
|
1552
|
-
* moment one lands rather than at send time.
|
|
1553
|
-
*/
|
|
1554
1062
|
declare function Composer({
|
|
1555
1063
|
onSend,
|
|
1556
1064
|
onInterrupt,
|
|
@@ -1566,28 +1074,20 @@ declare function Composer({
|
|
|
1566
1074
|
fontSize,
|
|
1567
1075
|
lineHeight,
|
|
1568
1076
|
affordances,
|
|
1077
|
+
draft,
|
|
1569
1078
|
className,
|
|
1570
1079
|
ref
|
|
1571
1080
|
}: ComposerProps): _$react.JSX.Element;
|
|
1572
1081
|
//#endregion
|
|
1573
1082
|
//#region src/components/agent/ModelSelect.d.ts
|
|
1574
1083
|
interface ModelSelectProps {
|
|
1575
|
-
/** Models the session can switch to (TranscriptState.models). */
|
|
1576
1084
|
models: ModelOption[];
|
|
1577
|
-
/** The session's current model id (TranscriptState.model), possibly decorated
|
|
1578
|
-
* (e.g. "claude-fable-5[1m]") — matched leniently against the options.
|
|
1579
|
-
* `undefined` selects the list's default row, if it has one. */
|
|
1580
1085
|
model?: string;
|
|
1581
|
-
/** `undefined` = back to the CLI's default model. */
|
|
1582
1086
|
onModelChange: (model?: string) => void;
|
|
1583
|
-
/** 'toolbar' (default) is the composer's compact borderless trigger;
|
|
1584
|
-
* 'form' is a standard field-sized Select for create/settings forms. */
|
|
1585
1087
|
variant?: 'toolbar' | 'form';
|
|
1586
1088
|
disabled?: boolean;
|
|
1587
1089
|
className?: string;
|
|
1588
1090
|
}
|
|
1589
|
-
/** Compact model switcher for the composer toolbar; fed by the `capabilities` event.
|
|
1590
|
-
* Rows render CLI-style: bold display name with the model's description beneath. */
|
|
1591
1091
|
declare function ModelSelect({
|
|
1592
1092
|
models,
|
|
1593
1093
|
model,
|
|
@@ -1600,42 +1100,15 @@ declare function ModelSelect({
|
|
|
1600
1100
|
//#region src/components/agent/StatusBar.d.ts
|
|
1601
1101
|
interface StatusBarProps {
|
|
1602
1102
|
state: TranscriptState;
|
|
1603
|
-
/**
|
|
1604
|
-
* Plan windows to draw, when they should not be the session's own. The panel
|
|
1605
|
-
* hands over the gateway's per-profile state merged over this transcript's
|
|
1606
|
-
* reading (`mergeUsage`): a session's own `rate_limit` readings arrive only at
|
|
1607
|
-
* a turn's edges, so one idle since yesterday would otherwise render
|
|
1608
|
-
* yesterday's number as current. Absent = `state.rateLimits`, which is what a
|
|
1609
|
-
* bar composed by hand outside the panel gets.
|
|
1610
|
-
*/
|
|
1611
1103
|
rateLimits?: Record<string, RateLimitInfo>;
|
|
1612
|
-
/** @deprecated Pass {@link StatusBarProps.connection}
|
|
1613
|
-
* still handing over a boolean keeps working. */
|
|
1104
|
+
/** @deprecated Pass {@link StatusBarProps.connection}. */
|
|
1614
1105
|
connected?: boolean;
|
|
1615
|
-
/** How the client is doing at reaching the gateway. A dropped socket wins the
|
|
1616
|
-
* status slot: the session status held over a dead socket is a stale reading,
|
|
1617
|
-
* and presenting it as a live one is the thing worth avoiding. */
|
|
1618
1106
|
connection?: ConnectionState;
|
|
1619
|
-
/**
|
|
1620
|
-
* Where the gauges lead. Each one opens the panel that answers *its* question
|
|
1621
|
-
* — the two meters measure different things, so sending both to one "details"
|
|
1622
|
-
* list would be a detour every time. Omit a handler and that gauge stays a
|
|
1623
|
-
* read-only tooltip.
|
|
1624
|
-
*/
|
|
1625
1107
|
onOpenStatus?: () => void;
|
|
1626
1108
|
onOpenContext?: () => void;
|
|
1627
1109
|
onOpenUsage?: () => void;
|
|
1628
|
-
/**
|
|
1629
|
-
* The session's own controls (model, permission mode), for
|
|
1630
|
-
* `controlsSurface: 'status'`. They sit at the end of the readings cluster —
|
|
1631
|
-
* status, context, usage, then what you can *change* — rather than out by the
|
|
1632
|
-
* actions menu, because they belong with the session facts they act on.
|
|
1633
|
-
*/
|
|
1634
1110
|
controls?: ReactNode;
|
|
1635
|
-
/** Trailing slot — the session-actions menu, at the bar's trailing edge. */
|
|
1636
1111
|
actions?: ReactNode;
|
|
1637
|
-
/** Which edge the bar sits on, so its separating rule goes on the other side.
|
|
1638
|
-
* Placement is the panel's decision; this only styles it. */
|
|
1639
1112
|
placement?: 'top' | 'bottom';
|
|
1640
1113
|
className?: string;
|
|
1641
1114
|
}
|
|
@@ -1660,13 +1133,6 @@ interface ContextDialogProps {
|
|
|
1660
1133
|
onOpenChange: (open: boolean) => void;
|
|
1661
1134
|
className?: string;
|
|
1662
1135
|
}
|
|
1663
|
-
/**
|
|
1664
|
-
* What is in the model's context window right now, category by category.
|
|
1665
|
-
*
|
|
1666
|
-
* One of the three panels the status bar opens. Context, usage and session info
|
|
1667
|
-
* are different questions asked at different moments, so they are different
|
|
1668
|
-
* screens rather than one "details" list you scroll past two answers to reach.
|
|
1669
|
-
*/
|
|
1670
1136
|
declare function ContextDialog({
|
|
1671
1137
|
usage,
|
|
1672
1138
|
open,
|
|
@@ -1676,33 +1142,15 @@ declare function ContextDialog({
|
|
|
1676
1142
|
//#endregion
|
|
1677
1143
|
//#region src/components/agent/UsageDialog.d.ts
|
|
1678
1144
|
interface UsageDialogProps {
|
|
1679
|
-
/**
|
|
1680
|
-
* Windows in reading order — session, weekly, then per-model weeklies.
|
|
1681
|
-
*
|
|
1682
|
-
* `updatedAt`/`inferredReset` ride each window because the readings no longer
|
|
1683
|
-
* share one clock: the panel merges the gateway's per-profile state over this
|
|
1684
|
-
* session's, so a `five_hour` learned from a sibling session two minutes ago
|
|
1685
|
-
* can sit beside a `seven_day` this session last heard about yesterday.
|
|
1686
|
-
* `inferredReset` marks the ones the *gateway* zeroed because their own reset
|
|
1687
|
-
* time passed with nothing newer — a floor, not a report.
|
|
1688
|
-
*/
|
|
1689
1145
|
rateLimits: UsageWindowRow[];
|
|
1690
|
-
/** claude.ai plan behind the windows ('max', 'pro', …), when there is one. */
|
|
1691
1146
|
subscriptionType?: string;
|
|
1692
1147
|
engine: ProfileEngine;
|
|
1693
1148
|
totalCostUsd: number;
|
|
1694
|
-
/** When the *freshest* of the windows was read, for the footer line. Readings
|
|
1695
|
-
* arrive one per turn at best (and for an idle session, not at all), so a
|
|
1696
|
-
* stale one is normal and worth saying out loud. */
|
|
1697
1149
|
updatedAt?: number;
|
|
1698
1150
|
open: boolean;
|
|
1699
1151
|
onOpenChange: (open: boolean) => void;
|
|
1700
1152
|
className?: string;
|
|
1701
1153
|
}
|
|
1702
|
-
/**
|
|
1703
|
-
* The session's view of the plan: every window as a meter (see
|
|
1704
|
-
* {@link UsageMeters}), the plan tier, and what this session itself has cost.
|
|
1705
|
-
*/
|
|
1706
1154
|
declare function UsageDialog({
|
|
1707
1155
|
rateLimits,
|
|
1708
1156
|
subscriptionType,
|
|
@@ -1715,39 +1163,13 @@ declare function UsageDialog({
|
|
|
1715
1163
|
}: UsageDialogProps): _$react.JSX.Element;
|
|
1716
1164
|
//#endregion
|
|
1717
1165
|
//#region src/components/agent/UsageMeters.d.ts
|
|
1718
|
-
/**
|
|
1719
|
-
* Ticking clock — the countdowns and the pace markers both move with it, and a
|
|
1720
|
-
* minute is the finest resolution either of them prints.
|
|
1721
|
-
*
|
|
1722
|
-
* `active` is what a dialog passes its `open`: a closed panel's clock is a timer
|
|
1723
|
-
* re-rendering something nobody can see.
|
|
1724
|
-
*/
|
|
1725
1166
|
declare function useMinuteClock(active?: boolean): number;
|
|
1726
|
-
/**
|
|
1727
|
-
* The plan's rate-limit windows, spelled out: how much of each is used, how that
|
|
1728
|
-
* compares to the pace that would spend the window exactly, and when it resets.
|
|
1729
|
-
*
|
|
1730
|
-
* The pace marker is the point. A bar alone says "17% used", which is only
|
|
1731
|
-
* alarming or reassuring once you know how far into the week you are — so every
|
|
1732
|
-
* window draws a tick at the elapsed share of its duration. Left of the tick is
|
|
1733
|
-
* under budget, right of it is ahead of it. The duration comes from the window
|
|
1734
|
-
* key (5h, 7d) because the engine reports a reset time and a percentage and
|
|
1735
|
-
* never a duration; a window whose key doesn't say gets no marker rather than a
|
|
1736
|
-
* guessed one.
|
|
1737
|
-
*
|
|
1738
|
-
* Its own component rather than the Usage dialog's private helper because two
|
|
1739
|
-
* surfaces draw these now — the session panel's Usage panel, from the session's
|
|
1740
|
-
* readings merged with the gateway's, and the dashboard's profile page, straight
|
|
1741
|
-
* off `ProfileInfo.usage` with no session in sight. Same account, same bars.
|
|
1742
|
-
*/
|
|
1743
1167
|
declare function UsageMeters({
|
|
1744
1168
|
windows,
|
|
1745
1169
|
now,
|
|
1746
1170
|
className
|
|
1747
1171
|
}: {
|
|
1748
|
-
|
|
1749
|
-
/** A shared clock, when the caller already ticks one. Omitted, this ticks its
|
|
1750
|
-
* own for as long as it is mounted. */
|
|
1172
|
+
windows: UsageWindowRow[];
|
|
1751
1173
|
now?: number;
|
|
1752
1174
|
className?: string;
|
|
1753
1175
|
}): _$react.JSX.Element;
|
|
@@ -1760,14 +1182,6 @@ interface SessionInfoDialogProps {
|
|
|
1760
1182
|
open: boolean;
|
|
1761
1183
|
onOpenChange: (open: boolean) => void;
|
|
1762
1184
|
}
|
|
1763
|
-
/**
|
|
1764
|
-
* What this session *is*: engine, profile, model, mode, where it runs, which
|
|
1765
|
-
* credentials it found, and the files it has handed over.
|
|
1766
|
-
*
|
|
1767
|
-
* The identity half of the session's facts. Context and usage have their own
|
|
1768
|
-
* panels — they change every turn and are consulted mid-run, while everything
|
|
1769
|
-
* here is fixed at creation and looked up once.
|
|
1770
|
-
*/
|
|
1771
1185
|
declare function SessionInfoDialog({
|
|
1772
1186
|
state,
|
|
1773
1187
|
client,
|
|
@@ -1782,27 +1196,9 @@ interface McpDialogProps {
|
|
|
1782
1196
|
sessionId: string | undefined;
|
|
1783
1197
|
open: boolean;
|
|
1784
1198
|
onOpenChange: (open: boolean) => void;
|
|
1785
|
-
/**
|
|
1786
|
-
* Whether this engine can reconnect/enable/disable a server
|
|
1787
|
-
* (`EngineCapabilities.mcpServerActions`). False renders the panel read-only:
|
|
1788
|
-
* codex reports rich status but exposes no per-server action, and buttons
|
|
1789
|
-
* that 501 are worse than buttons that aren't there.
|
|
1790
|
-
*/
|
|
1791
1199
|
canManageServers?: boolean;
|
|
1792
1200
|
className?: string;
|
|
1793
1201
|
}
|
|
1794
|
-
/**
|
|
1795
|
-
* The session's MCP servers, at the CLI's own `/mcp` depth: servers → one server
|
|
1796
|
-
* → its tools → one tool, with Reconnect / Enable / Disable where they apply.
|
|
1797
|
-
*
|
|
1798
|
-
* Two things vary by engine rather than being fixed here. **The actions** exist
|
|
1799
|
-
* only where the engine has them (`canManageServers`): codex reports rich status
|
|
1800
|
-
* but has no per-server reconnect or toggle, so its panel is read-only. And
|
|
1801
|
-
* **tool parameters** appear only where the engine reports a schema — codex
|
|
1802
|
-
* returns each tool's full JSON Schema, the Agent SDK returns none at all, so
|
|
1803
|
-
* the tool view either renders it or says why it can't, rather than leaving a
|
|
1804
|
-
* silent gap or claiming the absence is universal.
|
|
1805
|
-
*/
|
|
1806
1202
|
declare function McpDialog({
|
|
1807
1203
|
client,
|
|
1808
1204
|
sessionId,
|
|
@@ -1817,24 +1213,9 @@ interface SkillsDialogProps {
|
|
|
1817
1213
|
skills: SkillInfo[] | undefined;
|
|
1818
1214
|
open: boolean;
|
|
1819
1215
|
onOpenChange: (open: boolean) => void;
|
|
1820
|
-
/** Insert a skill's opening message into the composer, if the host offers
|
|
1821
|
-
* that. Omit and the dialog is read-only. */
|
|
1822
1216
|
onUse?: (skill: SkillInfo) => void;
|
|
1823
1217
|
className?: string;
|
|
1824
1218
|
}
|
|
1825
|
-
/**
|
|
1826
|
-
* What this session's engine can do beyond its own tools: the skills it found,
|
|
1827
|
-
* grouped by where they came from, with one drilled-down view each.
|
|
1828
|
-
*
|
|
1829
|
-
* The framing matters more here than in most panels. A skill is **not** a
|
|
1830
|
-
* command — the model decides to use one by reading its description, and there
|
|
1831
|
-
* is no wire syntax that invokes it. So this screen is a *discovery* surface,
|
|
1832
|
-
* and the one action it offers ("Use this skill") is honest about being a
|
|
1833
|
-
* drafting aid: it types a message for the operator to edit and send.
|
|
1834
|
-
*
|
|
1835
|
-
* Fed from the session's `skills` event rather than a REST route, because that
|
|
1836
|
-
* is the channel the engine refreshes on its own when a skill changes on disk.
|
|
1837
|
-
*/
|
|
1838
1219
|
declare function SkillsDialog({
|
|
1839
1220
|
skills,
|
|
1840
1221
|
open,
|
|
@@ -1846,20 +1227,10 @@ declare function SkillsDialog({
|
|
|
1846
1227
|
//#region src/components/agent/HostFilesDialog.d.ts
|
|
1847
1228
|
interface HostFilesDialogProps {
|
|
1848
1229
|
client: WorkerDeckClient;
|
|
1849
|
-
/** The session's working directory — the browser is rooted here. */
|
|
1850
1230
|
cwd: string | undefined;
|
|
1851
1231
|
open: boolean;
|
|
1852
1232
|
onOpenChange: (open: boolean) => void;
|
|
1853
1233
|
}
|
|
1854
|
-
/**
|
|
1855
|
-
* Browse the project the session is working in.
|
|
1856
|
-
*
|
|
1857
|
-
* Deliberately rooted at the session's cwd rather than at the server's
|
|
1858
|
-
* `hostFiles.roots`: the roots are the *security* boundary (the server enforces
|
|
1859
|
-
* them on every request), but what someone wants while watching an agent is this
|
|
1860
|
-
* project's tree. Read-only — writing is a separate server opt-in and not
|
|
1861
|
-
* something a session viewer should be doing behind the agent's back.
|
|
1862
|
-
*/
|
|
1863
1234
|
declare function HostFilesDialog({
|
|
1864
1235
|
client,
|
|
1865
1236
|
cwd,
|
|
@@ -1900,28 +1271,6 @@ declare function SessionList({
|
|
|
1900
1271
|
}: SessionListProps): _$react.JSX.Element;
|
|
1901
1272
|
//#endregion
|
|
1902
1273
|
//#region src/components/agent/SessionStatusIcon.d.ts
|
|
1903
|
-
/**
|
|
1904
|
-
* State as one glyph — a ringing bell when it wants a human, a spinner while it
|
|
1905
|
-
* works, a moon when it is only sleeping. Replaces the text badge: in a sidebar
|
|
1906
|
-
* the word costs more room than it earns, and the states that matter are the two
|
|
1907
|
-
* you can recognise without reading.
|
|
1908
|
-
*
|
|
1909
|
-
* **It reads `row.state`, not `info.status`, and that distinction is the whole
|
|
1910
|
-
* point of the row model.** `sessionState` already folds in the arm this glyph
|
|
1911
|
-
* cannot see for itself: a *background* sub-agent outlives its turn by design,
|
|
1912
|
-
* so the turn ends, `status` comes to rest at `idle`, and the agent keeps
|
|
1913
|
-
* working. Reading the raw status drew a **moon on a row filed under the
|
|
1914
|
-
* "Working" header** — the list contradicting itself on one line, which is
|
|
1915
|
-
* exactly what a derived view model exists to prevent. The value was in scope
|
|
1916
|
-
* and unread.
|
|
1917
|
-
*
|
|
1918
|
-
* The terminal statuses still come off `info.status`, because `ended` collapses
|
|
1919
|
-
* `failed` and `closed` into one bucket and those are worth telling apart here.
|
|
1920
|
-
*
|
|
1921
|
-
* It lives in its own file rather than inside the dashboard's browser because
|
|
1922
|
-
* the extension's cards draw it too, and a second copy there is how the two
|
|
1923
|
-
* lists last disagreed about what a parked session looks like.
|
|
1924
|
-
*/
|
|
1925
1274
|
declare function SessionStatusIcon({
|
|
1926
1275
|
row,
|
|
1927
1276
|
className
|
|
@@ -1931,109 +1280,24 @@ declare function SessionStatusIcon({
|
|
|
1931
1280
|
}): _$react.JSX.Element;
|
|
1932
1281
|
//#endregion
|
|
1933
1282
|
//#region src/components/agent/SessionBrowser.d.ts
|
|
1934
|
-
/**
|
|
1935
|
-
* A sessions list with the affordances a list of thirty needs: search, facets,
|
|
1936
|
-
* grouping, sorting, unread counts, and one honest line about what is hidden.
|
|
1937
|
-
*
|
|
1938
|
-
* The *rules* are `@workerdeck/protocol`'s (`filterRows`/`groupRows`/
|
|
1939
|
-
* `subsetSummary`), not this component's — the VS Code sidebar renders the same
|
|
1940
|
-
* model with workbench chrome, its activity-bar badge counts the same rows this
|
|
1941
|
-
* would show, and iOS mirrors them in Swift. What lives here is the styled
|
|
1942
|
-
* rendering of that model, so a host that wants the dashboard's look gets it
|
|
1943
|
-
* without reimplementing the model behind it.
|
|
1944
|
-
*
|
|
1945
|
-
* `SessionList` remains beside this for the plain case (a fixed set of rows, no
|
|
1946
|
-
* controls); this is what you reach for when the list is the screen.
|
|
1947
|
-
*/
|
|
1948
1283
|
interface SessionBrowserProps {
|
|
1949
1284
|
rows: SessionRow[];
|
|
1950
1285
|
config: ViewConfig;
|
|
1951
1286
|
onConfigChange: (config: ViewConfig) => void;
|
|
1952
|
-
/** The host's own folders, if it has such a notion. Absent — a dashboard, a
|
|
1953
|
-
* phone — makes the scope filter genuinely inert rather than empty. */
|
|
1954
1287
|
scope?: WorkspaceScope;
|
|
1955
1288
|
activeId?: string;
|
|
1956
|
-
/**
|
|
1957
|
-
* Which sub-agent the host currently has open, by tool-use id — the *finer*
|
|
1958
|
-
* of the two selections. The card holding it drops to the secondary grey and
|
|
1959
|
-
* that step takes the blue; see `SessionItem`. A host with no sub-agent
|
|
1960
|
-
* surface leaves it undefined and nothing changes.
|
|
1961
|
-
*/
|
|
1962
1289
|
activeSubagentId?: string;
|
|
1963
1290
|
onSelect?: (row: SessionRow) => void;
|
|
1964
1291
|
onDelete?: (row: SessionRow) => void;
|
|
1965
|
-
/**
|
|
1966
|
-
* Rename, from the row's pencil. Empty string restores the derived title. A
|
|
1967
|
-
* gateway edit (`PATCH /sessions/:id`), never a local override — every client
|
|
1968
|
-
* should see the same name. Omit to make titles read-only.
|
|
1969
|
-
*
|
|
1970
|
-
* A hover affordance rather than the extension's double-click-the-title,
|
|
1971
|
-
* because here a single click on the row navigates: the *first* click of a
|
|
1972
|
-
* double-click would have already left the page.
|
|
1973
|
-
*/
|
|
1974
1292
|
onRename?: (row: SessionRow, title: string) => void;
|
|
1975
|
-
/**
|
|
1976
|
-
* Clear the conversation in place, from the row's eraser. Same session, empty
|
|
1977
|
-
* context — **not** a delete: the engine keeps the old conversation and it
|
|
1978
|
-
* stays resumable, which is why the row's copy never says "deleted".
|
|
1979
|
-
*
|
|
1980
|
-
* Rendered only where the session's own capability record allows it
|
|
1981
|
-
* (`capabilities.clearContext`, absent = false), so a row that cannot be
|
|
1982
|
-
* cleared has no eraser rather than one that errors. Omit the prop to have
|
|
1983
|
-
* none at all — a host with no way to send a session command has nothing to
|
|
1984
|
-
* hang it on (this is a WS command, not a REST route).
|
|
1985
|
-
*/
|
|
1986
1293
|
onClearContext?: (row: SessionRow) => void;
|
|
1987
|
-
/** Open a session *at* one of its sub-agents, when the host can scroll a
|
|
1988
|
-
* transcript to a `Task` row. Absent, the sub-agent list still expands and a
|
|
1989
|
-
* step just opens its session — see `SessionRowItemProps`. */
|
|
1990
1294
|
onSelectSubagent?: (row: SessionRow, toolUseId: string) => void;
|
|
1991
|
-
/** Open a session and travel to one of its **tasks** — see
|
|
1992
|
-
* `SessionItem.onRevealStep`. A task has no agent behind it, so it is a place
|
|
1993
|
-
* to go rather than a thing to open, and framing it as an agent drew an empty
|
|
1994
|
-
* view. */
|
|
1995
1295
|
onRevealStep?: (row: SessionRow, toolUseId: string) => void;
|
|
1996
|
-
/** Rendered when nothing at all exists (as opposed to nothing matching). */
|
|
1997
1296
|
emptyState?: React.ReactNode;
|
|
1998
|
-
/**
|
|
1999
|
-
* Whether the search + facet bar is shown. Defaults to `true` — a list that
|
|
2000
|
-
* *is* the screen shows its controls.
|
|
2001
|
-
*
|
|
2002
|
-
* A host with somewhere better to put the toggle (a view title bar) passes
|
|
2003
|
-
* `false` and owns the boolean itself, the way the VS Code extension does: the
|
|
2004
|
-
* key lives where the commands do. Two rules come with it, and they are why
|
|
2005
|
-
* this hides only the bar and nothing else — **closing the bar never clears
|
|
2006
|
-
* the filters**, and the subset line below it renders either way, so a list
|
|
2007
|
-
* filtered by a control you can't currently see still says so.
|
|
2008
|
-
*/
|
|
2009
1297
|
showControls?: boolean;
|
|
2010
|
-
/**
|
|
2011
|
-
* Resolved project-icon bytes by content hash — `useProjectIcons`' output.
|
|
2012
|
-
*
|
|
2013
|
-
* Passed in rather than fetched here for the reason `ProjectIcon` states: the
|
|
2014
|
-
* wire carries an *address*, and who can fetch it differs per client. Absent,
|
|
2015
|
-
* or a hash not in it yet, simply draws no picture; the project's name is
|
|
2016
|
-
* already there.
|
|
2017
|
-
*/
|
|
2018
1298
|
projectIcons?: Record<string, string>;
|
|
2019
1299
|
className?: string;
|
|
2020
1300
|
}
|
|
2021
|
-
/**
|
|
2022
|
-
* How a list row is drawn, in one place, so `SidebarRow` in `web` matches this
|
|
2023
|
-
* exactly rather than approximating it — the dashboard's other three sidebars
|
|
2024
|
-
* are that component, and a sessions list that hovered differently from the
|
|
2025
|
-
* gateways list beside it would read as a different product.
|
|
2026
|
-
*
|
|
2027
|
-
* Two rules are load-bearing:
|
|
2028
|
-
*
|
|
2029
|
-
* - **Fill means hover, and only hover.** It stays on the row whether or not
|
|
2030
|
-
* the row is selected, because a selected row still has to answer the
|
|
2031
|
-
* pointer. Selection gets the gutter instead.
|
|
2032
|
-
* - **`ml-0` on the selected row is not cosmetic.** It hands the accent border
|
|
2033
|
-
* the 4px the margin was holding, so the text does not shift sideways as a
|
|
2034
|
-
* row becomes the selected one. The squared left corners are what let the bar
|
|
2035
|
-
* sit flush against the sidebar edge.
|
|
2036
|
-
*/
|
|
2037
1301
|
declare function rowShapeClass(active: boolean): string;
|
|
2038
1302
|
declare function SessionBrowser({
|
|
2039
1303
|
rows,
|
|
@@ -2055,132 +1319,22 @@ declare function SessionBrowser({
|
|
|
2055
1319
|
}: SessionBrowserProps): _$react.JSX.Element;
|
|
2056
1320
|
//#endregion
|
|
2057
1321
|
//#region src/components/agent/SessionItem.d.ts
|
|
2058
|
-
/**
|
|
2059
|
-
* One session in a list — the **card**, and the only drawing of it in the
|
|
2060
|
-
* product.
|
|
2061
|
-
*
|
|
2062
|
-
* The dashboard's `SessionBrowser` and the VS Code sidebar both render this;
|
|
2063
|
-
* before it existed they rendered two hand-kept copies that agreed on the model
|
|
2064
|
-
* and disagreed on every measurement, and the two lists read as two products.
|
|
2065
|
-
* iOS mirrors this file's geometry rather than either copy.
|
|
2066
|
-
*
|
|
2067
|
-
* ## The shape
|
|
2068
|
-
*
|
|
2069
|
-
* A 4px-padded, 4px-rounded card whose whole surface is the hit target, holding
|
|
2070
|
-
* two 20px lines and, when it is open, the work under them.
|
|
2071
|
-
*
|
|
2072
|
-
* **Line one is state and identity**: the status glyph leads, the title takes
|
|
2073
|
-
* the rest, and the line closes with the unread badge and the context ring. The
|
|
2074
|
-
* glyph leads because a sessions list is scanned for *state* first — which of
|
|
2075
|
-
* these is working, which is waiting on me — and the title is what you read once
|
|
2076
|
-
* the glyph has told you which row to read. The two readings that close the line
|
|
2077
|
-
* are the two that change while you are looking at them.
|
|
2078
|
-
*
|
|
2079
|
-
* **Line two is identity and cost**: the engine's mark and its model in the
|
|
2080
|
-
* vendor's own colour, then the project, then everything else the host wants
|
|
2081
|
-
* said, then the age — a `·`-joined run that ends in the one part of it that
|
|
2082
|
-
* keeps moving. The line's right edge belongs to the disclosure (which doubles
|
|
2083
|
-
* as the count of the work below, so the card says how much there is without
|
|
2084
|
-
* being opened) and to the host's own actions.
|
|
2085
|
-
*
|
|
2086
|
-
* **The gutter is one 16px cell, shared by both lines.** The two glyphs are
|
|
2087
|
-
* different sizes and laying them out as plain flex children starts the two
|
|
2088
|
-
* text columns at different x — two pixels, invisible as a measurement and
|
|
2089
|
-
* obvious as a misalignment. Centring inside a fixed cell fixes the text edges
|
|
2090
|
-
* and the ink centres at once. It is the terminal gutter's argument at card
|
|
2091
|
-
* scale.
|
|
2092
|
-
*
|
|
2093
|
-
* ## Selection
|
|
2094
|
-
*
|
|
2095
|
-
* **Selection is the card's own fill**, not a gutter bar: the card is an inset
|
|
2096
|
-
* shape with air around it, so filling it is unambiguous in a way a fill on a
|
|
2097
|
-
* full-bleed row is not, and it leaves the left edge to the state glyph.
|
|
2098
|
-
*
|
|
2099
|
-
* There are **two selections at two grains**, and the card and its steps split
|
|
2100
|
-
* them:
|
|
2101
|
-
*
|
|
2102
|
-
* | what is on screen | card | the step |
|
|
2103
|
-
* | --- | --- | --- |
|
|
2104
|
-
* | nothing | transparent, hovers | transparent, hovers |
|
|
2105
|
-
* | this session | `--row-selected` (blue) | transparent, hovers |
|
|
2106
|
-
* | one of its sub-agents | `--row-selected-weak` (grey) | `--row-selected` (blue) |
|
|
2107
|
-
*
|
|
2108
|
-
* **The blue always marks the finest thing selected.** Opening a sub-agent
|
|
2109
|
-
* selects its session too, so both claims are true at once and the blue can only
|
|
2110
|
-
* carry one; it goes to the agent, and the card steps back to grey — present,
|
|
2111
|
-
* holding what you are looking at, not itself the thing you are looking at.
|
|
2112
|
-
* Reversing that (blue card, blue row inside it) says nothing, which is what a
|
|
2113
|
-
* blue-on-blue card looked like.
|
|
2114
|
-
*
|
|
2115
|
-
* A filled card does **not** also answer hover: the fill is already spent, and a
|
|
2116
|
-
* selected row that lightened under the pointer read as a third state nobody
|
|
2117
|
-
* could name. Its steps still do, on `--row-active`, which is a tint and so
|
|
2118
|
-
* works on all three grounds.
|
|
2119
|
-
*
|
|
2120
|
-
* A **task** never takes the blue. It is a reference to a place inside a
|
|
2121
|
-
* session, so pressing one selects the session and travels to its marker — see
|
|
2122
|
-
* `StepRow`.
|
|
2123
|
-
*/
|
|
2124
1322
|
interface SessionItemProps {
|
|
2125
1323
|
row: SessionRow;
|
|
2126
|
-
/** This session is the one the host is showing. */
|
|
2127
1324
|
active?: boolean;
|
|
2128
|
-
/**
|
|
2129
|
-
* Which sub-agent is open, by `Step.key` — the *finer* of the two selections.
|
|
2130
|
-
* When it names one of this card's agents, that step takes the blue and the
|
|
2131
|
-
* card drops to the secondary grey. A key belonging to some other card's
|
|
2132
|
-
* agent, or to a task, changes nothing here.
|
|
2133
|
-
*/
|
|
2134
1325
|
activeStepKey?: string;
|
|
2135
|
-
/** Shown when the list is not already grouped by gateway. */
|
|
2136
1326
|
showGateway?: boolean;
|
|
2137
|
-
/**
|
|
2138
|
-
* False when the list is already grouped by project — the header above has
|
|
2139
|
-
* said the name, so the card must not spend its metadata line repeating it.
|
|
2140
|
-
* What takes the slot is the *sub-path inside the project*
|
|
2141
|
-
* (`projectSubpath`): `packages/ui`, `packages/server` — the one thing the
|
|
2142
|
-
* header cannot say and the only thing that tells two sessions in one repo
|
|
2143
|
-
* apart. A session at the project root has nothing to add and the slot
|
|
2144
|
-
* disappears entirely. Exactly the rule `showGateway` follows one facet over.
|
|
2145
|
-
*/
|
|
2146
1327
|
showProject?: boolean;
|
|
2147
|
-
/** Resolved project-icon bytes by content hash. A hash this map has not got
|
|
2148
|
-
* yet simply draws no icon. */
|
|
2149
1328
|
projectIcons?: Record<string, string>;
|
|
2150
|
-
/** Uncontrolled by default — pass both to drive expansion from the host. */
|
|
2151
1329
|
expanded?: boolean;
|
|
2152
1330
|
onExpandedChange?: (expanded: boolean) => void;
|
|
2153
1331
|
onSelect?: () => void;
|
|
2154
|
-
/** Open the session *at* one of its sub-agents — hand the panel body over to
|
|
2155
|
-
* that agent's own work. Only ever called for an **agent** step. Absent is not
|
|
2156
|
-
* a missing feature: without it a step just opens the session, which is all a
|
|
2157
|
-
* host with no sub-agent surface can offer. */
|
|
2158
1332
|
onSelectSubagent?: (toolUseId: string) => void;
|
|
2159
|
-
/**
|
|
2160
|
-
* Open the session and travel to a **task**'s row in the transcript — where
|
|
2161
|
-
* the work was started, and where it finished.
|
|
2162
|
-
*
|
|
2163
|
-
* A separate seam from `onSelectSubagent` because the destinations are
|
|
2164
|
-
* different, and conflating them is not a styling detail: a task has no agent
|
|
2165
|
-
* behind it, so framing its tool-use id selects **no items at all** and the
|
|
2166
|
-
* panel draws an empty agent view. That was the bug. A task is a reference,
|
|
2167
|
-
* and the only honest thing to do with a reference is follow it.
|
|
2168
|
-
*/
|
|
2169
1333
|
onRevealStep?: (toolUseId: string) => void;
|
|
2170
|
-
/** Enables in-place rename. The trigger is the host's — see `renameOn`. */
|
|
2171
1334
|
onRename?: (title: string) => void;
|
|
2172
|
-
/**
|
|
2173
|
-
* How a rename starts. `doubleClick` is the editor feel (a rename is a thing
|
|
2174
|
-
* you do to the word you are looking at); `external` means the host opens it
|
|
2175
|
-
* from its own affordance — a menu entry, a pencil in `actions` — and drives
|
|
2176
|
-
* it through `editing`/`onEditingChange`.
|
|
2177
|
-
*/
|
|
2178
1335
|
renameOn?: 'doubleClick' | 'external';
|
|
2179
1336
|
editing?: boolean;
|
|
2180
1337
|
onEditingChange?: (editing: boolean) => void;
|
|
2181
|
-
/** The card's trailing controls, at the end of line two. A single overflow
|
|
2182
|
-
* glyph is what the design draws; a host with three always-on actions can put
|
|
2183
|
-
* them here instead. */
|
|
2184
1338
|
actions?: ReactNode;
|
|
2185
1339
|
className?: string;
|
|
2186
1340
|
}
|
|
@@ -2205,25 +1359,8 @@ declare function SessionItem({
|
|
|
2205
1359
|
}: SessionItemProps): _$react.JSX.Element;
|
|
2206
1360
|
//#endregion
|
|
2207
1361
|
//#region src/components/agent/EngineIcon.d.ts
|
|
2208
|
-
/**
|
|
2209
|
-
* Which mark a session wears.
|
|
2210
|
-
*
|
|
2211
|
-
* The two first-party engines are named directly. A `provider` session is
|
|
2212
|
-
* whatever the host wired up, so its *model* is the only thing that says whose
|
|
2213
|
-
* it is — sniffed loosely on purpose (`gemini-2.5-pro`, `deepseek-chat`,
|
|
2214
|
-
* `kimi-k2`), and falling through to no mark rather than guessing wrong.
|
|
2215
|
-
*/
|
|
2216
1362
|
declare function engineMark(engine: string, model?: string): string | undefined;
|
|
2217
|
-
/** The colour a session's engine mark wears. Pass it to `EngineIcon`'s
|
|
2218
|
-
* `className` rather than to a parent: the svg carries its own `text-fg-3`,
|
|
2219
|
-
* and only a class on the element itself is merged over it. */
|
|
2220
1363
|
declare function vendorMarkClass(engine: string, model?: string): string;
|
|
2221
|
-
/** The colour the model *name* wears beside that mark — muted unless the vendor
|
|
2222
|
-
* is one whose accent survives at label size. See `VENDOR_TEXT`.
|
|
2223
|
-
*
|
|
2224
|
-
* The fallback is `text-fg-3` rather than the metadata line's own `text-fg-4`,
|
|
2225
|
-
* so an unbranded model still sits one step above the project and gateway
|
|
2226
|
-
* beside it — the order the spec lists them in, held without a colour. */
|
|
2227
1364
|
declare function vendorTextClass(engine: string, model?: string): string;
|
|
2228
1365
|
declare function EngineIcon({
|
|
2229
1366
|
engine,
|
|
@@ -2236,88 +1373,18 @@ declare function EngineIcon({
|
|
|
2236
1373
|
}): _$react.JSX.Element;
|
|
2237
1374
|
//#endregion
|
|
2238
1375
|
//#region src/components/agent/SessionSteps.d.ts
|
|
2239
|
-
/**
|
|
2240
|
-
* The work *under* a session row, and the one row shape every client renders it
|
|
2241
|
-
* through.
|
|
2242
|
-
*
|
|
2243
|
-
* This lived inside the VS Code webview first, which is exactly why the
|
|
2244
|
-
* dashboard had none of it. Nothing in here is extension-specific: a session's
|
|
2245
|
-
* sub-agents are a protocol fact, and a disclosure over them is a list
|
|
2246
|
-
* affordance. It sits in `packages/ui` so the sidebar, the dashboard and (in its
|
|
2247
|
-
* own idiom) the phone are annotating rows the same way rather than three ways.
|
|
2248
|
-
*
|
|
2249
|
-
* Today the only source is `SessionInfo.subagents`. The other — the CLI's own
|
|
2250
|
-
* **task checklist**, the to-do list it keeps for the current turn — is what the
|
|
2251
|
-
* design was drawn from, and it is not built: nothing on the wire carries it yet
|
|
2252
|
-
* (see `_docs/features/sub-agent-handling.md`, second thread, which opens with
|
|
2253
|
-
* "check a capture" rather than "design a surface"). When it arrives it is a
|
|
2254
|
-
* *source*, not a second row component: checklist when the session has one, its
|
|
2255
|
-
* sub-agents otherwise.
|
|
2256
|
-
*
|
|
2257
|
-
* That is also why `state` has a `pending` arm no sub-agent can produce. A
|
|
2258
|
-
* sub-agent record exists only once dispatched, so it is never queued; a to-do
|
|
2259
|
-
* is queued for most of its life, and dropping the state would mean widening the
|
|
2260
|
-
* union later — the shape is cheaper to state now than to retrofit.
|
|
2261
|
-
*/
|
|
2262
1376
|
type Step = {
|
|
2263
1377
|
key: string;
|
|
2264
|
-
label: string;
|
|
1378
|
+
label: string;
|
|
2265
1379
|
noun: string;
|
|
2266
|
-
/**
|
|
2267
|
-
* Both kinds press. The kind decides **where the press goes**, which is the
|
|
2268
|
-
* whole of the distinction.
|
|
2269
|
-
*
|
|
2270
|
-
* An **agent** has an identity and work of its own, so it wears the sub-agent
|
|
2271
|
-
* colour and opens that agent's own frame. A **task** is something the model
|
|
2272
|
-
* described with no agent behind it (`isAgentRecord`), so there is no frame:
|
|
2273
|
-
* framing its id selects no items and draws an empty screen. What it has
|
|
2274
|
-
* instead is a *place* — the spawning call's row in the transcript — so it is
|
|
2275
|
-
* muted, never selected, and travels there. See `StepRow` for why an inert
|
|
2276
|
-
* row was the worse answer.
|
|
2277
|
-
*
|
|
2278
|
-
* Two values and not a boolean because the checklist source this shape was
|
|
2279
|
-
* drawn for (see above) produces the second kind natively — a to-do is a task
|
|
2280
|
-
* in exactly this sense, and it will slot in here rather than widening
|
|
2281
|
-
* anything.
|
|
2282
|
-
*/
|
|
2283
1380
|
kind: 'agent' | 'task';
|
|
2284
|
-
state: 'done' | 'running' | 'pending' | 'failed';
|
|
1381
|
+
state: 'done' | 'running' | 'pending' | 'failed';
|
|
2285
1382
|
detail?: string;
|
|
2286
1383
|
title: string;
|
|
2287
1384
|
onSelect: () => void;
|
|
2288
1385
|
};
|
|
2289
|
-
/**
|
|
2290
|
-
* The steps under one session, **agents first**.
|
|
2291
|
-
*
|
|
2292
|
-
* The two kinds do different things when pressed and are worth different
|
|
2293
|
-
* amounts of attention: an agent has work of its own to go and read, a task is a
|
|
2294
|
-
* marker in a transcript. Interleaved in dispatch order they read as one
|
|
2295
|
-
* undifferentiated list, and the rows you can actually open are scattered
|
|
2296
|
-
* through it. Grouped, the openable ones are a block at the top and the markers
|
|
2297
|
-
* are a tail you can skip.
|
|
2298
|
-
*
|
|
2299
|
-
* Stable **within** each group, deliberately: dispatch order is the only order
|
|
2300
|
-
* these records have that means anything (it is the order the work was started
|
|
2301
|
-
* in), so the sort partitions and never reorders inside a partition.
|
|
2302
|
-
*
|
|
2303
|
-
* `onSelect` is handed the **kind** as well as the id, because the two kinds go
|
|
2304
|
-
* to different places — see `SessionItem`, which is what routes them. Passing
|
|
2305
|
-
* only the id is what let a task be opened as if it were an agent, and a framed
|
|
2306
|
-
* task id matches no items, so the panel drew an **empty agent view**.
|
|
2307
|
-
*/
|
|
2308
1386
|
declare function sessionSteps(info: SessionInfo, onSelect: (toolUseId: string, kind: Step['kind']) => void): Step[];
|
|
2309
|
-
/** How many of these are still going — the live half of the disclosure's count. */
|
|
2310
1387
|
declare function runningSteps(steps: readonly Step[]): number;
|
|
2311
|
-
/**
|
|
2312
|
-
* The disclosure, which is also the reading: `3 agents` — or `2 of 3 agents`
|
|
2313
|
-
* while some have settled, because "how many are still going" is the live
|
|
2314
|
-
* question and a bare total answers it wrong the moment one finishes.
|
|
2315
|
-
*
|
|
2316
|
-
* Sub-agents are an annotation on a working row rather than a state of their own
|
|
2317
|
-
* (see `runningSubagents` in protocol's `session-list.ts`), so this never
|
|
2318
|
-
* competes with the row's status glyph: that still says what the *session* is
|
|
2319
|
-
* doing.
|
|
2320
|
-
*/
|
|
2321
1388
|
declare function StepToggle({
|
|
2322
1389
|
expanded,
|
|
2323
1390
|
running,
|
|
@@ -2331,78 +1398,17 @@ declare function StepToggle({
|
|
|
2331
1398
|
noun: string;
|
|
2332
1399
|
onToggle: () => void;
|
|
2333
1400
|
}): _$react.JSX.Element;
|
|
2334
|
-
/**
|
|
2335
|
-
* One step under its session — **pressable, all of them**, and what a press
|
|
2336
|
-
* means is what tells the two kinds apart.
|
|
2337
|
-
*
|
|
2338
|
-
* Pressing an **agent** hands the panel over to that agent's own work
|
|
2339
|
-
* (`SessionPanel.openSubagent`): it is not a session and never becomes one, but
|
|
2340
|
-
* it has a surface, so it can be the selected thing. Pressing a **task** selects
|
|
2341
|
-
* the *session* and travels to that task's marker inside it — a task is a
|
|
2342
|
-
* reference to a place in a transcript, not a thing with a screen, so it can be
|
|
2343
|
-
* followed but never held.
|
|
2344
|
-
*
|
|
2345
|
-
* That is a reversal, and a deliberate one. A task used to be inert markup on
|
|
2346
|
-
* the argument that "a disabled-looking button still announces itself as one" —
|
|
2347
|
-
* correct about the markup, wrong about the premise, because there *was* always
|
|
2348
|
-
* somewhere to go and the row simply swallowed the click on its way there. A row
|
|
2349
|
-
* that looks like a list item, sits in a list, and does nothing when pressed is
|
|
2350
|
-
* the worse lie. So every step answers the pointer and every step answers a
|
|
2351
|
-
* press; only what the press does differs.
|
|
2352
|
-
*
|
|
2353
|
-
* Divided from the card's header by **indentation and its own hit shape**, not
|
|
2354
|
-
* by a rule. The rules came first, on the argument that at 11px an indent is not
|
|
2355
|
-
* enough to say "list inside a row" — and they were right about the reading and
|
|
2356
|
-
* wrong about the cost: a stack of hairlines across every open card turned the
|
|
2357
|
-
* list into a ledger, and a rule cannot answer a pointer. A step that lights up
|
|
2358
|
-
* under the cursor and fills when it is the one on screen says *list* far more
|
|
2359
|
-
* plainly than a line between two of them, and it says it while doing the job
|
|
2360
|
-
* the rule could not.
|
|
2361
|
-
*
|
|
2362
|
-
* **Only an agent can wear the selection**, and `active` is guarded on that here
|
|
2363
|
-
* rather than trusted from the caller: a host that hands back a task's key is
|
|
2364
|
-
* describing where it navigated, not what it selected, and the row must not
|
|
2365
|
-
* paint itself blue for it.
|
|
2366
|
-
*
|
|
2367
|
-
* The hover is `--row-active` — **alpha, not a flat fill** — because this row
|
|
2368
|
-
* has to answer the pointer on three different grounds: a transparent card, a
|
|
2369
|
-
* blue one (its session is selected), and a grey one (a sibling agent is). A
|
|
2370
|
-
* flat value tuned for any of those is wrong on the other two; a tint darkens or
|
|
2371
|
-
* lifts whatever it lands on. It is the one place in the list where the alpha
|
|
2372
|
-
* token earns its keep.
|
|
2373
|
-
*/
|
|
2374
1401
|
declare function StepRow({
|
|
2375
1402
|
step,
|
|
2376
1403
|
active,
|
|
2377
1404
|
onSelect
|
|
2378
1405
|
}: {
|
|
2379
1406
|
step: Step;
|
|
2380
|
-
/** The panel is showing this step's own work. Ignored for tasks, which cannot
|
|
2381
|
-
* be the selected thing — see above. */
|
|
2382
1407
|
active?: boolean;
|
|
2383
1408
|
onSelect: () => void;
|
|
2384
1409
|
}): _$react.JSX.Element;
|
|
2385
1410
|
//#endregion
|
|
2386
1411
|
//#region src/components/agent/SubagentStrip.d.ts
|
|
2387
|
-
/**
|
|
2388
|
-
* The one line above a sub-agent takeover: who this is, how it is doing, and the
|
|
2389
|
-
* way back.
|
|
2390
|
-
*
|
|
2391
|
-
* **It claims exactly what the `TaskRow` it was opened from claims** — the same
|
|
2392
|
-
* `taskBusy` / `taskFailed` / tool count over the same items — and deliberately
|
|
2393
|
-
* *not* `SubagentInfo.status`. Protocol documents those two as divergent on
|
|
2394
|
-
* purpose (`index.ts:1476-1487`), but that divergence is transcript-versus-*list*
|
|
2395
|
-
* and this surface **is** the transcript. The disagreement that must not exist
|
|
2396
|
-
* here is between a header and the rows directly beneath it.
|
|
2397
|
-
*
|
|
2398
|
-
* The rollup is still allowed one job — naming an agent whose `Task` call is not
|
|
2399
|
-
* in the transcript — because a label is not content, and `SessionInfo.subagents`
|
|
2400
|
-
* keeps only eight settled records (`SUBAGENT_HISTORY`), so it can never be the
|
|
2401
|
-
* source of what a frame *shows*.
|
|
2402
|
-
*
|
|
2403
|
-
* Both variants, because the panel has two and a strip that only existed in one
|
|
2404
|
-
* would make the takeover a terminal-theme feature rather than a session feature.
|
|
2405
|
-
*/
|
|
2406
1412
|
declare function SubagentStrip({
|
|
2407
1413
|
task,
|
|
2408
1414
|
items,
|
|
@@ -2412,10 +1418,8 @@ declare function SubagentStrip({
|
|
|
2412
1418
|
fontSize,
|
|
2413
1419
|
lineHeight
|
|
2414
1420
|
}: {
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
task: ToolCallItem$1 | undefined; /** The frame's items, for the busy reading and the tool count. */
|
|
2418
|
-
items: readonly TranscriptItem[]; /** Fallback name when there is no task item. */
|
|
1421
|
+
task: ToolCallItem$1 | undefined;
|
|
1422
|
+
items: readonly TranscriptItem[];
|
|
2419
1423
|
label: string;
|
|
2420
1424
|
onBack: () => void;
|
|
2421
1425
|
terminal: boolean;
|
|
@@ -2431,9 +1435,7 @@ declare function ProjectIcon({
|
|
|
2431
1435
|
className
|
|
2432
1436
|
}: {
|
|
2433
1437
|
icon: ProjectIcon$1 | undefined;
|
|
2434
|
-
|
|
2435
|
-
* caller fetches (see the note above); absent draws nothing. */
|
|
2436
|
-
src?: string; /** The project's name, for the alt text. */
|
|
1438
|
+
src?: string;
|
|
2437
1439
|
name?: string;
|
|
2438
1440
|
className?: string;
|
|
2439
1441
|
}): _$react.JSX.Element | null;
|
|
@@ -2441,29 +1443,11 @@ declare function ProjectIcon({
|
|
|
2441
1443
|
//#region src/components/agent/SessionEmptyState.d.ts
|
|
2442
1444
|
interface SessionEmptyStateProps {
|
|
2443
1445
|
cwd?: string;
|
|
2444
|
-
/** Whether `/command` completion is live yet — the CLI reports its commands a
|
|
2445
|
-
* beat after the session starts, and promising a feature that isn't wired up
|
|
2446
|
-
* yet is worse than not mentioning it. */
|
|
2447
1446
|
hasCommands?: boolean;
|
|
2448
|
-
/** Whether the engine has reported skills the `/` popover can offer. Its own
|
|
2449
|
-
* flag, not a variant of `hasCommands`: what `/` does differs — a command is
|
|
2450
|
-
* submitted, a skill is typed for you to edit — and an engine can have one
|
|
2451
|
-
* without the other. */
|
|
2452
1447
|
hasSkills?: boolean;
|
|
2453
|
-
/** Whether this gateway serves `@file` search for the session's directory. */
|
|
2454
1448
|
canBrowseFiles?: boolean;
|
|
2455
1449
|
className?: string;
|
|
2456
1450
|
}
|
|
2457
|
-
/**
|
|
2458
|
-
* What a session shows before it has said anything: where the agent is sitting,
|
|
2459
|
-
* and what the composer accepts beyond prose.
|
|
2460
|
-
*
|
|
2461
|
-
* Every hint is conditional on the affordance actually existing — an engine
|
|
2462
|
-
* without slash commands, or a gateway without host files, is not told about
|
|
2463
|
-
* them. Deliberately no project name (the header already carries it) and no
|
|
2464
|
-
* brand mark (its geometry is inlined in several places already and they are
|
|
2465
|
-
* meant to stay identical).
|
|
2466
|
-
*/
|
|
2467
1451
|
declare function SessionEmptyState({
|
|
2468
1452
|
cwd,
|
|
2469
1453
|
hasCommands,
|
|
@@ -2473,16 +1457,6 @@ declare function SessionEmptyState({
|
|
|
2473
1457
|
}: SessionEmptyStateProps): _$react.JSX.Element;
|
|
2474
1458
|
//#endregion
|
|
2475
1459
|
//#region src/components/agent/PromptTokenText.d.ts
|
|
2476
|
-
/**
|
|
2477
|
-
* A sent message, with its `@file` and `/command` tokens styled the way the CLI
|
|
2478
|
-
* writes them: monospace and tinted, no background — the bubble already has one,
|
|
2479
|
-
* and a second fill inside it reads as a button.
|
|
2480
|
-
*
|
|
2481
|
-
* Literal text, never markdown: what was typed is what was sent. The one pass
|
|
2482
|
-
* over it is this, so a message reads the same after sending as it did in the
|
|
2483
|
-
* composer. Two tokens, two meanings — a file is a reference, a command is an
|
|
2484
|
-
* action — so they are told apart by hue rather than by shape alone.
|
|
2485
|
-
*/
|
|
2486
1460
|
declare function PromptTokenText({
|
|
2487
1461
|
text,
|
|
2488
1462
|
className
|
|
@@ -2499,23 +1473,6 @@ declare const STATUS_META: Record<SessionStatus, {
|
|
|
2499
1473
|
}>;
|
|
2500
1474
|
//#endregion
|
|
2501
1475
|
//#region src/components/agent/ContextRing.d.ts
|
|
2502
|
-
/**
|
|
2503
|
-
* How full a session's context window is, sized for a **list row**.
|
|
2504
|
-
*
|
|
2505
|
-
* The reading the session screen has always drawn, moved somewhere it answers a
|
|
2506
|
-
* question the session screen cannot: *which* of these thirty sessions is
|
|
2507
|
-
* bloating. That is also why it is a ring and not a number — across a list, a
|
|
2508
|
-
* ring is read at a glance and `71%` has to be read one row at a time.
|
|
2509
|
-
*
|
|
2510
|
-
* **Absent draws nothing, and absent is not zero.** A promptless session, a
|
|
2511
|
-
* parked one from before the field existed, or an engine that reports no window
|
|
2512
|
-
* has no reading; an empty ring would claim its context is empty rather than
|
|
2513
|
-
* unknown. The title carries the exact numbers for anyone who wants them.
|
|
2514
|
-
*
|
|
2515
|
-
* Shared rather than spelled per client: the dashboard's row and the VS Code
|
|
2516
|
-
* sidebar's card both draw it, and two copies would be two sets of thresholds
|
|
2517
|
-
* the day one of them is nudged.
|
|
2518
|
-
*/
|
|
2519
1476
|
declare function ContextRing({
|
|
2520
1477
|
usage,
|
|
2521
1478
|
size,
|
|
@@ -2530,42 +1487,10 @@ declare function ContextRing({
|
|
|
2530
1487
|
declare function cn(...inputs: ClassValue[]): string;
|
|
2531
1488
|
//#endregion
|
|
2532
1489
|
//#region src/lib/clipboard.d.ts
|
|
2533
|
-
/**
|
|
2534
|
-
* Copy text to the clipboard, on origins where the modern API does not exist.
|
|
2535
|
-
*
|
|
2536
|
-
* `navigator.clipboard` is gated on a **secure context**: HTTPS, or localhost.
|
|
2537
|
-
* A WorkerDeck dashboard reached the way it is meant to be reached — plain HTTP
|
|
2538
|
-
* on a LAN address, from a laptop or a phone — is neither, so `navigator.clipboard`
|
|
2539
|
-
* is `undefined` there and touching `.writeText` throws outright. That is the
|
|
2540
|
-
* normal deployment, not an edge case, which is why this falls back rather than
|
|
2541
|
-
* feature-detecting into a disabled button.
|
|
2542
|
-
*
|
|
2543
|
-
* The fallback is `document.execCommand('copy')` over an off-screen textarea.
|
|
2544
|
-
* It is deprecated and it is also the only thing that works here; every browser
|
|
2545
|
-
* still implements it. Returns whether the text actually landed, so a caller can
|
|
2546
|
-
* avoid claiming success it did not have.
|
|
2547
|
-
*/
|
|
2548
1490
|
declare function copyText(value: string): Promise<boolean>;
|
|
2549
1491
|
//#endregion
|
|
2550
1492
|
//#region src/lib/tool-icon.d.ts
|
|
2551
|
-
/**
|
|
2552
|
-
* An icon per tool, so a transcript can be skimmed by shape rather than read.
|
|
2553
|
-
*
|
|
2554
|
-
* The same mapping the iOS app makes, in lucide's vocabulary rather than SF
|
|
2555
|
-
* Symbols — the two clients should be recognisably showing the same thing. An
|
|
2556
|
-
* unknown tool falls back to a wrench, and an MCP tool (`mcp__server__name`) to
|
|
2557
|
-
* the puzzle piece the MCP screens use, because "which server is this from" is
|
|
2558
|
-
* the useful thing to see at a glance.
|
|
2559
|
-
*/
|
|
2560
1493
|
declare function toolIcon(toolName: string): LucideIcon;
|
|
2561
|
-
/**
|
|
2562
|
-
* Does this tool *change* the workspace?
|
|
2563
|
-
*
|
|
2564
|
-
* Worth its own colour in a transcript: skimming a run, "what did it edit" is a
|
|
2565
|
-
* different question from "what did it look at", and a write is the one you
|
|
2566
|
-
* might need to undo. Names from both first-party engines; an MCP tool is
|
|
2567
|
-
* unknowable from its name, so it reads as neutral rather than guessed.
|
|
2568
|
-
*/
|
|
2569
1494
|
declare function isMutatingTool(toolName: string): boolean;
|
|
2570
1495
|
//#endregion
|
|
2571
1496
|
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, type BadgeProps, Band, Blank, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type ChipSegment, CodeBlock, type CodeBlockProps, Composer, type ComposerFileMatch, type ComposerHandle, type ComposerProps, ContextDialog, type ContextDialogProps, ContextRing, Conversation, ConversationContent, type ConversationProps, ConversationScrollButton, CopyAction, CopyButton, type CopyButtonProps, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, Empty, EmptyKey, EngineIcon, FileCard, type FileCardProps, type FileDeliveredItem, HostFilesDialog, type HostFilesDialogProps, Ink, Input, Loader, McpDialog, type McpDialogProps, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, type MessageProps, ModelSelect, type ModelSelectProps, PERMISSION_MODES, type PermissionModeChoice, type PermissionModeMeta, PermissionModeSelect, type PermissionModeSelectProps, PermissionPrompt, type PermissionPromptProps, ProgressRing, type ProgressRingProps, ProjectIcon, PromptArea, type PromptAreaHandle, type PromptAreaProps, PromptTokenText, QUESTION_BEHAVIORS, type QuestionBehaviorMeta, QuestionPrompt, type QuestionPromptProps, Reasoning, type ReasoningProps, Response, type ResponseProps, Row, type RowProps, STATUS_META, type Segment, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, type SessionBrowserProps, type SessionControls, SessionEmptyState, type SessionEmptyStateProps, SessionInfoDialog, type SessionInfoDialogProps, SessionItem, type SessionItemProps, SessionList, SessionListItem, type SessionListItemProps, type SessionListProps, SessionPanel, type SessionPanelProps, SessionStatusIcon, type SessionSurfacePanel, type SessionVitals, SkillsDialog, type SkillsDialogProps, Spinner, Splitter, type SplitterProps, StatusBar, type StatusBarProps, type Step, StepRow, StepToggle, SubagentStrip, type TerminalAffordances, TerminalDiff, TerminalItemView, TerminalMarkdown, type TerminalMarkdownProps, type TerminalMetrics, TerminalPermissionPrompt, type TerminalPermissionPromptProps, TerminalQuestionPrompt, type TerminalQuestionPromptProps, TerminalStatusLine, type TerminalStatusLineProps, TerminalSurface, type TerminalSurfaceProps, TerminalTranscript, type TerminalTranscriptProps, type TextSegment, Textarea, Tip, Toaster, type Tone, ToolCallCard, type ToolCallCardProps, type ToolCallItem, TooltipContent, TooltipProvider, Transcript, type TranscriptDensity, TranscriptDensityProvider, type TranscriptFont, type TranscriptProps, type TranscriptVariant, TranscriptVariantProvider, type TriggerConfig, type TriggerSuggestion, UsageDialog, type UsageDialogProps, UsageMeters, WithActions, badgeVariants, buttonVariants, cn, commandTrigger, copyText, engineMark, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, previewPatch, rateLimitWindowSeconds, rowShapeClass, runningSteps, segmentsToPlainText, sessionSteps, skillPrompt, toast, toolIcon, toolInputPreview, useAffordances, useMinuteClock, usePromptAreaState, useTranscriptDensity, useTranscriptVariant, vendorMarkClass, vendorTextClass };
|