@qredence/fleet 0.5.9 → 0.5.11

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 (121) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/web/client/assets/agent-activity-CwMDU7aP.js +1 -0
  3. package/dist/web/client/assets/artifacts-panel-CQmFEF_H.js +1 -0
  4. package/dist/web/client/assets/{button-BV9NafmI.js → button-BR2WWrFo.js} +1 -1
  5. package/dist/web/client/assets/{chat-command-palette-C_HgND2N.js → chat-command-palette-CmHTS3rs.js} +1 -1
  6. package/dist/web/client/assets/{chat-DdPRGn-U.js → chat-yh02zgA7.js} +2 -2
  7. package/dist/web/client/assets/{citations-BQ_pr_9_.js → citations-C_tPOJE_.js} +1 -1
  8. package/dist/web/client/assets/{command-Cx-UYeQ9.js → command-DPfiaYUL.js} +1 -1
  9. package/dist/web/client/assets/{dialog-Dh7WpGIu.js → dialog-BEZuZhzk.js} +1 -1
  10. package/dist/web/client/assets/{fleet-message-queue-DPBMIZSU.js → fleet-message-queue-DUz6Hfrf.js} +1 -1
  11. package/dist/web/client/assets/{fleet-pi-tool-renderer-DMjrKLi2.js → fleet-pi-tool-renderer-BEDIO3al.js} +4 -4
  12. package/dist/web/client/assets/fleet-reasoning-panel-CbkO7u-v.js +1 -0
  13. package/dist/web/client/assets/{fleet-subagent-list-BnRnrWKS.js → fleet-subagent-list-iKUtLJKZ.js} +1 -1
  14. package/dist/web/client/assets/fleet-tool-timeline-C8heL7ae.js +1 -0
  15. package/dist/web/client/assets/{fork-picker-dialog-CAhWx0G5.js → fork-picker-dialog-ByBOGVsa.js} +1 -1
  16. package/dist/web/client/assets/globals-B_I1Eq1u.css +2 -0
  17. package/dist/web/client/assets/horizontal-resize-qK6eRhIG.js +1 -0
  18. package/dist/web/client/assets/{index-CwtZA4hF.js → index-C1zOjrMK.js} +3 -3
  19. package/dist/web/client/assets/{input-Bol3TP4v.js → input-0wwjWjKq.js} +1 -1
  20. package/dist/web/client/assets/{input-group-D5gi9zBK.js → input-group-BFDsCVS9.js} +1 -1
  21. package/dist/web/client/assets/{ipython-tool-BrMePqD-.js → ipython-tool-ldJ9F1Cw.js} +1 -1
  22. package/dist/web/client/assets/model-selector-list-DsKTuAgS.js +1 -0
  23. package/dist/web/client/assets/{notify-BnNaNaBU.js → notify-DgMKgZZW.js} +1 -1
  24. package/dist/web/client/assets/{openui-renderer-nuOkzdau.js → openui-renderer-J3dhPpL4.js} +5 -5
  25. package/dist/web/client/assets/prompt-input-qPIXZ-Rb.js +1 -0
  26. package/dist/web/client/assets/prompt-suggestions-Cc--lSNR.js +1 -0
  27. package/dist/web/client/assets/{provider-catalog-CO1GxLYe.js → provider-catalog-D8G66gwc.js} +1 -1
  28. package/dist/web/client/assets/{provider-label-B0E-wWFV.js → provider-label-Dpr7djG9.js} +1 -1
  29. package/dist/web/client/assets/repl-panel-DsPX04Xr.js +1 -0
  30. package/dist/web/client/assets/{resources-panel-Bo8dfUdm.js → resources-panel-D867-goy.js} +1 -1
  31. package/dist/web/client/assets/right-panel-registry-DewpBWHM.js +2 -0
  32. package/dist/web/client/assets/routes-vNkVToAF.js +16 -0
  33. package/dist/web/client/assets/safe-storage-s25GrfpH.js +1 -0
  34. package/dist/web/client/assets/session-insights-panel-YnaXvTpi.js +1 -0
  35. package/dist/web/client/assets/settings-dialog-B-v4me3Y.js +1 -0
  36. package/dist/web/client/assets/skeleton-loaders-C9vHwAYV.js +1 -0
  37. package/dist/web/client/assets/{subagent-chat-panel-Ck06wcIJ.js → subagent-chat-panel-DkVUumrP.js} +1 -1
  38. package/dist/web/client/assets/subagent-transcript-D8wmQxXe.js +1 -0
  39. package/dist/web/client/assets/subagents-panel-BMp2Ego0.js +1 -0
  40. package/dist/web/client/assets/{surfaces-cW-gp56p.js → surfaces-DI-U-_2a.js} +1 -1
  41. package/dist/web/client/assets/{switch-J2Lvo_tF.js → switch-9rTeg6J6.js} +1 -1
  42. package/dist/web/client/assets/{toast-BzAKULar.js → toast-Bt9p2OL4.js} +1 -1
  43. package/dist/web/client/assets/tool-result-DfnPN0FQ.js +4 -0
  44. package/dist/web/client/assets/ui-preferences-CImQGZm_.js +1 -0
  45. package/dist/web/client/assets/virtualized-turn-list-DMJENRY0.js +6 -0
  46. package/dist/web/client/assets/{workspace-panel-DI1W3ce9.js → workspace-panel-G6yMpKJ8.js} +1 -1
  47. package/dist/web/client/bundle-budget.json +6 -6
  48. package/dist/web/server/{_tanstack-start-manifest_v-DkghjPW8-5E6WBVI6.js → _tanstack-start-manifest_v-po4woX6g-AUGCOEZ2.js} +20 -19
  49. package/dist/web/server/{agent-activity-B-JMvecd-SLE3GGY2.js → agent-activity-CS2rbF_C-A3R26CYH.js} +2 -2
  50. package/dist/web/server/{artifacts-panel-D20iI9ud-YGBYV6NF.js → artifacts-panel-8GGUCtOd-X5TNKTY2.js} +17 -17
  51. package/dist/web/server/{chat-command-palette-DmDvAEZe-CONFK6YH.js → chat-command-palette-Dgl5tqWn-72LLEWUD.js} +7 -7
  52. package/dist/web/server/{chunk-K5ESTT4A.js → chunk-7MDZVLIY.js} +11 -3
  53. package/dist/web/server/{chunk-EBCYJSBR.js → chunk-7SD2ZSEA.js} +3 -3
  54. package/dist/web/server/{chunk-BTXNB4CP.js → chunk-ABBWBBSS.js} +13 -13
  55. package/dist/web/server/{chunk-VMYYWXF4.js → chunk-AGFRJQZ7.js} +2 -2
  56. package/dist/web/server/{chunk-FZMWPQNE.js → chunk-BXWAUTTH.js} +4 -4
  57. package/dist/web/server/{chunk-54II5QXQ.js → chunk-ETTDO4UO.js} +6 -3
  58. package/dist/web/server/{chunk-EHNIN245.js → chunk-GETSIVNU.js} +5 -5
  59. package/dist/web/server/{chunk-NRDG2ISJ.js → chunk-GGT2ZKDB.js} +49 -49
  60. package/dist/web/server/{chunk-X2R5YPQZ.js → chunk-IJPCV6DH.js} +3 -2
  61. package/dist/web/server/{chunk-TFHXOWFX.js → chunk-JQDLJ7KI.js} +20 -20
  62. package/dist/web/server/{chunk-VHBFU4TG.js → chunk-JUROEEWM.js} +43 -14
  63. package/dist/web/server/{chunk-WQDG5ZM2.js → chunk-KOUEJ3NU.js} +2 -2
  64. package/dist/web/server/{chunk-JICJWC33.js → chunk-LZ4Q5KUJ.js} +10 -10
  65. package/dist/web/server/{chunk-W6IZDM2G.js → chunk-MIW4LJTV.js} +4 -4
  66. package/dist/web/server/{chunk-2TRF62K5.js → chunk-N6NOTURM.js} +3 -3
  67. package/dist/web/server/{chunk-5XX7RKJ6.js → chunk-NXJ32VFR.js} +5 -5
  68. package/dist/web/server/{chunk-EFNPNSDO.js → chunk-O4OTWWPF.js} +7 -7
  69. package/dist/web/server/{chunk-X6RKK47S.js → chunk-P6UMR32I.js} +2 -2
  70. package/dist/web/server/{chunk-QJQZLBLU.js → chunk-P7H2OPKF.js} +3 -3
  71. package/dist/web/server/{chunk-MLPLZVON.js → chunk-RNOJACWQ.js} +54 -30
  72. package/dist/web/server/chunk-SZJUXVWG.js +40 -0
  73. package/dist/web/server/{chunk-ZCJXHV2R.js → chunk-UAPNEWCA.js} +4 -4
  74. package/dist/web/server/{chunk-WVBBA2VV.js → chunk-WILCIZYU.js} +195 -11
  75. package/dist/web/server/{chunk-FED63ZHU.js → chunk-WKV2Z4KO.js} +10 -5
  76. package/dist/web/server/{chunk-TGZIE2T6.js → chunk-WM4PUT6M.js} +4 -4
  77. package/dist/web/server/{chunk-56NGD3FN.js → chunk-WYL2DW5R.js} +2 -2
  78. package/dist/web/server/{chunk-IMK45Q23.js → chunk-XKKXXG6N.js} +3 -3
  79. package/dist/web/server/{chunk-ANL4B775.js → chunk-XLNCWZMZ.js} +2 -2
  80. package/dist/web/server/{chunk-ZVL6TBG5.js → chunk-YKVGQBZA.js} +13 -9
  81. package/dist/web/server/{chunk-IFHABBJO.js → chunk-YXXRP3NS.js} +18 -10
  82. package/dist/web/server/{fleet-message-queue-BvMcWtLo-6CMMI73U.js → fleet-message-queue-j0DCU5Xy-5HKBHMPV.js} +5 -5
  83. package/dist/web/server/{fleet-pi-tool-renderer-CgbmlIoe-7MSJLEGU.js → fleet-pi-tool-renderer-umKunT3K-O4GBH35V.js} +5 -5
  84. package/dist/web/server/{fleet-reasoning-panel-D_K48UOT-GN2PA6KT.js → fleet-reasoning-panel-BxC2COxi-GPLMQSTT.js} +9 -9
  85. package/dist/web/server/{fleet-subagent-list-5luKtpds-3OTVFHJQ.js → fleet-subagent-list-CpSYzCIq-JDH2LHSS.js} +1 -1
  86. package/dist/web/server/{fleet-tool-timeline-DwRqQgOj-HUFLGMDV.js → fleet-tool-timeline-IB36_PB2-XJENTO6I.js} +1 -1
  87. package/dist/web/server/{fork-picker-dialog-DfSRzUI5-EBRK5HNO.js → fork-picker-dialog-DlINz9UQ-UWIXFDJX.js} +5 -5
  88. package/dist/web/server/{model-selector-list-wCp4_UWC-2NQUCAM3.js → model-selector-list-OYnzNbyu-HBGCNF2L.js} +10 -10
  89. package/dist/web/server/{openui-renderer-BNLpfzyj-JUPJXUWF.js → openui-renderer-Cj7kfqyL-EKJ6JTTQ.js} +9 -9
  90. package/dist/web/server/{prompt-suggestions-BOmHi4-J-C563CHFU.js → prompt-suggestions-D4AEEY7K-RZSP7PWV.js} +3 -3
  91. package/dist/web/server/{repl-panel-yyxhwe4c-7U6HXYPS.js → repl-panel-D5KsoJik-BQKO53JO.js} +9 -9
  92. package/dist/web/server/{resources-panel-j4fAIi9g-5C267IXV.js → resources-panel-CE5pD4vy-V5FXBTYC.js} +2 -2
  93. package/dist/web/server/{router-dnEmu1cU-LUH74TAC.js → router-Ci1wxI7I-E2AYMNON.js} +255 -78
  94. package/dist/web/server/{routes-Ci5_8lws-F54KB46D.js → routes-CRpm9-Sa-IYK6MUJO.js} +720 -549
  95. package/dist/web/server/server.js +2 -2
  96. package/dist/web/server/{session-insights-panel-BHZyKDTo-LRMAMA3O.js → session-insights-panel-CUhdgvRt-VB2HUCQP.js} +4 -4
  97. package/dist/web/server/{settings-dialog-CdFpyzR--JVYIS5OD.js → settings-dialog-BvkgNflv-GPJ6COQO.js} +22 -18
  98. package/dist/web/server/{subagent-chat-panel-DVgf-whR-6G2ASMGU.js → subagent-chat-panel-CMuvW9Sd-M5TEEGQW.js} +14 -14
  99. package/dist/web/server/{subagents-panel-D2CN0IYy-3L6ZNQ3Q.js → subagents-panel-DgfB6_Yy-4INEPE3Y.js} +16 -16
  100. package/dist/web/server/{workspace-panel-BOs-58Cv-SWQBMZSB.js → workspace-panel-bpwj-Veu-Q2CEJMN4.js} +4 -3
  101. package/package.json +1 -1
  102. package/dist/web/client/assets/agent-activity-CDcDNVC6.js +0 -1
  103. package/dist/web/client/assets/artifacts-panel-N4k9VcJr.js +0 -1
  104. package/dist/web/client/assets/fleet-reasoning-panel-MtbSdoCv.js +0 -1
  105. package/dist/web/client/assets/fleet-tool-timeline-COzPrwr8.js +0 -1
  106. package/dist/web/client/assets/generative-text-renderer-CzwNIs3b.js +0 -6
  107. package/dist/web/client/assets/globals-C7ovVTh2.css +0 -2
  108. package/dist/web/client/assets/horizontal-resize-Bl3AyBJg.js +0 -1
  109. package/dist/web/client/assets/model-selector-list-CJY9pyt2.js +0 -1
  110. package/dist/web/client/assets/prompt-input-BpuTiX7Z.js +0 -1
  111. package/dist/web/client/assets/prompt-suggestions-CXM6knMK.js +0 -1
  112. package/dist/web/client/assets/repl-panel-BDQ5MEgV.js +0 -1
  113. package/dist/web/client/assets/right-panel-registry-DOyEvIMD.js +0 -2
  114. package/dist/web/client/assets/routes-DkefU9yA.js +0 -16
  115. package/dist/web/client/assets/session-insights-panel-CQdT90Op.js +0 -1
  116. package/dist/web/client/assets/settings-dialog-B6rt69m_.js +0 -1
  117. package/dist/web/client/assets/skeleton-loaders-DjGv9LLA.js +0 -1
  118. package/dist/web/client/assets/subagent-transcript-BwCv3nTL.js +0 -1
  119. package/dist/web/client/assets/subagents-panel-BkOorzzy.js +0 -1
  120. package/dist/web/client/assets/tool-result-Cp13oeRn.js +0 -4
  121. package/dist/web/client/assets/ui-preferences-DUEFuJFj.js +0 -1
@@ -21,12 +21,12 @@ import {
21
21
  useMutation,
22
22
  useQuery,
23
23
  useQueryClient
24
- } from "./chunk-VHBFU4TG.js";
24
+ } from "./chunk-JUROEEWM.js";
25
25
  import {
26
26
  Library,
27
27
  RIGHT_PANEL_LAUNCHER_DEFINITIONS,
28
28
  getRightPanelDefinition
29
- } from "./chunk-EFNPNSDO.js";
29
+ } from "./chunk-O4OTWWPF.js";
30
30
  import {
31
31
  AlertDialog,
32
32
  AlertDialogAction,
@@ -51,7 +51,7 @@ import {
51
51
  useHoverFloatingInteraction,
52
52
  useHoverReferenceInteraction,
53
53
  usePopupHandleStore
54
- } from "./chunk-W6IZDM2G.js";
54
+ } from "./chunk-MIW4LJTV.js";
55
55
  import {
56
56
  RightPanelProvider,
57
57
  useChatPanelDataContext,
@@ -66,7 +66,7 @@ import {
66
66
  PromptInput,
67
67
  useHydrated,
68
68
  usePopoverPortalPosition
69
- } from "./chunk-ZVL6TBG5.js";
69
+ } from "./chunk-YKVGQBZA.js";
70
70
  import "./chunk-7CNGNFFK.js";
71
71
  import {
72
72
  Plus
@@ -81,18 +81,19 @@ import {
81
81
  MessageContent,
82
82
  MessageScroller,
83
83
  UserMessage,
84
+ VirtualizedTurnList,
84
85
  buildAssistantElements,
85
86
  groupMessages,
86
87
  normalizeAssistantToolParts
87
- } from "./chunk-WVBBA2VV.js";
88
+ } from "./chunk-WILCIZYU.js";
88
89
  import "./chunk-FJV6EQDW.js";
89
90
  import {
90
91
  RefreshCw
91
92
  } from "./chunk-OKL5ZRVB.js";
92
93
  import {
93
94
  notify
94
- } from "./chunk-56NGD3FN.js";
95
- import "./chunk-WQDG5ZM2.js";
95
+ } from "./chunk-WYL2DW5R.js";
96
+ import "./chunk-KOUEJ3NU.js";
96
97
  import {
97
98
  Bot
98
99
  } from "./chunk-UCA4WN66.js";
@@ -105,14 +106,14 @@ import {
105
106
  MessageCircleQuestionMark,
106
107
  PI_TOOL_RENDERERS,
107
108
  useHoverCapable
108
- } from "./chunk-2TRF62K5.js";
109
+ } from "./chunk-N6NOTURM.js";
109
110
  import "./chunk-QPNUGF3V.js";
110
111
  import {
111
112
  field,
112
113
  floating,
113
114
  mono,
114
115
  paper
115
- } from "./chunk-ANL4B775.js";
116
+ } from "./chunk-XLNCWZMZ.js";
116
117
  import "./chunk-BLSX7WHW.js";
117
118
  import {
118
119
  Sparkles
@@ -136,11 +137,16 @@ import {
136
137
  thinkingLevelLabel,
137
138
  toModelOption,
138
139
  toModelSelection
139
- } from "./chunk-FED63ZHU.js";
140
+ } from "./chunk-WKV2Z4KO.js";
140
141
  import "./chunk-QK4CHLVV.js";
141
142
  import {
142
143
  Folder
143
144
  } from "./chunk-GS2IZGRC.js";
145
+ import {
146
+ readStoredValue,
147
+ removeStoredValue,
148
+ writeStoredValue
149
+ } from "./chunk-SZJUXVWG.js";
144
150
  import {
145
151
  resolveWorkspacePanelTarget
146
152
  } from "./chunk-P66QQWUM.js";
