@tutti-os/agent-gui 0.0.133 → 0.0.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +19 -5
  2. package/dist/{AgentRichTextReadonly-PEKCMRPE.js → AgentRichTextReadonly-HCKTNAYO.js} +7 -6
  3. package/dist/agent-conversation/index.d.ts +2 -2
  4. package/dist/agent-conversation/index.js +9 -9
  5. package/dist/agent-gui.d.ts +34 -6
  6. package/dist/agent-gui.js +17 -17
  7. package/dist/agent-message-center/index.js +7 -7
  8. package/dist/{agentFileMentionContracts-CWAeuL7S.d.ts → agentFileMentionContracts-B0yQizXB.d.ts} +5 -0
  9. package/dist/{agentGuiNodeTypes-B57MfwVo.d.ts → agentGuiNodeTypes-DV7KvZRe.d.ts} +6 -5
  10. package/dist/agents.d.ts +1 -1
  11. package/dist/agents.js +1 -1
  12. package/dist/app/renderer/agentactivity.css +6 -0
  13. package/dist/{chunk-GBBNYGL7.js → chunk-25VMCMAQ.js} +4 -4
  14. package/dist/{chunk-VS5BRBY6.js → chunk-5WOCGIXJ.js} +4 -1
  15. package/dist/chunk-5WOCGIXJ.js.map +1 -0
  16. package/dist/chunk-DLCZJKCA.js +1 -0
  17. package/dist/chunk-DLCZJKCA.js.map +1 -0
  18. package/dist/{chunk-QQRTUHCH.js → chunk-EU7DCT4F.js} +2 -2
  19. package/dist/{chunk-SZOTLVH6.js → chunk-GIYGO2PB.js} +2 -2
  20. package/dist/{chunk-HCRROERX.js → chunk-IN3HXYOO.js} +4 -4
  21. package/dist/{chunk-N62NVPHT.js → chunk-IYZ4GOSN.js} +4 -4
  22. package/dist/{chunk-A6NSHCRP.js → chunk-JI5KND3K.js} +54 -51
  23. package/dist/chunk-JI5KND3K.js.map +1 -0
  24. package/dist/{chunk-J4TTEMRW.js → chunk-KWGMK4IZ.js} +4 -4
  25. package/dist/{chunk-NE6H7S5Z.js → chunk-OFJNIQWR.js} +2 -2
  26. package/dist/{chunk-NE6H7S5Z.js.map → chunk-OFJNIQWR.js.map} +1 -1
  27. package/dist/{chunk-UARZZJJB.js → chunk-OI6BYC7P.js} +4 -4
  28. package/dist/{chunk-OBWM2RFE.js → chunk-QPEO4OQS.js} +308 -8
  29. package/dist/chunk-QPEO4OQS.js.map +1 -0
  30. package/dist/{chunk-XNE2ROCP.js → chunk-UA75CGAG.js} +3 -3
  31. package/dist/{chunk-PVTAFUDS.js → chunk-VGS7S7YT.js} +2 -2
  32. package/dist/{chunk-OQR3HXPF.js → chunk-VUNVGEQG.js} +7 -1
  33. package/dist/chunk-VUNVGEQG.js.map +1 -0
  34. package/dist/{chunk-IZ626FDO.js → chunk-Y5HD6XHP.js} +485 -361
  35. package/dist/chunk-Y5HD6XHP.js.map +1 -0
  36. package/dist/{chunk-KPMQGPYU.js → chunk-ZVYUTXQJ.js} +1 -1
  37. package/dist/chunk-ZVYUTXQJ.js.map +1 -0
  38. package/dist/context-mention-palette/index.d.ts +1 -1
  39. package/dist/context-mention-palette/index.js +8 -7
  40. package/dist/{contribution-BbW-kkpi.d.ts → contribution-CDdwTppn.d.ts} +2 -0
  41. package/dist/custom-mention.js +1 -0
  42. package/dist/i18n/index.d.ts +6 -0
  43. package/dist/i18n/index.js +2 -2
  44. package/dist/index.d.ts +53 -9
  45. package/dist/index.js +20 -20
  46. package/dist/index.js.map +1 -1
  47. package/dist/mention-search.d.ts +1 -1
  48. package/dist/mention-search.js +6 -5
  49. package/dist/{types-BeAVr4of.d.ts → types-ee3zJ6Cc.d.ts} +3 -0
  50. package/dist/workbench/browser-element-context/index.d.ts +37 -0
  51. package/dist/workbench/browser-element-context/index.js +750 -0
  52. package/dist/workbench/browser-element-context/index.js.map +1 -0
  53. package/dist/workbench/contribution.d.ts +1 -1
  54. package/dist/workbench/contribution.js +4 -4
  55. package/dist/workbench/index.d.ts +1 -1
  56. package/dist/workbench/index.js +4 -4
  57. package/dist/workbench/sessionTitle.js +2 -2
  58. package/dist/workbench/tool-sidebar/index.d.ts +189 -0
  59. package/dist/workbench/tool-sidebar/index.js +1492 -0
  60. package/dist/workbench/tool-sidebar/index.js.map +1 -0
  61. package/package.json +27 -12
  62. package/dist/chunk-A6NSHCRP.js.map +0 -1
  63. package/dist/chunk-IZ626FDO.js.map +0 -1
  64. package/dist/chunk-KPMQGPYU.js.map +0 -1
  65. package/dist/chunk-OBWM2RFE.js.map +0 -1
  66. package/dist/chunk-OQR3HXPF.js.map +0 -1
  67. package/dist/chunk-VS5BRBY6.js.map +0 -1
  68. /package/dist/{AgentRichTextReadonly-PEKCMRPE.js.map → AgentRichTextReadonly-HCKTNAYO.js.map} +0 -0
  69. /package/dist/{chunk-GBBNYGL7.js.map → chunk-25VMCMAQ.js.map} +0 -0
  70. /package/dist/{chunk-QQRTUHCH.js.map → chunk-EU7DCT4F.js.map} +0 -0
  71. /package/dist/{chunk-SZOTLVH6.js.map → chunk-GIYGO2PB.js.map} +0 -0
  72. /package/dist/{chunk-HCRROERX.js.map → chunk-IN3HXYOO.js.map} +0 -0
  73. /package/dist/{chunk-N62NVPHT.js.map → chunk-IYZ4GOSN.js.map} +0 -0
  74. /package/dist/{chunk-J4TTEMRW.js.map → chunk-KWGMK4IZ.js.map} +0 -0
  75. /package/dist/{chunk-UARZZJJB.js.map → chunk-OI6BYC7P.js.map} +0 -0
  76. /package/dist/{chunk-XNE2ROCP.js.map → chunk-UA75CGAG.js.map} +0 -0
  77. /package/dist/{chunk-PVTAFUDS.js.map → chunk-VGS7S7YT.js.map} +0 -0
