@truefoundry/trueforge-ui 0.3.0 → 0.4.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/NOTICE +1 -1
  3. package/README.md +26 -89
  4. package/dist/{AgentCodeSnippets-EK7KMIY2.js → AgentCodeSnippets-BPC6TD7K.js} +7 -7
  5. package/dist/AgentMetricChart-T6DZZ37Y.js +15 -0
  6. package/dist/{AgentOverview-5UPMYHT2.js → AgentOverview-BFU7EO4Y.js} +7 -7
  7. package/dist/{AgentSessionEventTimeline-V6NPCYMW.js → AgentSessionEventTimeline-ATVBTYDF.js} +7 -7
  8. package/dist/{AgentSessionEventTimelineChart-YQWZBQCG.js → AgentSessionEventTimelineChart-H577STKW.js} +7 -7
  9. package/dist/{AgentSessions-WNYVVB6Q.js → AgentSessions-GDLBXFIK.js} +8 -8
  10. package/dist/{ConnectorSettings-O4I24244.js → ConnectorSettings-FYNF6J3F.js} +7 -7
  11. package/dist/{DockLayout-JMBZVMGB.js → DockLayout-SGUOMZ5E.js} +10 -10
  12. package/dist/{DrawerLayout-E6G3IF6R.js → DrawerLayout-MJJYQDCW.js} +11 -11
  13. package/dist/{ModelSettings-ZVXMXIU4.js → ModelSettings-6EW7U2MP.js} +9 -9
  14. package/dist/ModelSettings-6EW7U2MP.js.map +1 -0
  15. package/dist/OpenUiFenceBlock-BZPFNXWZ.js +9 -0
  16. package/dist/{SandboxSettings-H6BA2DJQ.js → SandboxSettings-HQVBGHXZ.js} +7 -7
  17. package/dist/SchedulesPage-ZO3PJY4J.js +15 -0
  18. package/dist/{SettingsBuilder-VA3VGWZC.js → SettingsBuilder-FODMI7HG.js} +20 -11
  19. package/dist/SettingsBuilder-FODMI7HG.js.map +1 -0
  20. package/dist/{ShellRouteSync-ZT4PBE6T.js → ShellRouteSync-4I5BP2VY.js} +4 -4
  21. package/dist/{SidebarLayout-ICXEN7ZL.js → SidebarLayout-ZLWG2YGO.js} +12 -12
  22. package/dist/{SkillSettings-F5JGGFXR.js → SkillSettings-AFSAOU6O.js} +7 -7
  23. package/dist/{TrueForgeUIWithRouter-MKJ7IEWG.js → TrueForgeUIWithRouter-RQX5XWGI.js} +9 -9
  24. package/dist/WebSearchSettings-BW4CWGRR.js +322 -0
  25. package/dist/WebSearchSettings-BW4CWGRR.js.map +1 -0
  26. package/dist/{WidgetLayout-J7ZRW3V3.js → WidgetLayout-WIPKUIL4.js} +10 -10
  27. package/dist/chunk-6UACSIIY.js +587 -0
  28. package/dist/chunk-6UACSIIY.js.map +1 -0
  29. package/dist/{chunk-U7WONUMR.js → chunk-7S7A3PNP.js} +6 -4
  30. package/dist/chunk-7S7A3PNP.js.map +1 -0
  31. package/dist/{chunk-VTOW2UIX.js → chunk-GHXA46A2.js} +78 -43
  32. package/dist/chunk-GHXA46A2.js.map +1 -0
  33. package/dist/{chunk-7AAO4UDQ.js → chunk-HCGDDQ4G.js} +5 -5
  34. package/dist/chunk-HCGDDQ4G.js.map +1 -0
  35. package/dist/{chunk-SCIEO6CF.js → chunk-HDMBSLDC.js} +2 -2
  36. package/dist/{chunk-KZK2PQ4A.js → chunk-MLMR26WQ.js} +244 -152
  37. package/dist/chunk-MLMR26WQ.js.map +1 -0
  38. package/dist/{chunk-BREN6OSX.js → chunk-Q22RHDYS.js} +42 -61
  39. package/dist/chunk-Q22RHDYS.js.map +1 -0
  40. package/dist/{chunk-WFIA627Q.js → chunk-QKFMAQ7O.js} +2 -2
  41. package/dist/{chunk-7VWUB5OV.js → chunk-TFQWCBFQ.js} +12 -12
  42. package/dist/chunk-TFQWCBFQ.js.map +1 -0
  43. package/dist/{chunk-JEAULQNF.js → chunk-TJGGIEF6.js} +3 -3
  44. package/dist/{chunk-KDCVFHPZ.js → chunk-TX6PB3DY.js} +3 -3
  45. package/dist/{chunk-MEW7WZ7Q.js → chunk-VBZXCX7Y.js} +253 -99
  46. package/dist/chunk-VBZXCX7Y.js.map +1 -0
  47. package/dist/{chunk-QI4HGU5E.js → chunk-Y47LJKXD.js} +13 -19
  48. package/dist/{chunk-QI4HGU5E.js.map → chunk-Y47LJKXD.js.map} +1 -1
  49. package/dist/{chunk-MB7Z5FPI.js → chunk-YN5ZBBQM.js} +9 -9
  50. package/dist/{chunk-UN7WPTTK.js → chunk-ZYJ2SBF7.js} +2 -2
  51. package/dist/createTrueForgeServer-DiSooQdh.d.ts +42 -0
  52. package/dist/index.d.ts +45 -39
  53. package/dist/index.js +43 -43
  54. package/dist/index.js.map +1 -1
  55. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +57 -894
  56. package/dist/plugins/trueforge-agent-server-adapter/index.js +110 -7
  57. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  58. package/dist/styles.css +1 -1
  59. package/package.json +8 -7
  60. package/dist/AgentMetricChart-UZCYOC4M.js +0 -15
  61. package/dist/ModelSettings-ZVXMXIU4.js.map +0 -1
  62. package/dist/OpenUiFenceBlock-F3YVDKAG.js +0 -9
  63. package/dist/SchedulesPage-FS2QZ5KB.js +0 -15
  64. package/dist/SettingsBuilder-VA3VGWZC.js.map +0 -1
  65. package/dist/chunk-7AAO4UDQ.js.map +0 -1
  66. package/dist/chunk-7VWUB5OV.js.map +0 -1
  67. package/dist/chunk-BREN6OSX.js.map +0 -1
  68. package/dist/chunk-KZK2PQ4A.js.map +0 -1
  69. package/dist/chunk-MEW7WZ7Q.js.map +0 -1
  70. package/dist/chunk-NXK4XW4U.js +0 -587
  71. package/dist/chunk-NXK4XW4U.js.map +0 -1
  72. package/dist/chunk-U7WONUMR.js.map +0 -1
  73. package/dist/chunk-VTOW2UIX.js.map +0 -1
  74. package/dist/createTrueFoundryServer-B_FYhSdn.d.ts +0 -42
  75. /package/dist/{AgentCodeSnippets-EK7KMIY2.js.map → AgentCodeSnippets-BPC6TD7K.js.map} +0 -0
  76. /package/dist/{AgentMetricChart-UZCYOC4M.js.map → AgentMetricChart-T6DZZ37Y.js.map} +0 -0
  77. /package/dist/{AgentOverview-5UPMYHT2.js.map → AgentOverview-BFU7EO4Y.js.map} +0 -0
  78. /package/dist/{AgentSessionEventTimeline-V6NPCYMW.js.map → AgentSessionEventTimeline-ATVBTYDF.js.map} +0 -0
  79. /package/dist/{AgentSessionEventTimelineChart-YQWZBQCG.js.map → AgentSessionEventTimelineChart-H577STKW.js.map} +0 -0
  80. /package/dist/{AgentSessions-WNYVVB6Q.js.map → AgentSessions-GDLBXFIK.js.map} +0 -0
  81. /package/dist/{ConnectorSettings-O4I24244.js.map → ConnectorSettings-FYNF6J3F.js.map} +0 -0
  82. /package/dist/{DockLayout-JMBZVMGB.js.map → DockLayout-SGUOMZ5E.js.map} +0 -0
  83. /package/dist/{DrawerLayout-E6G3IF6R.js.map → DrawerLayout-MJJYQDCW.js.map} +0 -0
  84. /package/dist/{OpenUiFenceBlock-F3YVDKAG.js.map → OpenUiFenceBlock-BZPFNXWZ.js.map} +0 -0
  85. /package/dist/{SandboxSettings-H6BA2DJQ.js.map → SandboxSettings-HQVBGHXZ.js.map} +0 -0
  86. /package/dist/{SchedulesPage-FS2QZ5KB.js.map → SchedulesPage-ZO3PJY4J.js.map} +0 -0
  87. /package/dist/{ShellRouteSync-ZT4PBE6T.js.map → ShellRouteSync-4I5BP2VY.js.map} +0 -0
  88. /package/dist/{SidebarLayout-ICXEN7ZL.js.map → SidebarLayout-ZLWG2YGO.js.map} +0 -0
  89. /package/dist/{SkillSettings-F5JGGFXR.js.map → SkillSettings-AFSAOU6O.js.map} +0 -0
  90. /package/dist/{TrueForgeUIWithRouter-MKJ7IEWG.js.map → TrueForgeUIWithRouter-RQX5XWGI.js.map} +0 -0
  91. /package/dist/{WidgetLayout-J7ZRW3V3.js.map → WidgetLayout-WIPKUIL4.js.map} +0 -0
  92. /package/dist/{chunk-SCIEO6CF.js.map → chunk-HDMBSLDC.js.map} +0 -0
  93. /package/dist/{chunk-WFIA627Q.js.map → chunk-QKFMAQ7O.js.map} +0 -0
  94. /package/dist/{chunk-JEAULQNF.js.map → chunk-TJGGIEF6.js.map} +0 -0
  95. /package/dist/{chunk-KDCVFHPZ.js.map → chunk-TX6PB3DY.js.map} +0 -0
  96. /package/dist/{chunk-MB7Z5FPI.js.map → chunk-YN5ZBBQM.js.map} +0 -0
  97. /package/dist/{chunk-UN7WPTTK.js.map → chunk-ZYJ2SBF7.js.map} +0 -0