@@ -224,7 +230,7 @@ import {
224
230
  Badge,
225
231
  UiErrorBoundary,
226
232
  decodeOpenPanelActionMessage
227
- } from "./chunk-FZMWPQNE.js";
233
+ } from "./chunk-BXWAUTTH.js";
228
234
  import {
229
235
  ChatOpenUIArtifactUpsertRequestSchema,
230
236
  ChatOpenUIArtifactUpsertResponseSchema,
@@ -248,7 +254,7 @@ import {
248
254
  UploadedAttachmentSchema,
249
255
  WorkspaceRelativePathSchema,
250
256
  external_exports
251
- } from "./chunk-NRDG2ISJ.js";
257
+ } from "./chunk-GGT2ZKDB.js";
252
258
  import {
253
259
  CompositeList,
254
260
  Select,
@@ -262,7 +268,7 @@ import {
262
268
  useOpenMethodTriggerProps,
263
269
  usePositioner,
264
270
  useToolbarRootContext
265
- } from "./chunk-TGZIE2T6.js";
271
+ } from "./chunk-WM4PUT6M.js";
266
272
  import "./chunk-RJOANOT4.js";
267
273
  import "./chunk-NFRJDPB3.js";
268
274
  import {
@@ -274,7 +280,7 @@ import {
274
280
  } from "./chunk-WWJF4RO2.js";
275
281
  import {
276
282
  Input
277
- } from "./chunk-X6RKK47S.js";
283
+ } from "./chunk-P6UMR32I.js";
278
284
  import {
279
285
  ARROW_DOWN,
280
286
  ARROW_LEFT,
@@ -317,7 +323,7 @@ import {
317
323
  usePopupRootSync,
318
324
  useSurface,
319
325
  useTriggerDataForwarding
320
- } from "./chunk-VMYYWXF4.js";
326
+ } from "./chunk-AGFRJQZ7.js";
321
327
  import {
322
328
  Button,
323
329
  CLICK_TRIGGER_IDENTIFIER,
@@ -341,7 +347,7 @@ import {
341
347
  isListIndexDisabled,
342
348
  isOutsideEvent,
343
349
  ownerDocument
344
- } from "./chunk-JICJWC33.js";
350
+ } from "./chunk-LZ4Q5KUJ.js";
345
351
  import {
346
352
  Check
347
353
  } from "./chunk-4QD4PCVP.js";
@@ -409,7 +415,7 @@ import "./chunk-JDCCC7A7.js";
409
415
  import "./chunk-L547YHC4.js";
410
416
  import "./chunk-MLKGABMK.js";
411
417
 
412
- // web/app/dist/server/assets/routes-Ci5_8lws.js
418
+ // web/app/dist/server/assets/routes-CRpm9-Sa.js
413
419
  import * as React$1 from "react";
414
420
  import { Suspense, createContext as createContext2, createElement, forwardRef as forwardRef2, isValidElement, lazy, memo, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useEffectEvent, useId, useLayoutEffect, useMemo as useMemo2, useReducer, useRef as useRef2, useState as useState2, useSyncExternalStore } from "react";