@@ -0,0 +1,1492 @@
1
+ // workbench/tool-sidebar/model.ts
2
+ var agentToolPanelIds = [
3
+ "files",
4
+ "terminal",
5
+ "browser",
6
+ "tasks",
7
+ "apps",
8
+ "messages"
9
+ ];
10
+ var supportedPanelIds = new Set(agentToolPanelIds);
11
+ function isAgentToolPanelId(value) {
12
+ return supportedPanelIds.has(value);
13
+ }
14
+ function filterAgentToolPanels(panels) {
15
+ const seen = /* @__PURE__ */ new Set();
16
+ const filtered = [];
17
+ for (const panel of panels) {
18
+ if (!isAgentToolPanelId(panel.id) || seen.has(panel.id)) {
19
+ continue;
20
+ }
21
+ seen.add(panel.id);
22
+ filtered.push({ id: panel.id, label: panel.label });
23
+ }
24
+ return filtered;
25
+ }
26
+ var adjacentPanelDefaultWidth = 720;
27
+ var agentToolEmptySidebarWidth = Math.round(
28
+ adjacentPanelDefaultWidth * 0.6
29
+ );
30
+ var agentToolMainMinWidth = 280;
31
+ var agentToolPanelDefaultWidthById = {
32
+ apps: adjacentPanelDefaultWidth,
33
+ browser: adjacentPanelDefaultWidth,
34
+ files: adjacentPanelDefaultWidth,
35
+ messages: 440,
36
+ tasks: 860,
37
+ terminal: adjacentPanelDefaultWidth
38
+ };
39
+ var agentToolPanelMinWidthById = {
40
+ apps: 420,
41
+ browser: 420,
42
+ files: 480,
43
+ messages: 320,
44
+ tasks: 420,
45
+ terminal: 420
46
+ };
47
+ var agentToolPanelMaxWidthById = {
48
+ apps: 1200,
49
+ browser: 1200,
50
+ files: Number.MAX_SAFE_INTEGER,
51
+ messages: 1200,
52
+ tasks: 1200,
53
+ terminal: 1200
54
+ };
55
+ function createAgentToolSidebarState(initial) {
56
+ const activePanel = initial?.activePanel ?? null;
57
+ const mountedTabs = initial?.mountedTabs ?? [];
58
+ const activeTabId = initial?.activeTabId ?? (activePanel === null ? null : findLastTab(mountedTabs, activePanel)?.id ?? null);
59
+ return {
60
+ activePanel: activeTabId === null ? null : activePanel,
61
+ activeTabId,
62
+ mountedTabs
63
+ };
64
+ }
65
+ function reduceAgentToolSidebarState(state, action) {
66
+ switch (action.type) {
67
+ case "close":
68
+ return state.activeTabId === null ? state : { ...state, activePanel: null, activeTabId: null };
69
+ case "close-tab": {
70
+ const closingIndex = state.mountedTabs.findIndex(
71
+ (tab) => tab.id === action.tabId
72
+ );
73
+ if (closingIndex < 0) {
74
+ return state;
75
+ }
76
+ const mountedTabs = state.mountedTabs.filter(
77
+ (tab) => tab.id !== action.tabId
78
+ );
79
+ if (state.activeTabId !== action.tabId) {
80
+ return { ...state, mountedTabs };
81
+ }
82
+ const nextTab = mountedTabs[Math.max(0, closingIndex - 1)] ?? mountedTabs[0] ?? null;
83
+ return {
84
+ activePanel: nextTab?.panel ?? null,
85
+ activeTabId: nextTab?.id ?? null,
86
+ mountedTabs
87
+ };
88
+ }
89
+ case "activate-tab": {
90
+ const tab = state.mountedTabs.find(
91
+ (candidate) => candidate.id === action.tabId
92
+ );
93
+ return tab ? { ...state, activePanel: tab.panel, activeTabId: tab.id } : state;
94
+ }
95
+ case "add-panel":
96
+ return addTab(state, action);
97
+ case "open-panel": {
98
+ const existing = findLastTab(
99
+ state.mountedTabs,
100
+ action.panel,
101
+ action.resourceId
102
+ );
103
+ return existing ? { ...state, activePanel: existing.panel, activeTabId: existing.id } : addTab(state, action);
104
+ }
105
+ }
106
+ }
107
+ function addTab(state, tab) {
108
+ const nextTab = {
109
+ id: tab.tabId,
110
+ panel: tab.panel,
111
+ ...tab.resourceId ? { resourceId: tab.resourceId } : {}
112
+ };
113
+ return {
114
+ activePanel: nextTab.panel,
115
+ activeTabId: nextTab.id,
116
+ mountedTabs: state.mountedTabs.some(
117
+ (candidate) => candidate.id === nextTab.id
118
+ ) ? state.mountedTabs : [...state.mountedTabs, nextTab]
119
+ };
120
+ }
121
+ function findLastTab(tabs, panel, resourceId) {
122
+ for (let index = tabs.length - 1; index >= 0; index -= 1) {
123
+ const tab = tabs[index];
124
+ if (tab?.panel === panel && (tab.resourceId ?? void 0) === resourceId) {
125
+ return tab;
126
+ }
127
+ }
128
+ return null;
129
+ }
130
+ function resolveAgentToolPanelExpansionReset(input) {
131
+ if (input.expandedPanel === null || input.expandedPanel === input.nextPanel) {
132
+ return null;
133
+ }
134
+ return {
135
+ panel: input.expandedPanel,
136
+ width: typeof input.widthBeforeExpansion === "number" && Number.isFinite(input.widthBeforeExpansion) ? input.widthBeforeExpansion : agentToolPanelDefaultWidthById[input.expandedPanel]
137
+ };
138
+ }
139
+ function resolveAgentToolPanelExpansionTransfer(input) {
140
+ const reset = resolveAgentToolPanelExpansionReset(input);
141
+ if (!reset || input.nextPanel === null) {
142
+ return null;
143
+ }
144
+ return {
145
+ expandedPanel: input.nextPanel,
146
+ nextPanelWidthBeforeExpansion: Number.isFinite(input.nextPanelWidth) && input.nextPanelWidth > 0 ? input.nextPanelWidth : agentToolPanelDefaultWidthById[input.nextPanel],
147
+ previousPanel: reset.panel,
148
+ previousPanelWidth: reset.width
149
+ };
150
+ }
151
+ function resolveAgentToolPanelMaxWidth(panel, viewportWidth, allowFullWidth = false, mainContentMinWidth = agentToolMainMinWidth) {
152
+ const resolvedMainMin = Number.isFinite(mainContentMinWidth) ? Math.max(0, mainContentMinWidth) : agentToolMainMinWidth;
153
+ const resolvedViewport = Number.isFinite(viewportWidth) ? viewportWidth : resolvedMainMin + agentToolPanelMinWidthById[panel];
154
+ return Math.max(
155
+ 0,
156
+ Math.min(
157
+ allowFullWidth ? Number.MAX_SAFE_INTEGER : agentToolPanelMaxWidthById[panel],
158
+ resolvedViewport - resolvedMainMin
159
+ )
160
+ );
161
+ }
162
+ function clampAgentToolPanelWidth(input) {
163
+ const maxWidth = resolveAgentToolPanelMaxWidth(
164
+ input.panel,
165
+ input.viewportWidth,
166
+ input.allowFullWidth,
167
+ input.mainContentMinWidth
168
+ );
169
+ const minWidth = Math.min(agentToolPanelMinWidthById[input.panel], maxWidth);
170
+ const width = Number.isFinite(input.width) ? input.width : agentToolPanelDefaultWidthById[input.panel];
171
+ return Math.round(Math.min(maxWidth, Math.max(minWidth, width)));
172
+ }
173
+ function resolveAgentToolSidebarWidth(input) {
174
+ const baseline = Number.isFinite(input.baselineViewportWidth) ? Math.max(0, input.baselineViewportWidth) : input.viewportWidth;
175
+ return clampAgentToolPanelWidth({
176
+ allowFullWidth: input.allowFullWidth,
177
+ mainContentMinWidth: input.mainContentMinWidth,
178
+ panel: input.panel,
179
+ viewportWidth: input.viewportWidth,
180
+ width: Math.max(input.preferredWidth, input.viewportWidth - baseline)
181
+ });
182
+ }
183
+ function resolveAgentToolSidebarLayoutWidth(input) {
184
+ return Math.round(Math.max(0, input.panelWidth));
185
+ }
186
+ function resolveAgentToolPanelPreferredWidth(input) {
187
+ return !input.isExpanded && typeof input.manuallyResizedWidth === "number" && Number.isFinite(input.manuallyResizedWidth) ? input.manuallyResizedWidth : input.panelWidth;
188
+ }
189
+ function shouldResizeAgentToolContainer(input) {
190
+ return input.currentWidth !== input.requestedWidth && !(input.lastResize?.requestedWidth === input.requestedWidth && input.lastResize.actualWidth === input.currentWidth);
191
+ }
192
+ function formatAgentToolReminderCount(value) {
193
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
194
+ return null;
195
+ }
196
+ const count = Math.floor(value);
197
+ return count > 99 ? "99+" : String(count);
198
+ }
199
+
200
+ // workbench/tool-sidebar/AgentToolBrowserPanel.tsx
201
+ import { lazy, Suspense, useMemo, useState } from "react";
202
+ import {
203
+ createBrowserNodeFeature,
204
+ isBrowserNodeSurfaceEvent
205
+ } from "@tutti-os/browser-node";
206
+ import { jsx } from "react/jsx-runtime";
207
+ var LazyBrowserNode = lazy(
208
+ () => import("@tutti-os/browser-node/react").then(({ BrowserNode }) => ({
209
+ default: BrowserNode
210
+ }))
211
+ );
212
+ var agentToolBrowserDefaultUrl = "https://www.google.com/";
213
+ function AgentToolBrowserPanel({
214
+ browserApi,
215
+ defaultUrl = agentToolBrowserDefaultUrl,
216
+ hidden,
217
+ i18n,
218
+ loadingFallback = null,
219
+ navigationActions,
220
+ nodeIdPrefix = "browser:agent-tool",
221
+ profileId = null,
222
+ sessionMode = "shared",
223
+ sessionPartition = null
224
+ }) {
225
+ const [nodeId] = useState(() => createAgentToolBrowserNodeId(nodeIdPrefix));
226
+ const feature = useMemo(
227
+ () => createAgentToolBrowserFeature({ browserApi, i18n, nodeId }),
228
+ [browserApi, i18n, nodeId]
229
+ );
230
+ return /* @__PURE__ */ jsx(
231
+ "div",
232
+ {
233
+ className: "relative h-full min-h-0 overflow-hidden",
234
+ "data-agent-tool-browser-surface": "true",
235
+ "data-agent-tool-browser-surface-id": nodeId,
236
+ children: /* @__PURE__ */ jsx(Suspense, { fallback: loadingFallback, children: /* @__PURE__ */ jsx(
237
+ LazyBrowserNode,
238
+ {
239
+ defaultUrl,
240
+ feature,
241
+ hidden,
242
+ navigationActions,
243
+ nodeId,
244
+ profileId,
245
+ sessionMode,
246
+ sessionPartition,
247
+ syncDefaultUrl: true,
248
+ tabs: true
249
+ }
250
+ ) })
251
+ }
252
+ );
253
+ }
254
+ function createAgentToolBrowserFeature(input) {
255
+ return createBrowserNodeFeature({
256
+ hostApi: createScopedAgentToolBrowserHostApi(
257
+ input.browserApi,
258
+ input.nodeId
259
+ ),
260
+ i18n: input.i18n,
261
+ resolveSearchUrl: resolveAgentToolBrowserSearchUrl
262
+ });
263
+ }
264
+ function createScopedAgentToolBrowserHostApi(browserApi, nodeId) {
265
+ return {
266
+ ...browserApi,
267
+ onEvent(listener) {
268
+ return browserApi.onEvent((event) => {
269
+ if (isBrowserNodeSurfaceEvent(nodeId, event)) {
270
+ listener(event);
271
+ }
272
+ });
273
+ }
274
+ };
275
+ }
276
+ function resolveAgentToolBrowserSearchUrl(query) {
277
+ const searchUrl = new URL("https://www.google.com/search");
278
+ searchUrl.searchParams.set("q", query);
279
+ return searchUrl.toString();
280
+ }
281
+ function createAgentToolBrowserNodeId(prefix) {
282
+ const instanceId = typeof globalThis.crypto?.randomUUID === "function" ? globalThis.crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
283
+ return `${prefix}:${instanceId}`;
284
+ }
285
+
286
+ // workbench/tool-sidebar/AgentToolSidebar.tsx
287
+ import {
288
+ forwardRef,
289
+ useImperativeHandle
290
+ } from "react";
291
+ import { CloseIcon, cn as cn2 } from "@tutti-os/ui-system";
292
+
293
+ // workbench/tool-sidebar/Picker.tsx
294
+ import { Button as Button2 } from "@tutti-os/ui-system";
295
+
296
+ // workbench/tool-sidebar/Toolbar.tsx
297
+ import {
298
+ AddLinedIcon,
299
+ Button,
300
+ ChatIcon,
301
+ cn,
302
+ DropdownMenu,
303
+ DropdownMenuContent,
304
+ DropdownMenuItem,
305
+ DropdownMenuTrigger,
306
+ FolderIcon,
307
+ MaximizeIcon,
308
+ NavApplicationsLinedIcon,
309
+ PanelIcon,
310
+ RestoreIcon,
311
+ TaskIcon,
312
+ TerminalLinedIcon,
313
+ Tooltip,
314
+ TooltipContent,
315
+ TooltipProvider,
316
+ TooltipTrigger,
317
+ WebIcon
318
+ } from "@tutti-os/ui-system";
319
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
320
+ var iconByPanel = {
321
+ apps: NavApplicationsLinedIcon,
322
+ browser: WebIcon,
323
+ files: FolderIcon,
324
+ messages: ChatIcon,
325
+ tasks: TaskIcon,
326
+ terminal: TerminalLinedIcon
327
+ };
328
+ function AgentToolPanelIcon({
329
+ panel,
330
+ ...iconProps
331
+ }) {
332
+ const Icon = iconByPanel[panel];
333
+ return /* @__PURE__ */ jsx2(Icon, { ...iconProps });
334
+ }
335
+ function AgentToolSidebarToolbar({
336
+ activePanel,
337
+ copy,
338
+ isExpanded,
339
+ isOpen,
340
+ panels,
341
+ quickActionPanels = [],
342
+ reminders = {},
343
+ onAddPanel,
344
+ onOpenPanel,
345
+ onToggleExpansion,
346
+ onToggleSidebar
347
+ }) {
348
+ const label = isOpen ? copy.closeRightPanel : copy.openRightPanel;
349
+ const labelByPanel = new Map(panels.map((panel) => [panel.id, panel.label]));
350
+ const quickActions = quickActionPanels.filter(
351
+ (panel) => labelByPanel.has(panel)
352
+ );
353
+ return /* @__PURE__ */ jsx2(TooltipProvider, { children: /* @__PURE__ */ jsxs(
354
+ "nav",
355
+ {
356
+ "aria-label": copy.tool,
357
+ className: cn(
358
+ "nodrag pointer-events-auto flex h-[var(--agent-gui-workbench-header-height,44px)] items-center gap-1 [-webkit-app-region:no-drag]",
359
+ activePanel === null && isOpen && "ml-auto"
360
+ ),
361
+ "data-standalone-agent-tool-sidebar-toolbar": "true",
362
+ onDoubleClick: (event) => event.stopPropagation(),
363
+ onPointerDown: (event) => event.stopPropagation(),
364
+ children: [
365
+ activePanel ? /* @__PURE__ */ jsxs(DropdownMenu, { modal: false, children: [
366
+ /* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx2(
367
+ Button,
368
+ {
369
+ "aria-label": copy.newTab,
370
+ className: "text-[var(--text-secondary)]",
371
+ size: "icon-sm",
372
+ type: "button",
373
+ variant: "chrome",
374
+ children: /* @__PURE__ */ jsx2(AddLinedIcon, { "aria-hidden": true, className: "size-4" })
375
+ }
376
+ ) }),
377
+ /* @__PURE__ */ jsx2(
378
+ DropdownMenuContent,
379
+ {
380
+ align: "end",
381
+ className: "min-w-36",
382
+ style: { zIndex: "var(--z-panel-popover)" },
383
+ children: panels.map((panel) => /* @__PURE__ */ jsxs(
384
+ DropdownMenuItem,
385
+ {
386
+ onSelect: () => onAddPanel(panel.id),
387
+ children: [
388
+ /* @__PURE__ */ jsx2(
389
+ AgentToolPanelIcon,
390
+ {
391
+ "aria-hidden": true,
392
+ className: "size-4",
393
+ panel: panel.id
394
+ }
395
+ ),
396
+ /* @__PURE__ */ jsx2("span", { children: panel.label })
397
+ ]
398
+ },
399
+ panel.id
400
+ ))
401
+ }
402
+ )
403
+ ] }) : null,
404
+ activePanel === null && !isOpen ? quickActions.map((panel) => /* @__PURE__ */ jsx2(
405
+ ToolbarQuickActionTooltip,
406
+ {
407
+ label: labelByPanel.get(panel) ?? panel,
408
+ children: /* @__PURE__ */ jsxs(
409
+ Button,
410
+ {
411
+ "aria-label": labelByPanel.get(panel) ?? panel,
412
+ "aria-pressed": false,
413
+ className: "relative text-[var(--text-secondary)]",
414
+ "data-standalone-agent-tool-sidebar-quick-action": panel,
415
+ size: "icon-sm",
416
+ type: "button",
417
+ variant: "chrome",
418
+ onClick: () => onOpenPanel(panel),
419
+ children: [
420
+ /* @__PURE__ */ jsx2(
421
+ AgentToolPanelIcon,
422
+ {
423
+ "aria-hidden": true,
424
+ className: "size-4",
425
+ panel
426
+ }
427
+ ),
428
+ /* @__PURE__ */ jsx2(ReminderBadge, { count: reminders[panel] })
429
+ ]
430
+ }
431
+ )
432
+ },
433
+ panel
434
+ )) : null,
435
+ activePanel ? /* @__PURE__ */ jsx2(
436
+ Button,
437
+ {
438
+ "aria-label": `${isExpanded ? copy.shrink : copy.expand} ${labelByPanel.get(activePanel) ?? activePanel}`,
439
+ "aria-pressed": isExpanded,
440
+ className: "text-[var(--text-secondary)]",
441
+ size: "icon-sm",
442
+ type: "button",
443
+ variant: "chrome",
444
+ onClick: onToggleExpansion,
445
+ children: isExpanded ? /* @__PURE__ */ jsx2(RestoreIcon, { "aria-hidden": true, className: "size-3.5" }) : /* @__PURE__ */ jsx2(MaximizeIcon, { "aria-hidden": true, className: "size-3.5" })
446
+ }
447
+ ) : null,
448
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
449
+ /* @__PURE__ */ jsx2(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx2(
450
+ Button,
451
+ {
452
+ "aria-label": label,
453
+ "aria-pressed": isOpen,
454
+ className: "relative",
455
+ "data-standalone-agent-tool-sidebar-toggle": "true",
456
+ size: "icon-sm",
457
+ type: "button",
458
+ variant: isOpen && activePanel !== null ? "secondary" : "chrome",
459
+ onClick: onToggleSidebar,
460
+ children: /* @__PURE__ */ jsx2(PanelIcon, { "aria-hidden": true, className: "size-[18px] -scale-x-100" })
461
+ }
462
+ ) }),
463
+ /* @__PURE__ */ jsx2(TooltipContent, { side: "bottom", children: label })
464
+ ] })
465
+ ]
466
+ }
467
+ ) });
468
+ }
469
+ function ToolbarQuickActionTooltip({
470
+ children,
471
+ label
472
+ }) {
473
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
474
+ /* @__PURE__ */ jsx2(TooltipTrigger, { asChild: true, children }),
475
+ /* @__PURE__ */ jsx2(TooltipContent, { side: "bottom", children: label })
476
+ ] });
477
+ }
478
+ function ReminderBadge({ count }) {
479
+ const label = formatAgentToolReminderCount(count);
480
+ return label ? /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 inline-flex min-w-4 items-center justify-center rounded-full bg-[var(--state-danger)] px-1 text-[9px] leading-4 font-semibold text-[var(--white-stationary)]", children: label }) : null;
481
+ }
482
+
483
+ // workbench/tool-sidebar/Picker.tsx
484
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
485
+ function AgentToolSidebarPicker({
486
+ panels,
487
+ onSelect
488
+ }) {
489
+ return /* @__PURE__ */ jsx3(
490
+ "div",
491
+ {
492
+ className: "flex h-full min-h-0 items-center justify-center overflow-auto px-6 py-10",
493
+ "data-standalone-agent-tool-sidebar-picker": "true",
494
+ children: /* @__PURE__ */ jsx3("div", { className: "flex w-full max-w-[340px] flex-col gap-2", children: panels.map((panel) => /* @__PURE__ */ jsxs2(
495
+ Button2,
496
+ {
497
+ className: "h-12 w-full justify-start gap-2.5 rounded-lg border border-[var(--line-1)] bg-[var(--background-fronted)] px-2.5 text-left text-[14px] font-medium text-[var(--text-primary)] shadow-none hover:border-[var(--line-2)] hover:bg-[var(--transparency-hover)]",
498
+ type: "button",
499
+ variant: "ghost",
500
+ onClick: () => onSelect(panel.id),
501
+ children: [
502
+ /* @__PURE__ */ jsx3("span", { className: "flex size-7 shrink-0 items-center justify-center rounded-[7px] bg-[var(--transparency-block)] text-[var(--text-secondary)] group-hover/button:text-[var(--text-primary)]", children: /* @__PURE__ */ jsx3(
503
+ AgentToolPanelIcon,
504
+ {
505
+ "aria-hidden": true,
506
+ className: "size-4",
507
+ panel: panel.id
508
+ }
509
+ ) }),
510
+ /* @__PURE__ */ jsx3("span", { children: panel.label })
511
+ ]
512
+ },
513
+ panel.id
514
+ )) })
515
+ }
516
+ );
517
+ }
518
+
519
+ // workbench/tool-sidebar/useAgentToolSidebarController.ts
520
+ import {
521
+ useCallback as useCallback2,
522
+ useReducer,
523
+ useRef as useRef2,
524
+ useState as useState3
525
+ } from "react";
526
+
527
+ // workbench/tool-sidebar/useAgentToolSidebarLayout.ts
528
+ import {
529
+ useCallback,
530
+ useRef,
531
+ useState as useState2
532
+ } from "react";
533
+ function useAgentToolSidebarLayout({
534
+ activePanel,
535
+ activePanelPreferredWidth,
536
+ containerWidth,
537
+ mainContentMinWidthPx,
538
+ resizeContainerContentWidth
539
+ }) {
540
+ const [containerResolution, setContainerResolution] = useState2(() => ({
541
+ resolved: containerWidth,
542
+ source: containerWidth
543
+ }));
544
+ if (containerResolution.source !== containerWidth) {
545
+ setContainerResolution({
546
+ resolved: containerWidth,
547
+ source: containerWidth
548
+ });
549
+ }
550
+ const resolvedContainerWidth = containerResolution.resolved;
551
+ const [panelWidths, setPanelWidths] = useState2(() => ({
552
+ ...agentToolPanelDefaultWidthById
553
+ }));
554
+ const [manuallyResizedWidth, setManuallyResizedWidth] = useState2(null);
555
+ const [expandedPanel, setExpandedPanel] = useState2(
556
+ null
557
+ );
558
+ const expandedPanelRef = useRef(null);
559
+ const baselineContainerWidthRef = useRef(null);
560
+ const panelWidthBeforeExpandRef = useRef({});
561
+ const resizeRequestRef = useRef(0);
562
+ const lastContainerResizeRef = useRef(null);
563
+ const dragRef = useRef(null);
564
+ const resizeStyleRef = useRef(
565
+ null
566
+ );
567
+ const isActivePanelExpanded = activePanel !== null && expandedPanel === activePanel;
568
+ const activePanelMaxWidth = activePanel ? resolveAgentToolPanelMaxWidth(
569
+ activePanel,
570
+ resolvedContainerWidth,
571
+ isActivePanelExpanded,
572
+ mainContentMinWidthPx
573
+ ) : 0;
574
+ const activePanelMinWidth = activePanel ? Math.min(agentToolPanelMinWidthById[activePanel], activePanelMaxWidth) : 0;
575
+ const activePanelWidth = activePanel ? resolveActivePanelWidth({
576
+ activePanel,
577
+ activePanelMaxWidth,
578
+ activePanelPreferredWidth,
579
+ baselineContainerWidth: baselineContainerWidthRef.current ?? resolvedContainerWidth,
580
+ containerWidth: resolvedContainerWidth,
581
+ isActivePanelExpanded,
582
+ mainContentMinWidthPx,
583
+ panelWidth: resolveAgentToolPanelPreferredWidth({
584
+ isExpanded: isActivePanelExpanded,
585
+ manuallyResizedWidth,
586
+ panelWidth: panelWidths[activePanel]
587
+ })
588
+ }) : 0;
589
+ const activePanelLayoutWidth = activePanel ? resolveAgentToolSidebarLayoutWidth({
590
+ baselineContainerWidth: baselineContainerWidthRef.current ?? resolvedContainerWidth,
591
+ containerWidth: resolvedContainerWidth,
592
+ panelWidth: activePanelWidth
593
+ }) : 0;
594
+ const resetPanelExpansion = useCallback(
595
+ (nextPanel) => {
596
+ const reset = resolveAgentToolPanelExpansionReset({
597
+ expandedPanel: expandedPanelRef.current,
598
+ nextPanel,
599
+ widthBeforeExpansion: expandedPanelRef.current === null ? void 0 : panelWidthBeforeExpandRef.current[expandedPanelRef.current]
600
+ });
601
+ if (!reset) return null;
602
+ if (nextPanel !== null) {
603
+ const transfer = resolveAgentToolPanelExpansionTransfer({
604
+ expandedPanel: expandedPanelRef.current,
605
+ nextPanel,
606
+ nextPanelWidth: resolveAgentToolPanelPreferredWidth({
607
+ isExpanded: false,
608
+ manuallyResizedWidth,
609
+ panelWidth: panelWidths[nextPanel]
610
+ }),
611
+ widthBeforeExpansion: panelWidthBeforeExpandRef.current[expandedPanelRef.current] ?? manuallyResizedWidth ?? void 0
612
+ });
613
+ if (!transfer) return null;
614
+ expandedPanelRef.current = transfer.expandedPanel;
615
+ setExpandedPanel(transfer.expandedPanel);
616
+ setPanelWidths((current) => ({
617
+ ...current,
618
+ [transfer.previousPanel]: transfer.previousPanelWidth,
619
+ [transfer.expandedPanel]: Number.MAX_SAFE_INTEGER
620
+ }));
621
+ panelWidthBeforeExpandRef.current[transfer.expandedPanel] = transfer.nextPanelWidthBeforeExpansion;
622
+ delete panelWidthBeforeExpandRef.current[transfer.previousPanel];
623
+ return "transferred";
624
+ }
625
+ expandedPanelRef.current = null;
626
+ setExpandedPanel(null);
627
+ setPanelWidths((current) => ({ ...current, [reset.panel]: reset.width }));
628
+ delete panelWidthBeforeExpandRef.current[reset.panel];
629
+ return "reset";
630
+ },
631
+ [manuallyResizedWidth, panelWidths]
632
+ );
633
+ const resizeForPanel = useCallback(
634
+ async (nextPanel, preferredWidth, options) => {
635
+ const requestId = ++resizeRequestRef.current;
636
+ const expansionTransition = resetPanelExpansion(nextPanel);
637
+ if (expansionTransition === "transferred" || nextPanel !== null && expandedPanelRef.current === nextPanel) {
638
+ return true;
639
+ }
640
+ if (nextPanel !== null && baselineContainerWidthRef.current === null) {
641
+ baselineContainerWidthRef.current = resolvedContainerWidth;
642
+ }
643
+ const baseline = baselineContainerWidthRef.current;
644
+ const requestedWidth = nextPanel === null ? baseline : (baseline ?? resolvedContainerWidth) + resolvePreferredWidth(
645
+ preferredWidth,
646
+ resolveAgentToolPanelPreferredWidth({
647
+ isExpanded: expandedPanelRef.current === nextPanel,
648
+ manuallyResizedWidth,
649
+ panelWidth: panelWidths[nextPanel]
650
+ })
651
+ );
652
+ if (requestedWidth !== null && shouldResizeAgentToolContainer({
653
+ currentWidth: resolvedContainerWidth,
654
+ lastResize: lastContainerResizeRef.current,
655
+ requestedWidth
656
+ })) {
657
+ try {
658
+ const result = await resizeContainerContentWidth(
659
+ requestedWidth,
660
+ options?.animateContainer
661
+ );
662
+ if (requestId !== resizeRequestRef.current) return false;
663
+ if (result.width > 0) {
664
+ lastContainerResizeRef.current = {
665
+ actualWidth: result.width,
666
+ requestedWidth
667
+ };
668
+ setContainerResolution((current) => ({
669
+ ...current,
670
+ resolved: result.width
671
+ }));
672
+ }
673
+ } catch {
674
+ if (requestId !== resizeRequestRef.current) return false;
675
+ }
676
+ }
677
+ if (nextPanel === null && options?.preserveBaseline !== true) {
678
+ baselineContainerWidthRef.current = null;
679
+ }
680
+ return true;
681
+ },
682
+ [
683
+ manuallyResizedWidth,
684
+ panelWidths,
685
+ resetPanelExpansion,
686
+ resizeContainerContentWidth,
687
+ resolvedContainerWidth
688
+ ]
689
+ );
690
+ const resetContainerResizeBaseline = useCallback(() => {
691
+ baselineContainerWidthRef.current = null;
692
+ }, []);
693
+ const updatePanelWidth = useCallback(
694
+ (panel, width) => {
695
+ const nextWidth = clampAgentToolPanelWidth({
696
+ allowFullWidth: expandedPanel === panel,
697
+ mainContentMinWidth: mainContentMinWidthPx,
698
+ panel,
699
+ viewportWidth: resolvedContainerWidth,
700
+ width
701
+ });
702
+ setManuallyResizedWidth(nextWidth);
703
+ setPanelWidths((current) => ({ ...current, [panel]: nextWidth }));
704
+ },
705
+ [expandedPanel, mainContentMinWidthPx, resolvedContainerWidth]
706
+ );
707
+ const togglePanelExpansion = useCallback(
708
+ (panel) => {
709
+ if (expandedPanelRef.current === panel) {
710
+ resetPanelExpansion(null);
711
+ return;
712
+ }
713
+ resetPanelExpansion(panel);
714
+ expandedPanelRef.current = panel;
715
+ setExpandedPanel(panel);
716
+ setPanelWidths((current) => {
717
+ panelWidthBeforeExpandRef.current[panel] = resolveAgentToolPanelPreferredWidth({
718
+ isExpanded: false,
719
+ manuallyResizedWidth,
720
+ panelWidth: current[panel]
721
+ });
722
+ return { ...current, [panel]: Number.MAX_SAFE_INTEGER };
723
+ });
724
+ },
725
+ [manuallyResizedWidth, resetPanelExpansion]
726
+ );
727
+ const stopResizing = useCallback(() => {
728
+ dragRef.current = null;
729
+ const styles = resizeStyleRef.current;
730
+ if (!styles) return;
731
+ document.body.style.cursor = styles.cursor;
732
+ document.body.style.userSelect = styles.userSelect;
733
+ resizeStyleRef.current = null;
734
+ }, []);
735
+ const bindLayoutRoot = useCallback(
736
+ (node) => {
737
+ if (!node) stopResizing();
738
+ },
739
+ [stopResizing]
740
+ );
741
+ const handleResizePointerDown = useCallback(
742
+ (event) => {
743
+ if (event.button !== 0 || activePanel === null) return;
744
+ event.preventDefault();
745
+ event.currentTarget.setPointerCapture(event.pointerId);
746
+ dragRef.current = {
747
+ panel: activePanel,
748
+ pointerId: event.pointerId,
749
+ startClientX: event.clientX,
750
+ startWidth: activePanelWidth
751
+ };
752
+ resizeStyleRef.current = {
753
+ cursor: document.body.style.cursor,
754
+ userSelect: document.body.style.userSelect
755
+ };
756
+ document.body.style.cursor = "col-resize";
757
+ document.body.style.userSelect = "none";
758
+ },
759
+ [activePanel, activePanelWidth]
760
+ );
761
+ const handleResizePointerMove = useCallback(
762
+ (event) => {
763
+ const resizeState = dragRef.current;
764
+ if (!resizeState || resizeState.pointerId !== event.pointerId) return;
765
+ updatePanelWidth(
766
+ resizeState.panel,
767
+ resizeState.startWidth + resizeState.startClientX - event.clientX
768
+ );
769
+ },
770
+ [updatePanelWidth]
771
+ );
772
+ const handleResizeKeyDown = useCallback(
773
+ (event) => {
774
+ if (activePanel === null) return;
775
+ if (event.key === "Home") {
776
+ event.preventDefault();
777
+ updatePanelWidth(activePanel, activePanelMinWidth);
778
+ } else if (event.key === "End") {
779
+ event.preventDefault();
780
+ updatePanelWidth(activePanel, Number.MAX_SAFE_INTEGER);
781
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
782
+ event.preventDefault();
783
+ updatePanelWidth(
784
+ activePanel,
785
+ activePanelWidth + (event.key === "ArrowLeft" ? 24 : -24)
786
+ );
787
+ }
788
+ },
789
+ [activePanel, activePanelMinWidth, activePanelWidth, updatePanelWidth]
790
+ );
791
+ return {
792
+ activePanelLayoutWidth,
793
+ activePanelMaxWidth,
794
+ activePanelMinWidth,
795
+ activePanelWidth,
796
+ bindLayoutRoot,
797
+ handleResizeKeyDown,
798
+ handleResizePointerDown,
799
+ handleResizePointerMove,
800
+ isActivePanelExpanded,
801
+ resetContainerResizeBaseline,
802
+ resizeForPanel,
803
+ stopResizing,
804
+ togglePanelExpansion
805
+ };
806
+ }
807
+ function resolveActivePanelWidth(input) {
808
+ if (typeof input.activePanelPreferredWidth === "number" && Number.isFinite(input.activePanelPreferredWidth)) {
809
+ return Math.round(
810
+ Math.max(
811
+ 0,
812
+ Math.min(input.activePanelMaxWidth, input.activePanelPreferredWidth)
813
+ )
814
+ );
815
+ }
816
+ return resolveAgentToolSidebarWidth({
817
+ allowFullWidth: input.isActivePanelExpanded,
818
+ baselineViewportWidth: input.baselineContainerWidth,
819
+ mainContentMinWidth: input.mainContentMinWidthPx,
820
+ panel: input.activePanel,
821
+ preferredWidth: input.panelWidth,
822
+ viewportWidth: input.containerWidth
823
+ });
824
+ }
825
+ function resolvePreferredWidth(preferredWidth, fallbackWidth) {
826
+ return typeof preferredWidth === "number" && Number.isFinite(preferredWidth) ? Math.max(0, Math.round(preferredWidth)) : fallbackWidth;
827
+ }
828
+
829
+ // workbench/tool-sidebar/useAgentToolSidebarController.ts
830
+ var collapsedToolActionsWidthPx = 132;
831
+ function useAgentToolSidebarController({
832
+ containerWidth,
833
+ mainContentMinWidthPx,
834
+ panels,
835
+ resizeContainerContentWidth,
836
+ onActivePanelChange,
837
+ onLayoutWidthChange,
838
+ onPanelOpen,
839
+ onTabsChange,
840
+ onTabClose
841
+ }) {
842
+ const panelIds = new Set(panels.map((panel) => panel.id));
843
+ const [state, dispatch] = useReducer(
844
+ reduceAgentToolSidebarState,
845
+ void 0,
846
+ createAgentToolSidebarState
847
+ );
848
+ const [isSidebarOpen, setIsSidebarOpen] = useState3(false);
849
+ const [isEmptySidebarClosing, setIsEmptySidebarClosing] = useState3(false);
850
+ const [contentReadyTabIds, setContentReadyTabIds] = useState3([]);
851
+ const [toolActionsWidth, setToolActionsWidth] = useState3(
852
+ collapsedToolActionsWidthPx
853
+ );
854
+ const activePanel = state.activePanel;
855
+ const activeTabId = state.activeTabId;
856
+ const fallbackPanel = panels[0]?.id ?? null;
857
+ const isEmptySidebar = isSidebarOpen && state.mountedTabs.length === 0;
858
+ const isEmptySidebarSurface = (isSidebarOpen || isEmptySidebarClosing) && state.mountedTabs.length === 0;
859
+ const layoutPanel = activePanel ?? (isEmptySidebarSurface ? fallbackPanel : null);
860
+ const isActivePanelContentReady = activeTabId !== null && contentReadyTabIds.includes(activeTabId);
861
+ const shouldAnimateSidebarLayout = state.mountedTabs.length === 0 || isActivePanelContentReady;
862
+ const shouldAnimateSidebarWidth = isEmptySidebarSurface;
863
+ const layout = useAgentToolSidebarLayout({
864
+ activePanel: layoutPanel,
865
+ activePanelPreferredWidth: isEmptySidebarSurface ? agentToolEmptySidebarWidth : void 0,
866
+ containerWidth,
867
+ mainContentMinWidthPx,
868
+ resizeContainerContentWidth
869
+ });
870
+ const resizeAnimationFrameRef = useRef2(null);
871
+ const contentAnimationFrameIdsRef = useRef2(/* @__PURE__ */ new Set());
872
+ const toolActionsResizeObserverRef = useRef2(null);
873
+ const scheduleResizeForPanel = useCallback2(
874
+ (panel, preferredWidth, options) => {
875
+ if (resizeAnimationFrameRef.current !== null) {
876
+ window.cancelAnimationFrame(resizeAnimationFrameRef.current);
877
+ }
878
+ resizeAnimationFrameRef.current = window.requestAnimationFrame(() => {
879
+ resizeAnimationFrameRef.current = null;
880
+ void layout.resizeForPanel(panel, preferredWidth, options);
881
+ });
882
+ },
883
+ [layout.resizeForPanel]
884
+ );
885
+ const showSidebar = useCallback2(() => {
886
+ setIsEmptySidebarClosing(false);
887
+ setIsSidebarOpen(true);
888
+ }, []);
889
+ const markContentReady = useCallback2((tabId) => {
890
+ if (prefersReducedMotion()) {
891
+ setContentReadyTabIds(
892
+ (current) => current.includes(tabId) ? current : [...current, tabId]
893
+ );
894
+ return;
895
+ }
896
+ let completedSynchronously = false;
897
+ let frameId = 0;
898
+ frameId = window.requestAnimationFrame(() => {
899
+ completedSynchronously = true;
900
+ contentAnimationFrameIdsRef.current.delete(frameId);
901
+ setContentReadyTabIds(
902
+ (current) => current.includes(tabId) ? current : [...current, tabId]
903
+ );
904
+ });
905
+ if (!completedSynchronously) {
906
+ contentAnimationFrameIdsRef.current.add(frameId);
907
+ }
908
+ }, []);
909
+ const closePanel = useCallback2(() => {
910
+ setIsSidebarOpen(false);
911
+ dispatch({ type: "close" });
912
+ onActivePanelChange?.(null);
913
+ if (state.mountedTabs.length > 0 || prefersReducedMotion()) {
914
+ setIsEmptySidebarClosing(false);
915
+ scheduleResizeForPanel(null);
916
+ return;
917
+ }
918
+ setIsEmptySidebarClosing(true);
919
+ scheduleResizeForPanel(null, void 0, {
920
+ animateContainer: true,
921
+ preserveBaseline: true
922
+ });
923
+ }, [onActivePanelChange, scheduleResizeForPanel, state.mountedTabs.length]);
924
+ const openPanel = useCallback2(
925
+ (panel, resourceId) => {
926
+ if (!panelIds.has(panel)) return null;
927
+ showSidebar();
928
+ onPanelOpen?.(panel, resourceId);
929
+ const tabId = resolveToolTabId(state.mountedTabs, panel, resourceId);
930
+ const action = { panel, resourceId, tabId, type: "open-panel" };
931
+ const nextState = reduceAgentToolSidebarState(state, action);
932
+ dispatch(action);
933
+ onActivePanelChange?.(panel);
934
+ if (nextState.mountedTabs !== state.mountedTabs) {
935
+ onTabsChange?.(nextState.mountedTabs);
936
+ }
937
+ markContentReady(tabId);
938
+ scheduleResizeForPanel(panel);
939
+ return tabId;
940
+ },
941
+ [
942
+ markContentReady,
943
+ onActivePanelChange,
944
+ onPanelOpen,
945
+ onTabsChange,
946
+ panelIds,
947
+ scheduleResizeForPanel,
948
+ showSidebar,
949
+ state
950
+ ]
951
+ );
952
+ const addPanel = useCallback2(
953
+ (panel, resourceId) => {
954
+ if (!panelIds.has(panel)) return null;
955
+ showSidebar();
956
+ onPanelOpen?.(panel, resourceId);
957
+ const tabId = createToolTabId(panel);
958
+ const action = { panel, resourceId, tabId, type: "add-panel" };
959
+ const nextState = reduceAgentToolSidebarState(state, action);
960
+ dispatch(action);
961
+ onActivePanelChange?.(panel);
962
+ onTabsChange?.(nextState.mountedTabs);
963
+ markContentReady(tabId);
964
+ scheduleResizeForPanel(panel);
965
+ return tabId;
966
+ },
967
+ [
968
+ markContentReady,
969
+ onActivePanelChange,
970
+ onPanelOpen,
971
+ onTabsChange,
972
+ panelIds,
973
+ scheduleResizeForPanel,
974
+ showSidebar,
975
+ state
976
+ ]
977
+ );
978
+ const closePanelTab = useCallback2(
979
+ (tabId) => {
980
+ const closingIndex = state.mountedTabs.findIndex(
981
+ (tab) => tab.id === tabId
982
+ );
983
+ const closingTab = state.mountedTabs[closingIndex];
984
+ if (!closingTab) return;
985
+ const action = { tabId, type: "close-tab" };
986
+ const nextState = reduceAgentToolSidebarState(state, action);
987
+ setIsSidebarOpen(true);
988
+ dispatch(action);
989
+ onTabClose?.(closingTab);
990
+ onActivePanelChange?.(nextState.activePanel);
991
+ onTabsChange?.(nextState.mountedTabs);
992
+ if (nextState.activePanel === null) {
993
+ if (fallbackPanel) {
994
+ scheduleResizeForPanel(fallbackPanel, agentToolEmptySidebarWidth, {
995
+ animateContainer: !prefersReducedMotion()
996
+ });
997
+ }
998
+ return;
999
+ }
1000
+ scheduleResizeForPanel(nextState.activePanel);
1001
+ },
1002
+ [
1003
+ fallbackPanel,
1004
+ onActivePanelChange,
1005
+ onTabClose,
1006
+ onTabsChange,
1007
+ scheduleResizeForPanel,
1008
+ state
1009
+ ]
1010
+ );
1011
+ const activatePanelTab = useCallback2(
1012
+ (tab) => {
1013
+ onPanelOpen?.(tab.panel, tab.resourceId);
1014
+ dispatch({ tabId: tab.id, type: "activate-tab" });
1015
+ onActivePanelChange?.(tab.panel);
1016
+ markContentReady(tab.id);
1017
+ scheduleResizeForPanel(tab.panel);
1018
+ },
1019
+ [markContentReady, onActivePanelChange, onPanelOpen, scheduleResizeForPanel]
1020
+ );
1021
+ const toggleSidebar = useCallback2(() => {
1022
+ const nextPanel = activePanel ?? fallbackPanel;
1023
+ if (isSidebarOpen) {
1024
+ closePanel();
1025
+ return;
1026
+ }
1027
+ if (!nextPanel) return;
1028
+ showSidebar();
1029
+ if (state.mountedTabs.length === 0) {
1030
+ scheduleResizeForPanel(nextPanel, agentToolEmptySidebarWidth, {
1031
+ animateContainer: !prefersReducedMotion()
1032
+ });
1033
+ return;
1034
+ }
1035
+ const tabId = resolveToolTabId(state.mountedTabs, nextPanel);
1036
+ dispatch({ panel: nextPanel, tabId, type: "open-panel" });
1037
+ onActivePanelChange?.(nextPanel);
1038
+ markContentReady(tabId);
1039
+ scheduleResizeForPanel(nextPanel);
1040
+ }, [
1041
+ activePanel,
1042
+ closePanel,
1043
+ fallbackPanel,
1044
+ isSidebarOpen,
1045
+ markContentReady,
1046
+ onActivePanelChange,
1047
+ scheduleResizeForPanel,
1048
+ showSidebar,
1049
+ state.mountedTabs
1050
+ ]);
1051
+ const handleSidebarTransitionEnd = useCallback2(
1052
+ (event) => {
1053
+ if (event.currentTarget !== event.target || event.propertyName !== "width" || isSidebarOpen || !isEmptySidebarClosing) {
1054
+ return;
1055
+ }
1056
+ setIsEmptySidebarClosing(false);
1057
+ layout.resetContainerResizeBaseline();
1058
+ },
1059
+ [isEmptySidebarClosing, isSidebarOpen, layout.resetContainerResizeBaseline]
1060
+ );
1061
+ const bindLayoutWidthProjection = useCallback2(
1062
+ (node) => {
1063
+ if (node) {
1064
+ onLayoutWidthChange?.(
1065
+ isSidebarOpen ? layout.activePanelLayoutWidth : 0
1066
+ );
1067
+ }
1068
+ },
1069
+ [isSidebarOpen, layout.activePanelLayoutWidth, onLayoutWidthChange]
1070
+ );
1071
+ const bindLifecycle = useCallback2(
1072
+ (node) => {
1073
+ if (node) return;
1074
+ if (resizeAnimationFrameRef.current !== null) {
1075
+ window.cancelAnimationFrame(resizeAnimationFrameRef.current);
1076
+ resizeAnimationFrameRef.current = null;
1077
+ }
1078
+ for (const frameId of contentAnimationFrameIdsRef.current) {
1079
+ window.cancelAnimationFrame(frameId);
1080
+ }
1081
+ contentAnimationFrameIdsRef.current.clear();
1082
+ toolActionsResizeObserverRef.current?.disconnect();
1083
+ toolActionsResizeObserverRef.current = null;
1084
+ layout.bindLayoutRoot(null);
1085
+ },
1086
+ [layout.bindLayoutRoot]
1087
+ );
1088
+ const measureToolActions = useCallback2((node) => {
1089
+ toolActionsResizeObserverRef.current?.disconnect();
1090
+ toolActionsResizeObserverRef.current = null;
1091
+ if (!node) return;
1092
+ const measure = () => {
1093
+ const width = Math.ceil(node.getBoundingClientRect().width);
1094
+ if (width > 0) setToolActionsWidth(width);
1095
+ };
1096
+ measure();
1097
+ if (typeof ResizeObserver === "undefined") return;
1098
+ const observer = new ResizeObserver(measure);
1099
+ observer.observe(node);
1100
+ toolActionsResizeObserverRef.current = observer;
1101
+ }, []);
1102
+ return {
1103
+ ...layout,
1104
+ activePanel,
1105
+ activeTabId,
1106
+ activatePanelTab,
1107
+ addPanel,
1108
+ bindLayoutWidthProjection,
1109
+ bindLifecycle,
1110
+ closePanel,
1111
+ closePanelTab,
1112
+ contentReadyTabIds,
1113
+ handleSidebarTransitionEnd,
1114
+ isEmptySidebar,
1115
+ isEmptySidebarClosing,
1116
+ isSidebarOpen,
1117
+ markContentReady,
1118
+ measureToolActions,
1119
+ mountedTabs: state.mountedTabs,
1120
+ openPanel,
1121
+ shouldAnimateSidebarLayout,
1122
+ shouldAnimateSidebarWidth,
1123
+ toolActionsWidth,
1124
+ toggleSidebar
1125
+ };
1126
+ }
1127
+ function resolveToolTabId(tabs, panel, resourceId) {
1128
+ for (let index = tabs.length - 1; index >= 0; index -= 1) {
1129
+ const tab = tabs[index];
1130
+ if (tab?.panel === panel && (resourceId === void 0 || tab.resourceId === resourceId)) {
1131
+ return tab.id;
1132
+ }
1133
+ }
1134
+ return createToolTabId(panel);
1135
+ }
1136
+ function createToolTabId(panel) {
1137
+ const instanceId = typeof globalThis.crypto?.randomUUID === "function" ? globalThis.crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
1138
+ return `${panel}:${instanceId}`;
1139
+ }
1140
+ function prefersReducedMotion() {
1141
+ return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
1142
+ }
1143
+
1144
+ // workbench/tool-sidebar/AgentToolSidebar.tsx
1145
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1146
+ var AgentToolSidebar = forwardRef(function AgentToolSidebar2({
1147
+ children,
1148
+ containerWidth,
1149
+ copy,
1150
+ headerPlacement = "inline",
1151
+ mainContentMinWidthPx,
1152
+ panels: unfilteredPanels,
1153
+ quickActionPanels,
1154
+ reminders,
1155
+ renderHeader,
1156
+ renderLoading,
1157
+ renderPanel,
1158
+ renderTabIcon,
1159
+ resolveTabLabel,
1160
+ resizeContainerContentWidth,
1161
+ onActivePanelChange,
1162
+ onLayoutWidthChange,
1163
+ onPanelOpen,
1164
+ onTabsChange,
1165
+ onTabClose
1166
+ }, ref) {
1167
+ const panels = filterAgentToolPanels(unfilteredPanels);
1168
+ const labelByPanel = new Map(panels.map((panel) => [panel.id, panel.label]));
1169
+ const {
1170
+ activePanelLayoutWidth,
1171
+ activePanelMaxWidth,
1172
+ activePanelMinWidth,
1173
+ activePanelWidth,
1174
+ handleResizeKeyDown,
1175
+ handleResizePointerDown,
1176
+ handleResizePointerMove,
1177
+ isActivePanelExpanded,
1178
+ activePanel,
1179
+ activeTabId,
1180
+ activatePanelTab,
1181
+ addPanel,
1182
+ bindLayoutWidthProjection,
1183
+ bindLifecycle,
1184
+ closePanel,
1185
+ closePanelTab,
1186
+ contentReadyTabIds,
1187
+ handleSidebarTransitionEnd,
1188
+ isEmptySidebar,
1189
+ isEmptySidebarClosing,
1190
+ isSidebarOpen,
1191
+ measureToolActions,
1192
+ mountedTabs,
1193
+ openPanel,
1194
+ shouldAnimateSidebarLayout,
1195
+ shouldAnimateSidebarWidth,
1196
+ stopResizing,
1197
+ toolActionsWidth,
1198
+ toggleSidebar,
1199
+ togglePanelExpansion
1200
+ } = useAgentToolSidebarController({
1201
+ containerWidth,
1202
+ mainContentMinWidthPx,
1203
+ onActivePanelChange,
1204
+ onLayoutWidthChange,
1205
+ onPanelOpen,
1206
+ onTabClose,
1207
+ onTabsChange,
1208
+ panels,
1209
+ resizeContainerContentWidth
1210
+ });
1211
+ useImperativeHandle(
1212
+ ref,
1213
+ () => ({
1214
+ addPanel,
1215
+ close: closePanel,
1216
+ closeTab: closePanelTab,
1217
+ openPanel
1218
+ }),
1219
+ [addPanel, closePanel, closePanelTab, openPanel]
1220
+ );
1221
+ const toolActions = /* @__PURE__ */ jsxs3(
1222
+ "div",
1223
+ {
1224
+ className: cn2(
1225
+ "flex h-[var(--agent-gui-workbench-header-height,44px)] min-w-0 max-w-full shrink-0 cursor-grab items-center pr-[var(--agent-gui-workbench-header-padding-x)] active:cursor-grabbing [-webkit-app-region:drag]",
1226
+ isSidebarOpen && "border-b border-[var(--border-1)]"
1227
+ ),
1228
+ "data-standalone-agent-tool-sidebar-drag-region": "true",
1229
+ "data-standalone-agent-tool-sidebar-header": "true",
1230
+ ref: measureToolActions,
1231
+ style: isSidebarOpen ? { width: `${activePanelWidth}px`, maxWidth: "100%" } : void 0,
1232
+ children: [
1233
+ activeTabId ? /* @__PURE__ */ jsx4(
1234
+ ToolSidebarTabBar,
1235
+ {
1236
+ activeTabId,
1237
+ copy,
1238
+ labelByPanel,
1239
+ mountedTabs,
1240
+ renderTabIcon,
1241
+ resolveTabLabel,
1242
+ onClosePanel: closePanelTab,
1243
+ onOpenPanel: activatePanelTab
1244
+ }
1245
+ ) : null,
1246
+ /* @__PURE__ */ jsx4(
1247
+ AgentToolSidebarToolbar,
1248
+ {
1249
+ activePanel,
1250
+ copy,
1251
+ isExpanded: isActivePanelExpanded,
1252
+ isOpen: isSidebarOpen,
1253
+ panels,
1254
+ quickActionPanels,
1255
+ reminders,
1256
+ onAddPanel: addPanel,
1257
+ onOpenPanel: openPanel,
1258
+ onToggleExpansion: () => {
1259
+ if (activePanel) togglePanelExpansion(activePanel);
1260
+ },
1261
+ onToggleSidebar: toggleSidebar
1262
+ }
1263
+ )
1264
+ ]
1265
+ }
1266
+ );
1267
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
1268
+ headerPlacement === "external" || headerPlacement === "panel" ? renderHeader(
1269
+ headerPlacement === "panel" && isSidebarOpen ? null : toolActions
1270
+ ) : /* @__PURE__ */ jsx4(
1271
+ "div",
1272
+ {
1273
+ className: "workbench-window__header workbench-window__header--custom",
1274
+ style: {
1275
+ "--agent-gui-tool-sidebar-layout-width": isSidebarOpen ? `${activePanelLayoutWidth}px` : `${toolActionsWidth}px`
1276
+ },
1277
+ children: renderHeader(toolActions)
1278
+ }
1279
+ ),
1280
+ /* @__PURE__ */ jsx4(
1281
+ "div",
1282
+ {
1283
+ className: cn2(
1284
+ "flex h-full min-h-0 min-w-0 flex-col overflow-hidden",
1285
+ headerPlacement === "inline" && "workbench-window__body"
1286
+ ),
1287
+ ref: bindLifecycle,
1288
+ children: /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 min-w-0 flex-1 overflow-hidden", children: [
1289
+ /* @__PURE__ */ jsx4("div", { className: "h-full min-w-0 flex-1 overflow-hidden", children }),
1290
+ /* @__PURE__ */ jsx4(
1291
+ "aside",
1292
+ {
1293
+ "aria-hidden": !isSidebarOpen,
1294
+ className: cn2(
1295
+ "relative h-full min-h-0 shrink-0 overflow-hidden [contain:layout_paint]",
1296
+ shouldAnimateSidebarWidth && "motion-safe:transition-[width] motion-safe:duration-[260ms] motion-safe:ease-in-out motion-reduce:transition-none",
1297
+ isActivePanelExpanded && "border-l border-[var(--line-1)]",
1298
+ !isSidebarOpen && "pointer-events-none"
1299
+ ),
1300
+ "data-standalone-agent-tool-sidebar": "true",
1301
+ ref: bindLayoutWidthProjection,
1302
+ style: {
1303
+ width: isSidebarOpen ? `${activePanelLayoutWidth}px` : "0px",
1304
+ zIndex: "var(--z-panel)"
1305
+ },
1306
+ onTransitionEnd: handleSidebarTransitionEnd,
1307
+ children: /* @__PURE__ */ jsxs3(
1308
+ "div",
1309
+ {
1310
+ className: cn2(
1311
+ "absolute inset-y-0 right-0 flex flex-col bg-[var(--background-session-sidepanel)]",
1312
+ isSidebarOpen && !shouldAnimateSidebarLayout && "motion-safe:animate-in motion-safe:slide-in-from-right-3 motion-safe:duration-[160ms] motion-safe:ease-out motion-reduce:animate-none",
1313
+ !isSidebarOpen && !isEmptySidebarClosing && "invisible"
1314
+ ),
1315
+ style: {
1316
+ "--background-panel": "var(--background-session-sidepanel)",
1317
+ width: `${activePanelWidth}px`
1318
+ },
1319
+ children: [
1320
+ isSidebarOpen && !isEmptySidebar ? /* @__PURE__ */ jsx4(
1321
+ "div",
1322
+ {
1323
+ "aria-label": copy.resizeSidebar,
1324
+ "aria-orientation": "vertical",
1325
+ "aria-valuemax": activePanelMaxWidth,
1326
+ "aria-valuemin": activePanelMinWidth,
1327
+ "aria-valuenow": activePanelWidth,
1328
+ className: "absolute top-0 left-0 z-20 h-full w-2 cursor-col-resize touch-none outline-none before:absolute before:left-0 before:h-full before:w-px before:bg-transparent hover:before:bg-[var(--border-focus)] focus-visible:before:bg-[var(--border-focus)]",
1329
+ "data-standalone-agent-tool-sidebar-resize-handle": "true",
1330
+ role: "separator",
1331
+ tabIndex: 0,
1332
+ onKeyDown: handleResizeKeyDown,
1333
+ onLostPointerCapture: stopResizing,
1334
+ onPointerDown: handleResizePointerDown,
1335
+ onPointerMove: handleResizePointerMove,
1336
+ onPointerUp: stopResizing
1337
+ }
1338
+ ) : null,
1339
+ isSidebarOpen && headerPlacement === "panel" ? toolActions : null,
1340
+ isSidebarOpen && headerPlacement === "inline" ? /* @__PURE__ */ jsx4(
1341
+ "div",
1342
+ {
1343
+ "aria-hidden": true,
1344
+ className: "shrink-0",
1345
+ "data-standalone-agent-tool-sidebar-header-spacer": "true",
1346
+ style: {
1347
+ height: "var(--agent-gui-workbench-header-height, 44px)"
1348
+ }
1349
+ }
1350
+ ) : null,
1351
+ /* @__PURE__ */ jsxs3("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
1352
+ isEmptySidebar || isEmptySidebarClosing ? /* @__PURE__ */ jsx4(
1353
+ AgentToolSidebarPicker,
1354
+ {
1355
+ panels,
1356
+ onSelect: openPanel
1357
+ }
1358
+ ) : null,
1359
+ mountedTabs.map((tab) => /* @__PURE__ */ jsx4(
1360
+ "div",
1361
+ {
1362
+ "aria-hidden": activeTabId !== tab.id,
1363
+ className: cn2(
1364
+ "absolute inset-0 min-h-0 overflow-hidden",
1365
+ activeTabId !== tab.id && "invisible pointer-events-none"
1366
+ ),
1367
+ children: contentReadyTabIds.includes(tab.id) ? /* @__PURE__ */ jsx4(
1368
+ "div",
1369
+ {
1370
+ className: cn2(
1371
+ "h-full min-h-0",
1372
+ tab.panel !== "terminal" && "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-150 motion-reduce:animate-none"
1373
+ ),
1374
+ children: renderPanel({
1375
+ active: activeTabId === tab.id,
1376
+ closeSidebar: closePanel,
1377
+ tab
1378
+ })
1379
+ }
1380
+ ) : activeTabId === tab.id ? renderLoading?.(tab) ?? null : null
1381
+ },
1382
+ tab.id
1383
+ ))
1384
+ ] })
1385
+ ]
1386
+ }
1387
+ )
1388
+ }
1389
+ )
1390
+ ] })
1391
+ }
1392
+ )
1393
+ ] });
1394
+ });
1395
+ function ToolSidebarTabBar({
1396
+ activeTabId,
1397
+ copy,
1398
+ labelByPanel,
1399
+ mountedTabs,
1400
+ renderTabIcon,
1401
+ resolveTabLabel,
1402
+ onClosePanel,
1403
+ onOpenPanel
1404
+ }) {
1405
+ return /* @__PURE__ */ jsx4(
1406
+ "div",
1407
+ {
1408
+ "aria-label": copy.tool,
1409
+ className: "flex h-[var(--agent-gui-workbench-header-height,44px)] min-w-0 flex-1 cursor-grab items-center gap-1 overflow-hidden px-2 active:cursor-grabbing [-webkit-app-region:drag]",
1410
+ "data-standalone-agent-tool-tab-list": "true",
1411
+ role: "tablist",
1412
+ children: /* @__PURE__ */ jsx4("div", { className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto", children: mountedTabs.map((tab) => {
1413
+ const defaultLabel = labelByPanel.get(tab.panel) ?? tab.panel;
1414
+ const label = resolveTabLabel?.(tab, defaultLabel) ?? defaultLabel;
1415
+ return /* @__PURE__ */ jsxs3(
1416
+ "div",
1417
+ {
1418
+ className: cn2(
1419
+ "group flex h-7 max-w-44 shrink-0 items-center rounded-sm overflow-hidden border text-xs text-[var(--text-tertiary)]",
1420
+ activeTabId === tab.id ? "border-[var(--line-2)] bg-[var(--background-fronted)] text-[var(--text-primary)]" : "border-transparent"
1421
+ ),
1422
+ children: [
1423
+ /* @__PURE__ */ jsxs3(
1424
+ "button",
1425
+ {
1426
+ "aria-selected": activeTabId === tab.id,
1427
+ className: "nodrag flex h-full min-w-0 flex-1 items-center gap-1.5 overflow-hidden px-2 text-left outline-none [-webkit-app-region:no-drag] focus-visible:ring-2 focus-visible:ring-[var(--border-focus)]",
1428
+ "data-standalone-agent-tool-tab": tab.panel,
1429
+ "data-standalone-agent-tool-tab-id": tab.id,
1430
+ role: "tab",
1431
+ type: "button",
1432
+ onClick: () => onOpenPanel(tab),
1433
+ children: [
1434
+ renderTabIcon?.(tab) ?? /* @__PURE__ */ jsx4(
1435
+ AgentToolPanelIcon,
1436
+ {
1437
+ "aria-hidden": true,
1438
+ className: "size-3.5 shrink-0",
1439
+ panel: tab.panel
1440
+ }
1441
+ ),
1442
+ /* @__PURE__ */ jsx4("span", { className: "truncate", children: label })
1443
+ ]
1444
+ }
1445
+ ),
1446
+ /* @__PURE__ */ jsx4(
1447
+ "button",
1448
+ {
1449
+ "aria-label": `${copy.close} ${label}`,
1450
+ className: "nodrag mr-1 rounded p-0.5 opacity-100 hover:bg-[var(--transparency-block)] [-webkit-app-region:no-drag]",
1451
+ type: "button",
1452
+ onClick: () => onClosePanel(tab.id),
1453
+ children: /* @__PURE__ */ jsx4(CloseIcon, { "aria-hidden": true, className: "size-3" })
1454
+ }
1455
+ )
1456
+ ]
1457
+ },
1458
+ tab.id
1459
+ );
1460
+ }) })
1461
+ }
1462
+ );
1463
+ }
1464
+ export {
1465
+ AgentToolBrowserPanel,
1466
+ AgentToolPanelIcon,
1467
+ AgentToolSidebar,
1468
+ AgentToolSidebarPicker,
1469
+ AgentToolSidebarToolbar,
1470
+ agentToolBrowserDefaultUrl,
1471
+ agentToolEmptySidebarWidth,
1472
+ agentToolMainMinWidth,
1473
+ agentToolPanelDefaultWidthById,
1474
+ agentToolPanelIds,
1475
+ agentToolPanelMaxWidthById,
1476
+ agentToolPanelMinWidthById,
1477
+ clampAgentToolPanelWidth,
1478
+ createAgentToolBrowserFeature,
1479
+ createAgentToolSidebarState,
1480
+ filterAgentToolPanels,
1481
+ formatAgentToolReminderCount,
1482
+ isAgentToolPanelId,
1483
+ reduceAgentToolSidebarState,
1484
+ resolveAgentToolPanelExpansionReset,
1485
+ resolveAgentToolPanelExpansionTransfer,
1486
+ resolveAgentToolPanelMaxWidth,
1487
+ resolveAgentToolPanelPreferredWidth,
1488
+ resolveAgentToolSidebarLayoutWidth,
1489
+ resolveAgentToolSidebarWidth,
1490
+ shouldResizeAgentToolContainer
1491
+ };
1492
+ //# sourceMappingURL=index.js.map