@@ -1,7 +1,11 @@
1
1
  import {
2
2
  BottomSheet,
3
+ Button,
4
+ CenteredModal,
3
5
  DropdownMenuItem,
6
+ MAX_SESSION_TITLE_LENGTH,
4
7
  SearchInput_default,
8
+ auiInputClass,
5
9
  canReuseMutableShell,
6
10
  readThreadAgentName,
7
11
  themePortalRoot,
@@ -9,24 +13,25 @@ import {
9
13
  threadListItemIsMutable,
10
14
  useIsMobile,
11
15
  useResourcePermissions,
12
- useSlot
13
- } from "./chunk-KZK2PQ4A.js";
14
- import {
15
- useSearchAgentsList
16
- } from "./chunk-UN7WPTTK.js";
16
+ useSlot,
17
+ useToasterOptional
18
+ } from "./chunk-MLMR26WQ.js";
17
19
  import {
18
20
  Icon,
19
21
  auiButtonClass,
20
22
  useCompactLayout
21
- } from "./chunk-KDCVFHPZ.js";
23
+ } from "./chunk-TX6PB3DY.js";
24
+ import {
25
+ useSearchAgentsList
26
+ } from "./chunk-ZYJ2SBF7.js";
22
27
  import {
23
28
  libraryAgentId,
24
29
  useOptionalServer,
25
30
  useOptionalShellMode
26
- } from "./chunk-U7WONUMR.js";
31
+ } from "./chunk-7S7A3PNP.js";
27
32
  import {
28
33
  cn
29
- } from "./chunk-NXK4XW4U.js";
34
+ } from "./chunk-6UACSIIY.js";
30
35
 
31
36
  // src/containers/ThreadListContainer.tsx
32
37
  import {
@@ -37,7 +42,7 @@ import {
37
42
  useAui,
38
43
  useAuiState
39
44
  } from "@assistant-ui/react";
40
- import { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
45
+ import { useCallback, useEffect as useEffect3, useMemo, useRef as useRef3, useState as useState3 } from "react";
41
46
 
42
47
  // src/atoms/AgentHistoryFilterButton.tsx
43
48
  import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
@@ -205,15 +210,89 @@ function AgentHistoryFilterButton() {
205
210
  ] });
206
211
  }
207
212
 
213
+ // src/atoms/RenameSessionModal.tsx
214
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
215
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
216
+ function RenameSessionModal({
217
+ open,
218
+ initialTitle,
219
+ saving = false,
220
+ onOpenChange,
221
+ onSave
222
+ }) {
223
+ const [value, setValue] = useState2(initialTitle);
224
+ const inputRef = useRef2(null);
225
+ useEffect2(() => {
226
+ if (open) setValue(initialTitle);
227
+ }, [open, initialTitle]);
228
+ useEffect2(() => {
229
+ if (!open) return;
230
+ const input = inputRef.current;
231
+ if (input == null) return;
232
+ input.focus();
233
+ input.select();
234
+ }, [open]);
235
+ const trimmed = value.trim();
236
+ const isValid = trimmed.length > 0 && trimmed.length <= MAX_SESSION_TITLE_LENGTH;
237
+ const canSave = isValid && !saving;
238
+ const handleSave = () => {
239
+ if (!canSave) return;
240
+ onSave(trimmed);
241
+ };
242
+ const handleOpenChange = (next) => {
243
+ if (saving) return;
244
+ onOpenChange(next);
245
+ };
246
+ return /* @__PURE__ */ jsx2(
247
+ CenteredModal,
248
+ {
249
+ open,
250
+ onOpenChange: handleOpenChange,
251
+ title: "Rename session",
252
+ contentSized: true,
253
+ "aria-label": "Rename session",
254
+ footer: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-end gap-2", children: [
255
+ /* @__PURE__ */ jsx2(Button.Secondary, { type: "button", disabled: saving, onClick: () => handleOpenChange(false), children: "Cancel" }),
256
+ /* @__PURE__ */ jsx2(Button.Primary, { type: "button", disabled: !canSave, onClick: handleSave, children: "Save" })
257
+ ] }),
258
+ children: /* @__PURE__ */ jsx2("div", { className: "px-5 py-4", children: /* @__PURE__ */ jsx2(
259
+ "input",
260
+ {
261
+ ref: inputRef,
262
+ "aria-label": "Session title",
263
+ value,
264
+ readOnly: saving,
265
+ maxLength: MAX_SESSION_TITLE_LENGTH,
266
+ className: auiInputClass("h-9"),
267
+ onChange: (event) => setValue(event.target.value),
268
+ onKeyDown: (event) => {
269
+ if (event.key === "Enter") {
270
+ event.preventDefault();
271
+ handleSave();
272
+ }
273
+ }
274
+ }
275
+ ) })
276
+ }
277
+ );
278
+ }
279
+
208
280
  // src/containers/ThreadListContainer.tsx
209
- import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
281
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
282
+ var actionItemClass = "flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium outline-none transition-colors hover:bg-ghost-button-hover focus:bg-ghost-button-hover data-[highlighted]:bg-ghost-button-hover";
210
283
  var deleteItemClass = "flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-failure-bg outline-none transition-colors hover:bg-failure-bg/12 hover:text-failure-bg focus:bg-failure-bg/12 focus:text-failure-bg data-[highlighted]:bg-failure-bg/12 data-[highlighted]:text-failure-bg";