415
421
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -1231,139 +1237,6 @@ function agentTabTriggerId(tabId) {
1231
1237
  function agentTabPanelId(tabId) {
1232
1238
  return `agent-tab-panel-${encodeURIComponent(tabId)}`;
1233
1239
  }
1234
- function statusLabel(status) {
1235
- switch (status) {
1236
- case "queued":
1237
- return "queued";
1238
- case "running":
1239
- case "recovering":
1240
- return "streaming";
1241
- case "error":
1242
- case "failed":
1243
- return "error";
1244
- case "cancelled":
1245
- return "cancelled";
1246
- case "done":
1247
- return "complete";
1248
- default:
1249
- return "ready";
1250
- }
1251
- }
1252
- function statusDotClass(status) {
1253
- switch (status) {
1254
- case "running":
1255
- case "recovering":
1256
- return "bg-emerald-400 motion-safe:animate-pulse";
1257
- case "error":
1258
- case "failed":
1259
- return "bg-destructive";
1260
- case "queued":
1261
- return "bg-amber-300";
1262
- case "cancelled":
1263
- return "bg-foreground/35";
1264
- default:
1265
- return "bg-foreground/35";
1266
- }
1267
- }
1268
- function AgentTabBar({ tabs, value, onValueChange, onClose, onNewSession }) {
1269
- const tabRefs = useRef2(/* @__PURE__ */ new Map());
1270
- const setTabRef = useCallback2((tabId, node) => {
1271
- if (node) tabRefs.current.set(tabId, node);
1272
- else tabRefs.current.delete(tabId);
1273
- }, []);
1274
- useEffect2(() => {
1275
- for (const tabId of tabRefs.current.keys()) if (!tabs.some((tab) => tab.id === tabId)) tabRefs.current.delete(tabId);
1276
- }, [tabs]);
1277
- const focusTab = useCallback2((index) => {
1278
- const tab = tabs[index];
1279
- if (!tab) return;
1280
- tabRefs.current.get(tab.id)?.focus();
1281
- onValueChange(tab.id);
1282
- }, [onValueChange, tabs]);
1283
- const handleKeyDown = useCallback2((event, tabId) => {
1284
- const index = tabs.findIndex((tab) => tab.id === tabId);
1285
- if (index < 0) return;
1286
- let nextIndex;
1287
- if (event.key === "ArrowRight") nextIndex = (index + 1) % tabs.length;
1288
- if (event.key === "ArrowLeft") nextIndex = (index - 1 + tabs.length) % tabs.length;
1289
- if (event.key === "Home") nextIndex = 0;
1290
- if (event.key === "End") nextIndex = tabs.length - 1;
1291
- if (nextIndex === void 0) return;
1292
- event.preventDefault();
1293
- focusTab(nextIndex);
1294
- }, [focusTab, tabs]);
1295
- return /* @__PURE__ */ jsxs("div", {
1296
- className: "flex min-w-0 max-w-full items-center gap-1",
1297
- "data-testid": "agent-tab-bar",
1298
- children: [/* @__PURE__ */ jsx("div", {
1299
- "aria-label": "Agent conversations",
1300
- className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1301
- role: "tablist",
1302
- children: tabs.map((tab) => {
1303
- const active = tab.id === value;
1304
- const status = statusLabel(tab.status);
1305
- return /* @__PURE__ */ jsxs("div", {
1306
- className: "group/tab relative min-w-0 shrink-0 basis-[164px] sm:max-w-[164px]",
1307
- "data-tab-id": tab.id,
1308
- children: [/* @__PURE__ */ jsxs(Button, {
1309
- ref: (node) => setTabRef(tab.id, node),
1310
- "aria-controls": agentTabPanelId(tab.id),
1311
- "aria-selected": active,
1312
- "aria-label": `${tab.label}, ${status}`,
1313
- className: cn("h-7 w-full min-w-0 justify-start gap-1.5 rounded-[7px] border border-transparent px-2 text-[12px] font-medium leading-none transition-colors motion-reduce:transition-none", active ? "bg-[#2c2c2c] text-foreground shadow-none" : "bg-transparent text-foreground/45 hover:bg-foreground/5 hover:text-foreground/75", tab.kind === "subagent" && "pr-7"),
1314
- "data-state": active ? "active" : "inactive",
1315
- id: agentTabTriggerId(tab.id),
1316
- onClick: () => onValueChange(tab.id),
1317
- onKeyDown: (event) => handleKeyDown(event, tab.id),
1318
- role: "tab",
1319
- size: "sm",
1320
- tabIndex: active ? 0 : -1,
1321
- type: "button",
1322
- variant: "ghost",
1323
- children: [tab.kind === "main" ? /* @__PURE__ */ jsx(Bot, {
1324
- "aria-hidden": "true",
1325
- className: "size-3.5 shrink-0"
1326
- }) : /* @__PURE__ */ jsx("span", {
1327
- "aria-hidden": "true",
1328
- className: cn("size-1.5 shrink-0 rounded-full", statusDotClass(tab.status))
1329
- }), /* @__PURE__ */ jsx("span", {
1330
- className: "min-w-0 flex-1 truncate",
1331
- children: tab.label
1332
- })]
1333
- }), tab.kind === "subagent" && onClose ? /* @__PURE__ */ jsx(Button, {
1334
- "aria-label": `Close ${tab.label} tab`,
1335
- className: "absolute top-1/2 right-1 size-5 -translate-y-1/2 rounded-[5px] p-0 text-foreground/35 opacity-0 transition-opacity motion-reduce:transition-none hover:bg-foreground/10 hover:text-foreground/75 focus-visible:opacity-100 group-hover/tab:opacity-100",
1336
- onClick: (event) => {
1337
- event.stopPropagation();
1338
- onClose(tab.id);
1339
- },
1340
- size: "icon-xs",
1341
- title: `Close ${tab.label} tab`,
1342
- type: "button",
1343
- variant: "ghost",
1344
- children: /* @__PURE__ */ jsx(X, {
1345
- "aria-hidden": "true",
1346
- className: "size-3"
1347
- })
1348
- }) : null]
1349
- }, tab.id);
1350
- })
1351
- }), onNewSession ? /* @__PURE__ */ jsx(Button, {
1352
- "aria-label": "New chat",
1353
- className: "size-7 shrink-0 rounded-[7px] text-foreground/50 hover:bg-foreground/7 hover:text-foreground/85",
1354
- "data-testid": "new-chat-tab",
1355
- onClick: onNewSession,
1356
- size: "icon-sm",
1357
- title: "New chat",
1358
- type: "button",
1359
- variant: "ghost",
1360
- children: /* @__PURE__ */ jsx(Plus, {
1361
- "aria-hidden": "true",
1362
- className: "size-3.5"
1363
- })
1364
- }) : null]
1365
- });
1366
- }
1367
1240
  function ResizableCanvas({ children, dataTestid, headerLeading, loading, onClose, onRefresh, onResizeStart, open, headerActions, title, titleIcon: TitleIcon, width }) {
1368
1241
  const reduceMotion = useReducedMotion();
1369
1242
  const panelRef = useRef2(null);
@@ -1414,11 +1287,11 @@ function ResizableCanvas({ children, dataTestid, headerLeading, loading, onClose
1414
1287
  }), /* @__PURE__ */ jsxs("div", {
1415
1288
  className: "flex h-full min-w-0 flex-1 flex-col overflow-hidden",
1416
1289
  children: [/* @__PURE__ */ jsxs("div", {
1417
- className: "flex h-[60px] min-w-0 shrink-0 items-center justify-between gap-2 border-b border-border/60 px-3 py-1",
1290
+ className: "flex h-[var(--chat-header-height,44px)] min-h-[var(--chat-header-height,44px)] min-w-0 shrink-0 items-center justify-between gap-2 border-b border-border/60 px-3 py-1",
1418
1291
  children: [/* @__PURE__ */ jsx("div", {
1419
1292
  className: "min-w-0 flex-1",
1420
1293
  children: headerLeading ?? /* @__PURE__ */ jsxs("div", {
1421
- className: "flex min-w-0 items-center gap-2 text-[13px] font-medium text-foreground/80",
1294
+ className: "flex min-w-0 items-center gap-2 text-[0.8125rem] font-medium text-foreground/80",
1422
1295
  children: [/* @__PURE__ */ jsx(TitleIcon, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", { children: title })]
1423
1296
  })
1424
1297
  }), /* @__PURE__ */ jsxs("div", {
@@ -2426,7 +2299,7 @@ var TabsSubtleItem = forwardRef2(({ icon: Icon, label, index, badge, className,
2426
2299
  const tone = chromeTone(isPill, isActive);
2427
2300
  const ariaLabel = ariaLabelProp ?? (collapseLabel && !showLabel ? label : void 0);
2428
2301
  const labelContent = /* @__PURE__ */ jsxs("span", {
2429
- className: cn("inline-grid whitespace-nowrap", isPill ? "text-[12px] font-medium" : "text-[13px]"),
2302
+ className: cn("inline-grid whitespace-nowrap", isPill ? "text-[0.75rem] font-medium" : "text-[0.8125rem]"),
2430
2303
  children: [/* @__PURE__ */ jsx("span", {
2431
2304
  className: "invisible col-start-1 row-start-1 [text-box:trim-both_cap_alphabetic]",
2432
2305
  style: { fontVariationSettings: fontWeights.semibold },
@@ -2465,7 +2338,7 @@ var TabsSubtleItem = forwardRef2(({ icon: Icon, label, index, badge, className,
2465
2338
  strokeWidth: isActive ? 2 : 1.5,
2466
2339
  className: cn("shrink-0 transition-[color,stroke-width] duration-80", tone)
2467
2340
  }), badge !== void 0 ? /* @__PURE__ */ jsx("span", {
2468
- className: cn("text-[11px] tabular-nums transition-colors duration-80", tone),
2341
+ className: cn("text-[0.6875rem] tabular-nums transition-colors duration-80", tone),
2469
2342
  children: badge
2470
2343
  }) : null]
2471
2344
  }) : null,
@@ -2526,7 +2399,7 @@ function ChromePillButton({ active = false, ariaLabel, className, title, ...prop
2526
2399
  title: title ?? ariaLabel
2527
2400
  });
2528
2401
  }
2529
- var COMPACT_TABS_CLASS = "[&_[data-proximity-index]]:!h-7 [&_[data-proximity-index]]:!px-2 [&_[data-proximity-index]]:!text-[11px]";
2402
+ var COMPACT_TABS_CLASS = "[&_[data-proximity-index]]:!h-7 [&_[data-proximity-index]]:!px-2 [&_[data-proximity-index]]:!text-[0.6875rem]";
2530
2403
  function RightPanelLauncherFromContext({ compact = false } = {}) {
2531
2404
  const { reopenRightPanel, rightPanel } = useChatPanelDataContext();
2532
2405
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
@@ -2686,8 +2559,13 @@ function MobilePanel({ children, dataTestid, headerActions, icon: Icon, onClose,
2686
2559
  const panelTitleId = useId();
2687
2560
  const suppressCloseRef = useRef2(false);
2688
2561
  const onLightDismiss = useEffectEvent((event) => {
2689
- if (panelRef.current && event.target === panelRef.current) onClose?.();
2562
+ if (panelRef.current && event.target === panelRef.current) panelRef.current.close();
2690
2563
  });
2564
+ const handleHeaderClose = () => {
2565
+ const dialog = panelRef.current;
2566
+ if (dialog && dialog.open) dialog.close();
2567
+ else onClose?.();
2568
+ };
2691
2569
  useEffect2(() => {
2692
2570
  if (!open) return;
2693
2571
  const dialog = panelRef.current;
@@ -2749,7 +2627,7 @@ function MobilePanel({ children, dataTestid, headerActions, icon: Icon, onClose,
2749
2627
  title && /* @__PURE__ */ jsxs("div", {
2750
2628
  className: "flex h-10 shrink-0 items-center justify-between gap-2 border-b border-border/60 px-3",
2751
2629
  children: [/* @__PURE__ */ jsxs("div", {
2752
- className: "flex min-w-0 items-center gap-2 text-[13px] font-medium text-foreground/80",
2630
+ className: "flex min-w-0 items-center gap-2 text-[0.8125rem] font-medium text-foreground/80",
2753
2631
  children: [Icon && /* @__PURE__ */ jsx(Icon, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
2754
2632
  className: "truncate",
2755
2633
  children: title
@@ -2758,7 +2636,7 @@ function MobilePanel({ children, dataTestid, headerActions, icon: Icon, onClose,
2758
2636
  className: "flex shrink-0 items-center gap-1",
2759
2637
  children: [headerActions, onClose && /* @__PURE__ */ jsx(Button, {
2760
2638
  type: "button",
2761
- onClick: onClose,
2639
+ onClick: handleHeaderClose,
2762
2640
  variant: "ghost",
2763
2641
  size: "icon-sm",
2764
2642
  className: `relative after:absolute after:top-1/2 after:left-1/2 after:size-10 after:-translate-x-1/2 after:-translate-y-1/2 text-foreground/40 hover:text-foreground/70`,
@@ -2779,23 +2657,33 @@ function MobilePanel({ children, dataTestid, headerActions, icon: Icon, onClose,
2779
2657
  })
2780
2658
  });
2781
2659
  }
2660
+ var DESKTOP_PANEL_QUERY = `(min-width: 960px)`;
2661
+ function subscribeToDesktopPanel(onChange) {
2662
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => void 0;
2663
+ const media = window.matchMedia(DESKTOP_PANEL_QUERY);
2664
+ media.addEventListener("change", onChange);
2665
+ return () => media.removeEventListener("change", onChange);
2666
+ }
2667
+ function getDesktopPanelSnapshot() {
2668
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(DESKTOP_PANEL_QUERY).matches : false;
2669
+ }
2670
+ function getServerDesktopPanelSnapshot() {
2671
+ return false;
2672
+ }
2673
+ function useIsDesktopPanel() {
2674
+ return useSyncExternalStore(subscribeToDesktopPanel, getDesktopPanelSnapshot, getServerDesktopPanelSnapshot);
2675
+ }
2782
2676
  function RightPanelShell({ handleResourceCanvasResizeStart, onClose, resourceCanvasWidth }) {
2783
2677
  const chat = useChatPanelDataContext();
2784
2678
  const workspace = useWorkspaceTreeContext();
2785
2679
  const { rightPanel } = chat;
2786
2680
  const panelOpen = rightPanel !== null;
2681
+ const isDesktop = useIsDesktopPanel();
2787
2682
  const definition = rightPanel ? getRightPanelDefinition(rightPanel) : null;
2788
2683
  const PanelContent = definition?.component;
2789
2684
  const loading = definition?.loadingSource === "resources" ? chat.resourcesLoading : definition?.loadingSource === "workspace" ? workspace.workspaceLoading : false;
2790
2685
  const onRefresh = definition?.refreshSource === "resources" ? chat.refreshResources : definition?.refreshSource === "workspace" ? workspace.refreshWorkspace : void 0;
2791
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(MobilePanel, {
2792
- dataTestid: definition?.mobileDataTestid,
2793
- icon: definition?.icon,
2794
- onClose,
2795
- open: panelOpen,
2796
- title: definition?.title ?? "",
2797
- children: PanelContent ? /* @__PURE__ */ jsx(PanelContent, {}) : null
2798
- }), /* @__PURE__ */ jsx(ResizableCanvas, {
2686
+ return /* @__PURE__ */ jsx(Fragment$1, { children: isDesktop ? /* @__PURE__ */ jsx(ResizableCanvas, {
2799
2687
  dataTestid: definition?.dataTestid,
2800
2688
  headerLeading: /* @__PURE__ */ jsx(RightPanelTabsFromContext, { idPrefix: "right-panel-desktop" }),
2801
2689
  loading,
@@ -2807,7 +2695,14 @@ function RightPanelShell({ handleResourceCanvasResizeStart, onClose, resourceCan
2807
2695
  titleIcon: definition?.icon ?? Library,
2808
2696
  width: resourceCanvasWidth,
2809
2697
  children: PanelContent ? /* @__PURE__ */ jsx(PanelContent, {}) : null
2810
- })] });
2698
+ }) : /* @__PURE__ */ jsx(MobilePanel, {
2699
+ dataTestid: definition?.mobileDataTestid,
2700
+ icon: definition?.icon,
2701
+ onClose,
2702
+ open: panelOpen,
2703
+ title: definition?.title ?? "",
2704
+ children: PanelContent ? /* @__PURE__ */ jsx(PanelContent, {}) : null
2705
+ }) });
2811
2706
  }
2812
2707
  var layoutStyle = {
2813
2708
  "--chat-chrome-top": `52px`,
@@ -2823,7 +2718,7 @@ function ChatWorkspaceLayout({ children, headerCenter, headerLeft, headerRight,
2823
2718
  className: "relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
2824
2719
  "data-testid": "chat-column",
2825
2720
  children: [/* @__PURE__ */ jsxs("header", {
2826
- className: cn(CHAT_HEADER_LAYER_CLASS, "grid h-[var(--chat-header-height)] min-h-[var(--chat-header-height)] shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-1 border-b border-[#2e3033] px-2 py-2"),
2721
+ className: cn(CHAT_HEADER_LAYER_CLASS, "grid h-[var(--chat-header-height)] min-h-[var(--chat-header-height)] shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-1 border-b border-border/70 px-2 py-2"),
2827
2722
  "data-testid": "chat-header",
2828
2723
  children: [
2829
2724
  /* @__PURE__ */ jsx("div", {
@@ -3277,7 +3172,7 @@ var AnimatedSidebarGroupLabel = forwardRef2(function AnimatedSidebarGroupLabel2(
3277
3172
  ref: forwardedRef,
3278
3173
  "aria-hidden": collapsed,
3279
3174
  "data-slot": "sidebar-group-label",
3280
- className: cn("mb-1 h-7 overflow-hidden px-2 text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground transition-opacity", collapsed ? "opacity-0" : "opacity-100", className),
3175
+ className: cn("mb-1 h-7 overflow-hidden px-2 text-[0.625rem] font-medium uppercase tracking-[0.14em] text-muted-foreground transition-opacity", collapsed ? "opacity-0" : "opacity-100", className),
3281
3176
  children
3282
3177
  });
3283
3178
  });
@@ -3393,8 +3288,7 @@ function directoryErrorMessage(error, fallback) {
3393
3288
  return error instanceof Error && error.message.trim() ? error.message : fallback;
3394
3289
  }
3395
3290
  function readExpandedProjects(activeProjectId) {
3396
- if (typeof window === "undefined") return activeProjectId ? [projectResourceId(activeProjectId)] : [];
3397
- const stored = window.localStorage.getItem(EXPANDED_PROJECTS_STORAGE_KEY);
3291
+ const stored = readStoredValue(EXPANDED_PROJECTS_STORAGE_KEY);
3398
3292
  if (!stored) return activeProjectId ? [projectResourceId(activeProjectId)] : [];
3399
3293
  try {
3400
3294
  const parsed = JSON.parse(stored);
@@ -3602,7 +3496,7 @@ function useFleetSessionSidebarViewModel({ sessions, projects = EMPTY_PROJECTS,
3602
3496
  setExpandedProjectIds((current) => current.includes(resourceId) ? current : [...current, resourceId]);
3603
3497
  }, [activeProjectId, setExpandedProjectIds]);
3604
3498
  useEffect2(() => {
3605
- window.localStorage.setItem(EXPANDED_PROJECTS_STORAGE_KEY, JSON.stringify(expandedProjectIds));
3499
+ writeStoredValue(EXPANDED_PROJECTS_STORAGE_KEY, JSON.stringify(expandedProjectIds));
3606
3500
  }, [expandedProjectIds]);
3607
3501
  const sidebarItems = useMemo2(() => {
3608
3502
  const grouped = sortedProjects.map((project) => {
@@ -4458,7 +4352,7 @@ function ThreadSearch({ threads, query, activeId, onQueryChange, onSelect, class
4458
4352
  children: [/* @__PURE__ */ jsxs("span", {
4459
4353
  className: "flex items-center gap-1.5",
4460
4354
  children: [thread.pinned && /* @__PURE__ */ jsx(Pin, { className: "text-foreground/30 size-2.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
4461
- className: "min-w-0 flex-1 truncate text-[13px]",
4355
+ className: "min-w-0 flex-1 truncate text-[0.8125rem]",
4462
4356
  children: thread.title
4463
4357
  })]
4464
4358
  }), /* @__PURE__ */ jsx("span", {
@@ -4482,13 +4376,13 @@ function ThreadSearch({ threads, query, activeId, onQueryChange, onSelect, class
4482
4376
  onKeyDown,
4483
4377
  placeholder: "Search threads",
4484
4378
  "aria-label": "Search threads",
4485
- className: "text-foreground/85 placeholder:text-foreground/30 min-w-0 flex-1 bg-transparent text-base outline-none md:text-[13px]"
4379
+ className: "text-foreground/85 placeholder:text-foreground/30 min-w-0 flex-1 bg-transparent text-base outline-none md:text-[0.8125rem]"
4486
4380
  })]
4487
4381
  }),
4488
4382
  pinned.length > 0 && /* @__PURE__ */ jsxs("div", {
4489
4383
  className: "flex flex-col",
4490
4384
  children: [/* @__PURE__ */ jsx("span", {
4491
- className: cn("font-mono text-[11px] tracking-tight", "text-foreground/25 px-2 pb-1"),
4385
+ className: cn("font-mono text-[0.6875rem] tracking-tight", "text-foreground/25 px-2 pb-1"),
4492
4386
  children: "pinned"
4493
4387
  }), pinned.map(row)]
4494
4388
  }),
@@ -4512,7 +4406,7 @@ function ThreadSearch({ threads, query, activeId, onQueryChange, onSelect, class
4512
4406
  }
4513
4407
  function fleetVersion() {
4514
4408
  try {
4515
- return "0.5.9";
4409
+ return "0.5.11";
4516
4410
  } catch {
4517
4411
  return "dev";
4518
4412
  }
@@ -4523,7 +4417,7 @@ function FleetVersionBadge() {
4523
4417
  variant: "secondary",
4524
4418
  title: `Fleet ${version}`,
4525
4419
  "aria-label": `Fleet version ${version}`,
4526
- className: "shrink-0 font-mono text-[10px] font-normal text-muted-foreground",
4420
+ className: "shrink-0 font-mono text-[0.625rem] font-normal text-muted-foreground",
4527
4421
  children: ["v", version]
4528
4422
  });
4529
4423
  }
@@ -4751,7 +4645,7 @@ function ResourceActionMenu({ item, menuOpen, onMenuOpenChange, onRenameStart, r
4751
4645
  });
4752
4646
  }
4753
4647
  function getResourceRowClassName(acceptsChildren, active, containerActive, kind, disabled2) {
4754
- return cn("group/resource relative flex min-h-8 min-w-0 cursor-pointer items-center gap-2 rounded-lg pr-2 text-[13px] outline-none", "text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", "focus-visible:bg-muted/70 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", "data-[menu-open=true]:bg-muted data-[menu-open=true]:text-foreground", "data-[dragging=true]:opacity-40", "data-[drop=inside]:bg-primary/10 data-[drop=inside]:ring-1 data-[drop=inside]:ring-primary/45", "data-[drop=before]:before:absolute data-[drop=before]:before:-top-0.5 data-[drop=before]:before:right-2 data-[drop=before]:before:left-2 data-[drop=before]:before:h-0.5 data-[drop=before]:before:rounded-full data-[drop=before]:before:bg-primary", "data-[drop=after]:after:absolute data-[drop=after]:after:-bottom-0.5 data-[drop=after]:after:right-2 data-[drop=after]:after:left-2 data-[drop=after]:after:h-0.5 data-[drop=after]:after:rounded-full data-[drop=after]:after:bg-primary", !acceptsChildren && active && "bg-muted text-foreground", acceptsChildren && containerActive && "bg-muted/55 text-foreground ring-1 ring-border/70", kind === "action" && "text-xs text-muted-foreground", disabled2 && "cursor-not-allowed opacity-45");
4648
+ return cn("group/resource relative flex min-h-8 min-w-0 cursor-pointer items-center gap-2 rounded-lg pr-2 text-[0.8125rem] outline-none", "text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", "focus-visible:bg-muted/70 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", "data-[menu-open=true]:bg-muted data-[menu-open=true]:text-foreground", "data-[dragging=true]:opacity-40", "data-[drop=inside]:bg-primary/10 data-[drop=inside]:ring-1 data-[drop=inside]:ring-primary/45", "data-[drop=before]:before:absolute data-[drop=before]:before:-top-0.5 data-[drop=before]:before:right-2 data-[drop=before]:before:left-2 data-[drop=before]:before:h-0.5 data-[drop=before]:before:rounded-full data-[drop=before]:before:bg-primary", "data-[drop=after]:after:absolute data-[drop=after]:after:-bottom-0.5 data-[drop=after]:after:right-2 data-[drop=after]:after:left-2 data-[drop=after]:after:h-0.5 data-[drop=after]:after:rounded-full data-[drop=after]:after:bg-primary", !acceptsChildren && active && "bg-muted text-foreground", acceptsChildren && containerActive && "bg-muted/55 text-foreground ring-1 ring-border/70", kind === "action" && "text-xs text-muted-foreground", disabled2 && "cursor-not-allowed opacity-45");
4755
4649
  }
4756
4650
  function useResourceRowEvents({ acceptsChildren, allowMove, disabled: disabled2, kind, onContainerSelect, onDragEnd, onDragOver, onDragStart, onDrop, onRenameStart, onSelect, renaming, row }) {
4757
4651
  const draggedRef = useRef2(false);
@@ -4934,7 +4828,7 @@ function ResourceList({ flat, selectedId, activeContainerId, expandedIds, focuse
4934
4828
  }), draggingId ? /* @__PURE__ */ jsx("div", {
4935
4829
  "aria-hidden": "true",
4936
4830
  "data-active": dropTarget?.id === null || void 0,
4937
- className: "absolute inset-x-1 bottom-0 flex h-8 items-center justify-center rounded-lg border border-dashed border-border text-[10px] text-muted-foreground data-[active=true]:border-primary/50 data-[active=true]:bg-primary/10 data-[active=true]:text-foreground",
4831
+ className: "absolute inset-x-1 bottom-0 flex h-8 items-center justify-center rounded-lg border border-dashed border-border text-[0.625rem] text-muted-foreground data-[active=true]:border-primary/50 data-[active=true]:bg-primary/10 data-[active=true]:text-foreground",
4938
4832
  children: "Move to top level"
4939
4833
  }) : null]
4940
4834
  }), /* @__PURE__ */ jsx("span", {
@@ -5507,7 +5401,7 @@ function ProjectFolder({ title, description = "Updated recently", previews = [],
5507
5401
  "aria-hidden": "true",
5508
5402
  className: "pointer-events-none absolute inset-0",
5509
5403
  children: /* @__PURE__ */ jsx("span", {
5510
- className: "absolute left-1/2 top-0 block h-0 w-0",
5404
+ className: "absolute left-1/2 top-0 block size-0",
5511
5405
  children: /* @__PURE__ */ jsx(AnimatePresence, {
5512
5406
  initial: false,
5513
5407
  children: !isExpanded ? previewItems.map((preview, index) => {
@@ -5718,7 +5612,7 @@ function SidebarMenuItem({ icon: Icon, label, onClick, href }) {
5718
5612
  }
5719
5613
  function KbdHint({ children }) {
5720
5614
  return /* @__PURE__ */ jsx("kbd", {
5721
- className: "rounded border border-border/60 bg-muted/60 px-1 font-mono text-[10px] leading-4 text-muted-foreground",
5615
+ className: "rounded border border-border/60 bg-muted/60 px-1 font-mono text-[0.625rem] leading-4 text-muted-foreground",
5722
5616
  children
5723
5617
  });
5724
5618
  }
@@ -5816,7 +5710,7 @@ function FleetSessionSidebarNavigation({ brandMenuOpen, setBrandMenuOpen, search
5816
5710
  /* @__PURE__ */ jsxs("div", {
5817
5711
  className: "border-t border-border/60 px-2 pb-2 pt-1.5",
5818
5712
  children: [/* @__PURE__ */ jsx("span", {
5819
- className: "px-2 pb-1 font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground/60",
5713
+ className: "px-2 pb-1 font-mono text-[0.625rem] uppercase tracking-[0.14em] text-muted-foreground/60",
5820
5714
  children: "Projects"
5821
5715
  }), /* @__PURE__ */ jsxs("div", {
5822
5716
  className: "mt-1 flex flex-col gap-0.5",
@@ -5831,12 +5725,12 @@ function FleetSessionSidebarNavigation({ brandMenuOpen, setBrandMenuOpen, search
5831
5725
  children: project.name
5832
5726
  }),
5833
5727
  /* @__PURE__ */ jsx("span", {
5834
- className: "max-w-24 truncate text-[10px] text-muted-foreground/55",
5728
+ className: "max-w-24 truncate text-[0.625rem] text-muted-foreground/55",
5835
5729
  children: project.pathLabel
5836
5730
  })
5837
5731
  ]
5838
5732
  }, project.projectId)), matchingProjects.length === 0 ? /* @__PURE__ */ jsxs("span", {
5839
- className: "px-2 py-2 text-center text-[11px] text-muted-foreground/60",
5733
+ className: "p-2 text-center text-[0.6875rem] text-muted-foreground/60",
5840
5734
  children: [
5841
5735
  "No project matches \u201C",
5842
5736
  query,
@@ -5846,7 +5740,7 @@ function FleetSessionSidebarNavigation({ brandMenuOpen, setBrandMenuOpen, search
5846
5740
  })]
5847
5741
  }),
5848
5742
  /* @__PURE__ */ jsxs("div", {
5849
- className: "flex items-center justify-end gap-3 border-t border-border/60 px-3 py-2 text-[10px] text-muted-foreground/70",
5743
+ className: "flex items-center justify-end gap-3 border-t border-border/60 px-3 py-2 text-[0.625rem] text-muted-foreground/70",
5850
5744
  children: [
5851
5745
  /* @__PURE__ */ jsxs("span", {
5852
5746
  className: "flex items-center gap-1",
@@ -5872,7 +5766,7 @@ function FleetSessionSidebarNavigation({ brandMenuOpen, setBrandMenuOpen, search
5872
5766
  }), /* @__PURE__ */ jsxs("button", {
5873
5767
  type: "button",
5874
5768
  onClick: onNewSession,
5875
- className: "flex h-8 w-full items-center justify-start gap-2 rounded-lg px-2 text-[13px] font-normal text-sidebar-foreground outline-none transition-colors hover:bg-sidebar-accent focus-visible:bg-sidebar-accent focus-visible:ring-2 focus-visible:ring-sidebar-ring",
5769
+ className: "flex h-8 w-full items-center justify-start gap-2 rounded-lg px-2 text-[0.8125rem] font-normal text-sidebar-foreground outline-none transition-colors hover:bg-sidebar-accent focus-visible:bg-sidebar-accent focus-visible:ring-2 focus-visible:ring-sidebar-ring",
5876
5770
  children: [/* @__PURE__ */ jsx(SquarePen, { className: "size-4 shrink-0 text-muted-foreground" }), "New chat"]
5877
5771
  })]
5878
5772
  }),
@@ -5902,7 +5796,7 @@ function FleetSessionSidebarNavigation({ brandMenuOpen, setBrandMenuOpen, search
5902
5796
  /* @__PURE__ */ jsx("div", {
5903
5797
  className: "min-w-0 flex-1",
5904
5798
  children: accountMenu ?? /* @__PURE__ */ jsx("span", {
5905
- className: "flex h-8 items-center px-2 text-[13px]",
5799
+ className: "flex h-8 items-center px-2 text-[0.8125rem]",
5906
5800
  children: "Qredence"
5907
5801
  })
5908
5802
  }),
@@ -6571,12 +6465,12 @@ function FleetSessionSidebarCreateDialog({ createOpen, setCreateOpen, directoryB
6571
6465
  })]
6572
6466
  }),
6573
6467
  /* @__PURE__ */ jsx("span", {
6574
- className: "shrink-0 rounded-full bg-primary/10 px-2 py-1 text-[11px] font-medium text-primary",
6468
+ className: "shrink-0 rounded-full bg-primary/10 px-2 py-1 text-[0.6875rem] font-medium text-primary",
6575
6469
  children: "Selected"
6576
6470
  })
6577
6471
  ]
6578
6472
  }), /* @__PURE__ */ jsxs("div", {
6579
- className: "space-y-2 border-t px-3 py-3",
6473
+ className: "space-y-2 border-t p-3",
6580
6474
  children: [/* @__PURE__ */ jsxs("div", {
6581
6475
  className: "flex items-center justify-between gap-2",
6582
6476
  children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
@@ -6632,7 +6526,7 @@ function FleetSessionSidebarCreateDialog({ createOpen, setCreateOpen, directoryB
6632
6526
  className: "block truncate font-medium text-foreground",
6633
6527
  children: pathEntryLabel(entry)
6634
6528
  }), /* @__PURE__ */ jsx("span", {
6635
- className: "block truncate text-[11px] text-muted-foreground",
6529
+ className: "block truncate text-[0.6875rem] text-muted-foreground",
6636
6530
  title: entry.pathLabel,
6637
6531
  children: entry.pathLabel
6638
6532
  })]
@@ -7814,7 +7708,7 @@ function ApprovalCard({ title = "Approval required", description, children, ques
7814
7708
  questions.length
7815
7709
  ]
7816
7710
  }) : /* @__PURE__ */ jsx("span", {
7817
- className: cn("shrink-0 rounded-full border px-2 py-0.5 text-[11px] font-medium transition-colors", getStatusBadgeClass(status)),
7711
+ className: cn("shrink-0 rounded-full border px-2 py-0.5 text-[0.6875rem] font-medium transition-colors", getStatusBadgeClass(status)),
7818
7712
  children: statusLabel2
7819
7713
  }),
7820
7714
  onDismiss ? /* @__PURE__ */ jsx("button", {
@@ -7980,7 +7874,7 @@ function InputQuestionBar({ questionBar, navigation, roundedTop, onDismiss }) {
7980
7874
  className: "flex h-7 items-center justify-between border-b border-border px-3 text-xs text-an-tool-color-muted",
7981
7875
  children: [/* @__PURE__ */ jsxs("div", {
7982
7876
  className: "inline-flex items-center gap-1.5",
7983
- children: [/* @__PURE__ */ jsx(MessageCircleQuestionMark, { className: "h-3.5 w-3.5" }), "Question"]
7877
+ children: [/* @__PURE__ */ jsx(MessageCircleQuestionMark, { className: "size-3.5" }), "Question"]
7984
7878
  }), showQuestionNavigation && /* @__PURE__ */ jsxs("div", {
7985
7879
  className: "inline-flex items-center gap-1",
7986
7880
  children: [
@@ -7990,7 +7884,7 @@ function InputQuestionBar({ questionBar, navigation, roundedTop, onDismiss }) {
7990
7884
  disabled: !canGoPrev,
7991
7885
  className: "relative inline-flex size-5 items-center justify-center rounded-[4px] transition-[background-color,transform] duration-150 after:absolute after:inset-x-0 after:-top-2.5 after:-bottom-2.5 hover:bg-an-background-secondary active:scale-[0.96] disabled:opacity-40 disabled:active:scale-100",
7992
7886
  "aria-label": "Previous question",
7993
- children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5" })
7887
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-3.5" })
7994
7888
  }),
7995
7889
  /* @__PURE__ */ jsxs("span", {
7996
7890
  className: "tabular-nums",
@@ -8006,7 +7900,7 @@ function InputQuestionBar({ questionBar, navigation, roundedTop, onDismiss }) {
8006
7900
  disabled: !canGoNext,
8007
7901
  className: "relative inline-flex size-5 items-center justify-center rounded-[4px] transition-[background-color,transform] duration-150 after:absolute after:inset-x-0 after:-top-2.5 after:-bottom-2.5 hover:bg-an-background-secondary active:scale-[0.96] disabled:opacity-40 disabled:active:scale-100",
8008
7902
  "aria-label": "Next question",
8009
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" })
7903
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" })
8010
7904
  })
8011
7905
  ]
8012
7906
  })]
@@ -8047,7 +7941,7 @@ var ModeSelector = memo(function ModeSelector2({ modes, value, defaultValue, onC
8047
7941
  const hasMultiple = modes.length > 1;
8048
7942
  const trigger = /* @__PURE__ */ jsxs("button", {
8049
7943
  type: "button",
8050
- className: cn("relative inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-full px-2 text-[12px] leading-4 text-foreground/40 transition-[background-color,transform] duration-150 after:absolute after:inset-x-0 after:-top-1.5 after:-bottom-1.5 hover:bg-foreground/6 active:scale-[0.96]", !hasMultiple && "pointer-events-none", className),
7944
+ className: cn("relative inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-full px-2 text-[0.75rem] leading-4 text-foreground/40 transition-[background-color,transform] duration-150 after:absolute after:inset-x-0 after:-top-1.5 after:-bottom-1.5 hover:bg-foreground/6 active:scale-[0.96]", !hasMultiple && "pointer-events-none", className),
8051
7945
  "aria-label": "Select mode",
8052
7946
  children: [
8053
7947
  ActiveIcon && /* @__PURE__ */ jsx(ActiveIcon, { className: "size-3.5 shrink-0" }),
@@ -8071,7 +7965,7 @@ var ModeSelector = memo(function ModeSelector2({ modes, value, defaultValue, onC
8071
7965
  return /* @__PURE__ */ jsxs("button", {
8072
7966
  type: "button",
8073
7967
  onClick: () => handleSelect(mode.id),
8074
- className: cn("flex w-full cursor-pointer items-start gap-2 rounded-[6px] px-2 py-2 text-left text-[12px] leading-4 text-foreground transition-[background-color,transform] duration-150 hover:bg-foreground/6 active:scale-[0.96]", isActive && "bg-foreground/6"),
7968
+ className: cn("flex w-full cursor-pointer items-start gap-2 rounded-[6px] px-2 py-2 text-left text-[0.75rem] leading-4 text-foreground transition-[background-color,transform] duration-150 hover:bg-foreground/6 active:scale-[0.96]", isActive && "bg-foreground/6"),
8075
7969
  children: [
8076
7970
  Icon && /* @__PURE__ */ jsx(Icon, { className: "mt-0.5 size-3.5 shrink-0" }),
8077
7971
  /* @__PURE__ */ jsxs("span", {
@@ -8127,7 +8021,7 @@ function ComposerMenuItem({ active = false, className, ...props }) {
8127
8021
  type: "button",
8128
8022
  "data-slot": "composer-menu-item",
8129
8023
  "data-active": active || void 0,
8130
- className: cn("flex w-full items-center gap-2.5 rounded-[10px] px-2.5 py-2 text-[13.5px] transition-colors", active ? field : "hover:bg-foreground/[0.04]", className),
8024
+ className: cn("flex w-full items-center gap-2.5 rounded-[10px] px-2.5 py-2 text-[0.84375rem] transition-colors", active ? field : "hover:bg-foreground/[0.04]", className),
8131
8025
  ...props
8132
8026
  });
8133
8027
  }
@@ -8224,7 +8118,7 @@ var ComposerTriggerPopover = memo(function ComposerTriggerPopover2({ open, kind,
8224
8118
  children: title ?? (kind === "slash" ? "Commands" : "Workspace")
8225
8119
  }),
8226
8120
  query ? /* @__PURE__ */ jsx("span", {
8227
- className: "ml-auto max-w-[50%] truncate font-mono text-[11px]",
8121
+ className: "ml-auto max-w-[50%] truncate font-mono text-[0.6875rem]",
8228
8122
  children: query
8229
8123
  }) : null,
8230
8124
  onClose ? /* @__PURE__ */ jsx("button", {
@@ -8250,7 +8144,7 @@ var ComposerTriggerPopover = memo(function ComposerTriggerPopover2({ open, kind,
8250
8144
  role: "group",
8251
8145
  "aria-label": group.label,
8252
8146
  children: [/* @__PURE__ */ jsx("div", {
8253
- className: "px-3 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground",
8147
+ className: "px-3 pb-1 pt-2 text-[0.625rem] font-medium uppercase tracking-wide text-muted-foreground",
8254
8148
  children: group.label
8255
8149
  }), group.items.map((item, index) => renderItem(item, offset + index))]
8256
8150
  }, group.id);
@@ -8258,7 +8152,7 @@ var ComposerTriggerPopover = memo(function ComposerTriggerPopover2({ open, kind,
8258
8152
  })]
8259
8153
  }) : null;
8260
8154
  });
8261
- var LazyModelSelectorList = lazy(() => import("./model-selector-list-wCp4_UWC-2NQUCAM3.js").then(({ ModelSelectorList: ModelSelectorList2 }) => ({ default: ModelSelectorList2 })));
8155
+ var LazyModelSelectorList = lazy(() => import("./model-selector-list-OYnzNbyu-HBGCNF2L.js").then(({ ModelSelectorList: ModelSelectorList2 }) => ({ default: ModelSelectorList2 })));
8262
8156
  function ModelSelectorList(props) {
8263
8157
  return /* @__PURE__ */ jsx(Suspense, {
8264
8158
  fallback: /* @__PURE__ */ jsx("div", {
@@ -8314,14 +8208,14 @@ var ModelSelector = memo(function ModelSelector2({ models, value, effort, open:
8314
8208
  align: "start",
8315
8209
  className: cn("w-[min(24rem,calc(100vw-2rem))] max-h-[min(55vh,28rem)] overflow-hidden p-0", contentClassName),
8316
8210
  trigger,
8317
- children: /* @__PURE__ */ jsx(ModelSelectorList, {
8211
+ children: open ? /* @__PURE__ */ jsx(ModelSelectorList, {
8318
8212
  models,
8319
8213
  selectedModel,
8320
8214
  selectedEffort,
8321
8215
  effortLabel,
8322
8216
  onModelChange,
8323
8217
  onEffortChange
8324
- })
8218
+ }) : null
8325
8219
  });
8326
8220
  });
8327
8221
  function useQuestionBarNavigation(questionBar) {
@@ -8638,6 +8532,7 @@ var FLEET_PI_CHAT_MODES = [
8638
8532
  }
8639
8533
  ];
8640
8534
  var EMPTY_WORKSPACE_REFERENCES = [];
8535
+ var CHAT_MODES = [...FLEET_PI_CHAT_MODES];
8641
8536
  function FleetPiInputBar(props) {
8642
8537
  return /* @__PURE__ */ jsx(FleetPiInputBarContent, { ...props });
8643
8538
  }
@@ -8665,6 +8560,8 @@ function FleetPiInputBarContent({ modelKey, models, status, infoDescription, cha
8665
8560
  attachments,
8666
8561
  slashCommands
8667
8562
  });
8563
+ const handleChatModeChange = useCallback2((id) => onChatModeChange?.(id), [onChatModeChange]);
8564
+ const handleEffortChange = useCallback2((level) => onThinkingLevelChange?.(level), [onThinkingLevelChange]);
8668
8565
  return /* @__PURE__ */ jsx("div", {
8669
8566
  className: cn("shrink-0 px-3 pb-3", className),
8670
8567
  children: /* @__PURE__ */ jsxs("div", {
@@ -8774,15 +8671,15 @@ function FleetPiInputBarContent({ modelKey, models, status, infoDescription, cha
8774
8671
  },
8775
8672
  onKeyDown: handlePromptKeyDown,
8776
8673
  leadingAction: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ModeSelector, {
8777
- modes: [...FLEET_PI_CHAT_MODES],
8674
+ modes: CHAT_MODES,
8778
8675
  value: chatMode,
8779
- onChange: (id) => onChatModeChange?.(id)
8676
+ onChange: handleChatModeChange
8780
8677
  }), /* @__PURE__ */ jsx(ModelSelector, {
8781
8678
  models: selectorModels,
8782
8679
  value: modelKey,
8783
8680
  effort: thinkingLevel,
8784
8681
  onModelChange: handleSelectorModelChange,
8785
- onEffortChange: (level) => onThinkingLevelChange?.(level),
8682
+ onEffortChange: handleEffortChange,
8786
8683
  open: combinedPickerOpen,
8787
8684
  onOpenChange: handleCombinedPickerOpenChange,
8788
8685
  placeholder: "Model",
@@ -8803,7 +8700,7 @@ function getChatErrorPresentation(error) {
8803
8700
  message: error.message.replace(/\s+(?:Socket|Daemon log):\s*[^\n]*(?:\s+(?:Socket|Daemon log):\s*[^\n]*)*/gi, "")
8804
8701
  };
8805
8702
  }
8806
- var LazyFleetPiToolRenderer = lazy(() => import("./fleet-pi-tool-renderer-CgbmlIoe-7MSJLEGU.js").then((n) => n.n).then(({ FleetPiToolRenderer: FleetPiToolRenderer2 }) => ({ default: FleetPiToolRenderer2 })));
8703
+ var LazyFleetPiToolRenderer = lazy(() => import("./fleet-pi-tool-renderer-umKunT3K-O4GBH35V.js").then((n) => n.n).then(({ FleetPiToolRenderer: FleetPiToolRenderer2 }) => ({ default: FleetPiToolRenderer2 })));
8807
8704
  function FleetPiToolRenderer(props) {
8808
8705
  return /* @__PURE__ */ jsx(Suspense, {
8809
8706
  fallback: /* @__PURE__ */ jsx("div", {
@@ -8813,17 +8710,20 @@ function FleetPiToolRenderer(props) {
8813
8710
  children: /* @__PURE__ */ jsx(LazyFleetPiToolRenderer, { ...props })
8814
8711
  });
8815
8712
  }
8816
- var LazyAgentActivity = lazy(() => import("./agent-activity-B-JMvecd-SLE3GGY2.js").then(({ AgentActivity: AgentActivity2 }) => ({ default: AgentActivity2 })));
8713
+ var LazyAgentActivity = lazy(() => import("./agent-activity-CS2rbF_C-A3R26CYH.js").then(({ AgentActivity: AgentActivity2 }) => ({ default: AgentActivity2 })));
8817
8714
  function AgentActivity(props) {
8818
- return /* @__PURE__ */ jsx(Suspense, {
8819
- fallback: /* @__PURE__ */ jsx("div", {
8820
- className: "mt-2 h-8 animate-pulse rounded-md bg-muted/40",
8821
- "aria-label": "Loading activity"
8822
- }),
8823
- children: /* @__PURE__ */ jsx(LazyAgentActivity, { ...props })
8715
+ return /* @__PURE__ */ jsx("div", {
8716
+ className: "mt-2 min-h-8",
8717
+ children: /* @__PURE__ */ jsx(Suspense, {
8718
+ fallback: /* @__PURE__ */ jsx("div", {
8719
+ className: "h-8 animate-pulse rounded-md bg-muted/40",
8720
+ "aria-label": "Loading activity"
8721
+ }),
8722
+ children: /* @__PURE__ */ jsx(LazyAgentActivity, { ...props })
8723
+ })
8824
8724
  });
8825
8725
  }
8826
- var LazyFleetReasoningPanel = lazy(() => import("./fleet-reasoning-panel-D_K48UOT-GN2PA6KT.js").then(({ FleetReasoningPanel: FleetReasoningPanel2 }) => ({ default: FleetReasoningPanel2 })));
8726
+ var LazyFleetReasoningPanel = lazy(() => import("./fleet-reasoning-panel-BxC2COxi-GPLMQSTT.js").then(({ FleetReasoningPanel: FleetReasoningPanel2 }) => ({ default: FleetReasoningPanel2 })));
8827
8727
  function FleetReasoningPanel(props) {
8828
8728
  return /* @__PURE__ */ jsx(Suspense, {
8829
8729
  fallback: /* @__PURE__ */ jsx("div", {
@@ -8833,7 +8733,7 @@ function FleetReasoningPanel(props) {
8833
8733
  children: /* @__PURE__ */ jsx(LazyFleetReasoningPanel, { ...props })
8834
8734
  });
8835
8735
  }
8836
- var LazyFleetToolTimeline = lazy(() => import("./fleet-tool-timeline-DwRqQgOj-HUFLGMDV.js").then((n) => n.n).then(({ FleetToolTimeline: FleetToolTimeline2 }) => ({ default: FleetToolTimeline2 })));
8736
+ var LazyFleetToolTimeline = lazy(() => import("./fleet-tool-timeline-IB36_PB2-XJENTO6I.js").then((n) => n.n).then(({ FleetToolTimeline: FleetToolTimeline2 }) => ({ default: FleetToolTimeline2 })));
8837
8737
  function FleetToolTimeline(props) {
8838
8738
  return /* @__PURE__ */ jsx(Suspense, {
8839
8739
  fallback: /* @__PURE__ */ jsx("div", {
@@ -8843,7 +8743,7 @@ function FleetToolTimeline(props) {
8843
8743
  children: /* @__PURE__ */ jsx(LazyFleetToolTimeline, { ...props })
8844
8744
  });
8845
8745
  }
8846
- var LazyFleetSubagentList = lazy(() => import("./fleet-subagent-list-5luKtpds-3OTVFHJQ.js").then((n) => n.n).then(({ FleetSubagentList: FleetSubagentList2 }) => ({ default: FleetSubagentList2 })));
8746
+ var LazyFleetSubagentList = lazy(() => import("./fleet-subagent-list-CpSYzCIq-JDH2LHSS.js").then((n) => n.n).then(({ FleetSubagentList: FleetSubagentList2 }) => ({ default: FleetSubagentList2 })));
8847
8747
  function FleetSubagentList(props) {
8848
8748
  return /* @__PURE__ */ jsx(Suspense, {
8849
8749
  fallback: /* @__PURE__ */ jsx("div", {
@@ -8853,17 +8753,20 @@ function FleetSubagentList(props) {
8853
8753
  children: /* @__PURE__ */ jsx(LazyFleetSubagentList, { ...props })
8854
8754
  });
8855
8755
  }
8856
- var LazyPromptSuggestions = lazy(() => import("./prompt-suggestions-BOmHi4-J-C563CHFU.js").then(({ PromptSuggestions: PromptSuggestions2 }) => ({ default: PromptSuggestions2 })));
8756
+ var LazyPromptSuggestions = lazy(() => import("./prompt-suggestions-D4AEEY7K-RZSP7PWV.js").then(({ PromptSuggestions: PromptSuggestions2 }) => ({ default: PromptSuggestions2 })));
8857
8757
  function PromptSuggestions(props) {
8858
- return /* @__PURE__ */ jsx(Suspense, {
8859
- fallback: /* @__PURE__ */ jsx("div", {
8860
- className: "h-8 animate-pulse rounded-full bg-muted/40",
8861
- "aria-label": "Loading suggestions"
8862
- }),
8863
- children: /* @__PURE__ */ jsx(LazyPromptSuggestions, { ...props })
8758
+ return /* @__PURE__ */ jsx("div", {
8759
+ className: "min-h-8",
8760
+ children: /* @__PURE__ */ jsx(Suspense, {
8761
+ fallback: /* @__PURE__ */ jsx("div", {
8762
+ className: "h-8 animate-pulse rounded-full bg-muted/40",
8763
+ "aria-label": "Loading suggestions"
8764
+ }),
8765
+ children: /* @__PURE__ */ jsx(LazyPromptSuggestions, { ...props })
8766
+ })
8864
8767
  });
8865
8768
  }
8866
- var LazyFleetMessageQueue = lazy(() => import("./fleet-message-queue-BvMcWtLo-6CMMI73U.js").then(({ FleetMessageQueue: FleetMessageQueue2 }) => ({ default: FleetMessageQueue2 })));
8769
+ var LazyFleetMessageQueue = lazy(() => import("./fleet-message-queue-j0DCU5Xy-5HKBHMPV.js").then(({ FleetMessageQueue: FleetMessageQueue2 }) => ({ default: FleetMessageQueue2 })));
8867
8770
  function FleetMessageQueue(props) {
8868
8771
  return /* @__PURE__ */ jsx(Suspense, {
8869
8772
  fallback: null,
@@ -9072,8 +8975,8 @@ function AssistantMessage({ messages, isLast, isStreaming, suppressQuestionTool,
9072
8975
  className: "mt-2 max-w-none"
9073
8976
  }) : null,
9074
8977
  isLast && presentation ? /* @__PURE__ */ jsx(FleetSubagentList, {
9075
- children: presentation.rlmChildren,
9076
- tree: presentation.rlmTree
8978
+ tree: presentation.rlmTree,
8979
+ children: presentation.rlmChildren
9077
8980
  }) : null
9078
8981
  ] })
9079
8982
  }) })
@@ -9136,8 +9039,12 @@ function ChatComposerHost({ inputBar, status, suggestions, onSend, onStop, isEmp
9136
9039
  });
9137
9040
  }
9138
9041
  var MemoChatComposerHost = memo(ChatComposerHost);
9042
+ function getConversationTurnKey(turn, turnIndex) {
9043
+ return turn.user?.id ?? turn.assistants[0]?.id ?? `assistant-turn-${turnIndex}`;
9044
+ }
9139
9045
  function FleetPiAgentChat({ toolRenderers = PI_TOOL_RENDERERS, suggestions, status, onStop, onSend, inputBar, className, messages, error, suppressQuestionTool = false, onOpenUIAction, activityLabel, presentation, artifactRuns, onOpenArtifact, onOpenUIArtifactReady, queue, onDeleteQueuedMessage }) {
9140
9046
  const draftSetterRef = useRef2(null);
9047
+ const viewportRef = useRef2(null);
9141
9048
  const setDraft = useCallback2((value) => draftSetterRef.current?.(value), []);
9142
9049
  const turns = useMemo2(() => groupMessages(messages), [messages]);
9143
9050
  const suggestionItems2 = resolveSuggestions(suggestions);
@@ -9185,6 +9092,22 @@ function FleetPiAgentChat({ toolRenderers = PI_TOOL_RENDERERS, suggestions, stat
9185
9092
  presentation: void 0,
9186
9093
  artifactRuns: void 0
9187
9094
  }), []);
9095
+ const renderTurn = useCallback2((turn, turnIndex) => {
9096
+ const isLast = turnIndex === turns.length - 1;
9097
+ return /* @__PURE__ */ jsx(ConversationTurnView, {
9098
+ turn,
9099
+ state: isLast ? stateForLast : stateForRest,
9100
+ rendering,
9101
+ activity: isLast ? activityForLast : activityForRest
9102
+ });
9103
+ }, [
9104
+ activityForLast,
9105
+ activityForRest,
9106
+ rendering,
9107
+ stateForLast,
9108
+ stateForRest,
9109
+ turns.length
9110
+ ]);
9188
9111
  const isEmpty = turns.length === 0 && !error;
9189
9112
  const errorPresentation = error ? getChatErrorPresentation(error) : null;
9190
9113
  const composerNode = /* @__PURE__ */ jsx(MemoChatComposerHost, {
@@ -9203,6 +9126,7 @@ function FleetPiAgentChat({ toolRenderers = PI_TOOL_RENDERERS, suggestions, stat
9203
9126
  className: "flex-1",
9204
9127
  busy: isStreaming,
9205
9128
  followOutput: true,
9129
+ viewportRef,
9206
9130
  smooth: !isStreaming,
9207
9131
  contentClassName: cn("mx-auto flex w-full max-w-an flex-col gap-5 px-4", isEmpty ? "min-h-full items-center justify-center py-8" : "py-6"),
9208
9132
  children: [
@@ -9211,15 +9135,13 @@ function FleetPiAgentChat({ toolRenderers = PI_TOOL_RENDERERS, suggestions, stat
9211
9135
  onSelect: (item) => setDraft(item.value ?? item.label),
9212
9136
  composer: composerNode
9213
9137
  }) : null,
9214
- turns.map((turn, turnIndex) => {
9215
- const key = turn.user?.id ?? `assistant-turn-${turnIndex}`;
9216
- const isLast = turnIndex === turns.length - 1;
9217
- return /* @__PURE__ */ jsx(ConversationTurnView, {
9218
- turn,
9219
- state: isLast ? stateForLast : stateForRest,
9220
- rendering,
9221
- activity: isLast ? activityForLast : activityForRest
9222
- }, key);
9138
+ /* @__PURE__ */ jsx(VirtualizedTurnList, {
9139
+ estimateSize: 400,
9140
+ getItemKey: getConversationTurnKey,
9141
+ itemGap: 20,
9142
+ items: turns,
9143
+ renderItem: renderTurn,
9144
+ viewportRef
9223
9145
  }),
9224
9146
  errorPresentation ? /* @__PURE__ */ jsxs("div", {
9225
9147
  role: "alert",
@@ -9358,175 +9280,26 @@ function buildChatInputBarProps(composer, activeSessionId) {
9358
9280
  onEffortPickerOpenChange: composer.setEffortPickerOpen
9359
9281
  };
9360
9282
  }
9361
- var LazyChatCommandPalette = lazy(() => import("./chat-command-palette-DmDvAEZe-CONFK6YH.js").then(({ ChatCommandPalette }) => ({ default: ChatCommandPalette })));
9362
- var LazySettingsDialog = lazy(() => import("./settings-dialog-CdFpyzR--JVYIS5OD.js").then(({ SettingsDialog }) => ({ default: SettingsDialog })));
9363
- var LazyForkPickerDialog = lazy(() => import("./fork-picker-dialog-DfSRzUI5-EBRK5HNO.js").then(({ ForkPickerDialog }) => ({ default: ForkPickerDialog })));
9364
- function ChatCommandPaletteOverlay({ chrome, conversation, dialogs, panels, session }) {
9365
- return /* @__PURE__ */ jsx(Fragment$1, { children: dialogs.commandPaletteOpen ? /* @__PURE__ */ jsx(Suspense, {
9366
- fallback: null,
9367
- children: /* @__PURE__ */ jsx(LazyChatCommandPalette, {
9368
- open: true,
9369
- onOpenChange: dialogs.setCommandPaletteOpen,
9370
- onNewSession: () => void session.startNewSession(),
9371
- onStop: conversation.stop,
9372
- onResumeSession: (sessionToResume) => void session.resumeSession({ sessionId: sessionToResume.sessionId }),
9373
- onSetRightPanel: panels.setRightPanel,
9374
- onThemeChange: chrome.handleThemePreferenceChange,
9375
- sessions: session.sessions,
9376
- isStreaming: conversation.status === "streaming",
9377
- themePreference: chrome.themePreference
9378
- })
9379
- }) : null });
9283
+ function getChatAuthBearerToken$1() {
9284
+ return null;
9380
9285
  }
9381
- function ChatWorkspaceOverlayDialogs({ dialogs }) {
9382
- const { forkFromEntry, forkPickerEntries, setForkPickerEntries, setSettingsDialogOpen, setSettingsInitialTab, settingsDialogOpen, settingsInitialTab } = dialogs;
9383
- const handleSettingsOpenChange = useCallback2((open) => {
9384
- setSettingsDialogOpen(open);
9385
- if (!open) setSettingsInitialTab(void 0);
9386
- }, [setSettingsDialogOpen, setSettingsInitialTab]);
9387
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [settingsDialogOpen ? /* @__PURE__ */ jsx(Suspense, {
9388
- fallback: null,
9389
- children: /* @__PURE__ */ jsx(LazySettingsDialog, {
9390
- open: true,
9391
- onOpenChange: handleSettingsOpenChange,
9392
- initialTab: settingsInitialTab
9393
- })
9394
- }) : null, forkPickerEntries ? /* @__PURE__ */ jsx(Suspense, {
9395
- fallback: null,
9396
- children: /* @__PURE__ */ jsx(LazyForkPickerDialog, {
9397
- entries: forkPickerEntries,
9398
- onOpenChange: (open) => {
9399
- if (!open) setForkPickerEntries(null);
9400
- },
9401
- onPick: forkFromEntry
9402
- })
9403
- }) : null] });
9404
- }
9405
- var FLEET_PANEL_KEYBINDINGS_STORAGE_KEY = "fleet-prime:v1:panel-keybindings";
9406
- var DEFAULT_FLEET_PANEL_KEYBINDINGS = {
9407
- toggleResources: {
9408
- code: "Digit1",
9409
- ctrlOrMeta: true,
9410
- shift: true
9411
- },
9412
- toggleWorkspace: {
9413
- code: "Digit2",
9414
- ctrlOrMeta: true,
9415
- shift: true
9416
- },
9417
- toggleArtifacts: {
9418
- code: "Digit3",
9419
- ctrlOrMeta: true,
9420
- shift: true
9421
- },
9422
- toggleRepl: {
9423
- code: "Digit4",
9424
- ctrlOrMeta: true,
9425
- shift: true
9426
- },
9427
- toggleSubagents: {
9428
- code: "Digit5",
9429
- ctrlOrMeta: true,
9430
- shift: true
9431
- },
9432
- toggleCommandPalette: {
9433
- code: "KeyK",
9434
- ctrlOrMeta: true
9435
- },
9436
- closePanel: { code: "Escape" },
9437
- focusPanel: {
9438
- code: "KeyP",
9439
- ctrlOrMeta: true,
9440
- shift: true
9441
- },
9442
- focusChat: {
9443
- code: "KeyC",
9444
- ctrlOrMeta: true,
9445
- shift: true
9446
- }
9447
- };
9448
- function readKeybindings() {
9449
- try {
9450
- const value = window.localStorage.getItem(FLEET_PANEL_KEYBINDINGS_STORAGE_KEY);
9451
- if (!value) return DEFAULT_FLEET_PANEL_KEYBINDINGS;
9452
- const overrides = JSON.parse(value);
9453
- return {
9454
- ...DEFAULT_FLEET_PANEL_KEYBINDINGS,
9455
- ...overrides
9456
- };
9457
- } catch {
9458
- return DEFAULT_FLEET_PANEL_KEYBINDINGS;
9459
- }
9460
- }
9461
- function matches(event, binding) {
9462
- return event.code === binding.code && (event.ctrlKey || event.metaKey) === Boolean(binding.ctrlOrMeta) && event.shiftKey === Boolean(binding.shift) && event.altKey === Boolean(binding.alt);
9463
- }
9464
- function focusChatComposer() {
9465
- document.querySelector("[data-fleet-chat-focus] textarea, [data-fleet-chat-focus] [contenteditable='true'], [data-fleet-chat-focus] input")?.focus({ preventScroll: true });
9466
- }
9467
- function usePanelKeybindings({ onCommandPaletteToggle, onClosePanel, rightPanel, setRightPanel }) {
9468
- useEffect2(() => {
9469
- const keybindings = readKeybindings();
9470
- const handleKeyDown = (event) => {
9471
- const match = (action) => matches(event, keybindings[action]);
9472
- let handled = true;
9473
- if (match("toggleResources")) setRightPanel(rightPanel === "resources" ? null : "resources");
9474
- else if (match("toggleWorkspace")) setRightPanel(rightPanel === "workspace" ? null : "workspace");
9475
- else if (match("toggleArtifacts")) setRightPanel(rightPanel === "artifacts" ? null : "artifacts");
9476
- else if (match("toggleRepl")) setRightPanel(rightPanel === "repl" ? null : "repl");
9477
- else if (match("toggleSubagents")) setRightPanel(rightPanel === "subagents" ? null : "subagents");
9478
- else if (onCommandPaletteToggle && match("toggleCommandPalette")) onCommandPaletteToggle();
9479
- else if (rightPanel && match("closePanel")) {
9480
- if (onClosePanel) onClosePanel();
9481
- else {
9482
- setRightPanel(null);
9483
- focusChatComposer();
9484
- }
9485
- } else if (rightPanel && match("focusPanel")) document.querySelector("[data-fleet-panel-focus]")?.focus({ preventScroll: true });
9486
- else if (match("focusChat")) focusChatComposer();
9487
- else handled = false;
9488
- if (handled) {
9489
- event.preventDefault();
9490
- event.stopPropagation();
9491
- }
9492
- };
9493
- document.addEventListener("keydown", handleKeyDown);
9494
- return () => document.removeEventListener("keydown", handleKeyDown);
9495
- }, [
9496
- onCommandPaletteToggle,
9497
- onClosePanel,
9498
- rightPanel,
9499
- setRightPanel
9500
- ]);
9501
- }
9502
- function useOptionalUser() {
9503
- return null;
9504
- }
9505
- function getChatAuthBearerToken$1() {
9506
- return null;
9507
- }
9508
- async function signOut() {
9509
- }
9510
- function getChatAuthBearerToken() {
9511
- return null;
9512
- }
9513
- var ChatRequestError = class extends Error {
9514
- status;
9515
- body;
9516
- code;
9517
- remediation;
9518
- constructor(status, body) {
9519
- super(formatChatRequestErrorMessage(status, body));
9520
- this.name = "ChatRequestError";
9521
- this.status = status;
9522
- this.body = body;
9523
- const envelope = parseErrorEnvelope(body);
9524
- this.code = envelope?.code;
9525
- this.remediation = envelope?.remediation;
9526
- }
9527
- };
9528
- function isFleetErrorRemediation(value) {
9529
- return typeof value === "object" && value !== null && typeof value.action === "string" && typeof value.label === "string";
9286
+ var ChatRequestError = class extends Error {
9287
+ status;
9288
+ body;
9289
+ code;
9290
+ remediation;
9291
+ constructor(status, body) {
9292
+ super(formatChatRequestErrorMessage(status, body));
9293
+ this.name = "ChatRequestError";
9294
+ this.status = status;
9295
+ this.body = body;
9296
+ const envelope = parseErrorEnvelope(body);
9297
+ this.code = envelope?.code;
9298
+ this.remediation = envelope?.remediation;
9299
+ }
9300
+ };
9301
+ function isFleetErrorRemediation(value) {
9302
+ return typeof value === "object" && value !== null && typeof value.action === "string" && typeof value.label === "string";
9530
9303
  }
9531
9304
  function parseErrorEnvelope(body) {
9532
9305
  const trimmed = body.trim();
@@ -9569,7 +9342,7 @@ function chatErrorFromStreamEvent(event) {
9569
9342
  }
9570
9343
  async function withChatRequestHeaders(init) {
9571
9344
  const headers = new Headers(init?.headers);
9572
- const bearer = await getChatAuthBearerToken();
9345
+ const bearer = await getChatAuthBearerToken$1();
9573
9346
  if (bearer) headers.set("Authorization", `Bearer ${bearer}`);
9574
9347
  return headers;
9575
9348
  }
@@ -9669,6 +9442,167 @@ function labelForState(state) {
9669
9442
  return;
9670
9443
  }
9671
9444
  }
9445
+ function notifyChatError(error) {
9446
+ if (isDaemonDisconnectError(error)) return;
9447
+ notify.error(error instanceof Error ? error.message : String(error));
9448
+ }
9449
+ var LazyChatCommandPalette = lazy(() => import("./chat-command-palette-Dgl5tqWn-72LLEWUD.js").then(({ ChatCommandPalette }) => ({ default: ChatCommandPalette })));
9450
+ var LazySettingsDialog = lazy(() => import("./settings-dialog-BvkgNflv-GPJ6COQO.js").then(({ SettingsDialog }) => ({ default: SettingsDialog })));
9451
+ var LazyForkPickerDialog = lazy(() => import("./fork-picker-dialog-DlINz9UQ-UWIXFDJX.js").then(({ ForkPickerDialog }) => ({ default: ForkPickerDialog })));
9452
+ function ChatCommandPaletteOverlay({ chrome, conversation, dialogs, panels, session }) {
9453
+ return /* @__PURE__ */ jsx(Fragment$1, { children: dialogs.commandPaletteOpen ? /* @__PURE__ */ jsx(Suspense, {
9454
+ fallback: null,
9455
+ children: /* @__PURE__ */ jsx(LazyChatCommandPalette, {
9456
+ open: true,
9457
+ onOpenChange: dialogs.setCommandPaletteOpen,
9458
+ onNewSession: () => void session.startNewSession(),
9459
+ onStop: conversation.stop,
9460
+ onResumeSession: (sessionToResume) => void session.resumeSession({ sessionId: sessionToResume.sessionId }),
9461
+ onSetRightPanel: panels.setRightPanel,
9462
+ onThemeChange: chrome.handleThemePreferenceChange,
9463
+ sessions: session.sessions,
9464
+ isStreaming: conversation.status === "streaming",
9465
+ themePreference: chrome.themePreference
9466
+ })
9467
+ }) : null });
9468
+ }
9469
+ function ChatWorkspaceOverlayDialogs({ dialogs }) {
9470
+ const { forkFromEntry, forkPickerEntries, setForkPickerEntries, setSettingsDialogOpen, setSettingsInitialTab, settingsDialogOpen, settingsInitialTab } = dialogs;
9471
+ const [hasOpenedSettingsDialog, setHasOpenedSettingsDialog] = useState2(settingsDialogOpen);
9472
+ const [hasOpenedForkPickerDialog, setHasOpenedForkPickerDialog] = useState2(forkPickerEntries !== null);
9473
+ useEffect2(() => {
9474
+ if (settingsDialogOpen) setHasOpenedSettingsDialog(true);
9475
+ }, [settingsDialogOpen]);
9476
+ useEffect2(() => {
9477
+ if (forkPickerEntries !== null) setHasOpenedForkPickerDialog(true);
9478
+ }, [forkPickerEntries]);
9479
+ const handleSettingsOpenChange = useCallback2((open) => {
9480
+ setSettingsDialogOpen(open);
9481
+ if (!open) setSettingsInitialTab(void 0);
9482
+ }, [setSettingsDialogOpen, setSettingsInitialTab]);
9483
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [hasOpenedSettingsDialog ? /* @__PURE__ */ jsx(Suspense, {
9484
+ fallback: null,
9485
+ children: /* @__PURE__ */ jsx(LazySettingsDialog, {
9486
+ open: settingsDialogOpen,
9487
+ onOpenChange: handleSettingsOpenChange,
9488
+ initialTab: settingsInitialTab
9489
+ })
9490
+ }) : null, hasOpenedForkPickerDialog ? /* @__PURE__ */ jsx(Suspense, {
9491
+ fallback: null,
9492
+ children: /* @__PURE__ */ jsx(LazyForkPickerDialog, {
9493
+ entries: forkPickerEntries,
9494
+ onOpenChange: (open) => {
9495
+ if (!open) setForkPickerEntries(null);
9496
+ },
9497
+ onPick: forkFromEntry
9498
+ })
9499
+ }) : null] });
9500
+ }
9501
+ var FLEET_PANEL_KEYBINDINGS_STORAGE_KEY = "fleet-prime:v1:panel-keybindings";
9502
+ var DEFAULT_FLEET_PANEL_KEYBINDINGS = {
9503
+ toggleResources: {
9504
+ code: "Digit1",
9505
+ ctrlOrMeta: true,
9506
+ shift: true
9507
+ },
9508
+ toggleWorkspace: {
9509
+ code: "Digit2",
9510
+ ctrlOrMeta: true,
9511
+ shift: true
9512
+ },
9513
+ toggleArtifacts: {
9514
+ code: "Digit3",
9515
+ ctrlOrMeta: true,
9516
+ shift: true
9517
+ },
9518
+ toggleRepl: {
9519
+ code: "Digit4",
9520
+ ctrlOrMeta: true,
9521
+ shift: true
9522
+ },
9523
+ toggleSubagents: {
9524
+ code: "Digit5",
9525
+ ctrlOrMeta: true,
9526
+ shift: true
9527
+ },
9528
+ toggleCommandPalette: {
9529
+ code: "KeyK",
9530
+ ctrlOrMeta: true
9531
+ },
9532
+ closePanel: { code: "Escape" },
9533
+ focusPanel: {
9534
+ code: "KeyP",
9535
+ ctrlOrMeta: true,
9536
+ shift: true
9537
+ },
9538
+ focusChat: {
9539
+ code: "KeyC",
9540
+ ctrlOrMeta: true,
9541
+ shift: true
9542
+ }
9543
+ };
9544
+ function readKeybindings() {
9545
+ try {
9546
+ const value = readStoredValue(FLEET_PANEL_KEYBINDINGS_STORAGE_KEY);
9547
+ if (!value) return DEFAULT_FLEET_PANEL_KEYBINDINGS;
9548
+ const overrides = JSON.parse(value);
9549
+ return {
9550
+ ...DEFAULT_FLEET_PANEL_KEYBINDINGS,
9551
+ ...overrides
9552
+ };
9553
+ } catch {
9554
+ return DEFAULT_FLEET_PANEL_KEYBINDINGS;
9555
+ }
9556
+ }
9557
+ function matches(event, binding) {
9558
+ return event.code === binding.code && (event.ctrlKey || event.metaKey) === Boolean(binding.ctrlOrMeta) && event.shiftKey === Boolean(binding.shift) && event.altKey === Boolean(binding.alt);
9559
+ }
9560
+ function focusChatComposer() {
9561
+ document.querySelector("[data-fleet-chat-focus] textarea, [data-fleet-chat-focus] [contenteditable='true'], [data-fleet-chat-focus] input")?.focus({ preventScroll: true });
9562
+ }
9563
+ function usePanelKeybindings({ onCommandPaletteToggle, onClosePanel, rightPanel, setRightPanel }) {
9564
+ useEffect2(() => {
9565
+ const keybindings = readKeybindings();
9566
+ const handleKeyDown = (event) => {
9567
+ const match = (action) => matches(event, keybindings[action]);
9568
+ let handled = true;
9569
+ if (match("toggleResources")) setRightPanel(rightPanel === "resources" ? null : "resources");
9570
+ else if (match("toggleWorkspace")) setRightPanel(rightPanel === "workspace" ? null : "workspace");
9571
+ else if (match("toggleArtifacts")) setRightPanel(rightPanel === "artifacts" ? null : "artifacts");
9572
+ else if (match("toggleRepl")) setRightPanel(rightPanel === "repl" ? null : "repl");
9573
+ else if (match("toggleSubagents")) setRightPanel(rightPanel === "subagents" ? null : "subagents");
9574
+ else if (onCommandPaletteToggle && match("toggleCommandPalette")) onCommandPaletteToggle();
9575
+ else if (rightPanel && match("closePanel")) {
9576
+ if (onClosePanel) onClosePanel();
9577
+ else {
9578
+ setRightPanel(null);
9579
+ focusChatComposer();
9580
+ }
9581
+ } else if (rightPanel && match("focusPanel")) document.querySelector("[data-fleet-panel-focus]")?.focus({ preventScroll: true });
9582
+ else if (match("focusChat")) focusChatComposer();
9583
+ else handled = false;
9584
+ if (handled) {
9585
+ event.preventDefault();
9586
+ event.stopPropagation();
9587
+ }
9588
+ };
9589
+ document.addEventListener("keydown", handleKeyDown);
9590
+ return () => document.removeEventListener("keydown", handleKeyDown);
9591
+ }, [
9592
+ onCommandPaletteToggle,
9593
+ onClosePanel,
9594
+ rightPanel,
9595
+ setRightPanel
9596
+ ]);
9597
+ }
9598
+ function useOptionalUser() {
9599
+ return null;
9600
+ }
9601
+ function getChatAuthBearerToken() {
9602
+ return null;
9603
+ }
9604
+ async function signOut() {
9605
+ }
9672
9606
  var ProjectResponseSchema = external_exports.object({ project: ProjectSummarySchema });
9673
9607
  var chatClient = {
9674
9608
  async abortSession(metadata) {
@@ -9871,7 +9805,7 @@ var chatClient = {
9871
9805
  async streamMessage(request, onEvent, signal) {
9872
9806
  const attempt = async (allowRetry) => {
9873
9807
  const headers = new Headers({ "Content-Type": "application/json" });
9874
- const bearer = await getChatAuthBearerToken$1();
9808
+ const bearer = await getChatAuthBearerToken();
9875
9809
  if (bearer) headers.set("Authorization", `Bearer ${bearer}`);
9876
9810
  const response = await fetch(resolveChatApiUrl("/api/chat"), {
9877
9811
  method: "POST",
@@ -9954,7 +9888,8 @@ var keys = {
9954
9888
  function useChatModels(projectId) {
9955
9889
  return useQuery({
9956
9890
  queryKey: keys.models(projectId),
9957
- queryFn: () => chatClient.getModels({ projectId })
9891
+ queryFn: () => chatClient.getModels({ projectId }),
9892
+ enabled: Boolean(projectId)
9958
9893
  });
9959
9894
  }
9960
9895
  function useChatProjects() {
@@ -9971,7 +9906,7 @@ function useChatModelCatalog(options) {
9971
9906
  scope: "all",
9972
9907
  projectId: options?.projectId
9973
9908
  }),
9974
- enabled: options?.enabled
9909
+ enabled: Boolean(options?.projectId) && options?.enabled !== false
9975
9910
  });
9976
9911
  }
9977
9912
  function useDiscoverChatModels() {
@@ -9986,19 +9921,22 @@ function useDiscoverChatModels() {
9986
9921
  function useChatResources(projectId) {
9987
9922
  return useQuery({
9988
9923
  queryKey: keys.resources(projectId),
9989
- queryFn: () => chatClient.getResources(projectId)
9924
+ queryFn: () => chatClient.getResources(projectId),
9925
+ enabled: Boolean(projectId)
9990
9926
  });
9991
9927
  }
9992
9928
  function useChatCommands(projectId) {
9993
9929
  return useQuery({
9994
9930
  queryKey: keys.commands(projectId),
9995
- queryFn: () => chatClient.getCommands(projectId)
9931
+ queryFn: () => chatClient.getCommands(projectId),
9932
+ enabled: Boolean(projectId)
9996
9933
  });
9997
9934
  }
9998
9935
  function useChatSettings(projectId) {
9999
9936
  return useQuery({
10000
9937
  queryKey: keys.settings(projectId),
10001
- queryFn: () => chatClient.getSettings(projectId)
9938
+ queryFn: () => chatClient.getSettings(projectId),
9939
+ enabled: Boolean(projectId)
10002
9940
  });
10003
9941
  }
10004
9942
  function useUpdateChatSettings() {
@@ -10017,7 +9955,7 @@ function useWorkspaceTree(projectId, options) {
10017
9955
  return useQuery({
10018
9956
  queryKey: keys.workspace(projectId),
10019
9957
  queryFn: () => chatClient.getWorkspaceTree(projectId),
10020
- enabled: options?.enabled
9958
+ enabled: Boolean(projectId) && options?.enabled !== false
10021
9959
  });
10022
9960
  }
10023
9961
  function useChatProviders() {
@@ -10739,6 +10677,8 @@ function applyChatStreamEvent(transition, event) {
10739
10677
  if (event.type === "rlm") {
10740
10678
  const presentation = transition.snapshot.presentation;
10741
10679
  if (!presentation) return transition;
10680
+ const existingChild = presentation.rlmChildren.find((child) => child.id === event.child.id);
10681
+ if (existingChild && existingChild.timestamp > event.child.timestamp) return transition;
10742
10682
  const rlmChildren = [...presentation.rlmChildren.filter((child) => child.id !== event.child.id), event.child];
10743
10683
  return {
10744
10684
  ...transition,
@@ -10906,13 +10846,12 @@ function isConnectedFrame(value) {
10906
10846
  return typeof value === "object" && value !== null && value.type === "connected" && typeof value.sessionId === "string";
10907
10847
  }
10908
10848
  function readStoredSubagentCursor(key) {
10909
- if (typeof window === "undefined") return void 0;
10910
10849
  try {
10911
- const raw = window.sessionStorage.getItem(key);
10850
+ const raw = readStoredValue(key, "session");
10912
10851
  if (!raw) return void 0;
10913
10852
  const value = JSON.parse(raw);
10914
10853
  if (typeof value.generation !== "string" || value.generation.length === 0 || typeof value.lastEventId !== "number" || !Number.isInteger(value.lastEventId) || value.lastEventId < 0) {
10915
- window.sessionStorage.removeItem(key);
10854
+ removeStoredValue(key, "session");
10916
10855
  return;
10917
10856
  }
10918
10857
  return {
@@ -10920,7 +10859,7 @@ function readStoredSubagentCursor(key) {
10920
10859
  lastEventId: value.lastEventId
10921
10860
  };
10922
10861
  } catch {
10923
- window.sessionStorage.removeItem(key);
10862
+ removeStoredValue(key, "session");
10924
10863
  return;
10925
10864
  }
10926
10865
  }
@@ -11053,18 +10992,14 @@ function useSubagentChat({ client, enabled, child, loadSession, parentSessionId
11053
10992
  lastEventId = storedCursor.lastEventId;
11054
10993
  }
11055
10994
  const persistCursor = () => {
11056
- if (typeof window === "undefined") return;
11057
- try {
11058
- if (!streamGeneration) {
11059
- window.sessionStorage.removeItem(cursorKey);
11060
- return;
11061
- }
11062
- window.sessionStorage.setItem(cursorKey, JSON.stringify({
11063
- generation: streamGeneration,
11064
- lastEventId
11065
- }));
11066
- } catch {
10995
+ if (!streamGeneration) {
10996
+ removeStoredValue(cursorKey, "session");
10997
+ return;
11067
10998
  }
10999
+ writeStoredValue(cursorKey, JSON.stringify({
11000
+ generation: streamGeneration,
11001
+ lastEventId
11002
+ }), "session");
11068
11003
  };
11069
11004
  const clearCursor = () => {
11070
11005
  lastEventId = 0;
@@ -11354,12 +11289,11 @@ function storeResourceCanvasWidth(width) {
11354
11289
  }
11355
11290
  function readStoredThemePreference() {
11356
11291
  if (typeof window === "undefined") return "system";
11357
- const value = window.localStorage.getItem(THEME_PREFERENCE_STORAGE_KEY);
11292
+ const value = readStoredValue(THEME_PREFERENCE_STORAGE_KEY);
11358
11293
  return value === "light" || value === "dark" || value === "system" ? value : "system";
11359
11294
  }
11360
11295
  function storeThemePreference(preference) {
11361
- if (typeof window === "undefined") return;
11362
- window.localStorage.setItem(THEME_PREFERENCE_STORAGE_KEY, preference);
11296
+ writeStoredValue(THEME_PREFERENCE_STORAGE_KEY, preference);
11363
11297
  }
11364
11298
  function applyThemePreference(preference) {
11365
11299
  if (typeof window === "undefined") return;
@@ -11541,18 +11475,16 @@ function useChatStorage() {
11541
11475
  };
11542
11476
  }
11543
11477
  function readStoredBrowserSessions() {
11544
- if (typeof window === "undefined" || !window.localStorage) return {};
11478
+ const raw = readStoredValue(CHAT_SESSION_STORAGE_KEY);
11479
+ if (!raw) return readLegacyScopeStorage();
11545
11480
  try {
11546
- const raw = window.localStorage.getItem(CHAT_SESSION_STORAGE_KEY);
11547
- if (!raw) return readLegacyScopeStorage();
11548
11481
  return parseSessionMetadata(JSON.parse(raw));
11549
11482
  } catch {
11550
11483
  return readLegacyScopeStorage();
11551
11484
  }
11552
11485
  }
11553
11486
  function readLegacyScopeStorage() {
11554
- if (typeof window === "undefined" || !window.localStorage) return {};
11555
- const raw = window.localStorage.getItem("fleet-prime:v1:chat-sessions");
11487
+ const raw = readStoredValue("fleet-prime:v1:chat-sessions");
11556
11488
  if (!raw) return {};
11557
11489
  try {
11558
11490
  return parseSessionMetadata(JSON.parse(raw)?.normal);
@@ -11565,19 +11497,17 @@ function parseSessionMetadata(value) {
11565
11497
  return result.success ? result.data : {};
11566
11498
  }
11567
11499
  function clearBrowserChatSessions() {
11568
- if (typeof window === "undefined" || !window.localStorage) return;
11569
- window.localStorage.removeItem(CHAT_SESSION_STORAGE_KEY);
11570
- window.localStorage.removeItem("fleet-prime:v1:chat-sessions");
11571
- window.localStorage.removeItem("fleet-prime:v1:chat-mode");
11500
+ removeStoredValue(CHAT_SESSION_STORAGE_KEY);
11501
+ removeStoredValue("fleet-prime:v1:chat-sessions");
11502
+ removeStoredValue("fleet-prime:v1:chat-mode");
11572
11503
  }
11573
11504
  function storeBrowserSessions(metadata) {
11574
- if (typeof window === "undefined" || !window.localStorage) return;
11575
11505
  if (!metadata.sessionId && !metadata.projectId) {
11576
- window.localStorage.removeItem(CHAT_SESSION_STORAGE_KEY);
11577
- window.localStorage.removeItem("fleet-prime:v1:chat-sessions");
11506
+ removeStoredValue(CHAT_SESSION_STORAGE_KEY);
11507
+ removeStoredValue("fleet-prime:v1:chat-sessions");
11578
11508
  return;
11579
11509
  }
11580
- window.localStorage.setItem(CHAT_SESSION_STORAGE_KEY, JSON.stringify(metadata));
11510
+ writeStoredValue(CHAT_SESSION_STORAGE_KEY, JSON.stringify(metadata));
11581
11511
  }
11582
11512
  function useChatSuggestions({ messages, resources, workspaceTree }) {
11583
11513
  return useMemo2(() => buildContextSuggestions({
@@ -11722,7 +11652,7 @@ function AccountMenu({ user, onSignOut, onOpenSettings, compact = false, label =
11722
11652
  children: [
11723
11653
  /* @__PURE__ */ jsx(QredenceLogo, { className: "size-3.5 shrink-0" }),
11724
11654
  /* @__PURE__ */ jsx("span", {
11725
- className: compact ? "sr-only" : "text-[13px] font-medium tracking-[-0.01em] whitespace-nowrap",
11655
+ className: compact ? "sr-only" : "text-[0.8125rem] font-medium tracking-[-0.01em] whitespace-nowrap",
11726
11656
  children: label
11727
11657
  }),
11728
11658
  /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5 shrink-0 text-foreground/35" })
@@ -11790,6 +11720,139 @@ function AccountMenu({ user, onSignOut, onOpenSettings, compact = false, label =
11790
11720
  })
11791
11721
  });
11792
11722
  }
11723
+ function statusLabel(status) {
11724
+ switch (status) {
11725
+ case "queued":
11726
+ return "queued";
11727
+ case "running":
11728
+ case "recovering":
11729
+ return "streaming";
11730
+ case "error":
11731
+ case "failed":
11732
+ return "error";
11733
+ case "cancelled":
11734
+ return "cancelled";
11735
+ case "done":
11736
+ return "complete";
11737
+ default:
11738
+ return "ready";
11739
+ }
11740
+ }
11741
+ function statusDotClass(status) {
11742
+ switch (status) {
11743
+ case "running":
11744
+ case "recovering":
11745
+ return "bg-emerald-400 motion-safe:animate-pulse";
11746
+ case "error":
11747
+ case "failed":
11748
+ return "bg-destructive";
11749
+ case "queued":
11750
+ return "bg-amber-300";
11751
+ case "cancelled":
11752
+ return "bg-foreground/35";
11753
+ default:
11754
+ return "bg-foreground/35";
11755
+ }
11756
+ }
11757
+ function AgentTabBar({ tabs, value, onValueChange, onClose, onNewSession }) {
11758
+ const tabRefs = useRef2(/* @__PURE__ */ new Map());
11759
+ const setTabRef = useCallback2((tabId, node) => {
11760
+ if (node) tabRefs.current.set(tabId, node);
11761
+ else tabRefs.current.delete(tabId);
11762
+ }, []);
11763
+ useEffect2(() => {
11764
+ for (const tabId of tabRefs.current.keys()) if (!tabs.some((tab) => tab.id === tabId)) tabRefs.current.delete(tabId);
11765
+ }, [tabs]);
11766
+ const focusTab = useCallback2((index) => {
11767
+ const tab = tabs[index];
11768
+ if (!tab) return;
11769
+ tabRefs.current.get(tab.id)?.focus();
11770
+ onValueChange(tab.id);
11771
+ }, [onValueChange, tabs]);
11772
+ const handleKeyDown = useCallback2((event, tabId) => {
11773
+ const index = tabs.findIndex((tab) => tab.id === tabId);
11774
+ if (index < 0) return;
11775
+ let nextIndex;
11776
+ if (event.key === "ArrowRight") nextIndex = (index + 1) % tabs.length;
11777
+ if (event.key === "ArrowLeft") nextIndex = (index - 1 + tabs.length) % tabs.length;
11778
+ if (event.key === "Home") nextIndex = 0;
11779
+ if (event.key === "End") nextIndex = tabs.length - 1;
11780
+ if (nextIndex === void 0) return;
11781
+ event.preventDefault();
11782
+ focusTab(nextIndex);
11783
+ }, [focusTab, tabs]);
11784
+ return /* @__PURE__ */ jsxs("div", {
11785
+ className: "flex min-w-0 max-w-full items-center gap-1",
11786
+ "data-testid": "agent-tab-bar",
11787
+ children: [/* @__PURE__ */ jsx("div", {
11788
+ "aria-label": "Agent conversations",
11789
+ className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
11790
+ role: "tablist",
11791
+ children: tabs.map((tab) => {
11792
+ const active = tab.id === value;
11793
+ const status = statusLabel(tab.status);
11794
+ return /* @__PURE__ */ jsxs("div", {
11795
+ className: "group/tab relative min-w-0 shrink-0 basis-[164px] sm:max-w-[164px]",
11796
+ "data-tab-id": tab.id,
11797
+ children: [/* @__PURE__ */ jsxs(Button, {
11798
+ ref: (node) => setTabRef(tab.id, node),
11799
+ "aria-controls": agentTabPanelId(tab.id),
11800
+ "aria-selected": active,
11801
+ "aria-label": `${tab.label}, ${status}`,
11802
+ className: cn("h-7 w-full min-w-0 justify-start text-left gap-1.5 rounded-[7px] border border-transparent px-2 text-[0.75rem] font-medium leading-none transition-colors motion-reduce:transition-none", active ? "bg-surface-4 text-foreground shadow-none" : "bg-transparent text-foreground/45 hover:bg-foreground/5 hover:text-foreground/75", tab.kind === "subagent" && onClose && "pr-7"),
11803
+ "data-state": active ? "active" : "inactive",
11804
+ id: agentTabTriggerId(tab.id),
11805
+ onClick: () => onValueChange(tab.id),
11806
+ onKeyDown: (event) => handleKeyDown(event, tab.id),
11807
+ role: "tab",
11808
+ size: "sm",
11809
+ tabIndex: active ? 0 : -1,
11810
+ type: "button",
11811
+ variant: "ghost",
11812
+ children: [tab.kind === "main" ? /* @__PURE__ */ jsx(Bot, {
11813
+ "aria-hidden": "true",
11814
+ className: "size-3.5 shrink-0"
11815
+ }) : /* @__PURE__ */ jsx("span", {
11816
+ "aria-hidden": "true",
11817
+ className: cn("size-1.5 shrink-0 rounded-full", statusDotClass(tab.status))
11818
+ }), /* @__PURE__ */ jsx("span", {
11819
+ className: "min-w-0 flex-1 truncate text-left",
11820
+ children: tab.label
11821
+ })]
11822
+ }), tab.kind === "subagent" && onClose ? /* @__PURE__ */ jsx(Button, {
11823
+ "aria-label": `Close ${tab.label} tab`,
11824
+ className: "absolute top-1/2 right-1 size-5 -translate-y-1/2 rounded-[5px] p-0 text-foreground/35 opacity-0 transition-opacity motion-reduce:transition-none hover:bg-foreground/10 hover:text-foreground/75 focus-visible:opacity-100 group-hover/tab:opacity-100",
11825
+ onClick: (event) => {
11826
+ event.stopPropagation();
11827
+ onClose(tab.id);
11828
+ },
11829
+ size: "icon-xs",
11830
+ title: `Close ${tab.label} tab`,
11831
+ type: "button",
11832
+ variant: "ghost",
11833
+ children: /* @__PURE__ */ jsx(X, {
11834
+ "aria-hidden": "true",
11835
+ className: "size-3"
11836
+ })
11837
+ }) : null]
11838
+ }, tab.id);
11839
+ })
11840
+ }), onNewSession ? /* @__PURE__ */ jsx(Button, {
11841
+ "aria-label": "New chat",
11842
+ className: "size-7 shrink-0 rounded-[7px] text-foreground/50 hover:bg-foreground/7 hover:text-foreground/85",
11843
+ "data-testid": "new-chat-tab",
11844
+ onClick: onNewSession,
11845
+ size: "icon-sm",
11846
+ title: "New chat",
11847
+ type: "button",
11848
+ variant: "ghost",
11849
+ children: /* @__PURE__ */ jsx(Plus, {
11850
+ "aria-hidden": "true",
11851
+ className: "size-3.5"
11852
+ })
11853
+ }) : null]
11854
+ });
11855
+ }
11793
11856
  function useChatWorkspaceHeader({ activeTabId, tabs, onCloseTab, onNewSession, onSelectTab, onOpenSettings }) {
11794
11857
  const navigate = useNavigate();
11795
11858
  const user = useOptionalUser();
@@ -12344,10 +12407,6 @@ function answerToRecordValue(answer) {
12344
12407
  if (answer.kind === "text") return typeof answer.text === "string" ? answer.text : "";
12345
12408
  return answer.selectedIds?.[0] ?? answer.text ?? "";
12346
12409
  }
12347
- function notifyChatError(error) {
12348
- if (isDaemonDisconnectError(error)) return;
12349
- notify.error(error instanceof Error ? error.message : String(error));
12350
- }
12351
12410
  function cleanStepText(text) {
12352
12411
  let cleaned = text.replace(/\*{1,2}([^*]+)\*{1,2}/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^(Use|Run|Execute|Create|Write|Read|Check|Verify|Update|Modify|Add|Remove|Delete|Install)\s+(the\s+)?/i, "").replace(/\s+/g, " ").trim();
12353
12412
  if (cleaned.length > 0) cleaned = `${cleaned.charAt(0).toUpperCase()}${cleaned.slice(1)}`;
@@ -12672,23 +12731,34 @@ function usePiChatSessionEvents({ client, presentationRef, sessionId, sessionMet
12672
12731
  if (!sessionId || typeof window === "undefined") return;
12673
12732
  const lastEventIdKey = `pi:sse:last-event-id:${sessionId}`;
12674
12733
  const sseCapabilitiesRef = { current: void 0 };
12675
- let lastEventId = Number.parseInt(window.sessionStorage.getItem(lastEventIdKey) ?? "0", 10);
12734
+ let lastEventId = Number.parseInt(readStoredValue(lastEventIdKey, "session") ?? "0", 10);
12676
12735
  if (Number.isNaN(lastEventId)) lastEventId = 0;
12677
12736
  let source = null;
12678
12737
  let reconnectTimer = null;
12738
+ let reconnectAttempt = 0;
12739
+ let reconnectNoticeShown = false;
12740
+ let lastAppliedRlmSeq = 0;
12679
12741
  let closedByEffect = false;
12680
- const handleEvent = (raw) => {
12742
+ let activeAssistantId;
12743
+ const handleEvent = (raw, seq) => {
12681
12744
  let frame2;
12682
12745
  try {
12683
12746
  frame2 = JSON.parse(raw.data);
12684
12747
  } catch {
12685
12748
  return;
12686
12749
  }
12750
+ if (frame2.type === "start") activeAssistantId = frame2.id;
12751
+ if (frame2.type === "done") activeAssistantId = void 0;
12752
+ const statusAtFrame = statusRef.current;
12687
12753
  if (frame2.type === "presentation") {
12688
12754
  if (frame2.presentation.revision > (presentationRef.current?.revision ?? -1)) setPresentationSynced(frame2.presentation);
12689
12755
  return;
12690
12756
  }
12691
12757
  if (frame2.type === "rlm") {
12758
+ if (!Number.isNaN(seq) && seq > 0) {
12759
+ if (seq <= lastAppliedRlmSeq) return;
12760
+ lastAppliedRlmSeq = seq;
12761
+ }
12692
12762
  const current = presentationRef.current;
12693
12763
  const existing = current.rlmChildren.find((child) => child.id === frame2.child.id);
12694
12764
  if (existing && existing.timestamp > frame2.child.timestamp) return;
@@ -12699,45 +12769,78 @@ function usePiChatSessionEvents({ client, presentationRef, sessionId, sessionMet
12699
12769
  });
12700
12770
  return;
12701
12771
  }
12702
- if (statusRef.current === "streaming" || statusRef.current === "submitted") return;
12703
- const connected = frame2;
12704
- if (connected.type === "connected") {
12705
- sseCapabilitiesRef.current = connected.adapterCapabilities;
12706
- setAdapterCapabilities(connected.adapterCapabilities);
12707
- return;
12708
- }
12709
- if (frame2.type === "reasoning") {
12710
- const messageId = frame2.messageId;
12711
- if (!sseCapabilitiesRef.current?.features.includes("reasoning-summary-v1") || !messageId) return;
12712
- setMessagesSynced((current) => upsertAssistantReasoningPresentation(current, messageId, frame2.presentation));
12713
- return;
12714
- }
12715
12772
  if (frame2.type === "tool" && frame2.part?.type === "tool-Question") {
12716
12773
  setMessagesSynced((current) => {
12717
12774
  const toolCallId = frame2.part.toolCallId ?? "";
12718
- if (current.some((message) => message.parts.some((part) => part.type !== "text" && part.type !== "error" && "toolCallId" in part && part.toolCallId === toolCallId))) return current;
12775
+ if (!toolCallId) return current;
12776
+ const hasToolCall = (message) => message.parts.some((part) => part.type !== "text" && part.type !== "error" && "toolCallId" in part && part.toolCallId === toolCallId);
12777
+ let targetIndex = frame2.messageId ? current.findIndex((message) => message.id === frame2.messageId && message.role === "assistant") : -1;
12778
+ if (targetIndex < 0 && activeAssistantId) targetIndex = current.findIndex((message) => message.id === activeAssistantId && message.role === "assistant");
12779
+ if (targetIndex < 0) {
12780
+ let latestAssistantWithoutToolCall = -1;
12781
+ let latestMatchingToolCall = -1;
12782
+ for (let index = current.length - 1; index >= 0; index -= 1) {
12783
+ const message = current[index];
12784
+ if (message.role !== "assistant") continue;
12785
+ if (hasToolCall(message) && latestMatchingToolCall < 0) latestMatchingToolCall = index;
12786
+ else if (latestAssistantWithoutToolCall < 0) latestAssistantWithoutToolCall = index;
12787
+ }
12788
+ targetIndex = frame2.part.state === "input-streaming" ? latestAssistantWithoutToolCall >= 0 ? latestAssistantWithoutToolCall : latestMatchingToolCall : latestMatchingToolCall >= 0 ? latestMatchingToolCall : latestAssistantWithoutToolCall;
12789
+ }
12719
12790
  const questionPart = {
12720
12791
  ...frame2.part,
12721
12792
  type: "tool-Question"
12722
12793
  };
12723
- return [...current, {
12724
- id: crypto.randomUUID(),
12794
+ if (targetIndex < 0) return [...current, {
12795
+ id: frame2.messageId ?? crypto.randomUUID(),
12725
12796
  role: "assistant",
12726
12797
  parts: [questionPart],
12727
12798
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
12728
12799
  }];
12800
+ return current.flatMap((message, index) => {
12801
+ if (index === targetIndex) return [{
12802
+ ...message,
12803
+ parts: upsertToolPart(message.parts, questionPart)
12804
+ }];
12805
+ if (!hasToolCall(message)) return [message];
12806
+ const parts = message.parts.filter((part) => !(part.type !== "text" && part.type !== "error" && "toolCallId" in part && part.toolCallId === toolCallId));
12807
+ return parts.length > 0 ? [{
12808
+ ...message,
12809
+ parts
12810
+ }] : [];
12811
+ });
12729
12812
  });
12730
12813
  return;
12731
12814
  }
12815
+ if (statusRef.current === "streaming" || statusRef.current === "submitted") return;
12816
+ const connected = frame2;
12817
+ if (connected.type === "connected") {
12818
+ sseCapabilitiesRef.current = connected.adapterCapabilities;
12819
+ setAdapterCapabilities(connected.adapterCapabilities);
12820
+ if (connected.cursorReset) lastAppliedRlmSeq = 0;
12821
+ return;
12822
+ }
12823
+ if (frame2.type === "reasoning") {
12824
+ const messageId = frame2.messageId;
12825
+ if (!sseCapabilitiesRef.current?.features.includes("reasoning-summary-v1") || !messageId) return;
12826
+ setMessagesSynced((current) => upsertAssistantReasoningPresentation(current, messageId, frame2.presentation));
12827
+ return;
12828
+ }
12732
12829
  if (frame2.type === "state") {
12733
12830
  setActivityLabelSynced(typeof frame2.state?.message === "string" ? frame2.state.message : void 0);
12734
- if (frame2.state?.name === "agent_settled") client.loadSession({ sessionId }).then((result) => {
12735
- if (closedByEffect || sessionMetadataRef.current.sessionId !== sessionId) return;
12736
- setMessagesSynced(hydratePlanPresentationMessages(result.messages, result.planPresentations));
12737
- setPresentationSynced(result.presentation);
12738
- setSessionMetadataSynced(result.session);
12739
- setQueueSynced(EMPTY_QUEUE_STATE);
12740
- }).catch(() => void 0);
12831
+ if (frame2.state?.name === "agent_settled") {
12832
+ if (statusAtFrame === "streaming" || statusAtFrame === "submitted") return;
12833
+ const metadataSessionIdAtFrame = sessionMetadataRef.current.sessionId;
12834
+ client.loadSession({ sessionId }).then((result) => {
12835
+ if (closedByEffect || sessionMetadataRef.current.sessionId !== sessionId) return;
12836
+ if (sessionMetadataRef.current.sessionId !== metadataSessionIdAtFrame) return;
12837
+ if (statusRef.current === "streaming" || statusRef.current === "submitted") return;
12838
+ setMessagesSynced(hydratePlanPresentationMessages(result.messages, result.planPresentations));
12839
+ setPresentationSynced(result.presentation);
12840
+ setSessionMetadataSynced(result.session);
12841
+ setQueueSynced(EMPTY_QUEUE_STATE);
12842
+ }).catch(() => void 0);
12843
+ }
12741
12844
  return;
12742
12845
  }
12743
12846
  if (frame2.type === "queue") setQueueSynced({
@@ -12756,15 +12859,27 @@ function usePiChatSessionEvents({ client, presentationRef, sessionId, sessionMet
12756
12859
  const seq = Number.parseInt(event.lastEventId ?? "", 10);
12757
12860
  if (!Number.isNaN(seq) && seq > 0) {
12758
12861
  lastEventId = seq;
12759
- window.sessionStorage.setItem(lastEventIdKey, String(seq));
12862
+ writeStoredValue(lastEventIdKey, String(seq), "session");
12863
+ }
12864
+ if (reconnectAttempt > 0) {
12865
+ reconnectAttempt = 0;
12866
+ if (reconnectNoticeShown) {
12867
+ reconnectNoticeShown = false;
12868
+ if (statusRef.current !== "streaming" && statusRef.current !== "submitted") setActivityLabelSynced(void 0);
12869
+ }
12760
12870
  }
12761
- handleEvent(event);
12871
+ handleEvent(event, seq);
12762
12872
  };
12763
12873
  nextSource.onerror = () => {
12764
12874
  if (closedByEffect || source !== nextSource) return;
12765
12875
  nextSource.close();
12876
+ reconnectAttempt += 1;
12877
+ if (reconnectAttempt > 1 && statusRef.current !== "streaming" && statusRef.current !== "submitted") {
12878
+ reconnectNoticeShown = true;
12879
+ setActivityLabelSynced(reconnectAttempt > 2 ? `Reconnecting\u2026 (attempt ${reconnectAttempt})` : "Reconnecting\u2026");
12880
+ }
12766
12881
  if (reconnectTimer) clearTimeout(reconnectTimer);
12767
- reconnectTimer = setTimeout(connect, 2e3);
12882
+ reconnectTimer = setTimeout(connect, Math.min(2e3, 250 * 2 ** Math.min(reconnectAttempt, 3)));
12768
12883
  };
12769
12884
  };
12770
12885
  connect();
@@ -12816,6 +12931,10 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
12816
12931
  const streamAdmissionsRef = useRef2(/* @__PURE__ */ new Set());
12817
12932
  const queuedSubmissionTailRef = useRef2(RESOLVED_PROMISE);
12818
12933
  const adapterCapabilitiesRef = useRef2(void 0);
12934
+ const projectIdRef = useRef2(projectId);
12935
+ useEffect2(() => {
12936
+ projectIdRef.current = projectId;
12937
+ }, [projectId]);
12819
12938
  const findStreamAdmission = useCallback2((sessionId) => {
12820
12939
  for (const admission of streamAdmissionsRef.current) if (admission.sessionId === sessionId) return admission;
12821
12940
  }, []);
@@ -12860,7 +12979,7 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
12860
12979
  if (existing.sessionId) return existing;
12861
12980
  const inFlight = sessionCreatePromiseRef.current;
12862
12981
  if (inFlight) return inFlight;
12863
- const promise = client.createSession(projectId, signal).then((created) => {
12982
+ const promise = client.createSession(projectIdRef.current, signal).then((created) => {
12864
12983
  if (signal?.aborted) throw new Error("Session creation was aborted");
12865
12984
  setSessionMetadataSynced(created.session);
12866
12985
  setPresentationSynced(created.presentation);
@@ -12874,7 +12993,6 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
12874
12993
  return promise;
12875
12994
  }, [
12876
12995
  client,
12877
- projectId,
12878
12996
  refreshSessions,
12879
12997
  sessionMetadataRef,
12880
12998
  setPresentationSynced,
@@ -13023,22 +13141,21 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
13023
13141
  resetStreamAdmission,
13024
13142
  sendMessage: useCallback2(async ({ text, attachments, openUI, openUIArtifact, planAction, mode, altKey }) => {
13025
13143
  const trimmed = text.trim();
13026
- if (!trimmed) return;
13027
- if (status === "submitted" || status === "streaming" || findStreamAdmission(sessionMetadataRef.current.sessionId) !== void 0) {
13028
- try {
13029
- await enqueueDuringStream(trimmed, altKey ? "followUp" : "steer", {
13030
- attachments,
13031
- mode,
13032
- openUI,
13033
- openUIArtifact,
13034
- planAction
13035
- });
13036
- } catch (err) {
13037
- const nextError = err instanceof Error ? err : new Error(String(err));
13038
- setError(nextError);
13039
- notifyChatError(nextError);
13040
- }
13041
- return;
13144
+ if (!trimmed) return false;
13145
+ if (status === "submitted" || status === "streaming" || findStreamAdmission(sessionMetadataRef.current.sessionId) !== void 0) try {
13146
+ await enqueueDuringStream(trimmed, altKey ? "followUp" : "steer", {
13147
+ attachments,
13148
+ mode,
13149
+ openUI,
13150
+ openUIArtifact,
13151
+ planAction
13152
+ });
13153
+ return true;
13154
+ } catch (err) {
13155
+ const nextError = err instanceof Error ? err : new Error(String(err));
13156
+ setError(nextError);
13157
+ notifyChatError(nextError);
13158
+ return false;
13042
13159
  }
13043
13160
  setError(null);
13044
13161
  setActivityLabelSynced(void 0);
@@ -13056,7 +13173,7 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
13056
13173
  let terminalDoneSeen = false;
13057
13174
  try {
13058
13175
  const ensuredSession = await ensureSession(controller.signal);
13059
- if (controller.signal.aborted) return;
13176
+ if (controller.signal.aborted) return false;
13060
13177
  const ensuredStreamSessionId = ensuredSession.sessionId;
13061
13178
  if (!ensuredStreamSessionId) throw new Error("Unable to start a session stream");
13062
13179
  streamSessionId = ensuredStreamSessionId;
@@ -13084,23 +13201,25 @@ function usePiChatMessaging({ activityLabelRef, client, messagesRef, presentatio
13084
13201
  }
13085
13202
  if (sessionMetadataRef.current.sessionId === ensuredStreamSessionId && (terminalDoneSeen || !sessionStillRunning)) setStatus("ready");
13086
13203
  messagesRef.current.length;
13204
+ return true;
13087
13205
  } catch (err) {
13088
13206
  if (streamAdmissionsRef.current.delete(streamAdmission)) streamAdmission.reject(err);
13089
13207
  setMessagesSynced((current) => removeOptimisticUserMessage(current, userMessage.id));
13090
- if (controller.signal.aborted) return;
13208
+ if (controller.signal.aborted) return false;
13091
13209
  if (streamSessionId && sessionMetadataRef.current.sessionId !== streamSessionId) {
13092
13210
  refreshSessions();
13093
- return;
13211
+ return false;
13094
13212
  }
13095
13213
  const recoveryDeps = {
13096
13214
  setError,
13097
13215
  setStatus
13098
13216
  };
13099
- if (await tryRecoverForbiddenSession(err, recoverFromForbiddenSession, recoveryDeps) || await tryRecoverUnknownSession(err, recoverFromForbiddenSession, recoveryDeps)) return;
13217
+ if (await tryRecoverForbiddenSession(err, recoverFromForbiddenSession, recoveryDeps) || await tryRecoverUnknownSession(err, recoverFromForbiddenSession, recoveryDeps)) return false;
13100
13218
  const nextError = err instanceof Error ? err : new Error(String(err));
13101
13219
  setError(nextError);
13102
13220
  setStatus("error");
13103
13221
  notifyChatError(nextError);
13222
+ return false;
13104
13223
  } finally {
13105
13224
  if (streamAdmissionsRef.current.delete(streamAdmission)) streamAdmission.reject(/* @__PURE__ */ new Error("Chat stream ended before admission"));
13106
13225
  if (controller.signal.aborted) setMessagesSynced((current) => removeOptimisticUserMessage(current, userMessage.id));
@@ -13233,19 +13352,22 @@ function usePiChat(model, options) {
13233
13352
  artifactRuns: []
13234
13353
  }));
13235
13354
  const initialSessionMetadataRef = useRef2(initialSessionMetadata);
13355
+ const projectIdRef = useRef2(projectId);
13236
13356
  const messagesRef = useRef2(messages);
13237
13357
  const sessionMetadataRef = useRef2(sessionMetadata);
13238
13358
  const activityLabelRef = useRef2(activityLabel);
13239
13359
  const planLabelRef = useRef2(planLabel);
13240
13360
  const queueRef = useRef2(queue);
13241
13361
  const queueRevisionRef = useRef2(0);
13242
- const queuedDeletionTailRef = useRef2(Promise.resolve());
13362
+ const queuedDeletionTailRef = useRef2(null);
13243
13363
  const presentationRef = useRef2(presentation);
13244
13364
  const pendingSendControllerRef = useRef2(null);
13245
13365
  const streamControllersRef = useRef2(/* @__PURE__ */ new Map());
13366
+ const refreshSessionsPromiseRef = useRef2(null);
13367
+ const resumeRequestRef = useRef2(0);
13246
13368
  const statusRef = useRef2(status);
13247
13369
  const initializedRef = useRef2(false);
13248
- const sendMessageRef = useRef2(() => Promise.resolve());
13370
+ const sendMessageRef = useRef2(() => Promise.resolve(false));
13249
13371
  const setMessagesSynced = useCallback2((updater) => {
13250
13372
  const next = typeof updater === "function" ? updater(messagesRef.current) : updater;
13251
13373
  messagesRef.current = next;
@@ -13302,14 +13424,26 @@ function usePiChat(model, options) {
13302
13424
  if (sessionMetadataRef.current.sessionId === sessionId) setPresentationSynced(result.presentation);
13303
13425
  return result.artifact.id;
13304
13426
  }, [client, setPresentationSynced]);
13427
+ useEffect2(() => {
13428
+ projectIdRef.current = projectId;
13429
+ }, [projectId]);
13305
13430
  const refreshSessions = useCallback2(async () => {
13306
- const nextSessions = await client.listSessions();
13307
- setSessions(nextSessions);
13308
- return nextSessions;
13431
+ const pendingRefresh = refreshSessionsPromiseRef.current;
13432
+ if (pendingRefresh) return pendingRefresh;
13433
+ const refreshRequest = client.listSessions().then((nextSessions) => {
13434
+ setSessions(nextSessions);
13435
+ return nextSessions;
13436
+ });
13437
+ refreshSessionsPromiseRef.current = refreshRequest;
13438
+ try {
13439
+ return await refreshRequest;
13440
+ } finally {
13441
+ if (refreshSessionsPromiseRef.current === refreshRequest) refreshSessionsPromiseRef.current = null;
13442
+ }
13309
13443
  }, [client]);
13310
13444
  const recoverFromForbiddenSession = useCallback2((projectIdOverride) => runForbiddenSessionRecovery({
13311
13445
  client,
13312
- projectId: projectIdOverride ?? projectId,
13446
+ projectId: projectIdOverride ?? projectIdRef.current,
13313
13447
  refreshSessions,
13314
13448
  setActivityLabelSynced,
13315
13449
  setError,
@@ -13321,7 +13455,6 @@ function usePiChat(model, options) {
13321
13455
  setStatus
13322
13456
  }), [
13323
13457
  client,
13324
- projectId,
13325
13458
  refreshSessions,
13326
13459
  setActivityLabelSynced,
13327
13460
  setMessagesSynced,
@@ -13419,18 +13552,6 @@ function usePiChat(model, options) {
13419
13552
  controllers.clear();
13420
13553
  };
13421
13554
  }, []);
13422
- useEffect2(() => {
13423
- let cancelled = false;
13424
- refreshSessions().catch((err) => {
13425
- if (cancelled) return;
13426
- const nextError = err instanceof Error ? err : new Error(String(err));
13427
- setError(nextError);
13428
- notifyChatError(nextError);
13429
- });
13430
- return () => {
13431
- cancelled = true;
13432
- };
13433
- }, [refreshSessions]);
13434
13555
  usePiChatBootstrap({
13435
13556
  client,
13436
13557
  initialSessionMetadataRef,
@@ -13495,21 +13616,25 @@ function usePiChat(model, options) {
13495
13616
  const originatingSessionId = sessionMetadataRef.current.sessionId;
13496
13617
  const requestedRevision = queueRevisionRef.current;
13497
13618
  const requestedMatchCount = (lane === "steering" ? queueRef.current.steering : queueRef.current.followUp).filter((item) => item === expectedText).length;
13498
- const deletion = queuedDeletionTailRef.current.catch(() => void 0).then(async () => {
13619
+ const deletion = (queuedDeletionTailRef.current ?? Promise.resolve()).catch(() => void 0).then(async () => {
13499
13620
  if (!originatingSessionId || sessionMetadataRef.current.sessionId !== originatingSessionId) return false;
13621
+ const refuseStaleDeletion = (expectedRace) => {
13622
+ if (!expectedRace) notifyChatError(/* @__PURE__ */ new Error("The queued message changed before it could be deleted."));
13623
+ return false;
13624
+ };
13500
13625
  const current = queueRef.current;
13501
13626
  const items = lane === "steering" ? current.steering : current.followUp;
13502
13627
  let resolvedIndex;
13503
13628
  if (queueRevisionRef.current === requestedRevision) resolvedIndex = items[index] === expectedText ? index : void 0;
13504
13629
  else {
13505
- if (requestedMatchCount !== 1) return false;
13630
+ if (requestedMatchCount !== 1) return refuseStaleDeletion(true);
13506
13631
  const currentMatches = items.reduce((matches2, item, itemIndex) => {
13507
13632
  if (item === expectedText) matches2.push(itemIndex);
13508
13633
  return matches2;
13509
13634
  }, []);
13510
13635
  resolvedIndex = currentMatches.length === 1 ? currentMatches[0] : void 0;
13511
13636
  }
13512
- if (resolvedIndex === void 0) return false;
13637
+ if (resolvedIndex === void 0) return refuseStaleDeletion(queueRevisionRef.current !== requestedRevision);
13513
13638
  const optimistic = {
13514
13639
  ...current,
13515
13640
  [lane]: items.filter((_, itemIndex) => itemIndex !== resolvedIndex)
@@ -13540,7 +13665,7 @@ function usePiChat(model, options) {
13540
13665
  invalidateQueueMutations();
13541
13666
  setStatus("ready");
13542
13667
  }
13543
- const result = await client.createSession(options2?.projectId ?? projectId);
13668
+ const result = await client.createSession(options2?.projectId ?? projectIdRef.current ?? projectId);
13544
13669
  setSessionMetadataSynced(result.session);
13545
13670
  setMessagesSynced([]);
13546
13671
  setPresentationSynced(result.presentation);
@@ -13563,10 +13688,14 @@ function usePiChat(model, options) {
13563
13688
  projectId
13564
13689
  ]);
13565
13690
  const resumeSession = useCallback2(async (metadata, options2) => {
13691
+ const requestId = resumeRequestRef.current + 1;
13692
+ resumeRequestRef.current = requestId;
13693
+ const isCurrent = () => resumeRequestRef.current === requestId;
13566
13694
  invalidateQueueMutations();
13567
13695
  try {
13568
13696
  if (options2?.preserveRunning === false) stop();
13569
13697
  const result = await client.resumeSession(metadata);
13698
+ if (!isCurrent()) return false;
13570
13699
  setSessionMetadataSynced(result.session);
13571
13700
  setMessagesSynced(hydratePlanPresentationMessages(result.messages, result.planPresentations));
13572
13701
  setPresentationSynced(result.presentation);
@@ -13575,14 +13704,18 @@ function usePiChat(model, options) {
13575
13704
  setPlanLabelSynced(void 0);
13576
13705
  setStatus(streamControllersRef.current.has(result.session.sessionId ?? "") ? "streaming" : "ready");
13577
13706
  await refreshSessions();
13707
+ if (!isCurrent()) return false;
13578
13708
  return true;
13579
13709
  } catch (err) {
13710
+ if (!isCurrent()) return false;
13580
13711
  const recoveryDeps = {
13581
13712
  setError,
13582
13713
  setStatus
13583
13714
  };
13584
13715
  const recover = () => recoverFromForbiddenSession(metadata.projectId);
13585
- if (await tryRecoverForbiddenSession(err, recover, recoveryDeps) || await tryRecoverUnknownSession(err, recover, recoveryDeps)) return false;
13716
+ const recovered = await tryRecoverForbiddenSession(err, recover, recoveryDeps) || await tryRecoverUnknownSession(err, recover, recoveryDeps);
13717
+ if (!isCurrent()) return false;
13718
+ if (recovered) return false;
13586
13719
  const nextError = err instanceof Error ? err : new Error(String(err));
13587
13720
  setError(nextError);
13588
13721
  setStatus("error");
@@ -13650,13 +13783,24 @@ function usePiChat(model, options) {
13650
13783
  });
13651
13784
  const enhancedMessages = useMemo2(() => enhanceMessages(messages), [messages, enhanceMessages]);
13652
13785
  const renameSession = useCallback2(async (sessionId, title) => {
13653
- await client.renameSession(sessionId, title);
13654
- await refreshSessions();
13786
+ try {
13787
+ await client.renameSession(sessionId, title);
13788
+ await refreshSessions();
13789
+ return true;
13790
+ } catch (err) {
13791
+ notifyChatError(err);
13792
+ return false;
13793
+ }
13655
13794
  }, [client, refreshSessions]);
13656
13795
  const deleteSession = useCallback2(async (sessionId) => {
13657
13796
  const deletingActive = sessionMetadataRef.current.sessionId === sessionId;
13658
13797
  if (deletingActive) stop();
13659
- await client.deleteSession(sessionId);
13798
+ try {
13799
+ await client.deleteSession(sessionId);
13800
+ } catch (err) {
13801
+ notifyChatError(err);
13802
+ return false;
13803
+ }
13660
13804
  if (deletingActive) {
13661
13805
  setSessionMetadataSynced({});
13662
13806
  setMessagesSynced([]);
@@ -13669,6 +13813,7 @@ function usePiChat(model, options) {
13669
13813
  });
13670
13814
  }
13671
13815
  await refreshSessions();
13816
+ return true;
13672
13817
  }, [
13673
13818
  client,
13674
13819
  refreshSessions,
@@ -13895,7 +14040,7 @@ function useChatWorkspaceData() {
13895
14040
  const { data: commandsData } = useChatCommands(activeProjectId);
13896
14041
  const { data: settingsData, isLoading: settingsLoading, error: settingsError } = useChatSettings(activeProjectId);
13897
14042
  const updateSettings = useUpdateChatSettings();
13898
- const { data: workspaceData, isLoading: workspaceLoading, error: workspaceError, refetch: refetchWorkspace } = useWorkspaceTree(activeProjectId, { enabled: true });
14043
+ const { data: workspaceData, isLoading: workspaceLoading, error: workspaceError, refetch: refetchWorkspace } = useWorkspaceTree(activeProjectId, { enabled: rightPanel === "workspace" || rightPanel === "resources" });
13899
14044
  const resources = resourcesData ?? null;
13900
14045
  const workspaceTree = workspaceData ?? null;
13901
14046
  const refreshResources = useCallback2(() => {
@@ -13944,15 +14089,29 @@ function useChatWorkspaceData() {
13944
14089
  setUploadedAttachments([]);
13945
14090
  setWorkspaceAttachments([]);
13946
14091
  }, []);
14092
+ const workspaceSessionCreatePromiseRef = useRef2(null);
13947
14093
  const startNewSessionForWorkspace = useCallback2(async (options) => {
13948
- const currentMetadata = getSessionMetadata();
13949
- const targetProjectId = options?.projectId ?? activeProjectId;
13950
- const shouldClear = shouldClearPendingAttachmentsForNewSession({
13951
- ...currentMetadata,
13952
- projectId: currentMetadata.projectId ?? activeProjectId
13953
- }, targetProjectId);
13954
- await startNewSession(options);
13955
- if (shouldClear) clearPendingAttachments();
14094
+ const key = `${options?.projectId ?? ""}::${options?.preserveRunning ?? ""}`;
14095
+ const inFlight = workspaceSessionCreatePromiseRef.current;
14096
+ if (inFlight && inFlight.key === key) return inFlight.promise;
14097
+ const promise = (async () => {
14098
+ const currentMetadata = getSessionMetadata();
14099
+ const targetProjectId = options?.projectId ?? activeProjectId;
14100
+ const shouldClear = shouldClearPendingAttachmentsForNewSession({
14101
+ ...currentMetadata,
14102
+ projectId: currentMetadata.projectId ?? activeProjectId
14103
+ }, targetProjectId);
14104
+ await startNewSession(options);
14105
+ if (shouldClear) clearPendingAttachments();
14106
+ return getSessionMetadata();
14107
+ })().finally(() => {
14108
+ if (workspaceSessionCreatePromiseRef.current?.promise === promise) workspaceSessionCreatePromiseRef.current = null;
14109
+ });
14110
+ workspaceSessionCreatePromiseRef.current = {
14111
+ key,
14112
+ promise
14113
+ };
14114
+ return promise;
13956
14115
  }, [
13957
14116
  activeProjectId,
13958
14117
  clearPendingAttachments,
@@ -14007,8 +14166,7 @@ function useChatWorkspaceData() {
14007
14166
  ]);
14008
14167
  const deleteSessionForWorkspace = useCallback2(async (sessionId) => {
14009
14168
  const deletingActiveSession = getSessionMetadata().sessionId === sessionId;
14010
- await deleteSession(sessionId);
14011
- if (deletingActiveSession) clearPendingAttachments();
14169
+ if (await deleteSession(sessionId) && deletingActiveSession) clearPendingAttachments();
14012
14170
  }, [
14013
14171
  clearPendingAttachments,
14014
14172
  deleteSession,
@@ -14062,8 +14220,7 @@ function useChatWorkspaceData() {
14062
14220
  (async () => {
14063
14221
  const files = Array.from(input.files ?? []);
14064
14222
  if (files.length === 0) return;
14065
- if (!getSessionMetadata().sessionId) await startNewSessionForWorkspace();
14066
- const sessionId = getSessionMetadata().sessionId;
14223
+ const sessionId = getSessionMetadata().sessionId ?? (await startNewSessionForWorkspace()).sessionId;
14067
14224
  if (!sessionId) throw new Error("Unable to create a session for attachments");
14068
14225
  const uploaded = await chatClient.uploadAttachments(sessionId, files);
14069
14226
  setUploadedAttachments((current) => [...current, ...uploaded]);
@@ -14078,6 +14235,10 @@ function useChatWorkspaceData() {
14078
14235
  }, []);
14079
14236
  const clearUploadedAttachments = useCallback2(() => setUploadedAttachments([]), []);
14080
14237
  const clearWorkspaceAttachments = useCallback2(() => setWorkspaceAttachments([]), []);
14238
+ const restoreAttachments = useCallback2((uploaded, workspace) => {
14239
+ if (uploaded.length > 0) setUploadedAttachments((current) => [...uploaded, ...current]);
14240
+ if (workspace.length > 0) setWorkspaceAttachments((current) => [...workspace, ...current]);
14241
+ }, []);
14081
14242
  const addWorkspaceAttachment = useCallback2((item) => {
14082
14243
  const relativePath = workspacePathFromSuggestion(item);
14083
14244
  if (!relativePath) return;
@@ -14153,22 +14314,23 @@ function useChatWorkspaceData() {
14153
14314
  modelKey,
14154
14315
  models,
14155
14316
  onForkPicker: setForkPickerEntries,
14156
- onOpenUIRequest: useCallback2((request) => {
14317
+ onOpenUIRequest: useCallback2(async (request) => {
14157
14318
  const attachments = [...workspaceAttachments, ...uploadedAttachments];
14158
14319
  clearUploadedAttachments();
14159
14320
  clearWorkspaceAttachments();
14160
- return sendMessage({
14321
+ if (!await sendMessage({
14161
14322
  text: request,
14162
14323
  altKey: false,
14163
14324
  mode: chatMode,
14164
14325
  openUI: true,
14165
14326
  openUIArtifact: true,
14166
14327
  attachments
14167
- });
14328
+ })) restoreAttachments(uploadedAttachments, workspaceAttachments);
14168
14329
  }, [
14169
14330
  chatMode,
14170
14331
  clearUploadedAttachments,
14171
14332
  clearWorkspaceAttachments,
14333
+ restoreAttachments,
14172
14334
  sendMessage,
14173
14335
  uploadedAttachments,
14174
14336
  workspaceAttachments
@@ -14306,6 +14468,7 @@ function useChatWorkspaceData() {
14306
14468
  removeUploadedAttachment,
14307
14469
  removeWorkspaceAttachment,
14308
14470
  addWorkspaceAttachment,
14471
+ restoreAttachments,
14309
14472
  setChatMode,
14310
14473
  setEffortPickerOpen,
14311
14474
  setModelKey,
@@ -14343,7 +14506,7 @@ function useChatWorkspaceData() {
14343
14506
  }
14344
14507
  };
14345
14508
  }
14346
- var LazySubagentChatPanel = lazy(() => import("./subagent-chat-panel-DVgf-whR-6G2ASMGU.js").then(({ SubagentChatPanel }) => ({ default: SubagentChatPanel })));
14509
+ var LazySubagentChatPanel = lazy(() => import("./subagent-chat-panel-CMuvW9Sd-M5TEEGQW.js").then(({ SubagentChatPanel }) => ({ default: SubagentChatPanel })));
14347
14510
  function ChatWorkspaceShell() {
14348
14511
  const { session, conversation, composer, panels, dialogs, chrome, agentTabs } = useChatWorkspaceData();
14349
14512
  const toggleCommandPalette = useCallback2(() => {
@@ -14361,22 +14524,30 @@ function ChatWorkspaceShell() {
14361
14524
  });
14362
14525
  const activeProjectName = session.projects.find((project) => project.projectId === session.activeProjectId)?.name;
14363
14526
  const handleSend = useCallback2((text, altKey) => {
14364
- const attachments = [...composer.workspaceAttachments, ...composer.uploadedAttachments];
14527
+ const uploaded = [...composer.uploadedAttachments];
14528
+ const workspace = [...composer.workspaceAttachments];
14529
+ const attachments = [...workspace, ...uploaded];
14365
14530
  composer.clearUploadedAttachments();
14366
14531
  composer.clearWorkspaceAttachments();
14367
14532
  (async () => {
14368
- await conversation.sendMessage({
14369
- text,
14370
- altKey,
14371
- mode: composer.chatMode,
14372
- openUI: true,
14373
- attachments
14374
- });
14533
+ try {
14534
+ if (!await conversation.sendMessage({
14535
+ text,
14536
+ altKey,
14537
+ mode: composer.chatMode,
14538
+ openUI: true,
14539
+ attachments
14540
+ })) composer.restoreAttachments(uploaded, workspace);
14541
+ } catch (error) {
14542
+ composer.restoreAttachments(uploaded, workspace);
14543
+ notifyChatError(error);
14544
+ }
14375
14545
  })();
14376
14546
  }, [
14377
14547
  composer.chatMode,
14378
14548
  composer.clearUploadedAttachments,
14379
14549
  composer.clearWorkspaceAttachments,
14550
+ composer.restoreAttachments,
14380
14551
  composer.uploadedAttachments,
14381
14552
  composer.workspaceAttachments,
14382
14553
  conversation.sendMessage