@robota-sdk/agent-ui-web 0.0.0-stage → 3.0.0-beta.94
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/CHANGELOG.md +409 -0
- package/LICENSE +661 -0
- package/README.md +19 -2
- package/dist/browser/index.d.ts +715 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +7923 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/node/index.cjs +7973 -0
- package/dist/node/index.d.cts +715 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +715 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +7923 -0
- package/dist/node/index.js.map +1 -0
- package/docs/README.md +62 -0
- package/docs/SPEC.md +124 -0
- package/package.json +99 -3
- package/src/client/runtime-host.ts +84 -0
- package/src/client/ws-session-client.ts +131 -0
- package/src/clipboard.ts +81 -0
- package/src/components/AgentActivityPanel.tsx +371 -0
- package/src/components/AgentSwitcherSheet.tsx +93 -0
- package/src/components/Brand.tsx +33 -0
- package/src/components/Composer.tsx +685 -0
- package/src/components/ConversationView.tsx +772 -0
- package/src/components/Dialog.tsx +230 -0
- package/src/components/DiffLines.tsx +81 -0
- package/src/components/ExecutionDetailSheet.tsx +142 -0
- package/src/components/HelpSheet.tsx +104 -0
- package/src/components/PermissionPrompt.tsx +661 -0
- package/src/components/PersonalUsageDashboard.tsx +39 -0
- package/src/components/PersonalUsageDashboardDetails.tsx +368 -0
- package/src/components/PersonalUsageDashboardSections.tsx +250 -0
- package/src/components/PopupMenu.tsx +166 -0
- package/src/components/ProjectPanel.tsx +268 -0
- package/src/components/SessionMonitor.tsx +180 -0
- package/src/components/SessionSidebar.tsx +429 -0
- package/src/components/SessionSurface.tsx +455 -0
- package/src/components/SessionSurfaceChrome.tsx +316 -0
- package/src/components/SettingsFields.tsx +159 -0
- package/src/components/SettingsGeneralSection.tsx +49 -0
- package/src/components/SettingsMcpSection.tsx +157 -0
- package/src/components/SettingsPermissionsSection.tsx +137 -0
- package/src/components/SettingsPluginsSection.tsx +165 -0
- package/src/components/SettingsProvidersSection.tsx +211 -0
- package/src/components/SettingsScreen.tsx +340 -0
- package/src/components/StatusControls.tsx +294 -0
- package/src/components/composer-attachments.ts +246 -0
- package/src/components/personal-usage-dashboard-types.ts +26 -0
- package/src/driver-labels.ts +88 -0
- package/src/execution-entry-status.ts +55 -0
- package/src/goal-view.ts +19 -0
- package/src/hooks/command-menu.ts +65 -0
- package/src/hooks/excluded-commands.ts +52 -0
- package/src/hooks/prompt-state.ts +83 -0
- package/src/hooks/server-message-handling.ts +92 -0
- package/src/hooks/session-client-types.ts +329 -0
- package/src/hooks/ui-intent-state.ts +74 -0
- package/src/hooks/use-agent-switcher-state.ts +125 -0
- package/src/hooks/use-execution-detail.ts +118 -0
- package/src/hooks/use-media-query.ts +27 -0
- package/src/hooks/use-model-list.ts +45 -0
- package/src/hooks/use-personal-usage.ts +138 -0
- package/src/hooks/use-project-panel.ts +117 -0
- package/src/hooks/use-schedules-state.ts +92 -0
- package/src/hooks/use-session-directory.ts +202 -0
- package/src/hooks/use-settings-state.ts +115 -0
- package/src/hooks/useSessionClient.ts +991 -0
- package/src/index.ts +66 -0
- package/src/product-identity.tsx +26 -0
- package/src/schedule-view.ts +92 -0
- package/src/styles/surface.css +231 -0
- package/src/styles/surface.css.d.mts +1 -0
- package/src/styles/theme.css +38 -0
- package/src/styles/theme.css.d.mts +1 -0
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
import { IWireAgentDefinitionSummary, TClientMessage, TClientMessage as TClientMessage$1, TServerMessage, TServerMessage as TServerMessage$1 } from "@robota-sdk/agent-transport";
|
|
2
|
+
import { TActionResponse } from "@robota-sdk/agent-interface-transport";
|
|
3
|
+
import { IAskRequestEvent, IDiffLine, IGoalState, IPermissionRequestEvent, ISettingsSnapshot, IToolState, TDriverId, TPermissionResultValue, TSettingsPatch } from "@robota-sdk/agent-interface-session";
|
|
4
|
+
import { IBackgroundTaskState, IExecutionDetailRecord, IExecutionWorkspaceEntry, IExecutionWorkspaceSnapshot } from "@robota-sdk/agent-interface-execution";
|
|
5
|
+
import { TCommandUiIntent } from "@robota-sdk/agent-interface-command";
|
|
6
|
+
import React$1, { ReactNode } from "react";
|
|
7
|
+
//#region src/client/ws-session-client.d.ts
|
|
8
|
+
type TConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
9
|
+
interface IWsSessionClientCallbacks {
|
|
10
|
+
onMessage: (msg: TServerMessage$1) => void;
|
|
11
|
+
onStatusChange: (status: TConnectionStatus) => void;
|
|
12
|
+
/**
|
|
13
|
+
* The connection is gone for good: the retries ran out without reaching the server again. The status
|
|
14
|
+
* stays `disconnected`; this is what tells a host the runtime is not coming back by itself.
|
|
15
|
+
*/
|
|
16
|
+
onGiveUp?: () => void;
|
|
17
|
+
}
|
|
18
|
+
interface IWsSessionClient {
|
|
19
|
+
connect: () => void;
|
|
20
|
+
disconnect: () => void;
|
|
21
|
+
send: (msg: TClientMessage$1) => void;
|
|
22
|
+
status: () => TConnectionStatus;
|
|
23
|
+
}
|
|
24
|
+
declare function createWsSessionClient(url: string, callbacks: IWsSessionClientCallbacks): IWsSessionClient;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/hooks/prompt-state.d.ts
|
|
27
|
+
/** A prompt awaiting the owner's answer, rendered by the UI (built from the server event payloads). */
|
|
28
|
+
type TPendingPrompt = ({
|
|
29
|
+
readonly kind: 'permission';
|
|
30
|
+
} & IPermissionRequestEvent) | ({
|
|
31
|
+
readonly kind: 'ask';
|
|
32
|
+
} & IAskRequestEvent);
|
|
33
|
+
/**
|
|
34
|
+
* Fold a server message into the pending-prompt list: append on `permission_request`/`ask_request`, remove on
|
|
35
|
+
* `prompt_resolved`. Any other message returns the list unchanged (referential-equality preserved). Duplicate
|
|
36
|
+
* ids are not re-appended (idempotent against a resend).
|
|
37
|
+
*/
|
|
38
|
+
declare function applyPromptEvent(prompts: readonly TPendingPrompt[], msg: TServerMessage): readonly TPendingPrompt[];
|
|
39
|
+
/** Build the client message that answers a permission prompt. */
|
|
40
|
+
declare function permissionResponse(id: string, result: TPermissionResultValue): TClientMessage;
|
|
41
|
+
/** Build the client message that answers an ask prompt. */
|
|
42
|
+
declare function askResponse(id: string, response: TActionResponse): TClientMessage;
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/hooks/session-client-types.d.ts
|
|
45
|
+
type TPersonalUsageReport = Extract<TServerMessage, {
|
|
46
|
+
type: 'personal_usage_report';
|
|
47
|
+
}>['report'];
|
|
48
|
+
type TStoredSessionUsageReport = Extract<TServerMessage, {
|
|
49
|
+
type: 'stored_session_usage_report';
|
|
50
|
+
}>['report'];
|
|
51
|
+
/** The commands and skills the session offers — what a `/` menu lists. */
|
|
52
|
+
type TCommandCatalog = Omit<Extract<TServerMessage, {
|
|
53
|
+
type: 'commands';
|
|
54
|
+
}>, 'type'>;
|
|
55
|
+
/** The session's status beside the conversation: model, permission mode, effort, context. */
|
|
56
|
+
type TSessionStatus = Extract<TServerMessage, {
|
|
57
|
+
type: 'session_status';
|
|
58
|
+
}>['status'];
|
|
59
|
+
/**
|
|
60
|
+
* #3282 §2 (part 2): the models a person may switch to, grouped by configured provider profile —
|
|
61
|
+
* what the model control's pop-up menu is built from. `null` until requested (`list-models`).
|
|
62
|
+
*/
|
|
63
|
+
type TModelListSnapshot = Omit<Extract<TServerMessage, {
|
|
64
|
+
type: 'model_list';
|
|
65
|
+
}>, 'type' | 'requestId'>;
|
|
66
|
+
/** The host's sessions in this workspace, which one is current, and the records it could not read. */
|
|
67
|
+
type TSessionListing = Extract<TServerMessage, {
|
|
68
|
+
type: 'sessions';
|
|
69
|
+
}>['listing'];
|
|
70
|
+
/** Why the host did not list its sessions: it cannot (`not_available`), or listing failed. */
|
|
71
|
+
type TSessionsError = Omit<Extract<TServerMessage, {
|
|
72
|
+
type: 'sessions_error';
|
|
73
|
+
}>, 'type' | 'requestId'>;
|
|
74
|
+
type TCurrentSessionUsageReport = Extract<TServerMessage, {
|
|
75
|
+
type: 'usage_report';
|
|
76
|
+
}>['report'];
|
|
77
|
+
/** #3282 §4c — the Project panel's reads. Each result crosses the wire unchanged from the session
|
|
78
|
+
* method's own return value (see `wire-messages.ts`'s doc comment on `project_status`). */
|
|
79
|
+
type TProjectStatusRead = Extract<TServerMessage, {
|
|
80
|
+
type: 'project_status';
|
|
81
|
+
}>['result'];
|
|
82
|
+
type TProjectDiffRead = Extract<TServerMessage, {
|
|
83
|
+
type: 'project_diff';
|
|
84
|
+
}>['result'];
|
|
85
|
+
type TProjectMemoryRead = Extract<TServerMessage, {
|
|
86
|
+
type: 'project_memory';
|
|
87
|
+
}>['result'];
|
|
88
|
+
interface IConversationMessage {
|
|
89
|
+
id: string;
|
|
90
|
+
role: 'user' | 'assistant';
|
|
91
|
+
content: string;
|
|
92
|
+
isStreaming?: boolean;
|
|
93
|
+
/** REMOTE-014 E5: the co-driving author of a user turn. */
|
|
94
|
+
author?: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The outcome of a slash command, shown in the conversation where it was typed — the TUI adds the
|
|
98
|
+
* same outcome to its transcript. `info` is a command this surface cannot carry out.
|
|
99
|
+
*/
|
|
100
|
+
interface ICommandOutputEntry {
|
|
101
|
+
id: string;
|
|
102
|
+
role: 'command';
|
|
103
|
+
name: string;
|
|
104
|
+
content: string;
|
|
105
|
+
tone: 'success' | 'error' | 'info';
|
|
106
|
+
}
|
|
107
|
+
/** The tool calls of one finished turn, kept in the conversation ahead of the reply they led to. */
|
|
108
|
+
interface IToolGroupEntry {
|
|
109
|
+
id: string;
|
|
110
|
+
role: 'tools';
|
|
111
|
+
tools: readonly IActiveTool[];
|
|
112
|
+
}
|
|
113
|
+
/** One file an Edit/Write call touched during a turn, and the (latest) diff a click can open. */
|
|
114
|
+
interface IChangedFileSummary {
|
|
115
|
+
path: string;
|
|
116
|
+
added: number;
|
|
117
|
+
removed: number;
|
|
118
|
+
diffLines: readonly IDiffLine[];
|
|
119
|
+
}
|
|
120
|
+
/** #3288: a turn that changed files ends with this compact summary row. */
|
|
121
|
+
interface IChangedFilesEntry {
|
|
122
|
+
id: string;
|
|
123
|
+
role: 'changed-files';
|
|
124
|
+
files: readonly IChangedFileSummary[];
|
|
125
|
+
}
|
|
126
|
+
type TConversationEntry = IConversationMessage | ICommandOutputEntry | IToolGroupEntry | IChangedFilesEntry;
|
|
127
|
+
interface IActiveTool {
|
|
128
|
+
id: string;
|
|
129
|
+
name: string;
|
|
130
|
+
status: 'running' | 'done' | 'error';
|
|
131
|
+
input?: string;
|
|
132
|
+
result?: IToolState['result'];
|
|
133
|
+
/** #3288: correlates this call across `tool_start`/`tool_end` — how a finished call is matched. */
|
|
134
|
+
executionId?: string;
|
|
135
|
+
/** #3288: a unified diff (Edit/Write), built server-side — the same one an approval prompt showed. */
|
|
136
|
+
diffLines?: readonly IDiffLine[];
|
|
137
|
+
/** #3288: the file `diffLines` concerns, workspace-relative when the server could make it so. */
|
|
138
|
+
diffFile?: string;
|
|
139
|
+
/** #3288: the tool's raw result payload (Shell output, Read content, …), already capped server-side. */
|
|
140
|
+
toolResultData?: string;
|
|
141
|
+
/** Admitted observations; opaque resource URIs do not authorize a client-side fetch. */
|
|
142
|
+
toolResultParts?: IToolState['toolResultParts'];
|
|
143
|
+
/** #3288: a workspace-relative display form of a path argument, additive to `input`/`firstArg`. */
|
|
144
|
+
displayPath?: string;
|
|
145
|
+
/** #3288: set when this call is a projected `/command` tool — render "Ran /<commandName>". */
|
|
146
|
+
commandName?: string;
|
|
147
|
+
/** #3288: true for an internal signal tool (e.g. goal-status) — never rendered as a call. */
|
|
148
|
+
internal?: boolean;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* #3280 §2: a prompt the host queued behind the running turn — the server has already taken it, so it
|
|
152
|
+
* is not lost, but it will not run until the turn ends. `count` is the TOTAL number waiting (the shown
|
|
153
|
+
* `text` plus any behind it), matching the wire's `pendingCount`.
|
|
154
|
+
*/
|
|
155
|
+
interface IQueuedPrompt {
|
|
156
|
+
text: string;
|
|
157
|
+
count: number;
|
|
158
|
+
}
|
|
159
|
+
interface ISessionNotice {
|
|
160
|
+
id: string;
|
|
161
|
+
/**
|
|
162
|
+
* `session-change-refused`: the host refused a new or switch this surface asked for.
|
|
163
|
+
* `background-task-control-failed`: a Stop in the Agents panel did not take effect.
|
|
164
|
+
* `command-failed` (#3282 §2 part 2): a change made through a status control (model/mode/effort)
|
|
165
|
+
* failed — a plain notice rather than a conversation card, since the control's own label is where
|
|
166
|
+
* a successful change confirms itself and the label stays unchanged when it fails.
|
|
167
|
+
*/
|
|
168
|
+
kind: 'session-error' | 'protocol-error' | 'session-change-refused' | 'background-task-control-failed' | 'command-failed';
|
|
169
|
+
message: string;
|
|
170
|
+
/**
|
|
171
|
+
* A `session-error` classified at the wire boundary (#3289 §3) — present only when the host could
|
|
172
|
+
* tell what kind of failure this was. `SessionNotices` maps it to one plain sentence and keeps
|
|
173
|
+
* `message` behind a "Details" disclosure; absent, it shows `message` as before.
|
|
174
|
+
*/
|
|
175
|
+
code?: 'auth' | 'rate_limit' | 'model_unavailable' | 'network' | 'provider';
|
|
176
|
+
provider?: string;
|
|
177
|
+
retryAfterSeconds?: number;
|
|
178
|
+
/**
|
|
179
|
+
* For `code: 'model_unavailable'`, the model the failed request tried — captured when the notice
|
|
180
|
+
* was created (from the wire frame's own `model`, or `sessionStatus` at that moment), never read
|
|
181
|
+
* live off the CURRENT session status. The person may switch models before dismissing the notice,
|
|
182
|
+
* and a live read would then blame the new model for the old failure.
|
|
183
|
+
*/
|
|
184
|
+
model?: string;
|
|
185
|
+
}
|
|
186
|
+
interface ISessionClientHandle {
|
|
187
|
+
connect: () => void;
|
|
188
|
+
disconnect: () => void;
|
|
189
|
+
send: (msg: TClientMessage$1) => void;
|
|
190
|
+
}
|
|
191
|
+
type TMakeSessionClient<TStatus extends string = TConnectionStatus> = (callbacks: {
|
|
192
|
+
onMessage: (msg: TServerMessage) => void;
|
|
193
|
+
onStatusChange: (status: TStatus) => void;
|
|
194
|
+
}) => ISessionClientHandle;
|
|
195
|
+
interface IWsSessionState<TStatus extends string = TConnectionStatus> {
|
|
196
|
+
status: TStatus;
|
|
197
|
+
/**
|
|
198
|
+
* Set by `useWsSession` once its reconnect retries give up (issue #3280 §5): the runtime is not
|
|
199
|
+
* coming back by itself. Cleared again once `status` reaches `connected`. Undefined for a reducer
|
|
200
|
+
* with no such concept (e.g. the WebRTC surface, which has its own `failed`/`refused` statuses).
|
|
201
|
+
*/
|
|
202
|
+
connectionLost?: boolean;
|
|
203
|
+
messages: TConversationEntry[];
|
|
204
|
+
activeTools: IActiveTool[];
|
|
205
|
+
streamingText: string;
|
|
206
|
+
isThinking: boolean;
|
|
207
|
+
executionWorkspace: IExecutionWorkspaceSnapshot | null;
|
|
208
|
+
sessionName: string | null;
|
|
209
|
+
/** This connection's own driver id, learned from the server's first frame; null until then. */
|
|
210
|
+
ownDriverId: TDriverId | null;
|
|
211
|
+
/** Null until the session has answered; refreshed after every command. */
|
|
212
|
+
commandCatalog: TCommandCatalog | null;
|
|
213
|
+
/** Null until the session has answered; refreshed after every command and turn. */
|
|
214
|
+
sessionStatus: TSessionStatus | null;
|
|
215
|
+
/**
|
|
216
|
+
* #3282 §2 (part 2): the models the model control's pop-up menu offers. Null until requested — the
|
|
217
|
+
* menu asks for it when it opens (or refreshes it) rather than every surface fetching it eagerly.
|
|
218
|
+
*/
|
|
219
|
+
modelList: TModelListSnapshot | null;
|
|
220
|
+
/** Ask the session for the current model list (a fresh `list-models` round trip). */
|
|
221
|
+
requestModelList: () => void;
|
|
222
|
+
/** Null until the host has answered; refreshed on connect, after a switch, a rename and a turn. */
|
|
223
|
+
sessionListing: TSessionListing | null;
|
|
224
|
+
/** Set when the host answered the latest listing request with an error instead. */
|
|
225
|
+
sessionsError: TSessionsError | null;
|
|
226
|
+
requestSessions: () => void;
|
|
227
|
+
/** Make another stored session current. A refusal arrives as a notice saying why. */
|
|
228
|
+
switchSession: (sessionId: string) => void;
|
|
229
|
+
/** Start a fresh session and make it current. */
|
|
230
|
+
newSession: () => void;
|
|
231
|
+
/** Rename a row in the list — current or not. A refusal arrives as a notice saying why. */
|
|
232
|
+
renameSessionInList: (sessionId: string, name: string) => void;
|
|
233
|
+
/** Delete a stored session for good. A refusal arrives as a notice saying why. */
|
|
234
|
+
deleteSession: (sessionId: string) => void;
|
|
235
|
+
/** Whether the session sidebar is shown; `/resume` opens it. */
|
|
236
|
+
sessionSidebarOpen: boolean;
|
|
237
|
+
setSessionSidebarOpen: (open: boolean) => void;
|
|
238
|
+
send: (msg: TClientMessage$1) => void;
|
|
239
|
+
/**
|
|
240
|
+
* #3282 §2 (part 2): run a command the SAME way `send({type:'command', ...})` does, but mark its
|
|
241
|
+
* outcome as controls-triggered — `useSessionClient` skips the conversation card for a change made
|
|
242
|
+
* this way (the control's own label confirms it instead), while a typed command keeps its card.
|
|
243
|
+
*/
|
|
244
|
+
sendCommandSilently: (name: string, args?: string) => void;
|
|
245
|
+
pendingPrompts: readonly TPendingPrompt[];
|
|
246
|
+
/** #3280 §2: the prompt queued behind a running turn, or null when none is queued. */
|
|
247
|
+
queuedPrompt: IQueuedPrompt | null;
|
|
248
|
+
answerPermission: (id: string, result: TPermissionResultValue) => void;
|
|
249
|
+
answerAsk: (id: string, response: TActionResponse) => void;
|
|
250
|
+
personalUsageStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
251
|
+
personalUsageReport: TPersonalUsageReport | null;
|
|
252
|
+
personalUsageError: string | null;
|
|
253
|
+
requestPersonalUsage: (period: '7d' | '30d') => void;
|
|
254
|
+
storedSessionUsageStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
255
|
+
storedSessionUsageReport: TStoredSessionUsageReport | null;
|
|
256
|
+
storedSessionUsageSessionId: string | null;
|
|
257
|
+
storedSessionUsageError: string | null;
|
|
258
|
+
requestStoredSessionUsage: (sessionId: string) => void;
|
|
259
|
+
currentSessionUsageStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
260
|
+
currentSessionUsageReport: TCurrentSessionUsageReport | null;
|
|
261
|
+
requestCurrentSessionUsage: () => void;
|
|
262
|
+
sessionNotices: readonly ISessionNotice[];
|
|
263
|
+
dismissSessionNotice: (id: string) => void;
|
|
264
|
+
/** #3282 §4a: whether the Settings modal is shown. `/settings` and the gear button both open it. */
|
|
265
|
+
settingsOpen: boolean;
|
|
266
|
+
settingsStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
267
|
+
/** Null until the first `get-settings` reply arrives. */
|
|
268
|
+
settingsSnapshot: ISettingsSnapshot | null;
|
|
269
|
+
/** The plain message from the most recent failed read or write, if any. */
|
|
270
|
+
settingsError: string | null;
|
|
271
|
+
/** #3282 §4 part b-2: which section the screen should land on for the open in progress. */
|
|
272
|
+
settingsInitialSectionId: string | null;
|
|
273
|
+
/**
|
|
274
|
+
* Opens the screen and (re-)fetches its snapshot — the "reopen and see the new value" path.
|
|
275
|
+
* `sectionId` jumps straight to that section (e.g. `/plugin` → `'plugins'`, "Manage providers…"
|
|
276
|
+
* (#3282 §2/§4b) → `'providers'`); omitted opens on the screen's own default (General).
|
|
277
|
+
*/
|
|
278
|
+
openSettings: (sectionId?: string) => void;
|
|
279
|
+
closeSettings: () => void;
|
|
280
|
+
/** A failed write leaves `settingsSnapshot` at its previous value; `settingsError` names why. */
|
|
281
|
+
updateSettings: (patch: TSettingsPatch) => void;
|
|
282
|
+
/** #3282 §4e: whether the Help sheet is shown. `/help` opens it instead of reaching the session. */
|
|
283
|
+
helpOpen: boolean;
|
|
284
|
+
openHelp: () => void;
|
|
285
|
+
closeHelp: () => void;
|
|
286
|
+
/** #3288 §1: the id of the execution-workspace entry open in the detail sheet, or null when closed. */
|
|
287
|
+
openEntryId: string | null;
|
|
288
|
+
executionDetailStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
289
|
+
executionDetailRecords: readonly IExecutionDetailRecord[];
|
|
290
|
+
executionDetailError: string | null;
|
|
291
|
+
/** True once the last page read had no further cursor — nothing more to load. */
|
|
292
|
+
executionDetailComplete: boolean;
|
|
293
|
+
openExecutionDetail: (entryId: string) => void;
|
|
294
|
+
loadMoreExecutionDetail: () => void;
|
|
295
|
+
closeExecutionDetail: () => void;
|
|
296
|
+
/** #3282 §4c — the Project panel's "Changes" section (git status). */
|
|
297
|
+
projectStatusState: 'idle' | 'loading' | 'ready' | 'error';
|
|
298
|
+
projectStatus: TProjectStatusRead | null;
|
|
299
|
+
requestProjectStatus: () => void;
|
|
300
|
+
/** #3282 §4c — the Project panel's "File diff" section, for the file `projectDiffPath` names. */
|
|
301
|
+
projectDiffState: 'idle' | 'loading' | 'ready' | 'error';
|
|
302
|
+
projectDiffPath: string | null;
|
|
303
|
+
projectDiff: TProjectDiffRead | null;
|
|
304
|
+
requestProjectDiff: (path: string) => void;
|
|
305
|
+
/** #3282 §4c — the Project panel's "Memory" section. */
|
|
306
|
+
projectMemoryState: 'idle' | 'loading' | 'ready' | 'error';
|
|
307
|
+
projectMemory: TProjectMemoryRead | null;
|
|
308
|
+
requestProjectMemory: () => void;
|
|
309
|
+
/**
|
|
310
|
+
* #3282 §4 part b-3: whether the agent switcher sheet is shown. `/agent` (bare) and this surface's
|
|
311
|
+
* own control both open it.
|
|
312
|
+
*/
|
|
313
|
+
agentSwitcherOpen: boolean;
|
|
314
|
+
agentSwitcherStatus: 'idle' | 'loading' | 'ready' | 'error';
|
|
315
|
+
/** The available agents: name, one-line description, and where each is defined in plain words. */
|
|
316
|
+
agentDefinitions: readonly IWireAgentDefinitionSummary[];
|
|
317
|
+
/** The agent type `/agent <name>` (no prompt) currently selects — the checked row. */
|
|
318
|
+
currentAgentType: string | null;
|
|
319
|
+
/** The plain confirmation of the last selection's result, shown in the sheet — never a conversation card. */
|
|
320
|
+
agentSwitchMessage: string | null;
|
|
321
|
+
/** Opens the sheet and (re-)fetches its roster. */
|
|
322
|
+
openAgentSwitcher: () => void;
|
|
323
|
+
closeAgentSwitcher: () => void;
|
|
324
|
+
/** Runs the same path as `/agent <name>`. */
|
|
325
|
+
selectAgent: (agentType: string) => void;
|
|
326
|
+
/**
|
|
327
|
+
* #3282 §4 part b-3: the schedules shown in the Agents panel's "Scheduled" group — every
|
|
328
|
+
* `IBackgroundTaskState` of `kind: 'scheduled'`, refreshed on connect and after a write.
|
|
329
|
+
*/
|
|
330
|
+
scheduledTasks: readonly IBackgroundTaskState<'scheduled'>[];
|
|
331
|
+
/** Runs the same path as `/schedule pause <id>` / `/schedule resume <id>`. */
|
|
332
|
+
pauseSchedule: (taskId: string) => void;
|
|
333
|
+
resumeSchedule: (taskId: string) => void;
|
|
334
|
+
/**
|
|
335
|
+
* Permanently stops a schedule — the same `cancel-background-task` write Stop already uses. A
|
|
336
|
+
* failure surfaces the same way a failed Stop does (#3288 §1's `background-task-control-failed`
|
|
337
|
+
* session notice) — no separate error state here.
|
|
338
|
+
*/
|
|
339
|
+
deleteSchedule: (taskId: string) => void;
|
|
340
|
+
}
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/hooks/useSessionClient.d.ts
|
|
343
|
+
declare function useSessionClient<TStatus extends string = TConnectionStatus>(makeClient: TMakeSessionClient<TStatus>): IWsSessionState<TStatus>;
|
|
344
|
+
/** Connect to a `agent` sidecar over WebSocket (loopback / localhost path). */
|
|
345
|
+
declare function useWsSession(url: string): IWsSessionState<TConnectionStatus> & {
|
|
346
|
+
connectionLost: boolean;
|
|
347
|
+
};
|
|
348
|
+
//#endregion
|
|
349
|
+
//#region src/hooks/use-session-directory.d.ts
|
|
350
|
+
/**
|
|
351
|
+
* Remember `sessionId` so the reload a desktop Reconnect triggers can switch back to it once the
|
|
352
|
+
* first session listing arrives (see {@link useSessionDirectoryState}). Best-effort: a host whose
|
|
353
|
+
* storage is unavailable simply lands on whatever session the daemon puts a fresh connection on, same
|
|
354
|
+
* as before this existed.
|
|
355
|
+
*/
|
|
356
|
+
declare function rememberSessionForRestore(namespace: string, sessionId: string): void;
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/components/composer-attachments.d.ts
|
|
359
|
+
/**
|
|
360
|
+
* One file the desktop host's native "Attach files" dialog returned (#3282 §4d). Kept in structural
|
|
361
|
+
* sync with `IPickedFile` in `apps/agent-gui-web/src/gui-host.ts` and
|
|
362
|
+
* `apps/agent-app/electron/sidecar.ts` — the three are not imported across the Electron/browser/
|
|
363
|
+
* presentation package boundaries, same as this codebase already does for the trust question.
|
|
364
|
+
*/
|
|
365
|
+
interface IPickedFile {
|
|
366
|
+
readonly path: string;
|
|
367
|
+
readonly name: string;
|
|
368
|
+
readonly size: number;
|
|
369
|
+
}
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region src/components/Composer.d.ts
|
|
372
|
+
/** What a caller can do to the composer from outside it — currently just reclaiming focus. */
|
|
373
|
+
interface IComposerHandle {
|
|
374
|
+
/** Focuses the message field — used to send focus back there once a docked prompt is answered. */
|
|
375
|
+
focus: () => void;
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region src/client/runtime-host.d.ts
|
|
379
|
+
/** Runtime events delivered by a native host. Browser pages have no process to supervise. */
|
|
380
|
+
type TClientRuntimeState = 'starting' | 'ready' | 'fatal';
|
|
381
|
+
/** A folder decision must be shown before requesting the runtime endpoint. */
|
|
382
|
+
interface IClientTrustQuestion {
|
|
383
|
+
readonly folder: string;
|
|
384
|
+
readonly loads: readonly string[];
|
|
385
|
+
}
|
|
386
|
+
type TClientTrustChoice = 'trust' | 'restricted' | 'quit';
|
|
387
|
+
/**
|
|
388
|
+
* Browser-safe shape for a narrow native preload bridge. The native host implements validation,
|
|
389
|
+
* trust, process lifecycle, and endpoint ownership; the renderer receives only these operations.
|
|
390
|
+
*/
|
|
391
|
+
interface IClientRuntimeBridge {
|
|
392
|
+
readonly runtimeMode?: 'local' | 'remote';
|
|
393
|
+
getEndpoint(): Promise<string | null>;
|
|
394
|
+
signalReady(): void;
|
|
395
|
+
onState(listener: (state: TClientRuntimeState, detail?: string) => void): () => void;
|
|
396
|
+
restartRuntime(): Promise<void>;
|
|
397
|
+
trustQuestion(): Promise<IClientTrustQuestion | null>;
|
|
398
|
+
answerTrust(choice: TClientTrustChoice): Promise<{
|
|
399
|
+
error?: string;
|
|
400
|
+
}>;
|
|
401
|
+
pickFiles?(): Promise<readonly IPickedFile[]>;
|
|
402
|
+
getPathForFile?(file: File): string;
|
|
403
|
+
onOpenSettings?(listener: () => void): () => void;
|
|
404
|
+
openPath?(path: string): Promise<{
|
|
405
|
+
error?: string;
|
|
406
|
+
}>;
|
|
407
|
+
}
|
|
408
|
+
/** A React renderer can use this contract with either a desktop bridge or a browser endpoint. */
|
|
409
|
+
interface IClientRuntimeHost {
|
|
410
|
+
readonly kind: 'desktop' | 'browser';
|
|
411
|
+
getEndpoint(): Promise<string | null>;
|
|
412
|
+
signalReady(): void;
|
|
413
|
+
onState(listener: (state: TClientRuntimeState, detail?: string) => void): () => void;
|
|
414
|
+
readonly restartRuntime?: () => Promise<void>;
|
|
415
|
+
readonly trustQuestion?: () => Promise<IClientTrustQuestion | null>;
|
|
416
|
+
readonly answerTrust?: (choice: TClientTrustChoice) => Promise<{
|
|
417
|
+
error?: string;
|
|
418
|
+
}>;
|
|
419
|
+
readonly pickFiles?: () => Promise<readonly IPickedFile[]>;
|
|
420
|
+
readonly getPathForFile?: (file: File) => string;
|
|
421
|
+
onOpenSettings(listener: () => void): () => void;
|
|
422
|
+
readonly openMemoryInEditor?: (path: string) => void;
|
|
423
|
+
}
|
|
424
|
+
interface IClientRuntimeEnvironment {
|
|
425
|
+
readonly bridge?: IClientRuntimeBridge;
|
|
426
|
+
readonly document: Pick<Document, 'querySelector'>;
|
|
427
|
+
readonly location: Pick<Location, 'search' | 'host' | 'protocol'>;
|
|
428
|
+
}
|
|
429
|
+
/** Resolve host capabilities without importing Electron or a Node CLI into the browser graph. */
|
|
430
|
+
declare function resolveClientRuntimeHost(environment: IClientRuntimeEnvironment): IClientRuntimeHost;
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/hooks/ui-intent-state.d.ts
|
|
433
|
+
/** The GUI screen an intent opens, or null when this surface has none for it. */
|
|
434
|
+
declare function guiScreenForUiIntent(intent: TCommandUiIntent): 'session-sidebar' | 'settings' | 'settings-plugins' | 'agent-switcher' | null;
|
|
435
|
+
/**
|
|
436
|
+
* Describe one intent for this surface: a plain, honest sentence for a screen this HOST cannot back
|
|
437
|
+
* right now (a session picker with no session list), the `/theme` exclusion this intent defensively
|
|
438
|
+
* reuses, or an unrecognized future kind. Never called for `show-settings`, `show-plugin-manager` or
|
|
439
|
+
* `show-agent-switcher` — all three always have a screen now (#3282 §4a, §4 part b-2, §4 part b-3) —
|
|
440
|
+
* but their cases are left out of this switch rather than kept as dead branches that would claim
|
|
441
|
+
* otherwise; an unknown wire-level kind (a newer host) still yields an explicit notice naming the raw
|
|
442
|
+
* kind, so the "never a silent no-op" floor holds for future intents too.
|
|
443
|
+
*/
|
|
444
|
+
declare function describeUiIntentForGui(intent: TCommandUiIntent): string;
|
|
445
|
+
//#endregion
|
|
446
|
+
//#region src/components/ConversationView.d.ts
|
|
447
|
+
interface IConversationViewProps {
|
|
448
|
+
messages: readonly TConversationEntry[];
|
|
449
|
+
activeTools: IActiveTool[];
|
|
450
|
+
streamingText: string;
|
|
451
|
+
isThinking: boolean;
|
|
452
|
+
/** This connection's own driver id (§3289 §3), threaded to every message it renders. */
|
|
453
|
+
ownDriverId: TDriverId | null;
|
|
454
|
+
}
|
|
455
|
+
declare function ConversationView({ messages, activeTools, streamingText, isThinking, ownDriverId }: IConversationViewProps): React$1.ReactElement;
|
|
456
|
+
//#endregion
|
|
457
|
+
//#region src/components/AgentActivityPanel.d.ts
|
|
458
|
+
interface IAgentActivityPanelProps {
|
|
459
|
+
tasks: readonly IExecutionWorkspaceEntry[];
|
|
460
|
+
/** #3282 §4 part b-3: the "Scheduled" group — every `kind: 'scheduled'` background task. */
|
|
461
|
+
schedules?: readonly IBackgroundTaskState<'scheduled'>[];
|
|
462
|
+
/** #3282 §4 part b-3: the current goal (`/goal`), or null/absent when none is set. */
|
|
463
|
+
goal?: IGoalState | null;
|
|
464
|
+
onPauseSchedule?: (taskId: string) => void;
|
|
465
|
+
onResumeSchedule?: (taskId: string) => void;
|
|
466
|
+
onDeleteSchedule?: (taskId: string) => void;
|
|
467
|
+
onCancelGoal?: () => void;
|
|
468
|
+
className?: string;
|
|
469
|
+
/** #3288 §1: open a non-main-thread entry's detail sheet. */
|
|
470
|
+
onSelect?: (entry: IExecutionWorkspaceEntry) => void;
|
|
471
|
+
/** #3288 §1: the main thread entry was clicked — the conversation beside this panel is it. */
|
|
472
|
+
onReturnToConversation?: () => void;
|
|
473
|
+
/** #3288 §1: Stop was clicked on a running/queued entry. */
|
|
474
|
+
onStop?: (entry: IExecutionWorkspaceEntry) => void;
|
|
475
|
+
/** #3288 §1: the entry whose detail sheet is currently open, for a highlighted row. */
|
|
476
|
+
selectedEntryId?: string;
|
|
477
|
+
}
|
|
478
|
+
declare function AgentActivityPanel({ tasks, schedules, goal, onPauseSchedule, onResumeSchedule, onDeleteSchedule, onCancelGoal, className, onSelect, onReturnToConversation, onStop, selectedEntryId }: IAgentActivityPanelProps): React$1.ReactElement;
|
|
479
|
+
//#endregion
|
|
480
|
+
//#region src/components/AgentSwitcherSheet.d.ts
|
|
481
|
+
/**
|
|
482
|
+
* #3282 §4 part b-3 — the agent switcher: `show-agent-switcher` (`/agent` with no args) opens this
|
|
483
|
+
* sheet instead of the surface's old "not available" line. It lists every agent this session can
|
|
484
|
+
* run — name, one-line description, and where each is defined in plain words — with the current one
|
|
485
|
+
* checked. Choosing a row runs the SAME path as typing `/agent <name>` (a plain `command`, wired in
|
|
486
|
+
* `useAgentSwitcherState`); the reply is this sheet's own confirmation line, never a conversation
|
|
487
|
+
* card (issue #3282 §4's decided design).
|
|
488
|
+
*/
|
|
489
|
+
declare function AgentSwitcherSheet({ state }: {
|
|
490
|
+
state: IWsSessionState;
|
|
491
|
+
}): React$1.ReactElement | null;
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/components/PermissionPrompt.d.ts
|
|
494
|
+
/**
|
|
495
|
+
* Renders the owner's pending permission/ask prompts (REMOTE-007/009). Under local == remote the paired
|
|
496
|
+
* browser owner answers its OWN prompts; the first pending prompt is shown. A gated tool call blocks
|
|
497
|
+
* until answered, so this is on the critical path — not decorative.
|
|
498
|
+
*
|
|
499
|
+
* `modal` covers the page; `dock` sits above the composer, as desktop agent apps place a pending
|
|
500
|
+
* question next to where the answer is typed. Once armed and focused, its keys answer it: 1–9 picks
|
|
501
|
+
* an option, Esc cancels a question or denies a permission — but it never takes that focus away from
|
|
502
|
+
* a field the person is typing in (#3280 §1). A click on a button always answers at once. An ask whose
|
|
503
|
+
* request sets `allowFreeText` also shows a text field (masked when `masked` is set); Enter there
|
|
504
|
+
* submits it, and its own keys never reach the prompt's shortcuts (#3280 §3). The field's typed value
|
|
505
|
+
* lives only in `FreeTextField`, keyed by `prompt.id`: a cancelled or answered prompt's text can
|
|
506
|
+
* never reach the next prompt's render, masked or not, because the field is a fresh component
|
|
507
|
+
* instance rather than a value carried over in this component's own state (#3280 §3 follow-up).
|
|
508
|
+
*/
|
|
509
|
+
interface IPermissionPromptProps {
|
|
510
|
+
prompts: readonly TPendingPrompt[];
|
|
511
|
+
onAnswerPermission: (id: string, result: boolean) => void;
|
|
512
|
+
onAnswerAsk: (id: string, response: TActionResponse) => void;
|
|
513
|
+
/** This connection's own driver id (§3289 §3): a prompt raised by its own turn shows no requester. */
|
|
514
|
+
ownDriverId?: TDriverId | null;
|
|
515
|
+
layout?: 'modal' | 'dock';
|
|
516
|
+
/** How long a new prompt waits before its keys answer it; tests pass their own. */
|
|
517
|
+
armDelayMs?: number;
|
|
518
|
+
/**
|
|
519
|
+
* Called once an answer (click or key) leaves no prompt behind, if focus was inside this prompt at
|
|
520
|
+
* the time — so the caller can send it back to the field the person was typing in (the composer,
|
|
521
|
+
* for the `dock` layout). Not called when another prompt immediately follows: focus stays on the
|
|
522
|
+
* prompt for that one instead.
|
|
523
|
+
*/
|
|
524
|
+
onFocusReturn?: () => void;
|
|
525
|
+
}
|
|
526
|
+
declare function PermissionPrompt({ prompts, onAnswerPermission, onAnswerAsk, ownDriverId, layout, armDelayMs, onFocusReturn }: IPermissionPromptProps): React$1.ReactElement | null;
|
|
527
|
+
//#endregion
|
|
528
|
+
//#region src/components/personal-usage-dashboard-types.d.ts
|
|
529
|
+
type TPersonalUsageDashboardState = Pick<IWsSessionState, 'personalUsageStatus' | 'personalUsageReport' | 'personalUsageError' | 'requestPersonalUsage' | 'storedSessionUsageStatus' | 'storedSessionUsageReport' | 'storedSessionUsageSessionId' | 'storedSessionUsageError' | 'requestStoredSessionUsage' | 'currentSessionUsageStatus' | 'currentSessionUsageReport' | 'requestCurrentSessionUsage' | 'sessionListing'>;
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region src/components/PersonalUsageDashboard.d.ts
|
|
532
|
+
declare function PersonalUsageDashboard({ state }: {
|
|
533
|
+
state: TPersonalUsageDashboardState;
|
|
534
|
+
}): React.ReactElement;
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region src/components/SessionSurface.d.ts
|
|
537
|
+
/**
|
|
538
|
+
* The full desktop layout over an `IWsSessionState`. `surface` is an optional label shown next to the
|
|
539
|
+
* mark (e.g. "app").
|
|
540
|
+
*/
|
|
541
|
+
declare function SessionSurface({ state, surface, personalUsageEnabled, onReconnect, pickFiles, getPathForFile, onOpenMemoryInEditor }: {
|
|
542
|
+
state: IWsSessionState;
|
|
543
|
+
surface?: string;
|
|
544
|
+
/** Desktop shells opt in; embedded/session-only surfaces keep their existing chat-only contract. */
|
|
545
|
+
personalUsageEnabled?: boolean;
|
|
546
|
+
/**
|
|
547
|
+
* Present only when the host can restart the runtime after the connection is lost for good (issue
|
|
548
|
+
* #3280 §5, the desktop app); absent in the browser, where the banner says how to reopen it instead.
|
|
549
|
+
*/
|
|
550
|
+
onReconnect?: () => Promise<void>;
|
|
551
|
+
/** Forwarded to the composer's attach button — present only on the desktop app (#3282 §4d). */
|
|
552
|
+
pickFiles?: () => Promise<readonly IPickedFile[]>;
|
|
553
|
+
/** Forwarded to the composer's drag-and-drop — present only on the desktop app (#3282 §4d). */
|
|
554
|
+
getPathForFile?: (file: File) => string;
|
|
555
|
+
/**
|
|
556
|
+
* The Project panel's memory "Open in editor" action — present only when the host can open a file
|
|
557
|
+
* in an external editor (the desktop app, #3282 §4c). Absent in the browser, where the action
|
|
558
|
+
* itself is hidden (only shown "if the host supports it").
|
|
559
|
+
*/
|
|
560
|
+
onOpenMemoryInEditor?: (path: string) => void;
|
|
561
|
+
}): React.ReactElement;
|
|
562
|
+
/**
|
|
563
|
+
* A centered chrome frame for the pre-session (loading) and fatal states — reused by app shells. Its
|
|
564
|
+
* content area is this page's `main` landmark (#3289 §3 review): nothing above `CenteredChrome`'s
|
|
565
|
+
* three call sites (starting, fatal, the trust question) supplies one, and none of the three ever
|
|
566
|
+
* render alongside `SessionSurface`'s own. `header` stays a sibling of `main`, not inside it, so it
|
|
567
|
+
* keeps its own implicit `banner` role.
|
|
568
|
+
*/
|
|
569
|
+
declare function CenteredChrome({ tone, children }: {
|
|
570
|
+
tone: 'muted' | 'fatal';
|
|
571
|
+
children: React.ReactNode;
|
|
572
|
+
}): React.ReactElement;
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region src/components/SessionSidebar.d.ts
|
|
575
|
+
/**
|
|
576
|
+
* #3189 — this workspace's sessions on the left of the conversation, as in Claude Code Desktop:
|
|
577
|
+
* start a new one, or click another to make it current. Rows the host could not read are listed,
|
|
578
|
+
* disabled, so a damaged session never looks deleted. A refused switch comes back as a notice.
|
|
579
|
+
* A host that keeps several sessions live marks the rows running now and counts who else is on them.
|
|
580
|
+
*
|
|
581
|
+
* #3289 §1 — each row also carries a "More" menu (or right-click) with Rename (inline) and Delete
|
|
582
|
+
* (confirmed). Rename on the current row reuses the `/rename` command, which also updates the live
|
|
583
|
+
* session's own name and title bar; rename on any other row writes the stored record directly.
|
|
584
|
+
*/
|
|
585
|
+
declare function SessionSidebar({ state, brand, className }: {
|
|
586
|
+
state: IWsSessionState;
|
|
587
|
+
/** The app's name, shown at the top of the sidebar while it is open. */
|
|
588
|
+
brand?: React.ReactNode;
|
|
589
|
+
className?: string;
|
|
590
|
+
}): React.ReactElement;
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region src/components/SessionMonitor.d.ts
|
|
593
|
+
interface ISessionMonitorProps {
|
|
594
|
+
/** WebSocket URL. Injected by the HTTP server via <meta name="ws-url">. */
|
|
595
|
+
wsUrl: string;
|
|
596
|
+
className?: string;
|
|
597
|
+
}
|
|
598
|
+
declare function SessionMonitor({ wsUrl, className }: ISessionMonitorProps): React$1.ReactElement;
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/components/Dialog.d.ts
|
|
601
|
+
/**
|
|
602
|
+
* The shared modal-shell primitive (#3282 §4a, coordinated with #3282 §2's model/mode controls,
|
|
603
|
+
* which also need a confirmation dialog). Whichever of the two lands first defines this file; the
|
|
604
|
+
* other rebases onto it rather than shipping a second copy.
|
|
605
|
+
*
|
|
606
|
+
* `role="dialog"` (or `"alertdialog"`, see `role` below), `aria-modal`, a labelled title, focus moved
|
|
607
|
+
* inside on open, a focus trap while open, Esc to close, and focus restored to whatever had it before
|
|
608
|
+
* the dialog opened. A backdrop click closes the dialog UNLESS `destructive` is set — a destructive
|
|
609
|
+
* dialog (e.g. "Remove this rule?") is dismissed only by an explicit choice, never an accidental
|
|
610
|
+
* outside click.
|
|
611
|
+
*/
|
|
612
|
+
interface IDialogProps {
|
|
613
|
+
open: boolean;
|
|
614
|
+
/** Called on Esc, a backdrop click (non-destructive only), or an explicit close control. */
|
|
615
|
+
onClose: () => void;
|
|
616
|
+
title: string;
|
|
617
|
+
children: React$1.ReactNode;
|
|
618
|
+
/** Disables backdrop-click-to-close for a dialog whose only correct exits are explicit buttons. */
|
|
619
|
+
destructive?: boolean;
|
|
620
|
+
/** Overrides the panel's own classes; the backdrop/overlay classes are never overridden. */
|
|
621
|
+
panelClassName?: string;
|
|
622
|
+
/** Id of an element describing the dialog, wired to `aria-describedby`. */
|
|
623
|
+
describedById?: string;
|
|
624
|
+
/**
|
|
625
|
+
* Overrides what focus returns to when the dialog closes (#3289 §1). Default behavior captures
|
|
626
|
+
* `document.activeElement` when the dialog opens — which fails for a caller whose opener element
|
|
627
|
+
* is removed from the DOM in the SAME update that opens this dialog (e.g. a menu item whose menu
|
|
628
|
+
* closes as this dialog opens): by the time this dialog's open-effect runs, the browser has already
|
|
629
|
+
* moved focus to `document.body`. Such a caller passes the stable element focus should return to.
|
|
630
|
+
*/
|
|
631
|
+
restoreFocusTo?: HTMLElement | null;
|
|
632
|
+
/**
|
|
633
|
+
* #3282 §4e: `'alertdialog'` for a dialog that interrupts to demand a decision before anything else
|
|
634
|
+
* can happen (a destructive confirmation) — WAI-ARIA's distinction from a dialog the user can set
|
|
635
|
+
* aside. Default `'dialog'`.
|
|
636
|
+
*/
|
|
637
|
+
role?: 'dialog' | 'alertdialog';
|
|
638
|
+
}
|
|
639
|
+
declare function Dialog({ open, onClose, title, children, destructive, panelClassName, describedById, restoreFocusTo, role }: IDialogProps): React$1.ReactElement | null;
|
|
640
|
+
interface IConfirmDialogProps {
|
|
641
|
+
open: boolean;
|
|
642
|
+
title: string;
|
|
643
|
+
body: React$1.ReactNode;
|
|
644
|
+
confirmLabel: string;
|
|
645
|
+
cancelLabel?: string;
|
|
646
|
+
/** Styles the confirm button as destructive; the dialog itself also stops closing on a backdrop click. */
|
|
647
|
+
destructive?: boolean;
|
|
648
|
+
onConfirm: () => void;
|
|
649
|
+
onCancel: () => void;
|
|
650
|
+
/** Forwarded to `Dialog` — see its doc comment. */
|
|
651
|
+
restoreFocusTo?: HTMLElement | null;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* A title, a body, Cancel focused by default, and a confirm button that can be styled destructive.
|
|
655
|
+
* #3282 §4e: `destructive` also picks the dialog's ARIA role — `"alertdialog"` when it is (an action
|
|
656
|
+
* that demands a decision before anything else, e.g. deleting a session), `"dialog"` otherwise.
|
|
657
|
+
*/
|
|
658
|
+
declare function ConfirmDialog({ open, title, body, confirmLabel, cancelLabel, destructive, onConfirm, onCancel, restoreFocusTo }: IConfirmDialogProps): React$1.ReactElement | null;
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/components/SettingsScreen.d.ts
|
|
661
|
+
/**
|
|
662
|
+
* A large modal sheet with a section sidebar on the left and content on the right (#3282 §4a) — the
|
|
663
|
+
* GUI's Settings screen, opened by the sidebar's gear button, the desktop app's ⌘, menu item, or
|
|
664
|
+
* `/settings` (its `show-settings` `ui_intent` calls `state.openSettings()`, wired in
|
|
665
|
+
* `useSessionClient`). Every change applies at once; there is no Save button. Esc and the Close
|
|
666
|
+
* button both close it and return focus to whatever opened it (`Dialog` owns that).
|
|
667
|
+
*/
|
|
668
|
+
declare function SettingsScreen({ state }: {
|
|
669
|
+
state: IWsSessionState;
|
|
670
|
+
}): React$1.ReactElement | null;
|
|
671
|
+
//#endregion
|
|
672
|
+
//#region src/components/HelpSheet.d.ts
|
|
673
|
+
/**
|
|
674
|
+
* The GUI's Help sheet (#3282 §4e), a `Dialog` opened by `/help` — client-only: `useSessionClient.ts`'s
|
|
675
|
+
* `send` catches `/help` before it ever reaches the session and opens this instead, so there is no
|
|
676
|
+
* round trip and nothing terminal-style to replace it with. It lists the same commands and skills the
|
|
677
|
+
* `/` menu offers (`commandMenuFor`, unfiltered by any query — an excluded command has no row here
|
|
678
|
+
* either, exactly like the menu), grouped the same way, plus the keyboard shortcuts this surface
|
|
679
|
+
* answers. The TUI keeps its own text `/help` output; this sheet is the GUI's alone.
|
|
680
|
+
*/
|
|
681
|
+
declare function HelpSheet({ open, onClose, catalog }: {
|
|
682
|
+
open: boolean;
|
|
683
|
+
onClose: () => void;
|
|
684
|
+
catalog: TCommandCatalog | null;
|
|
685
|
+
}): React.ReactElement | null;
|
|
686
|
+
//#endregion
|
|
687
|
+
//#region src/components/Brand.d.ts
|
|
688
|
+
/** Shared mark: a rounded face with two eyes, in the accent colour. */
|
|
689
|
+
declare function ProductMark({ size }: {
|
|
690
|
+
size?: number;
|
|
691
|
+
}): React.ReactElement;
|
|
692
|
+
/** The mark and the wordmark, as the app's name in its chrome. */
|
|
693
|
+
declare function ProductWordmark({ surface }: {
|
|
694
|
+
surface?: string;
|
|
695
|
+
}): React.ReactElement;
|
|
696
|
+
//#endregion
|
|
697
|
+
//#region src/product-identity.d.ts
|
|
698
|
+
/** Only the public identity needed by a browser surface; hosts resolve its values. */
|
|
699
|
+
interface IWebProductIdentity {
|
|
700
|
+
readonly identity: {
|
|
701
|
+
readonly displayName: string;
|
|
702
|
+
readonly cliName: string;
|
|
703
|
+
};
|
|
704
|
+
readonly storage: {
|
|
705
|
+
readonly browserNamespace: string;
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
declare function ProductIdentityProvider({ value, children }: {
|
|
709
|
+
readonly value: IWebProductIdentity;
|
|
710
|
+
readonly children?: ReactNode;
|
|
711
|
+
}): React.ReactElement;
|
|
712
|
+
declare function useProductIdentity(): IWebProductIdentity;
|
|
713
|
+
//#endregion
|
|
714
|
+
export { AgentActivityPanel, AgentSwitcherSheet, CenteredChrome, ConfirmDialog, ConversationView, Dialog, HelpSheet, type IActiveTool, type IClientRuntimeBridge, type IClientRuntimeEnvironment, type IClientRuntimeHost, type IClientTrustQuestion, type ICommandOutputEntry, type IComposerHandle, type IConfirmDialogProps, type IConversationMessage, type IDialogProps, type IPickedFile, type ISessionClientHandle, type ISessionNotice, type IToolGroupEntry, type IWebProductIdentity, type IWsSessionClientCallbacks, type IWsSessionState, PermissionPrompt, PersonalUsageDashboard, ProductIdentityProvider, ProductMark, ProductWordmark, SessionMonitor, SessionSidebar, SessionSurface, SettingsScreen, type TClientRuntimeState, type TClientTrustChoice, type TConnectionStatus, type TConversationEntry, type TMakeSessionClient, type TPendingPrompt, type TPersonalUsageDashboardState, type TSessionListing, type TSessionsError, applyPromptEvent, askResponse, createWsSessionClient, describeUiIntentForGui, guiScreenForUiIntent, permissionResponse, rememberSessionForRestore, resolveClientRuntimeHost, useProductIdentity, useSessionClient, useWsSession };
|
|
715
|
+
//# sourceMappingURL=index.d.cts.map
|