211
- function ThreadListItemDeleteMenu({ disabled }) {
284
+ function ThreadListItemActionsMenu({
285
+ canRename,
286
+ renameDisabled,
287
+ canDelete,
288
+ deleteDisabled,
289
+ onRename
290
+ }) {
212
291
  const PermissionGuard = useSlot("PermissionGuard");
213
292
  const compact = useCompactLayout();
214
293
  const isMobile = useIsMobile();
215
- const [sheetOpen, setSheetOpen] = useState2(false);
216
- const [portalContainer, setPortalContainer] = useState2();
294
+ const [sheetOpen, setSheetOpen] = useState3(false);
295
+ const [portalContainer, setPortalContainer] = useState3();
217
296
  const useSheet = isMobile || compact;
218
297
  const setTriggerElement = useCallback((element) => {
219
298
  const themeRoot = element?.closest(".aui-theme-root");
@@ -224,9 +303,39 @@ function ThreadListItemDeleteMenu({ disabled }) {
224
303
  size: "icon",
225
304
  className: "size-7 shrink-0 text-text-secondary hover:bg-transparent hover:text-text-primary"
226
305
  });
306
+ const renameButton = canRename ? /* @__PURE__ */ jsx3(PermissionGuard, { allowed: !renameDisabled, children: /* @__PURE__ */ jsxs3(
307
+ "button",
308
+ {
309
+ type: "button",
310
+ className: actionItemClass,
311
+ disabled: renameDisabled,
312
+ onClick: () => {
313
+ if (renameDisabled) return;
314
+ setSheetOpen(false);
315
+ onRename();
316
+ },
317
+ children: [
318
+ /* @__PURE__ */ jsx3(Icon, { name: "pencil", className: "size-3.5" }),
319
+ "Rename"
320
+ ]
321
+ }
322
+ ) }) : null;
323
+ const deleteButton = canDelete ? /* @__PURE__ */ jsx3(PermissionGuard, { allowed: !deleteDisabled, children: /* @__PURE__ */ jsxs3(
324
+ ThreadListItemPrimitive.Delete,
325
+ {
326
+ className: deleteItemClass,
327
+ onClick: () => {
328
+ if (!deleteDisabled) setSheetOpen(false);
329
+ },
330
+ children: [
331
+ /* @__PURE__ */ jsx3(Icon, { name: "trash", className: "size-3.5" }),
332
+ "Delete"
333
+ ]
334
+ }
335
+ ) }) : null;
227
336
  if (useSheet) {
228
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
229
- /* @__PURE__ */ jsx2(
337
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
338
+ /* @__PURE__ */ jsx3(
230
339
  "button",
231
340
  {
232
341
  type: "button",
@@ -236,57 +345,51 @@ function ThreadListItemDeleteMenu({ disabled }) {
236
345
  "aria-expanded": sheetOpen,
237
346
  className: moreButtonClass,
238
347
  onClick: () => setSheetOpen(true),
239
- children: /* @__PURE__ */ jsx2(Icon, { name: "ellipsis", className: "size-3.5" })
348
+ children: /* @__PURE__ */ jsx3(Icon, { name: "ellipsis", className: "size-3.5" })
240
349
  }
241
350
  ),
242
- sheetOpen ? /* @__PURE__ */ jsx2(BottomSheet, { open: true, onOpenChange: setSheetOpen, "aria-label": "Session actions", children: /* @__PURE__ */ jsx2("div", { className: "flex flex-col gap-1 p-2 *:w-full", role: "menu", children: /* @__PURE__ */ jsx2(PermissionGuard, { allowed: !disabled, children: /* @__PURE__ */ jsxs2(
243
- ThreadListItemPrimitive.Delete,
244
- {
245
- className: deleteItemClass,
246
- onClick: () => {
247
- if (!disabled) setSheetOpen(false);
248
- },
249
- children: [
250
- /* @__PURE__ */ jsx2(Icon, { name: "trash", className: "size-3.5" }),
251
- "Delete"
252
- ]
253
- }
254
- ) }) }) }) : null
351
+ sheetOpen ? /* @__PURE__ */ jsx3(BottomSheet, { open: true, onOpenChange: setSheetOpen, "aria-label": "Session actions", children: /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1 p-2 *:w-full", role: "menu", children: [
352
+ renameButton,
353
+ deleteButton
354
+ ] }) }) : null
255
355
  ] });
256
356
  }
257
- return /* @__PURE__ */ jsxs2(ThreadListItemMorePrimitive.Root, { sharedFocusGroup: true, children: [
258
- /* @__PURE__ */ jsx2(
357
+ return /* @__PURE__ */ jsxs3(ThreadListItemMorePrimitive.Root, { sharedFocusGroup: true, children: [
358
+ /* @__PURE__ */ jsx3(
259
359
  ThreadListItemMorePrimitive.Trigger,
260
360
  {
261
361
  ref: setTriggerElement,
262
362
  "aria-label": "Session actions",
263
363
  title: "Session actions",
264
364
  className: moreButtonClass,
265
- children: /* @__PURE__ */ jsx2(Icon, { name: "ellipsis", className: "size-3.5" })
365
+ children: /* @__PURE__ */ jsx3(Icon, { name: "ellipsis", className: "size-3.5" })
266
366
  }
267
367
  ),
268
- /* @__PURE__ */ jsx2(
368
+ /* @__PURE__ */ jsxs3(
269
369
  ThreadListItemMorePrimitive.Content,
270
370
  {
271
371
  portalProps: { container: portalContainer },
272
372
  align: "end",
273
373
  sideOffset: 4,
274
- className: "aui-popup-enter font-sans-flex z-50 min-w-[8rem] rounded-md border border-border bg-card-bg p-1 text-text-primary shadow-md *:w-full",
275
- children: /* @__PURE__ */ jsx2(PermissionGuard, { allowed: !disabled, children: /* @__PURE__ */ jsxs2(ThreadListItemPrimitive.Delete, { className: deleteItemClass, children: [
276
- /* @__PURE__ */ jsx2(Icon, { name: "trash", className: "size-3.5" }),
277
- "Delete"
278
- ] }) })
374
+ className: "aui-popup-enter font-sans-flex z-50 min-w-32 rounded-md border border-border bg-card-bg p-1 text-text-primary shadow-md *:w-full",
375
+ children: [
376
+ renameButton,
377
+ deleteButton
378
+ ]
279
379
  }
280
380
  )
281
381
  ] });
282
382
  }
283
383
  function ThreadListItemRow({
284
384
  onThreadOpen,
385
+ canRenameSession,
285
386
  canDeleteSession,
387
+ canManageResource,
286
388
  canDeleteResource
287
389
  }) {
288
390
  const aui = useAui();
289
391
  const shell = useOptionalShellMode();
392
+ const toaster = useToasterOptional();
290
393
  const ThreadListRow = useSlot("ThreadListRow");
291
394
  const id = useAuiState((s) => s.threadListItem.id);
292
395
  const remoteId = useAuiState((s) => s.threadListItem.remoteId);
@@ -295,48 +398,92 @@ function ThreadListItemRow({
295
398
  const custom = useAuiState((s) => s.threadListItem.custom);
296
399
  const mainThreadId = useAuiState((s) => s.threads.mainThreadId);
297
400
  const agentName = readThreadAgentName(custom);
401
+ const showRename = canRenameSession && remoteId != null;
298
402
  const showDelete = canDeleteSession && remoteId != null;
403
+ const showActions = showRename || showDelete;
404
+ const renameDisabled = remoteId != null && !canManageResource(remoteId);
299
405
  const deleteDisabled = remoteId != null && !canDeleteResource(remoteId);
300
406
  const sidebarNavOpen = shell?.libraryOpen === true || shell?.sessionsOpen === true || shell?.schedulesOpen === true;
301
- return /* @__PURE__ */ jsx2(ThreadListItemPrimitive.Root, { className: "min-w-0", children: /* @__PURE__ */ jsx2(
302
- ThreadListRow,
303
- {
304
- title: title ?? "New Chat",
305
- active: id === mainThreadId && !sidebarNavOpen,
306
- agentName,
307
- lastMessageAt,
308
- onSelect: () => {
309
- onThreadOpen?.();
310
- shell?.setSettingsOpen(false);
311
- shell?.setLibraryOpen(false);
312
- shell?.setSessionsOpen(false);
313
- shell?.setSchedulesOpen(false);
314
- const sessionMutable = threadListItemIsMutable(custom);
315
- const sameImmutable = !sessionMutable && shell?.mode.status === "active" && !shell.mode.isMutable && (agentName == null ? shell.mode.agentName == null && shell.mode.agentId == null : shell.mode.agentName === agentName || shell.mode.agentId === agentName);
316
- const sameMutable = canReuseMutableShell({
317
- sessionMutable,
318
- shellMutable: shell?.mode.status === "active" && shell.mode.isMutable,
319
- ...shell?.mode.status === "active" && shell.mode.isMutable ? { shellAgentName: shell.mode.agentName, shellAgentId: shell.mode.agentId } : {},
320
- remoteId,
321
- pendingSessionId: shell?.pendingSessionId
322
- });
323
- if ((sameImmutable || sameMutable) && remoteId != null) {
324
- void Promise.resolve(aui.threads().switchToThread(id)).catch(() => void 0);
325
- return;
326
- }
327
- if (remoteId != null) {
328
- shell?.openHistorySession({
329
- sessionId: remoteId,
330
- isMutable: sessionMutable,
331
- ...agentName != null ? { agentName } : {}
407
+ const [renameOpen, setRenameOpen] = useState3(false);
408
+ const [renameSaving, setRenameSaving] = useState3(false);
409
+ const displayTitle = title ?? "New Chat";
410
+ const persistRename = async (trimmed) => {
411
+ if (trimmed === (title ?? "").trim()) {
412
+ setRenameOpen(false);
413
+ return;
414
+ }
415
+ setRenameSaving(true);
416
+ try {
417
+ await aui.threadListItem().rename(trimmed);
418
+ setRenameOpen(false);
419
+ } catch (caught) {
420
+ toaster?.showError(caught);
421
+ } finally {
422
+ setRenameSaving(false);
423
+ }
424
+ };
425
+ return /* @__PURE__ */ jsxs3(ThreadListItemPrimitive.Root, { className: "min-w-0", children: [
426
+ /* @__PURE__ */ jsx3(
427
+ ThreadListRow,
428
+ {
429
+ title: displayTitle,
430
+ active: id === mainThreadId && !sidebarNavOpen,
431
+ agentName,
432
+ lastMessageAt,
433
+ onSelect: () => {
434
+ onThreadOpen?.();
435
+ shell?.setSettingsOpen(false);
436
+ shell?.setLibraryOpen(false);
437
+ shell?.setSessionsOpen(false);
438
+ shell?.setSchedulesOpen(false);
439
+ const sessionMutable = threadListItemIsMutable(custom);
440
+ const sameImmutable = !sessionMutable && shell?.mode.status === "active" && !shell.mode.isMutable && (agentName == null ? shell.mode.agentName == null && shell.mode.agentId == null : shell.mode.agentName === agentName || shell.mode.agentId === agentName);
441
+ const sameMutable = canReuseMutableShell({
442
+ sessionMutable,
443
+ shellMutable: shell?.mode.status === "active" && shell.mode.isMutable,
444
+ ...shell?.mode.status === "active" && shell.mode.isMutable ? { shellAgentName: shell.mode.agentName, shellAgentId: shell.mode.agentId } : {},
445
+ remoteId,
446
+ pendingSessionId: shell?.pendingSessionId
332
447
  });
333
- return;
448
+ if ((sameImmutable || sameMutable) && remoteId != null) {
449
+ void Promise.resolve(aui.threads().switchToThread(id)).catch(() => void 0);
450
+ return;
451
+ }
452
+ if (remoteId != null) {
453
+ shell?.openHistorySession({
454
+ sessionId: remoteId,
455
+ isMutable: sessionMutable,
456
+ ...agentName != null ? { agentName } : {}
457
+ });
458
+ return;
459
+ }
460
+ void Promise.resolve(aui.threads().switchToThread(id)).catch(() => void 0);
461
+ },
462
+ actions: showActions ? /* @__PURE__ */ jsx3(
463
+ ThreadListItemActionsMenu,
464
+ {
465
+ canRename: showRename,
466
+ renameDisabled,
467
+ canDelete: showDelete,
468
+ deleteDisabled,
469
+ onRename: () => setRenameOpen(true)
470
+ }
471
+ ) : void 0
472
+ }
473
+ ),
474
+ /* @__PURE__ */ jsx3(
475
+ RenameSessionModal,
476
+ {
477
+ open: renameOpen,
478
+ initialTitle: title ?? "",
479
+ saving: renameSaving,
480
+ onOpenChange: setRenameOpen,
481
+ onSave: (nextTitle) => {
482
+ void persistRename(nextTitle);
334
483
  }
335
- void Promise.resolve(aui.threads().switchToThread(id)).catch(() => void 0);
336
- },
337
- actions: showDelete ? /* @__PURE__ */ jsx2(ThreadListItemDeleteMenu, { disabled: deleteDisabled }) : void 0
338
- }
339
- ) });
484
+ }
485
+ )
486
+ ] });
340
487
  }
341
488
  function useThreadListIndicesByRecency(variant) {
342
489
  const threadIds = useAuiState((s) => s.threads.threadIds);
@@ -360,17 +507,21 @@ function useThreadListIndicesByRecency(variant) {
360
507
  function ThreadListItemsByRecency({
361
508
  indices,
362
509
  onThreadOpen,
510
+ canRenameSession,
363
511
  canDeleteSession,
512
+ canManageResource,
364
513
  canDeleteResource
365
514
  }) {
366
515
  const threadIds = useAuiState((s) => s.threads.threadIds);
367
- return /* @__PURE__ */ jsx2(Fragment2, { children: indices.map((index) => {
516
+ return /* @__PURE__ */ jsx3(Fragment2, { children: indices.map((index) => {
368
517
  const key = threadIds[index] ?? String(index);
369
- return /* @__PURE__ */ jsx2(ThreadListItemByIndexProvider, { index, archived: false, children: /* @__PURE__ */ jsx2(
518
+ return /* @__PURE__ */ jsx3(ThreadListItemByIndexProvider, { index, archived: false, children: /* @__PURE__ */ jsx3(
370
519
  ThreadListItemRow,
371
520
  {
372
521
  onThreadOpen,
522
+ canRenameSession,
373
523
  canDeleteSession,
524
+ canManageResource,
374
525
  canDeleteResource
375
526
  }
376
527
  ) }, key);
@@ -388,12 +539,12 @@ function RecentChatsSection({
388
539
  const historyFilterIntent = shell?.historyAgentFilter?.intent;
389
540
  const showFilter = shell?.isLibraryEnabled === true && historyFilterIntent !== "try-agent" && (historyFilterIntent === "history" || shell.mode.status !== "active" || shell.mode.isMutable || shell.pendingSessionId != null || activeRemoteId != null);
390
541
  const heading = shell?.historyAgentFilter == null ? "Chat History" : `Chats for ${shell.historyAgentFilter.agentName}`;
391
- return /* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-1 flex-col", children: [
392
- /* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-1 px-1 py-1", children: [
393
- /* @__PURE__ */ jsx2("h2", { className: "min-w-0 flex-1 truncate px-1.5 py-1 text-sm font-medium text-text-secondary", children: heading }),
394
- showFilter ? /* @__PURE__ */ jsx2(AgentHistoryFilterButton, {}) : null
542
+ return /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1 flex-col", children: [
543
+ /* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 items-center gap-1 px-1 py-1", children: [
544
+ /* @__PURE__ */ jsx3("h2", { className: "min-w-0 flex-1 truncate px-1.5 py-1 text-sm font-medium text-text-secondary", children: heading }),
545
+ showFilter ? /* @__PURE__ */ jsx3(AgentHistoryFilterButton, {}) : null
395
546
  ] }),
396
- /* @__PURE__ */ jsx2(
547
+ /* @__PURE__ */ jsx3(
397
548
  "div",
398
549
  {
399
550
  ref: viewportRef,
@@ -421,21 +572,22 @@ function ThreadListContainer({ onThreadOpen, variant = "default" } = {}) {
421
572
  const ThreadListRowSkeleton = useSlot("ThreadListRowSkeleton");
422
573
  const ThreadListEmptyState = useSlot("ThreadListEmptyState");
423
574
  const indices = useThreadListIndicesByRecency(variant);
424
- const viewportRef = useRef2(null);
425
- const hasMoreRef = useRef2(hasMore);
426
- const auiRef = useRef2(aui);
575
+ const viewportRef = useRef3(null);
576
+ const hasMoreRef = useRef3(hasMore);
577
+ const auiRef = useRef3(aui);
427
578
  hasMoreRef.current = hasMore;
428
579
  auiRef.current = aui;
429
580
  const showNewChat = shell?.isNewChatEnabled !== false;
430
581
  const isIdle = shell?.mode.status === "idle";
431
582
  const isRecentHistory = variant === "recent-history";
583
+ const canRenameSession = typeof server?.renameSession === "function";
432
584
  const canDeleteSession = typeof server?.deleteSession === "function";
433
585
  const remoteSessionIds = useMemo(
434
586
  () => threadItems.flatMap((item) => item.remoteId == null ? [] : [item.remoteId]),
435
587
  [threadItems]
436
588
  );
437
589
  const { allows } = useResourcePermissions({ resourceType: "session", resourceIds: remoteSessionIds });
438
- useEffect2(() => {
590
+ useEffect3(() => {
439
591
  if (isIdle || isLoading || isLoadingMore) return;
440
592
  const viewport = viewportRef.current;
441
593
  if (!viewport) return;
@@ -478,34 +630,36 @@ function ThreadListContainer({ onThreadOpen, variant = "default" } = {}) {
478
630
  };
479
631
  let listBody;
480
632
  if (isIdle) {
481
- listBody = /* @__PURE__ */ jsx2(ThreadListEmptyState, { message: isRecentHistory ? "No recent chats" : void 0 });
633
+ listBody = /* @__PURE__ */ jsx3(ThreadListEmptyState, { message: isRecentHistory ? "No recent chats" : void 0 });
482
634
  } else if (isLoading) {
483
- listBody = /* @__PURE__ */ jsx2(ThreadListRowSkeleton, {});
635
+ listBody = /* @__PURE__ */ jsx3(ThreadListRowSkeleton, {});
484
636
  } else if (indices.length === 0) {
485
- listBody = /* @__PURE__ */ jsx2(ThreadListEmptyState, { message: isRecentHistory ? "No recent chats" : void 0 });
637
+ listBody = /* @__PURE__ */ jsx3(ThreadListEmptyState, { message: isRecentHistory ? "No recent chats" : void 0 });
486
638
  } else {
487
- listBody = /* @__PURE__ */ jsx2(ThreadListPrimitive.Root, { className: "flex min-h-0 flex-col gap-0.5", children: /* @__PURE__ */ jsx2(
639
+ listBody = /* @__PURE__ */ jsx3(ThreadListPrimitive.Root, { className: "flex min-h-0 flex-col gap-0.5", children: /* @__PURE__ */ jsx3(
488
640
  ThreadListItemsByRecency,
489
641
  {
490
642
  indices,
491
643
  onThreadOpen,
644
+ canRenameSession,
492
645
  canDeleteSession,
646
+ canManageResource: (sessionId) => allows(sessionId, "MANAGE"),
493
647
  canDeleteResource: (sessionId) => allows(sessionId, "DELETE")
494
648
  }
495
649
  ) });
496
650
  }
497
- return /* @__PURE__ */ jsx2(
651
+ return /* @__PURE__ */ jsx3(
498
652
  ThreadListShell,
499
653
  {
500
- header: isRecentHistory ? null : /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-1", children: [
501
- showNewChat ? /* @__PURE__ */ jsx2(ThreadListNewButton, { onClick: handleNewChat }) : null,
502
- /* @__PURE__ */ jsx2(AgentsLibraryButton, {}),
503
- /* @__PURE__ */ jsx2(SessionsBrowserButton, {}),
504
- /* @__PURE__ */ jsx2(SchedulesButton, {})
654
+ header: isRecentHistory ? null : /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
655
+ showNewChat ? /* @__PURE__ */ jsx3(ThreadListNewButton, { onClick: handleNewChat }) : null,
656
+ /* @__PURE__ */ jsx3(AgentsLibraryButton, {}),
657
+ /* @__PURE__ */ jsx3(SessionsBrowserButton, {}),
658
+ /* @__PURE__ */ jsx3(SchedulesButton, {})
505
659
  ] }),
506
- children: /* @__PURE__ */ jsxs2(RecentChatsSection, { viewportRef, hideScrollbar: isRecentHistory, children: [
660
+ children: /* @__PURE__ */ jsxs3(RecentChatsSection, { viewportRef, hideScrollbar: isRecentHistory, children: [
507
661
  listBody,
508
- !isIdle && hasMore ? /* @__PURE__ */ jsx2("div", { className: "h-4 shrink-0", "aria-hidden": true }) : null
662
+ !isIdle && hasMore ? /* @__PURE__ */ jsx3("div", { className: "h-4 shrink-0", "aria-hidden": true }) : null
509
663
  ] })
510
664
  }
511
665
  );
@@ -514,4 +668,4 @@ function ThreadListContainer({ onThreadOpen, variant = "default" } = {}) {
514
668
  export {
515
669
  ThreadListContainer
516
670
  };
517
- //# sourceMappingURL=chunk-MEW7WZ7Q.js.map
671
+ //# sourceMappingURL=chunk-VBZXCX7Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/containers/ThreadListContainer.tsx","../src/atoms/AgentHistoryFilterButton.tsx","../src/atoms/RenameSessionModal.tsx"],"sourcesContent":["'use client';\n\nimport {\n ThreadListItemByIndexProvider,\n ThreadListItemMorePrimitive,\n ThreadListItemPrimitive,\n ThreadListPrimitive,\n useAui,\n useAuiState,\n} from '@assistant-ui/react';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode, type Ref } from 'react';\n\nimport { AgentHistoryFilterButton } from '../atoms/AgentHistoryFilterButton.js';\nimport { auiButtonClass } from '../atoms/lib/buttonClasses.js';\nimport { cn } from '../atoms/lib/cn.js';\nimport { useCompactLayout } from '../atoms/lib/CompactLayoutContext.js';\nimport {\n canReuseMutableShell,\n readThreadAgentName,\n threadListIndicesByRecency,\n threadListItemIsMutable,\n} from '../atoms/lib/threadListMeta.js';\nimport { useIsMobile } from '../atoms/lib/useIsMobile.js';\nimport { BottomSheet } from '../atoms/primitives/BottomSheet.js';\nimport { RenameSessionModal } from '../atoms/RenameSessionModal.js';\nimport { useResourcePermissions } from '../hooks/useResourcePermissions.js';\nimport { Icon } from '../icons/Icon.js';\nimport { useOptionalServer } from '../server/ServerContext.js';\nimport { useOptionalShellMode } from '../server/ShellModeContext.js';\nimport { useSlot } from '../theme/SlotsProvider.js';\nimport { useToasterOptional } from './ToasterContainer.js';\n\n/**\n * Simplified relative to the reference: renders threads in a single flat list\n * rather than grouping them by Today/Yesterday/Earlier.\n *\n * Delete uses assistant-ui ThreadListItemPrimitive.Delete / ThreadListItemMorePrimitive\n * (adapter.delete → server.deleteSession). Rename opens RenameSessionModal via\n * aui.threadListItem().rename (adapter.rename → server.renameSession) when\n * `renameSession` is implemented. Mobile/compact keeps a BottomSheet chrome.\n */\nexport type ThreadListContainerProps = {\n /** Called after New chat or selecting a row — used by stack/drawer chrome. */\n onThreadOpen?: () => void;\n /** `recent-history` hides navigation and lists only persisted sessions. */\n variant?: 'default' | 'recent-history';\n};\n\nconst actionItemClass =\n 'flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium outline-none transition-colors hover:bg-ghost-button-hover focus:bg-ghost-button-hover data-[highlighted]:bg-ghost-button-hover';\n\nconst deleteItemClass =\n 'flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-failure-bg outline-none transition-colors hover:bg-failure-bg/12 hover:text-failure-bg focus:bg-failure-bg/12 focus:text-failure-bg data-[highlighted]:bg-failure-bg/12 data-[highlighted]:text-failure-bg';\n\nfunction ThreadListItemActionsMenu({\n canRename,\n renameDisabled,\n canDelete,\n deleteDisabled,\n onRename,\n}: {\n canRename: boolean;\n renameDisabled: boolean;\n canDelete: boolean;\n deleteDisabled: boolean;\n onRename: () => void;\n}) {\n const PermissionGuard = useSlot('PermissionGuard');\n const compact = useCompactLayout();\n const isMobile = useIsMobile();\n const [sheetOpen, setSheetOpen] = useState(false);\n const [portalContainer, setPortalContainer] = useState<HTMLElement>();\n const useSheet = isMobile || compact;\n const setTriggerElement = useCallback((element: HTMLButtonElement | null) => {\n const themeRoot = element?.closest('.aui-theme-root');\n setPortalContainer(themeRoot instanceof HTMLElement ? themeRoot : undefined);\n }, []);\n\n const moreButtonClass = auiButtonClass({\n variant: 'ghost',\n size: 'icon',\n className: 'size-7 shrink-0 text-text-secondary hover:bg-transparent hover:text-text-primary',\n });\n\n const renameButton = canRename ? (\n <PermissionGuard allowed={!renameDisabled}>\n <button\n type=\"button\"\n className={actionItemClass}\n disabled={renameDisabled}\n onClick={() => {\n if (renameDisabled) return;\n setSheetOpen(false);\n onRename();\n }}\n >\n <Icon name=\"pencil\" className=\"size-3.5\" />\n Rename\n </button>\n </PermissionGuard>\n ) : null;\n\n const deleteButton = canDelete ? (\n <PermissionGuard allowed={!deleteDisabled}>\n <ThreadListItemPrimitive.Delete\n className={deleteItemClass}\n onClick={() => {\n if (!deleteDisabled) setSheetOpen(false);\n }}\n >\n <Icon name=\"trash\" className=\"size-3.5\" />\n Delete\n </ThreadListItemPrimitive.Delete>\n </PermissionGuard>\n ) : null;\n\n if (useSheet) {\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Session actions\"\n title=\"Session actions\"\n aria-haspopup=\"dialog\"\n aria-expanded={sheetOpen}\n className={moreButtonClass}\n onClick={() => setSheetOpen(true)}\n >\n <Icon name=\"ellipsis\" className=\"size-3.5\" />\n </button>\n {sheetOpen ? (\n <BottomSheet open onOpenChange={setSheetOpen} aria-label=\"Session actions\">\n <div className=\"flex flex-col gap-1 p-2 *:w-full\" role=\"menu\">\n {renameButton}\n {deleteButton}\n </div>\n </BottomSheet>\n ) : null}\n </>\n );\n }\n\n return (\n <ThreadListItemMorePrimitive.Root sharedFocusGroup>\n <ThreadListItemMorePrimitive.Trigger\n ref={setTriggerElement}\n aria-label=\"Session actions\"\n title=\"Session actions\"\n className={moreButtonClass}\n >\n <Icon name=\"ellipsis\" className=\"size-3.5\" />\n </ThreadListItemMorePrimitive.Trigger>\n <ThreadListItemMorePrimitive.Content\n portalProps={{ container: portalContainer }}\n align=\"end\"\n sideOffset={4}\n className=\"aui-popup-enter font-sans-flex z-50 min-w-32 rounded-md border border-border bg-card-bg p-1 text-text-primary shadow-md *:w-full\"\n >\n {renameButton}\n {deleteButton}\n </ThreadListItemMorePrimitive.Content>\n </ThreadListItemMorePrimitive.Root>\n );\n}\n\nfunction ThreadListItemRow({\n onThreadOpen,\n canRenameSession,\n canDeleteSession,\n canManageResource,\n canDeleteResource,\n}: {\n onThreadOpen?: () => void;\n canRenameSession: boolean;\n canDeleteSession: boolean;\n canManageResource: (sessionId: string) => boolean;\n canDeleteResource: (sessionId: string) => boolean;\n}) {\n const aui = useAui();\n const shell = useOptionalShellMode();\n const toaster = useToasterOptional();\n const ThreadListRow = useSlot('ThreadListRow');\n const id = useAuiState(s => s.threadListItem.id);\n const remoteId = useAuiState(s => s.threadListItem.remoteId);\n const title = useAuiState(s => s.threadListItem.title);\n const lastMessageAt = useAuiState(s => s.threadListItem.lastMessageAt);\n const custom = useAuiState(s => s.threadListItem.custom);\n const mainThreadId = useAuiState(s => s.threads.mainThreadId);\n const agentName = readThreadAgentName(custom);\n const showRename = canRenameSession && remoteId != null;\n const showDelete = canDeleteSession && remoteId != null;\n const showActions = showRename || showDelete;\n const renameDisabled = remoteId != null && !canManageResource(remoteId);\n const deleteDisabled = remoteId != null && !canDeleteResource(remoteId);\n const sidebarNavOpen = shell?.libraryOpen === true || shell?.sessionsOpen === true || shell?.schedulesOpen === true;\n const [renameOpen, setRenameOpen] = useState(false);\n const [renameSaving, setRenameSaving] = useState(false);\n\n const displayTitle = title ?? 'New Chat';\n\n const persistRename = async (trimmed: string) => {\n if (trimmed === (title ?? '').trim()) {\n setRenameOpen(false);\n return;\n }\n setRenameSaving(true);\n try {\n await aui.threadListItem().rename(trimmed);\n setRenameOpen(false);\n } catch (caught) {\n toaster?.showError(caught);\n } finally {\n setRenameSaving(false);\n }\n };\n\n return (\n <ThreadListItemPrimitive.Root className=\"min-w-0\">\n <ThreadListRow\n title={displayTitle}\n active={id === mainThreadId && !sidebarNavOpen}\n agentName={agentName}\n lastMessageAt={lastMessageAt}\n onSelect={() => {\n onThreadOpen?.();\n shell?.setSettingsOpen(false);\n shell?.setLibraryOpen(false);\n shell?.setSessionsOpen(false);\n shell?.setSchedulesOpen(false);\n\n // Prefer custom.isMutable (session wire); agentName-only is a legacy fallback.\n const sessionMutable = threadListItemIsMutable(custom);\n const sameImmutable =\n !sessionMutable &&\n shell?.mode.status === 'active' &&\n !shell.mode.isMutable &&\n (agentName == null\n ? shell.mode.agentName == null && shell.mode.agentId == null\n : shell.mode.agentName === agentName || shell.mode.agentId === agentName);\n const sameMutable = canReuseMutableShell({\n sessionMutable,\n shellMutable: shell?.mode.status === 'active' && shell.mode.isMutable,\n ...(shell?.mode.status === 'active' && shell.mode.isMutable\n ? { shellAgentName: shell.mode.agentName, shellAgentId: shell.mode.agentId }\n : {}),\n remoteId,\n pendingSessionId: shell?.pendingSessionId,\n });\n\n if ((sameImmutable || sameMutable) && remoteId != null) {\n void Promise.resolve(aui.threads().switchToThread(id)).catch(() => undefined);\n return;\n }\n if (remoteId != null) {\n shell?.openHistorySession({\n sessionId: remoteId,\n isMutable: sessionMutable,\n ...(agentName != null ? { agentName } : {}),\n });\n return;\n }\n void Promise.resolve(aui.threads().switchToThread(id)).catch(() => undefined);\n }}\n actions={\n showActions ? (\n <ThreadListItemActionsMenu\n canRename={showRename}\n renameDisabled={renameDisabled}\n canDelete={showDelete}\n deleteDisabled={deleteDisabled}\n onRename={() => setRenameOpen(true)}\n />\n ) : undefined\n }\n />\n <RenameSessionModal\n open={renameOpen}\n initialTitle={title ?? ''}\n saving={renameSaving}\n onOpenChange={setRenameOpen}\n onSave={nextTitle => {\n void persistRename(nextTitle);\n }}\n />\n </ThreadListItemPrimitive.Root>\n );\n}\n\nfunction useThreadListIndicesByRecency(variant: NonNullable<ThreadListContainerProps['variant']>): number[] {\n const threadIds = useAuiState(s => s.threads.threadIds);\n const threadItems = useAuiState(s => s.threads.threadItems);\n\n return useMemo(() => {\n const indices = threadListIndicesByRecency({ threadIds, threadItems });\n if (variant === 'default') return indices;\n\n const itemById = new Map<string, (typeof threadItems)[number]>();\n for (const item of threadItems) {\n itemById.set(item.id, item);\n if (item.remoteId != null) itemById.set(item.remoteId, item);\n }\n\n return indices.filter(index => {\n const id = threadIds[index];\n if (id === undefined) return false;\n const item = itemById.get(id);\n return item?.remoteId != null;\n });\n }, [threadIds, threadItems, variant]);\n}\n\nfunction ThreadListItemsByRecency({\n indices,\n onThreadOpen,\n canRenameSession,\n canDeleteSession,\n canManageResource,\n canDeleteResource,\n}: {\n indices: number[];\n onThreadOpen?: () => void;\n canRenameSession: boolean;\n canDeleteSession: boolean;\n canManageResource: (sessionId: string) => boolean;\n canDeleteResource: (sessionId: string) => boolean;\n}) {\n // Newest-first: remount/switchToThread can append the active session to threadIds.\n const threadIds = useAuiState(s => s.threads.threadIds);\n\n return (\n <>\n {indices.map(index => {\n const key = threadIds[index] ?? String(index);\n return (\n <ThreadListItemByIndexProvider key={key} index={index} archived={false}>\n <ThreadListItemRow\n onThreadOpen={onThreadOpen}\n canRenameSession={canRenameSession}\n canDeleteSession={canDeleteSession}\n canManageResource={canManageResource}\n canDeleteResource={canDeleteResource}\n />\n </ThreadListItemByIndexProvider>\n );\n })}\n </>\n );\n}\n\nconst THREAD_LIST_VIEWPORT_SLOT = 'aui_thread-list-viewport';\n/** How close to the bottom (px) before the next sessions page is fetched. */\nconst LOAD_MORE_BOTTOM_PX = 80;\n\nfunction RecentChatsSection({\n children,\n viewportRef,\n hideScrollbar,\n}: {\n children: ReactNode;\n viewportRef: Ref<HTMLDivElement>;\n hideScrollbar: boolean;\n}) {\n const shell = useOptionalShellMode();\n const activeRemoteId = useAuiState(s => s.threadListItem.remoteId);\n const historyFilterIntent = shell?.historyAgentFilter?.intent;\n const showFilter =\n shell?.isLibraryEnabled === true &&\n historyFilterIntent !== 'try-agent' &&\n (historyFilterIntent === 'history' ||\n shell.mode.status !== 'active' ||\n shell.mode.isMutable ||\n shell.pendingSessionId != null ||\n activeRemoteId != null);\n const heading =\n shell?.historyAgentFilter == null ? 'Chat History' : `Chats for ${shell.historyAgentFilter.agentName}`;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex shrink-0 items-center gap-1 px-1 py-1\">\n <h2 className=\"min-w-0 flex-1 truncate px-1.5 py-1 text-sm font-medium text-text-secondary\">{heading}</h2>\n {showFilter ? <AgentHistoryFilterButton /> : null}\n </div>\n <div\n ref={viewportRef}\n data-slot={THREAD_LIST_VIEWPORT_SLOT}\n className={cn('flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto', hideScrollbar && 'aui-scrollbar-hidden')}\n >\n {children}\n </div>\n </div>\n );\n}\n\nexport function ThreadListContainer({ onThreadOpen, variant = 'default' }: ThreadListContainerProps = {}) {\n const aui = useAui();\n const server = useOptionalServer();\n const isLoading = useAuiState(s => s.threads.isLoading);\n const isLoadingMore = useAuiState(s => s.threads.isLoadingMore);\n const hasMore = useAuiState(s => s.threads.hasMore);\n const threadIds = useAuiState(s => s.threads.threadIds);\n const threadItems = useAuiState(s => s.threads.threadItems);\n const shell = useOptionalShellMode();\n\n const ThreadListShell = useSlot('ThreadListShell');\n const ThreadListNewButton = useSlot('ThreadListNewButton');\n const AgentsLibraryButton = useSlot('AgentsLibraryButton');\n const SessionsBrowserButton = useSlot('SessionsBrowserButton');\n const SchedulesButton = useSlot('SchedulesButton');\n const ThreadListRowSkeleton = useSlot('ThreadListRowSkeleton');\n const ThreadListEmptyState = useSlot('ThreadListEmptyState');\n\n const indices = useThreadListIndicesByRecency(variant);\n const viewportRef = useRef<HTMLDivElement>(null);\n const hasMoreRef = useRef(hasMore);\n const auiRef = useRef(aui);\n hasMoreRef.current = hasMore;\n auiRef.current = aui;\n\n const showNewChat = shell?.isNewChatEnabled !== false;\n const isIdle = shell?.mode.status === 'idle';\n const isRecentHistory = variant === 'recent-history';\n const canRenameSession = typeof server?.renameSession === 'function';\n const canDeleteSession = typeof server?.deleteSession === 'function';\n const remoteSessionIds = useMemo(\n () => threadItems.flatMap(item => (item.remoteId == null ? [] : [item.remoteId])),\n [threadItems],\n );\n const { allows } = useResourcePermissions({ resourceType: 'session', resourceIds: remoteSessionIds });\n\n // Fill an underflowing viewport; once it scrolls, paginate only near the bottom.\n // Re-measure after commit (threadIds / hasMore) instead of rAF-chaining, which\n // raced layout and could drain every remaining listSessions page.\n // The runtime owns request deduplication, so Strict Mode remounts can recheck safely.\n useEffect(() => {\n if (isIdle || isLoading || isLoadingMore) return;\n const viewport = viewportRef.current;\n if (!viewport) return;\n\n let cancelled = false;\n\n const tryLoadMore = () => {\n if (cancelled || !hasMoreRef.current) return;\n if (viewport.clientHeight <= 0) return;\n\n const remaining = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n if (viewport.scrollHeight > viewport.clientHeight && remaining > LOAD_MORE_BOTTOM_PX) return;\n\n void auiRef.current.threads().loadMore();\n };\n\n viewport.addEventListener('scroll', tryLoadMore, { passive: true });\n const resizeObserver = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(() => tryLoadMore());\n if (resizeObserver) {\n resizeObserver.observe(viewport);\n } else {\n window.addEventListener('resize', tryLoadMore);\n }\n tryLoadMore();\n\n return () => {\n cancelled = true;\n viewport.removeEventListener('scroll', tryLoadMore);\n resizeObserver?.disconnect();\n if (!resizeObserver) {\n window.removeEventListener('resize', tryLoadMore);\n }\n };\n }, [hasMore, isIdle, isLoading, isLoadingMore, threadIds.length]);\n\n const handleNewChat = () => {\n onThreadOpen?.();\n shell?.setLibraryOpen(false);\n shell?.setSessionsOpen(false);\n if (shell?.isComposerEnabled) {\n shell.openDraft();\n return;\n }\n shell?.setSettingsOpen(false);\n shell?.setSchedulesOpen(false);\n void Promise.resolve(aui.threads().switchToNewThread()).catch(() => undefined);\n };\n\n let listBody: ReactNode;\n if (isIdle) {\n listBody = <ThreadListEmptyState message={isRecentHistory ? 'No recent chats' : undefined} />;\n } else if (isLoading) {\n listBody = <ThreadListRowSkeleton />;\n } else if (indices.length === 0) {\n listBody = <ThreadListEmptyState message={isRecentHistory ? 'No recent chats' : undefined} />;\n } else {\n listBody = (\n <ThreadListPrimitive.Root className=\"flex min-h-0 flex-col gap-0.5\">\n <ThreadListItemsByRecency\n indices={indices}\n onThreadOpen={onThreadOpen}\n canRenameSession={canRenameSession}\n canDeleteSession={canDeleteSession}\n canManageResource={sessionId => allows(sessionId, 'MANAGE')}\n canDeleteResource={sessionId => allows(sessionId, 'DELETE')}\n />\n </ThreadListPrimitive.Root>\n );\n }\n\n return (\n <ThreadListShell\n header={\n isRecentHistory ? null : (\n <div className=\"flex flex-col gap-1\">\n {showNewChat ? <ThreadListNewButton onClick={handleNewChat} /> : null}\n <AgentsLibraryButton />\n <SessionsBrowserButton />\n <SchedulesButton />\n </div>\n )\n }\n >\n <RecentChatsSection viewportRef={viewportRef} hideScrollbar={isRecentHistory}>\n {listBody}\n {!isIdle && hasMore ? <div className=\"h-4 shrink-0\" aria-hidden /> : null}\n </RecentChatsSection>\n </ThreadListShell>\n );\n}\n","'use client';\n\nimport { useEffect, useId, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Icon } from '../icons/Icon.js';\nimport { useOptionalServer } from '../server/ServerContext.js';\nimport { libraryAgentId, useOptionalShellMode, type HistoryAgentFilter } from '../server/ShellModeContext.js';\nimport { auiButtonClass } from './lib/buttonClasses.js';\nimport { cn } from './lib/cn.js';\nimport { useCompactLayout } from './lib/CompactLayoutContext.js';\nimport { themePortalRoot } from './lib/themePortalRoot.js';\nimport { useIsMobile } from './lib/useIsMobile.js';\nimport { useSearchAgentsList } from './lib/useSearchAgentsList.js';\nimport { BottomSheet } from './primitives/BottomSheet.js';\nimport { DropdownMenuItem } from './primitives/DropdownMenu.js';\nimport SearchInput from './primitives/SearchInput.js';\n\n/**\n * Funnel popover for filtering chat history by agent id.\n * Desktop: fixed menu to the right of the funnel. Mobile/compact: bottom sheet.\n */\nexport function AgentHistoryFilterButton() {\n const shell = useOptionalShellMode();\n const server = useOptionalServer();\n const isMobile = useIsMobile();\n const compact = useCompactLayout();\n const useSheet = isMobile || compact;\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [menuPos, setMenuPos] = useState<{ top: number; left: number } | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const menuId = useId();\n\n const enabled = shell?.isLibraryEnabled === true && server != null;\n const selected = shell?.historyAgentFilter ?? null;\n\n useEffect(() => {\n if (!open) setQuery('');\n }, [open]);\n\n const { agents, isInitialLoading, isSearching, loadingMore, hasMore, listRef, sentinelRef } = useSearchAgentsList({\n enabled: open && enabled,\n query,\n });\n\n // Desktop only: anchor to the right of the funnel; portal escapes sidebar overflow.\n useLayoutEffect(() => {\n if (!open || useSheet) {\n setMenuPos(null);\n return;\n }\n const update = () => {\n const rect = buttonRef.current?.getBoundingClientRect();\n if (!rect) return;\n setMenuPos({ top: rect.top, left: rect.right + 4 });\n };\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n };\n }, [open, useSheet]);\n\n useEffect(() => {\n if (!open || useSheet) return;\n const handler = (e: MouseEvent) => {\n const target = e.target as Node;\n if (buttonRef.current?.contains(target) || menuRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [open, useSheet]);\n\n if (!enabled) return null;\n\n // Reset the active session so the newly scoped history starts from a clean runtime and first page.\n const pick = (filter: HistoryAgentFilter | null) => {\n if (shell?.isComposerEnabled === true) {\n shell.openDraft();\n } else {\n shell?.openLibraryHome();\n }\n shell?.setHistoryAgentFilter(filter);\n setOpen(false);\n };\n\n const filterBody = (\n <>\n <div className=\"p-1\" onMouseDown={e => e.stopPropagation()}>\n <SearchInput query={query} setQuery={setQuery} placeholder=\"Search agents\" />\n {isSearching ? (\n <p className=\"text-text-secondary px-1 pt-1 text-[11px]\" role=\"status\">\n Searching…\n </p>\n ) : null}\n </div>\n <div\n ref={listRef}\n className={cn('mt-1 overflow-y-auto', useSheet ? 'min-h-0 flex-1 px-1 pb-2' : 'min-h-48 max-h-64')}\n >\n {query.trim() === '' ? (\n <DropdownMenuItem\n className={cn(\n 'justify-between',\n selected == null && 'bg-dropdown-selected-item-bg text-dropdown-selected-item-text',\n )}\n onClick={() => pick(null)}\n >\n All chats\n {selected == null ? <Icon name=\"check\" className=\"size-3.5 shrink-0\" /> : null}\n </DropdownMenuItem>\n ) : null}\n {isInitialLoading ? (\n <p className=\"px-2 py-3 text-center text-xs text-text-secondary\">Loading…</p>\n ) : agents.length === 0 ? (\n <p className=\"text-text-secondary px-2 py-6 text-center text-xs\" role=\"status\">\n {query.trim() ? `No agents match \"${query.trim()}\".` : 'No agents yet.'}\n </p>\n ) : (\n <>\n {agents.map(agent => {\n const id = libraryAgentId(agent);\n const active = selected?.agentId === id;\n return (\n <DropdownMenuItem\n key={id}\n className={cn(\n 'justify-between gap-2 text-left',\n active && 'bg-dropdown-selected-item-bg text-dropdown-selected-item-text',\n )}\n onClick={() => pick({ agentId: id, agentName: agent.name, intent: 'history' })}\n >\n <span className=\"min-w-0 truncate\">{agent.name}</span>\n {active ? <Icon name=\"check\" className=\"size-3.5 shrink-0\" /> : null}\n </DropdownMenuItem>\n );\n })}\n {hasMore ? (\n <div ref={sentinelRef} className=\"flex h-6 shrink-0 items-center justify-center\" aria-hidden>\n {loadingMore ? (\n <span className=\"text-text-secondary text-[11px]\" role=\"status\">\n Loading more…\n </span>\n ) : null}\n </div>\n ) : null}\n </>\n )}\n </div>\n </>\n );\n\n return (\n <div className=\"relative shrink-0\">\n <button\n ref={buttonRef}\n type=\"button\"\n aria-label={\n selected != null ? `Filter chat history by agent (${selected.agentName})` : 'Filter chat history by agent'\n }\n aria-haspopup={useSheet ? 'dialog' : 'menu'}\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n title=\"Filter by agent\"\n className={auiButtonClass({\n variant: 'ghost',\n size: 'icon',\n className: cn(\n 'relative size-7 shrink-0 text-text-secondary hover:bg-ghost-button-hover hover:text-ghost-button-text',\n selected != null && 'text-text-primary',\n ),\n })}\n onClick={() => setOpen(v => !v)}\n >\n <Icon name=\"funnel\" className=\"size-3.5\" />\n {selected != null ? (\n <span\n className=\"bg-primary-button-bg absolute top-1 right-1 size-1.5 rounded-full\"\n aria-hidden\n data-testid=\"history-filter-active-dot\"\n />\n ) : null}\n </button>\n {useSheet && open ? (\n <BottomSheet open onOpenChange={setOpen} id={menuId} aria-label=\"Filter agents\">\n <div className=\"flex min-h-0 flex-1 flex-col p-2\" role=\"menu\">\n {filterBody}\n </div>\n </BottomSheet>\n ) : null}\n {!useSheet && open && menuPos != null\n ? createPortal(\n <div\n ref={menuRef}\n id={menuId}\n role=\"menu\"\n aria-label=\"Filter agents\"\n style={{ top: menuPos.top, left: menuPos.left }}\n className=\"aui-popup-enter font-sans-flex fixed z-50 w-56 rounded-md border border-border bg-card-bg p-1 text-text-primary shadow-md\"\n >\n {filterBody}\n </div>,\n themePortalRoot(buttonRef.current),\n )\n : null}\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { auiInputClass } from './lib/inputClasses.js';\nimport { MAX_SESSION_TITLE_LENGTH } from './lib/threadListMeta.js';\nimport { Button } from './primitives/Button.js';\nimport { CenteredModal } from './primitives/CenteredModal.js';\n\nexport type RenameSessionModalProps = {\n open: boolean;\n initialTitle: string;\n saving?: boolean;\n onOpenChange: (open: boolean) => void;\n onSave: (title: string) => void;\n};\n\n/** Compact rename dialog: title field + Cancel / Save. */\nexport function RenameSessionModal({\n open,\n initialTitle,\n saving = false,\n onOpenChange,\n onSave,\n}: RenameSessionModalProps) {\n const [value, setValue] = useState(initialTitle);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (open) setValue(initialTitle);\n }, [open, initialTitle]);\n\n useEffect(() => {\n if (!open) return;\n const input = inputRef.current;\n if (input == null) return;\n input.focus();\n input.select();\n }, [open]);\n\n const trimmed = value.trim();\n const isValid = trimmed.length > 0 && trimmed.length <= MAX_SESSION_TITLE_LENGTH;\n const canSave = isValid && !saving;\n\n const handleSave = () => {\n if (!canSave) return;\n onSave(trimmed);\n };\n\n const handleOpenChange = (next: boolean) => {\n if (saving) return;\n onOpenChange(next);\n };\n\n return (\n <CenteredModal\n open={open}\n onOpenChange={handleOpenChange}\n title=\"Rename session\"\n contentSized\n aria-label=\"Rename session\"\n footer={\n <div className=\"flex items-center justify-end gap-2\">\n <Button.Secondary type=\"button\" disabled={saving} onClick={() => handleOpenChange(false)}>\n Cancel\n </Button.Secondary>\n <Button.Primary type=\"button\" disabled={!canSave} onClick={handleSave}>\n Save\n </Button.Primary>\n </div>\n }\n >\n <div className=\"px-5 py-4\">\n <input\n ref={inputRef}\n aria-label=\"Session title\"\n value={value}\n readOnly={saving}\n maxLength={MAX_SESSION_TITLE_LENGTH}\n className={auiInputClass('h-9')}\n onChange={event => setValue(event.target.value)}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleSave();\n }\n }}\n />\n </div>\n </CenteredModal>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","Fragment","jsx","jsxs","useState","useRef","useEffect"]}