@alivault/pico 0.2.1 → 0.3.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.
@@ -2,7 +2,7 @@ import { i as __toESM } from "../_runtime.mjs";
2
2
  import { A as DialogRoot, C as MenuPortal, D as TabsTab, E as TabsList$1, F as DialogBackdrop, I as Separator, K as mergeProps, L as Input, M as DialogPopup, N as DialogDescription$1, O as TabsRoot, P as DialogClose, R as Button, S as MenuPositioner, T as MenuItem, X as require_react, Y as require_jsx_runtime, _ as AccordionRoot, a as CollapsiblePanel, b as MenuSubmenuRoot, c as PopoverPopup, d as PopoverTrigger$1, f as PopoverRoot, g as AccordionItem$1, h as AccordionHeader, i as ContextMenuRoot, j as DialogPortal$1, k as DialogTitle$1, l as PopoverPositioner, m as AccordionTrigger$1, n as Toggle, o as CollapsibleTrigger$1, p as AccordionPanel, r as ContextMenuTrigger$1, s as CollapsibleRoot, t as ToggleGroup, u as PopoverPortal, v as MenuSubmenuTrigger, w as MenuPopup, x as MenuRoot, y as MenuTrigger, z as useRender } from "../_libs/@base-ui/react+[...].mjs";
3
3
  import { t as cva } from "../_libs/class-variance-authority+clsx.mjs";
4
4
  import { A as ChevronsUpDown, B as ArrowDown, C as FolderPlus, D as Copy, E as Download, F as Check, I as ArrowUp, L as ArrowUpToLine, M as ChevronUp, N as ChevronRight, O as Command, P as ChevronDown, S as Folder, T as EllipsisVertical, _ as ListEnd, a as Square, b as GitBranch, c as Settings2, d as PanelLeft, f as PanelLeftOpen, g as ListStart, h as OctagonX, j as ChevronsDownUp, l as Search, n as WandSparkles, o as SquarePen, p as PanelLeftClose, r as Upload, s as SquareArrowOutUpRight, t as X, u as PanelRight, w as Ellipsis, x as GitCommitHorizontal, y as ImagePlus, z as ArrowLeft } from "../_libs/lucide-react.mjs";
5
- import { $ as readStoredSessionDoneSoundEnabled, A as createContextId, B as normalizeStoredDirectoryList, D as buildItemsFromSync, F as flattenTree, G as readStoredCenterMessages, H as previewUrlForImage, I as getSessionTitle, J as readStoredHideToolBlocks, K as readStoredCollapsedDirectories, O as cn, Q as readStoredSessionDoneDesktopNotificationsEnabled, R as normalizePromptImage, S as TooltipContent, T as VIEWER_CONTEXT_STORAGE_KEY, U as promptDraftKey, V as normalizeThemeMode, W as readStoredAutoScrollEnabled, X as readStoredRecentDirectories, Y as readStoredPromptDraft, Z as readStoredRightSidebarOpen, _ as SIDEBAR_DIRECTORIES_STORAGE_KEY, a as HIDE_TOOL_BLOCKS_STORAGE_KEY, at as sessionListEntryKey, b as TitleTooltip, c as RECENT_DIRECTORIES_STORAGE_KEY, d as RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY, et as readStoredSidebarDirectories, f as RIGHT_SIDEBAR_OPEN_STORAGE_KEY, g as SESSION_DONE_SOUND_ENABLED_STORAGE_KEY, h as SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY, i as DRAFT_DIRECTORY_STORAGE_KEY, it as sameContextUsage, j as createInitialSessionState, l as RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY, m as Route, n as CENTER_MESSAGES_STORAGE_KEY, nt as safeLocalStorageGetItem, o as Kbd, ot as thinkingSummaryText, p as RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY, q as readStoredDraftDirectory, r as COLLAPSED_DIRECTORIES_STORAGE_KEY, rt as safeLocalStorageSetItem, s as KeyboardShortcutContent, t as AUTO_SCROLL_ENABLED_STORAGE_KEY, tt as rememberStoredPromptDraft, u as RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY, v as Spinner, w as TooltipTrigger, x as Tooltip$1, z as normalizeSessionSelectionKeys } from "./routes-C8zGEsem.mjs";
5
+ import { $ as readStoredRightSidebarOpen, B as normalizeSessionSelectionKeys, C as TooltipContent, E as VIEWER_CONTEXT_STORAGE_KEY, G as readStoredAutoScrollEnabled, H as normalizeThemeMode, I as flattenTree, J as readStoredDraftDirectory, K as readStoredCenterMessages, L as getSessionTitle, M as createInitialSessionState, O as buildItemsFromSync, Q as readStoredRecentDirectories, S as Tooltip$1, T as TooltipTrigger, U as previewUrlForImage, V as normalizeStoredDirectoryList, W as promptDraftKey, X as readStoredPinnedSessionKeys, Y as readStoredHideToolBlocks, Z as readStoredPromptDraft, _ as SESSION_DONE_SOUND_ENABLED_STORAGE_KEY, a as HIDE_TOOL_BLOCKS_STORAGE_KEY, at as safeLocalStorageSetItem, c as PINNED_SESSIONS_STORAGE_KEY, ct as thinkingSummaryText, d as RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY, et as readStoredSessionDoneDesktopNotificationsEnabled, f as RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY, g as SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY, h as Route, i as DRAFT_DIRECTORY_STORAGE_KEY, it as safeLocalStorageGetItem, j as createContextId, k as cn, l as RECENT_DIRECTORIES_STORAGE_KEY, m as RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY, n as CENTER_MESSAGES_STORAGE_KEY, nt as readStoredSidebarDirectories, o as Kbd, ot as sameContextUsage, p as RIGHT_SIDEBAR_OPEN_STORAGE_KEY, q as readStoredCollapsedDirectories, r as COLLAPSED_DIRECTORIES_STORAGE_KEY, rt as rememberStoredPromptDraft, s as KeyboardShortcutContent, st as sessionListEntryKey, t as AUTO_SCROLL_ENABLED_STORAGE_KEY, tt as readStoredSessionDoneSoundEnabled, u as RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY, v as SIDEBAR_DIRECTORIES_STORAGE_KEY, x as TitleTooltip, y as Spinner, z as normalizePromptImage } from "./routes-C2DKvBRY.mjs";
6
6
  import { i as useQuery, n as useIsMutating, o as useQueryClient, r as useIsFetching, t as useMutation } from "../_libs/tanstack__react-query.mjs";
7
7
  import { t as useHotkeys } from "../_libs/tanstack__react-hotkeys.mjs";
8
8
  import { a as matchesKeyboardEvent, i as batch, o as formatForDisplay, r as createStore } from "../_libs/@tanstack/hotkeys+[...].mjs";
@@ -19,7 +19,7 @@ import { t as remarkGfm } from "../_libs/remark-gfm.mjs";
19
19
  import { a as getBuiltInSpriteSheet, i as getBuiltInFileIconColor, n as FileTree, r as createFileTreeIconResolver, t as useFileTree } from "../_libs/@pierre/trees+[...].mjs";
20
20
  import { a as closestCenter, d as useSensors, f as CSS$1, i as PointerSensor, n as DragOverlay, t as DndContext, u as useSensor } from "../_libs/@dnd-kit/core+[...].mjs";
21
21
  import { a as verticalListSortingStrategy, i as useSortable, n as arrayMove, r as horizontalListSortingStrategy, t as SortableContext } from "../_libs/dnd-kit__sortable.mjs";
22
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-u4ntFNaT.js
22
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-RV18btaL.js
23
23
  var import_react = /* @__PURE__ */ __toESM(require_react());
24
24
  var import_jsx_runtime = require_jsx_runtime();
25
25
  var MOBILE_BREAKPOINT = 768;
@@ -637,6 +637,17 @@ function SidebarGroup({ className, ...props }) {
637
637
  ...props
638
638
  });
639
639
  }
640
+ function SidebarGroupLabel({ className, render, ...props }) {
641
+ return useRender({
642
+ defaultTagName: "div",
643
+ props: mergeProps({ className: cn("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", className) }, props),
644
+ render,
645
+ state: {
646
+ slot: "sidebar-group-label",
647
+ sidebar: "group-label"
648
+ }
649
+ });
650
+ }
640
651
  function SidebarGroupContent({ className, ...props }) {
641
652
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
642
653
  "data-slot": "sidebar-group-content",
@@ -5382,6 +5393,7 @@ function createInitialSidebarState() {
5382
5393
  sidebarSessionStatusByKey: {},
5383
5394
  sidebarDeferredDirectoryLoadingReady: false,
5384
5395
  sessionSearch: "",
5396
+ pinnedSidebarSessionKeys: [],
5385
5397
  selectedSidebarSessionKeys: [],
5386
5398
  sidebarSessionSelectionAnchor: ""
5387
5399
  };
@@ -5432,14 +5444,20 @@ function computeAppShellSidebarDerived(state) {
5432
5444
  }
5433
5445
  }
5434
5446
  const sidebarSessions = Array.from(sidebarSessionEntriesByKey.values());
5447
+ const pinnedSidebarSessions = state.pinnedSidebarSessionKeys.map((key) => sidebarSessionEntriesByKey.get(key)).filter((entry) => Boolean(entry?.path || entry?.id));
5435
5448
  const selectedSidebarSessions = state.selectedSidebarSessionKeys.map((key) => sidebarSessionEntriesByKey.get(key)).filter((entry) => Boolean(entry?.path || entry?.id));
5436
- const workspaceVersion = [baseSidebarDirectories.join("\n"), state.selectedSidebarSessionKeys.join("\n")].join("\0");
5449
+ const workspaceVersion = [
5450
+ baseSidebarDirectories.join("\n"),
5451
+ state.pinnedSidebarSessionKeys.join("\n"),
5452
+ state.selectedSidebarSessionKeys.join("\n")
5453
+ ].join("\0");
5437
5454
  return {
5438
5455
  baseSidebarDirectories,
5439
5456
  directoryStateByPath,
5440
5457
  directoryIndexes: sidebarDirectoryIndexes,
5441
5458
  sidebarDirectoryIndexes,
5442
5459
  sidebarSessions,
5460
+ pinnedSidebarSessions,
5443
5461
  selectedSidebarSessions,
5444
5462
  sidebarSessionEntriesByKey,
5445
5463
  visibleDirectories,
@@ -5509,6 +5527,11 @@ function createAppShellSidebarStore() {
5509
5527
  if (sessionSearch === store.state.state.sessionSearch) return;
5510
5528
  setSidebarState({ sessionSearch });
5511
5529
  },
5530
+ setPinnedSidebarSessionKeys: (action) => {
5531
+ const pinnedSidebarSessionKeys = applyStoreAction(store.state.state.pinnedSidebarSessionKeys, action);
5532
+ if (pinnedSidebarSessionKeys === store.state.state.pinnedSidebarSessionKeys) return;
5533
+ setSidebarState({ pinnedSidebarSessionKeys });
5534
+ },
5512
5535
  setSelectedSidebarSessionKeys: (action) => {
5513
5536
  const selectedSidebarSessionKeys = applyStoreAction(store.state.state.selectedSidebarSessionKeys, action);
5514
5537
  if (selectedSidebarSessionKeys === store.state.state.selectedSidebarSessionKeys) return;
@@ -10187,7 +10210,7 @@ var CompactionBlockCard = import_react.memo(function CompactionBlockCard({ block
10187
10210
  var UserMessageCard = import_react.memo(function UserMessageCard({ item }) {
10188
10211
  const labelText = userMessageLabel(item);
10189
10212
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
10190
- className: "mr-7 ml-auto w-fit max-w-[80%]",
10213
+ className: "mr-2 ml-auto w-fit max-w-[80%]",
10191
10214
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
10192
10215
  className: "relative rounded-3xl bg-primary px-5 py-2.5 text-primary-foreground before:absolute before:-right-1.75 before:bottom-0 before:h-5.5 before:w-4 before:rounded-bl-[16px_14px] before:bg-primary before:content-[''] after:absolute after:-right-6.5 after:bottom-0 after:h-6.25 after:w-6.5 after:rounded-bl-[10px] after:bg-background after:content-['']",
10193
10216
  children: [
@@ -16245,7 +16268,7 @@ function AppShellTabsController({ actionsRef, appUiStore, awaitingFirstTurn, com
16245
16268
  })]
16246
16269
  });
16247
16270
  }
16248
- var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ actionsRef, defaultNewSessionDirectory, displaySessionCwd, gitPanelOpen, loadingDisplaySessionTitle, displaySettingsStore, isSessionViewLoading, newSessionDirectoryOptions, onToggleGitPanel, sessionStore, viewerContextId }) {
16271
+ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ actionsRef, defaultNewSessionDirectory, displaySessionCwd, gitPanelOpen, loadingDisplaySessionTitle, currentSessionPinned, displaySettingsStore, isSessionViewLoading, newSessionDirectoryOptions, onToggleGitPanel, sessionStore, viewerContextId }) {
16249
16272
  const sessionHeaderState = useSelector(sessionStore, (sessionState) => ({
16250
16273
  firstMessage: sessionState.firstMessage,
16251
16274
  hideThinkingBlock: sessionState.hideThinkingBlock,
@@ -16355,6 +16378,13 @@ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ a
16355
16378
  }, option.path))
16356
16379
  })] }) : null,
16357
16380
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DropdownMenuSeparator, {}),
16381
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DropdownMenuItem, {
16382
+ disabled: !sessionHeaderState.sessionHasFile,
16383
+ onClick: () => {
16384
+ actionsRef.current.onToggleCurrentSessionPinned();
16385
+ },
16386
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: currentSessionPinned ? "Unpin from sidebar" : "Pin to sidebar" })
16387
+ }),
16358
16388
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DropdownMenuItem, {
16359
16389
  onClick: () => {
16360
16390
  actionsRef.current.onRunCompact();
@@ -16490,6 +16520,8 @@ function DirectoryPathLabel({ path }) {
16490
16520
  });
16491
16521
  }
16492
16522
  var EMPTY_DIRECTORY_SESSION_KEYS = [];
16523
+ var PINNED_SESSION_GROUP_COLLAPSE_KEY = "__pico_pinned_sessions__";
16524
+ var DIRECTORIES_SESSION_GROUP_COLLAPSE_KEY = "__pico_directories__";
16493
16525
  function isMacPlatform() {
16494
16526
  if (typeof window === "undefined") return false;
16495
16527
  const platform = window.navigator.platform || window.navigator.userAgent;
@@ -16593,10 +16625,14 @@ function createCollapsedDirectoryStore() {
16593
16625
  setStoreState(store, readStoredCollapsedDirectories());
16594
16626
  },
16595
16627
  toggle(directory) {
16628
+ store.setCollapsed(directory, !store.state[directory]);
16629
+ },
16630
+ setCollapsed(directory, collapsed) {
16596
16631
  setStoreState(store, (current) => {
16632
+ if (Boolean(current[directory]) === collapsed) return current;
16597
16633
  const next = { ...current };
16598
- if (next[directory]) delete next[directory];
16599
- else next[directory] = true;
16634
+ if (collapsed) next[directory] = true;
16635
+ else delete next[directory];
16600
16636
  return next;
16601
16637
  });
16602
16638
  persist();
@@ -16700,7 +16736,7 @@ function useSidebarSessionActive(store, entryKey, sessionId) {
16700
16736
  return Boolean(active.sessionId && sessionId === active.sessionId);
16701
16737
  });
16702
16738
  }
16703
- function SidebarSessionItem({ entryKey, directorySessionsStore, activeSessionStore, selectedSessionKeyStore, isMobile, overlay, setOpenMobile, onSessionClick, onRenameSession, onDeleteSession }) {
16739
+ function SidebarSessionItem({ entryKey, directorySessionsStore, activeSessionStore, selectedSessionKeyStore, isPinned, isMobile, overlay, setOpenMobile, onSessionClick, onRenameSession, onDeleteSession, onTogglePinnedSession }) {
16704
16740
  const entry = useDirectorySessionEntry(directorySessionsStore, entryKey);
16705
16741
  const isSelected = useSidebarSessionSelected(selectedSessionKeyStore, entryKey);
16706
16742
  const isActive = useSidebarSessionActive(activeSessionStore, entryKey, entry?.id);
@@ -16708,70 +16744,91 @@ function SidebarSessionItem({ entryKey, directorySessionsStore, activeSessionSto
16708
16744
  const timestamp = entry.lastMessageAt || entry.modified || entry.lastUserMessageAt;
16709
16745
  const hasTimestamp = isValidSidebarTimestamp(timestamp);
16710
16746
  const lastMessagePreview = entry.lastMessagePreview?.trim() || "";
16747
+ const pinnedDirectoryLabel = isPinned ? formatDisplayPath$1(entry.cwd?.trim() || entry.path?.trim() || "") : "";
16711
16748
  const exactTimestamp = hasTimestamp && timestamp ? new Date(timestamp).toLocaleString() : void 0;
16712
16749
  const showUnread = Boolean(entry.unread) && !entry.streaming;
16713
- const hasSessionActions = Boolean(entry.path) && (onRenameSession || onDeleteSession) && !overlay;
16714
- const sessionButton = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuButton, {
16715
- type: "button",
16716
- "data-sidebar-session-item": true,
16717
- "data-session-key": entryKey,
16718
- isActive: isActive || isSelected,
16719
- className: cn("relative h-auto min-w-0 items-start gap-2 py-2 pr-2 pl-8", (isActive || isSelected) && "bg-sidebar-accent text-sidebar-accent-foreground"),
16720
- onClick: (event) => {
16721
- onSessionClick?.(entry, {
16722
- multiSelectKey: isSidebarMultiSelectModifier(event),
16723
- shiftKey: event.shiftKey
16724
- });
16725
- if (isMobile) setOpenMobile(false);
16726
- },
16727
- children: [entry.streaming ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16728
- className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
16729
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
16730
- className: "size-3.5",
16731
- "aria-label": "Session streaming"
16732
- })
16733
- }) : showUnread ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16734
- className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
16735
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16736
- className: "size-2 rounded-full bg-primary",
16737
- "aria-label": "Session done"
16738
- })
16739
- }) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16740
- className: "flex min-w-0 flex-1 items-start gap-2",
16741
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
16742
- className: "flex min-w-0 flex-1 flex-col gap-0.5",
16743
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
16744
- className: "flex min-w-0 items-center gap-2",
16745
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16746
- className: "min-w-0 flex-1 truncate font-medium",
16747
- children: entry.title
16748
- }), hasTimestamp ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
16749
- title: isMobile ? void 0 : exactTimestamp,
16750
- side: "right",
16751
- align: "center",
16752
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarSessionTime, {
16753
- value: timestamp,
16754
- className: "ml-auto shrink-0 text-[11px] font-normal text-sidebar-foreground/50"
16755
- })
16756
- }) : null]
16757
- }), lastMessagePreview ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16758
- className: "min-w-0 truncate text-[11px] font-normal text-sidebar-foreground/50",
16759
- children: lastMessagePreview
16760
- }) : null]
16750
+ const hasSessionActions = Boolean(onTogglePinnedSession || entry.path && (onRenameSession || onDeleteSession)) && !overlay;
16751
+ const sessionRow = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16752
+ className: "group/session relative",
16753
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuButton, {
16754
+ type: "button",
16755
+ "data-sidebar-session-item": true,
16756
+ "data-session-key": entryKey,
16757
+ isActive: isActive || isSelected,
16758
+ className: cn("relative h-auto min-w-0 items-start gap-2 py-2 pr-2 pl-8 not-data-active:hover:bg-transparent! not-data-active:hover:text-sidebar-foreground! not-data-active:data-open:hover:bg-transparent! not-data-active:data-open:hover:text-sidebar-foreground!", (isActive || isSelected) && "bg-sidebar-accent text-sidebar-accent-foreground"),
16759
+ onClick: (event) => {
16760
+ onSessionClick?.(entry, {
16761
+ multiSelectKey: isSidebarMultiSelectModifier(event),
16762
+ shiftKey: event.shiftKey
16763
+ });
16764
+ if (isMobile) setOpenMobile(false);
16765
+ },
16766
+ children: [entry.streaming ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16767
+ className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
16768
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
16769
+ className: "size-3.5",
16770
+ "aria-label": "Session streaming"
16771
+ })
16772
+ }) : showUnread ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16773
+ className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
16774
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16775
+ className: "size-2 rounded-full bg-primary",
16776
+ "aria-label": "Session done"
16777
+ })
16778
+ }) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16779
+ className: "flex min-w-0 flex-1 items-start gap-2",
16780
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
16781
+ className: "flex min-w-0 flex-1 flex-col gap-0.5",
16782
+ children: [
16783
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16784
+ className: "flex min-w-0 items-center gap-2",
16785
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16786
+ className: "min-w-0 flex-1 truncate pr-16 font-medium",
16787
+ children: entry.title
16788
+ })
16789
+ }),
16790
+ lastMessagePreview ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16791
+ className: "min-w-0 truncate text-[11px] font-normal text-sidebar-foreground/50",
16792
+ children: lastMessagePreview
16793
+ }) : null,
16794
+ pinnedDirectoryLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16795
+ className: "min-w-0 truncate text-[11px] font-normal text-sidebar-foreground/50",
16796
+ children: pinnedDirectoryLabel
16797
+ }) : null
16798
+ ]
16799
+ })
16800
+ })]
16801
+ }), hasTimestamp ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16802
+ className: "absolute top-2.5 right-2 z-10 flex min-w-4 items-center justify-end",
16803
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
16804
+ title: isMobile ? void 0 : exactTimestamp,
16805
+ side: "right",
16806
+ align: "center",
16807
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarSessionTime, {
16808
+ value: timestamp,
16809
+ className: "shrink-0 text-[11px] font-normal text-sidebar-foreground/50"
16810
+ })
16761
16811
  })
16762
- })]
16763
- });
16764
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuItem, { children: hasSessionActions ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenu$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuTrigger, { render: sessionButton }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuContent, {
16765
- className: "w-40",
16766
- children: [onRenameSession ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16767
- onClick: () => onRenameSession(entry),
16768
- children: "Rename"
16769
- }) : null, onDeleteSession ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16770
- variant: "destructive",
16771
- onClick: () => onDeleteSession(entry),
16772
- children: "Delete"
16773
16812
  }) : null]
16774
- })] }) : sessionButton });
16813
+ });
16814
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuItem, { children: hasSessionActions ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenu$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuTrigger, { render: sessionRow }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuContent, {
16815
+ className: "w-44",
16816
+ children: [
16817
+ onTogglePinnedSession ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16818
+ onClick: () => onTogglePinnedSession(entry),
16819
+ children: isPinned ? "Unpin" : "Pin to sidebar"
16820
+ }) : null,
16821
+ onRenameSession && entry.path ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16822
+ onClick: () => onRenameSession(entry),
16823
+ children: "Rename"
16824
+ }) : null,
16825
+ onDeleteSession && entry.path ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16826
+ variant: "destructive",
16827
+ onClick: () => onDeleteSession(entry),
16828
+ children: "Delete"
16829
+ }) : null
16830
+ ]
16831
+ })] }) : sessionRow });
16775
16832
  }
16776
16833
  function sameDirectorySessionEntry(left, right) {
16777
16834
  if (left === right) return true;
@@ -16831,41 +16888,35 @@ function useDirectorySessions(store, directory) {
16831
16888
  function useDirectorySessionEntry(store, entryKey) {
16832
16889
  return useSelector(store, (state) => state.entriesByKey.get(entryKey), { compare: sameDirectorySessionEntry });
16833
16890
  }
16834
- var DirectorySessionGroup = import_react.memo(function DirectorySessionGroup({ directory, directorySessionsStore, collapsedDirectoryStore, searchActive, directoryOrderingEnabled, activeSessionStore, selectedSessionKeyStore, isMobile, setOpenMobile, isDragging, overlay = false, attributes, listeners, onSessionClick, onRenameSession, onDeleteSession, onCreateSessionInDirectory, onDeleteOldSessionsInDirectory, onRemoveDirectory }) {
16891
+ var DirectorySessionGroup = import_react.memo(function DirectorySessionGroup({ directory, directorySessionsStore, collapsedDirectoryStore, searchActive, directoryOrderingEnabled, activeSessionStore, selectedSessionKeyStore, pinnedSessionKeys, isMobile, setOpenMobile, isDragging, overlay = false, attributes, listeners, onSessionClick, onRenameSession, onDeleteSession, onTogglePinnedSession, onCreateSessionInDirectory, onDeleteOldSessionsInDirectory, onRemoveDirectory }) {
16835
16892
  const [renderCount, setRenderCount] = import_react.useState(5);
16836
16893
  const { isLoadingSessions, sessionKeys } = useDirectorySessions(directorySessionsStore, directory);
16837
16894
  const collapsed = useDirectoryCollapsed(collapsedDirectoryStore, directory, searchActive);
16838
- const visibleCount = searchActive ? sessionKeys.length : Math.min(sessionKeys.length, renderCount);
16839
- const visibleSessionKeys = sessionKeys.slice(0, visibleCount);
16840
- const hasMoreSessions = visibleCount < sessionKeys.length;
16895
+ const pinnedSessionKeySet = new Set(pinnedSessionKeys);
16896
+ const unpinnedSessionKeys = sessionKeys.filter((entryKey) => !pinnedSessionKeySet.has(entryKey));
16897
+ const visibleCount = searchActive ? unpinnedSessionKeys.length : Math.min(unpinnedSessionKeys.length, renderCount);
16898
+ const visibleSessionKeys = unpinnedSessionKeys.slice(0, visibleCount);
16899
+ const hasMoreSessions = visibleCount < unpinnedSessionKeys.length;
16841
16900
  const showLoadingSpinner = useDelayedTrue(isLoadingSessions, SIDEBAR_LOADING_SPINNER_DELAY_MS);
16842
16901
  const showLoadingState = isLoadingSessions && sessionKeys.length === 0;
16843
- const showHeaderLoadingSpinner = showLoadingSpinner && sessionKeys.length === 0 && collapsed;
16902
+ const showHeaderLoadingSpinner = showLoadingSpinner && unpinnedSessionKeys.length === 0 && collapsed;
16844
16903
  const hasDirectoryActions = !overlay && Boolean(onCreateSessionInDirectory || onDeleteOldSessionsInDirectory || onRemoveDirectory);
16845
16904
  const directoryHeader = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16846
- className: "flex items-center gap-2 rounded-lg px-2 py-2 hover:bg-sidebar-accent/50",
16905
+ className: "flex items-center gap-2 rounded-lg px-2",
16847
16906
  children: [
16848
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
16907
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CollapsibleTrigger, {
16849
16908
  type: "button",
16850
- className: cn("flex min-w-0 flex-1 items-center gap-2 text-left text-sm text-sidebar-foreground", directoryOrderingEnabled && !overlay && "cursor-grab active:cursor-grabbing", searchActive && "cursor-default"),
16851
- onClick: () => {
16852
- if (!searchActive && !overlay) collapsedDirectoryStore.toggle(directory);
16853
- },
16909
+ className: cn("group/directory-label flex min-w-0 flex-1 items-center gap-2 text-left text-sm text-sidebar-foreground", directoryOrderingEnabled && !overlay && "cursor-grab active:cursor-grabbing", searchActive && "cursor-default"),
16910
+ disabled: searchActive || overlay,
16854
16911
  ...attributes ?? {},
16855
16912
  ...listeners ?? {},
16856
16913
  children: [
16857
- !searchActive ? collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 shrink-0" }) : null,
16858
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
16859
- className: "flex min-w-0 flex-1 flex-col gap-0.5",
16860
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectoryPathLabel, { path: directory }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
16861
- className: "min-w-0 truncate text-[11px] font-normal text-sidebar-foreground/50",
16862
- children: [
16863
- sessionKeys.length,
16864
- " session",
16865
- sessionKeys.length === 1 ? "" : "s"
16866
- ]
16867
- })]
16914
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Folder, { className: "size-4 shrink-0 text-sidebar-foreground/50" }),
16915
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16916
+ className: "max-w-full min-w-0",
16917
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectoryPathLabel, { path: directory })
16868
16918
  }),
16919
+ !searchActive ? collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directory-label:opacity-100 group-focus-visible/directory-label:opacity-100" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directory-label:opacity-100 group-focus-visible/directory-label:opacity-100" }) : null,
16869
16920
  showHeaderLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { className: "size-3.5 shrink-0" }) : null
16870
16921
  ]
16871
16922
  }),
@@ -16908,64 +16959,114 @@ var DirectorySessionGroup = import_react.memo(function DirectorySessionGroup({ d
16908
16959
  })] }) : null
16909
16960
  ]
16910
16961
  });
16911
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroup, {
16962
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collapsible$1, {
16963
+ open: !collapsed,
16964
+ onOpenChange: (open) => {
16965
+ if (searchActive || overlay) return;
16966
+ collapsedDirectoryStore.setCollapsed(directory, !open);
16967
+ },
16912
16968
  className: cn("rounded-lg py-1", isDragging && !overlay && "opacity-0"),
16913
- children: [hasDirectoryActions && !isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenu$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuTrigger, { render: directoryHeader }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuContent, {
16914
- className: "w-48",
16915
- children: [
16916
- onCreateSessionInDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16917
- onClick: () => onCreateSessionInDirectory(directory),
16918
- children: "New session"
16919
- }) : null,
16920
- onDeleteOldSessionsInDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16921
- onClick: () => onDeleteOldSessionsInDirectory(directory),
16922
- children: "Delete old sessions…"
16923
- }) : null,
16924
- onRemoveDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16925
- variant: "destructive",
16926
- onClick: () => onRemoveDirectory(directory),
16927
- children: "Remove from sidebar"
16928
- }) : null
16929
- ]
16930
- })] }) : directoryHeader, !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: showLoadingState ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16931
- className: "flex items-center gap-2 px-2 py-2 text-sm text-sidebar-foreground/70",
16932
- children: [showLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16933
- className: "size-4",
16934
- "aria-hidden": "true"
16935
- }), "Loading sessions…"]
16936
- }) : sessionKeys.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16937
- className: "flex flex-col",
16938
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenu, { children: visibleSessionKeys.map((entryKey) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarSessionItem, {
16969
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroup, {
16970
+ className: "py-0",
16971
+ children: [hasDirectoryActions && !isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenu$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuTrigger, { render: directoryHeader }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuContent, {
16972
+ className: "w-48",
16973
+ children: [
16974
+ onCreateSessionInDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16975
+ onClick: () => onCreateSessionInDirectory(directory),
16976
+ children: "New session"
16977
+ }) : null,
16978
+ onDeleteOldSessionsInDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16979
+ onClick: () => onDeleteOldSessionsInDirectory(directory),
16980
+ children: "Delete old sessions…"
16981
+ }) : null,
16982
+ onRemoveDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuItem, {
16983
+ variant: "destructive",
16984
+ onClick: () => onRemoveDirectory(directory),
16985
+ children: "Remove from sidebar"
16986
+ }) : null
16987
+ ]
16988
+ })] }) : directoryHeader, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: showLoadingState ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16989
+ className: "flex items-center gap-2 px-2 py-2 text-sm text-sidebar-foreground/70",
16990
+ children: [showLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
16991
+ className: "size-4",
16992
+ "aria-hidden": "true"
16993
+ }), "Loading sessions…"]
16994
+ }) : unpinnedSessionKeys.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
16995
+ className: "flex flex-col",
16996
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenu, { children: visibleSessionKeys.map((entryKey) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarSessionItem, {
16997
+ entryKey,
16998
+ directorySessionsStore,
16999
+ activeSessionStore,
17000
+ selectedSessionKeyStore,
17001
+ isPinned: pinnedSessionKeys.includes(entryKey),
17002
+ isMobile,
17003
+ overlay,
17004
+ setOpenMobile,
17005
+ onSessionClick,
17006
+ onRenameSession,
17007
+ onDeleteSession,
17008
+ onTogglePinnedSession
17009
+ }, entryKey)) }), hasMoreSessions && !overlay ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
17010
+ variant: "ghost",
17011
+ className: "h-8 justify-start pl-8 text-sidebar-foreground/60 hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground",
17012
+ onClick: () => {
17013
+ setRenderCount((current) => Math.min(unpinnedSessionKeys.length, current + 5));
17014
+ },
17015
+ children: [
17016
+ "Show",
17017
+ " ",
17018
+ Math.min(5, unpinnedSessionKeys.length - visibleCount),
17019
+ " ",
17020
+ "more"
17021
+ ]
17022
+ }) : null]
17023
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
17024
+ className: "px-2 py-2 text-sm text-sidebar-foreground/70",
17025
+ children: searchActive ? "No matching unpinned sessions." : "No unpinned sessions."
17026
+ }) }) })]
17027
+ })
17028
+ });
17029
+ });
17030
+ function PinnedSessionGroup({ pinnedSessionKeys, directorySessionsStore, collapsedDirectoryStore, searchActive, activeSessionStore, selectedSessionKeyStore, isMobile, setOpenMobile, onSessionClick, onRenameSession, onDeleteSession, onTogglePinnedSession }) {
17031
+ const collapsed = useDirectoryCollapsed(collapsedDirectoryStore, PINNED_SESSION_GROUP_COLLAPSE_KEY, searchActive);
17032
+ if (pinnedSessionKeys.length === 0) return null;
17033
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collapsible$1, {
17034
+ open: !collapsed,
17035
+ onOpenChange: (open) => {
17036
+ if (searchActive) return;
17037
+ collapsedDirectoryStore.setCollapsed(PINNED_SESSION_GROUP_COLLAPSE_KEY, !open);
17038
+ },
17039
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroup, {
17040
+ className: "py-1",
17041
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroupLabel, {
17042
+ render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleTrigger, { className: "group/pinned-label justify-between gap-3" }),
17043
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
17044
+ className: "flex min-w-0 flex-1 items-center gap-2 text-left",
17045
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
17046
+ className: "min-w-0 truncate",
17047
+ children: "Pinned"
17048
+ }), !searchActive ? collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/pinned-label:opacity-100 group-focus-visible/pinned-label:opacity-100" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/pinned-label:opacity-100 group-focus-visible/pinned-label:opacity-100" }) : null]
17049
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
17050
+ className: "text-[11px] font-normal text-sidebar-foreground/50",
17051
+ children: pinnedSessionKeys.length
17052
+ })]
17053
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenu, { children: pinnedSessionKeys.map((entryKey) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarSessionItem, {
16939
17054
  entryKey,
16940
17055
  directorySessionsStore,
16941
17056
  activeSessionStore,
16942
17057
  selectedSessionKeyStore,
17058
+ isPinned: true,
16943
17059
  isMobile,
16944
- overlay,
17060
+ overlay: false,
16945
17061
  setOpenMobile,
16946
17062
  onSessionClick,
16947
17063
  onRenameSession,
16948
- onDeleteSession
16949
- }, entryKey)) }), hasMoreSessions && !overlay ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
16950
- variant: "ghost",
16951
- className: "h-8 justify-start pl-8 text-sidebar-foreground/60 hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground",
16952
- onClick: () => {
16953
- setRenderCount((current) => Math.min(sessionKeys.length, current + 5));
16954
- },
16955
- children: [
16956
- "Show",
16957
- " ",
16958
- Math.min(5, sessionKeys.length - visibleCount),
16959
- " ",
16960
- "more"
16961
- ]
16962
- }) : null]
16963
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
16964
- className: "px-2 py-2 text-sm text-sidebar-foreground/70",
16965
- children: searchActive ? "No matching sessions." : "No sessions yet."
16966
- }) }) : null]
17064
+ onDeleteSession,
17065
+ onTogglePinnedSession
17066
+ }, entryKey)) }) }) })]
17067
+ })
16967
17068
  });
16968
- });
17069
+ }
16969
17070
  function DirectoryCollapseAllButton({ searchActive, visibleDirectories, collapsedDirectoryStore }) {
16970
17071
  const allDirectoriesCollapsed = useAllDirectoriesCollapsed(collapsedDirectoryStore, visibleDirectories);
16971
17072
  const tooltipTitle = allDirectoriesCollapsed ? "Expand all directories" : "Collapse all directories";
@@ -16984,11 +17085,10 @@ function DirectoryCollapseAllButton({ searchActive, visibleDirectories, collapse
16984
17085
  })
16985
17086
  });
16986
17087
  }
16987
- function AppSidebarHeader({ sessionSearch, onOpenSessionsDialog, visibleDirectories, matchingSessionCount, collapsedDirectoryStore, onCreateSession, onOpenAddDirectoryDialog }) {
16988
- const searchActive = sessionSearch.trim().length > 0;
16989
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarHeader, {
17088
+ function AppSidebarHeader({ onOpenSessionsDialog, onCreateSession }) {
17089
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarHeader, {
16990
17090
  className: "gap-2 border-b border-sidebar-border/70",
16991
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenu, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuButton, {
17091
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenu, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuButton, {
16992
17092
  type: "button",
16993
17093
  onClick: onOpenSessionsDialog,
16994
17094
  children: [
@@ -17010,31 +17110,41 @@ function AppSidebarHeader({ sessionSearch, onOpenSessionsDialog, visibleDirector
17010
17110
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Kbd, { children: formatShortcutLabel("Control+N") })
17011
17111
  })
17012
17112
  ]
17013
- }) })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
17014
- className: "flex items-center justify-between gap-3 text-xs text-sidebar-foreground/70",
17015
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: searchActive ? `${matchingSessionCount} matching session${matchingSessionCount === 1 ? "" : "s"}` : "Directories" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
17016
- className: "flex items-center gap-1",
17017
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectoryCollapseAllButton, {
17018
- searchActive,
17019
- visibleDirectories,
17020
- collapsedDirectoryStore
17021
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
17022
- title: "Add directory",
17023
- kbd: formatShortcutLabel("Control+D"),
17024
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
17025
- variant: "outline",
17026
- size: "icon",
17027
- className: "hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground",
17028
- onClick: onOpenAddDirectoryDialog,
17029
- "aria-label": "Add directory",
17030
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FolderPlus, {})
17031
- })
17032
- })]
17113
+ }) })] })
17114
+ });
17115
+ }
17116
+ function AppSidebarDirectoriesHeader({ sessionSearch, visibleDirectories, matchingSessionCount, collapsed, collapsedDirectoryStore, onOpenAddDirectoryDialog }) {
17117
+ const searchActive = sessionSearch.trim().length > 0;
17118
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroupLabel, {
17119
+ render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleTrigger, { className: "group/directories-label justify-between gap-3" }),
17120
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
17121
+ className: "flex min-w-0 flex-1 items-center gap-2 text-left",
17122
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
17123
+ className: "min-w-0 truncate",
17124
+ children: searchActive ? `${matchingSessionCount} matching session${matchingSessionCount === 1 ? "" : "s"}` : "Directories"
17125
+ }), !searchActive ? collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directories-label:opacity-100 group-focus-visible/directories-label:opacity-100" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directories-label:opacity-100 group-focus-visible/directories-label:opacity-100" }) : null]
17126
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
17127
+ className: "flex items-center gap-1",
17128
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectoryCollapseAllButton, {
17129
+ searchActive,
17130
+ visibleDirectories,
17131
+ collapsedDirectoryStore
17132
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
17133
+ title: "Add directory",
17134
+ kbd: formatShortcutLabel("Control+D"),
17135
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
17136
+ variant: "ghost",
17137
+ size: "icon",
17138
+ className: "hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground",
17139
+ onClick: onOpenAddDirectoryDialog,
17140
+ "aria-label": "Add directory",
17141
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FolderPlus, {})
17142
+ })
17033
17143
  })]
17034
17144
  })]
17035
17145
  });
17036
17146
  }
17037
- function AppSidebar({ sessionSearch, onOpenSessionsDialog, visibleDirectories, directorySessionsStore, matchingSessionCount, selectedSessionKeys, activeSessionId, activeSessionKey, emptyStateText, onCreateSession, onOpenAddDirectoryDialog, onOpenCommandPalette, onOpenSettings, onSessionClick, onRenameSession, onDeleteSession, onCreateSessionInDirectory, onDeleteOldSessionsInDirectory, onRemoveDirectory, onReorderDirectories }) {
17147
+ function AppSidebar({ sessionSearch, onOpenSessionsDialog, visibleDirectories, directorySessionsStore, matchingSessionCount, selectedSessionKeys, activeSessionId, activeSessionKey, pinnedSessionKeys, emptyStateText, onCreateSession, onOpenAddDirectoryDialog, onOpenCommandPalette, onOpenSettings, onSessionClick, onRenameSession, onDeleteSession, onTogglePinnedSession, onCreateSessionInDirectory, onDeleteOldSessionsInDirectory, onRemoveDirectory, onReorderDirectories }) {
17038
17148
  const { isMobile, setOpenMobile } = useSidebar();
17039
17149
  const searchActive = sessionSearch.trim().length > 0;
17040
17150
  const directoryOrderingEnabled = !searchActive && visibleDirectories.length > 1;
@@ -17043,6 +17153,7 @@ function AppSidebar({ sessionSearch, onOpenSessionsDialog, visibleDirectories, d
17043
17153
  const [collapsedDirectoryStore] = import_react.useState(createCollapsedDirectoryStore);
17044
17154
  const [selectedSessionKeyStore] = import_react.useState(createSelectedSessionKeyStore);
17045
17155
  const [activeSessionStore] = import_react.useState(createActiveSidebarSessionStore);
17156
+ const directoriesCollapsed = useDirectoryCollapsed(collapsedDirectoryStore, DIRECTORIES_SESSION_GROUP_COLLAPSE_KEY, searchActive);
17046
17157
  import_react.useLayoutEffect(() => {
17047
17158
  selectedSessionKeyStore.setKeys(selectedSessionKeys);
17048
17159
  }, [selectedSessionKeyStore, selectedSessionKeys]);
@@ -17126,78 +17237,107 @@ function AppSidebar({ sessionSearch, onOpenSessionsDialog, visibleDirectories, d
17126
17237
  className: "top-(--header-height) !h-[calc(100svh-var(--header-height))] border-r border-sidebar-border/70",
17127
17238
  children: [
17128
17239
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppSidebarHeader, {
17129
- sessionSearch,
17130
17240
  onOpenSessionsDialog,
17131
- visibleDirectories,
17132
- matchingSessionCount,
17133
- collapsedDirectoryStore,
17134
- onCreateSession,
17135
- onOpenAddDirectoryDialog
17241
+ onCreateSession
17136
17242
  }),
17137
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarContent, { children: visibleDirectories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroup, {
17138
- className: "px-2 py-2",
17139
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, {
17140
- className: "rounded-xl border border-dashed bg-sidebar-accent/10 py-10",
17141
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(EmptyHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyMedia, {
17142
- variant: "icon",
17143
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Folder, {})
17144
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyTitle, { children: emptyStateText })] })
17145
- })
17146
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DndContext, {
17147
- sensors,
17148
- collisionDetection: closestCenter,
17149
- onDragStart: directoryOrderingEnabled ? handleDragStart : void 0,
17150
- onDragOver: directoryOrderingEnabled ? handleDragOver : void 0,
17151
- onDragEnd: directoryOrderingEnabled ? handleDragEnd : void 0,
17152
- onDragCancel: directoryOrderingEnabled ? handleDragCancel : void 0,
17153
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableContext, {
17154
- items: orderedVisibleDirectories,
17155
- strategy: verticalListSortingStrategy,
17156
- children: orderedVisibleDirectories.map((directory) => {
17157
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableDirectoryGroup, {
17158
- id: directory,
17159
- disabled: !directoryOrderingEnabled,
17160
- children: ({ attributes, listeners, isDragging }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectorySessionGroup, {
17161
- directory,
17162
- directorySessionsStore,
17163
- collapsedDirectoryStore,
17164
- searchActive,
17165
- directoryOrderingEnabled,
17166
- activeSessionStore,
17167
- selectedSessionKeyStore,
17168
- isMobile,
17169
- setOpenMobile,
17170
- isDragging,
17171
- attributes,
17172
- listeners,
17173
- onSessionClick,
17174
- onRenameSession,
17175
- onDeleteSession,
17176
- onCreateSessionInDirectory,
17177
- onDeleteOldSessionsInDirectory,
17178
- onRemoveDirectory: onRemoveDirectory ? removeDirectory : void 0
17243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarContent, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PinnedSessionGroup, {
17244
+ pinnedSessionKeys,
17245
+ directorySessionsStore,
17246
+ collapsedDirectoryStore,
17247
+ searchActive,
17248
+ activeSessionStore,
17249
+ selectedSessionKeyStore,
17250
+ isMobile,
17251
+ setOpenMobile,
17252
+ onSessionClick,
17253
+ onRenameSession,
17254
+ onDeleteSession,
17255
+ onTogglePinnedSession
17256
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collapsible$1, {
17257
+ open: !directoriesCollapsed,
17258
+ onOpenChange: (open) => {
17259
+ if (searchActive) return;
17260
+ collapsedDirectoryStore.setCollapsed(DIRECTORIES_SESSION_GROUP_COLLAPSE_KEY, !open);
17261
+ },
17262
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarGroup, {
17263
+ className: "py-1",
17264
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppSidebarDirectoriesHeader, {
17265
+ sessionSearch,
17266
+ visibleDirectories,
17267
+ matchingSessionCount,
17268
+ collapsed: directoriesCollapsed,
17269
+ collapsedDirectoryStore,
17270
+ onOpenAddDirectoryDialog
17271
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: visibleDirectories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
17272
+ className: "px-2 py-2",
17273
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, {
17274
+ className: "rounded-xl border border-dashed bg-sidebar-accent/10 py-10",
17275
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(EmptyHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyMedia, {
17276
+ variant: "icon",
17277
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Folder, {})
17278
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyTitle, { children: emptyStateText })] })
17279
+ })
17280
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DndContext, {
17281
+ sensors,
17282
+ collisionDetection: closestCenter,
17283
+ onDragStart: directoryOrderingEnabled ? handleDragStart : void 0,
17284
+ onDragOver: directoryOrderingEnabled ? handleDragOver : void 0,
17285
+ onDragEnd: directoryOrderingEnabled ? handleDragEnd : void 0,
17286
+ onDragCancel: directoryOrderingEnabled ? handleDragCancel : void 0,
17287
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableContext, {
17288
+ items: orderedVisibleDirectories,
17289
+ strategy: verticalListSortingStrategy,
17290
+ children: orderedVisibleDirectories.map((directory) => {
17291
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableDirectoryGroup, {
17292
+ id: directory,
17293
+ disabled: !directoryOrderingEnabled,
17294
+ children: ({ attributes, listeners, isDragging }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectorySessionGroup, {
17295
+ directory,
17296
+ directorySessionsStore,
17297
+ collapsedDirectoryStore,
17298
+ searchActive,
17299
+ directoryOrderingEnabled,
17300
+ activeSessionStore,
17301
+ selectedSessionKeyStore,
17302
+ pinnedSessionKeys,
17303
+ isMobile,
17304
+ setOpenMobile,
17305
+ isDragging,
17306
+ attributes,
17307
+ listeners,
17308
+ onSessionClick,
17309
+ onRenameSession,
17310
+ onDeleteSession,
17311
+ onTogglePinnedSession,
17312
+ onCreateSessionInDirectory,
17313
+ onDeleteOldSessionsInDirectory,
17314
+ onRemoveDirectory: onRemoveDirectory ? removeDirectory : void 0
17315
+ })
17316
+ }, directory);
17179
17317
  })
17180
- }, directory);
17181
- })
17182
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DragOverlay, { children: activeDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectorySessionGroup, {
17183
- directory: activeDirectory,
17184
- directorySessionsStore,
17185
- collapsedDirectoryStore,
17186
- searchActive,
17187
- directoryOrderingEnabled,
17188
- activeSessionStore,
17189
- selectedSessionKeyStore,
17190
- isMobile,
17191
- setOpenMobile,
17192
- overlay: true,
17193
- onSessionClick,
17194
- onRenameSession,
17195
- onDeleteSession,
17196
- onCreateSessionInDirectory,
17197
- onDeleteOldSessionsInDirectory,
17198
- onRemoveDirectory: onRemoveDirectory ? removeDirectory : void 0
17199
- }) : null })]
17200
- }) }),
17318
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DragOverlay, { children: activeDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectorySessionGroup, {
17319
+ directory: activeDirectory,
17320
+ directorySessionsStore,
17321
+ collapsedDirectoryStore,
17322
+ searchActive,
17323
+ directoryOrderingEnabled,
17324
+ activeSessionStore,
17325
+ selectedSessionKeyStore,
17326
+ pinnedSessionKeys,
17327
+ isMobile,
17328
+ setOpenMobile,
17329
+ overlay: true,
17330
+ onSessionClick,
17331
+ onRenameSession,
17332
+ onDeleteSession,
17333
+ onTogglePinnedSession,
17334
+ onCreateSessionInDirectory,
17335
+ onDeleteOldSessionsInDirectory,
17336
+ onRemoveDirectory: onRemoveDirectory ? removeDirectory : void 0
17337
+ }) : null })]
17338
+ }) }) })]
17339
+ })
17340
+ })] }),
17201
17341
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarFooter, {
17202
17342
  className: "gap-2 border-t border-sidebar-border/70",
17203
17343
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenu, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SidebarMenuButton, {
@@ -17228,6 +17368,7 @@ function AppSidebar({ sessionSearch, onOpenSessionsDialog, visibleDirectories, d
17228
17368
  ]
17229
17369
  });
17230
17370
  }
17371
+ var PINNED_SESSION_STORE_DIRECTORY = "__pico_pinned_sessions__";
17231
17372
  function findSidebarSessionSelectionKey(entriesByKey, sessionLike) {
17232
17373
  const sessionPath = sessionLike.sessionPath?.trim() || "";
17233
17374
  const sessionId = sessionLike.sessionId?.trim() || "";
@@ -17248,6 +17389,8 @@ function AppShellSidebarController({ viewerContextId, sidebarStore, sessionWorks
17248
17389
  const directoryStateByPath = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.directoryStateByPath, sameMapEntries);
17249
17390
  const emptySidebarStateText = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.emptySidebarStateText);
17250
17391
  const filteredDirectorySessions = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.filteredDirectorySessions, sameSessionEntryRecord);
17392
+ const pinnedSidebarSessions = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.pinnedSidebarSessions);
17393
+ const pinnedSidebarSessionKeys = pinnedSidebarSessions.map((entry) => sessionListEntryKey(entry)).filter(Boolean);
17251
17394
  const sidebarSessionEntriesByKey = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.sidebarSessionEntriesByKey, sameMapEntries);
17252
17395
  const visibleDirectories = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.derived.visibleDirectories, sameStringArray$3);
17253
17396
  const directoryIndexDataByPath = useAppShellSidebarValue(sidebarStore, (snapshot) => snapshot.state.directoryIndexDataByPath);
@@ -17294,11 +17437,15 @@ function AppShellSidebarController({ viewerContextId, sidebarStore, sessionWorks
17294
17437
  for (const directory of directories) if (directoryIndexRequestIdsByPathRef.current[directory] === requestId) delete directoryIndexRequestIdsByPathRef.current[directory];
17295
17438
  };
17296
17439
  import_react.useLayoutEffect(() => {
17297
- directorySessionsStore.setData(filteredDirectorySessions, directoryIndexLoading);
17440
+ directorySessionsStore.setData(pinnedSidebarSessions.length > 0 ? {
17441
+ ...filteredDirectorySessions,
17442
+ [PINNED_SESSION_STORE_DIRECTORY]: pinnedSidebarSessions
17443
+ } : filteredDirectorySessions, directoryIndexLoading);
17298
17444
  }, [
17299
17445
  directoryIndexLoading,
17300
17446
  directorySessionsStore,
17301
- filteredDirectorySessions
17447
+ filteredDirectorySessions,
17448
+ pinnedSidebarSessions
17302
17449
  ]);
17303
17450
  import_react.useEffect(() => {
17304
17451
  let timeoutId = 0;
@@ -17513,6 +17660,16 @@ function AppShellSidebarController({ viewerContextId, sidebarStore, sessionWorks
17513
17660
  return normalizedNext;
17514
17661
  });
17515
17662
  };
17663
+ const togglePinnedSession = (entry) => {
17664
+ const key = sessionListEntryKey(entry);
17665
+ if (!key) return;
17666
+ sidebarStore.setPinnedSidebarSessionKeys((current) => {
17667
+ const currentKeys = normalizeSessionSelectionKeys(current);
17668
+ const nextKeys = currentKeys.includes(key) ? currentKeys.filter((currentKey) => currentKey !== key) : [key, ...currentKeys];
17669
+ safeLocalStorageSetItem(PINNED_SESSIONS_STORAGE_KEY, JSON.stringify(nextKeys));
17670
+ return nextKeys;
17671
+ });
17672
+ };
17516
17673
  const setSidebarSelection = (nextKeys, anchorKey = "") => {
17517
17674
  const normalizedKeys = normalizeSessionSelectionKeys(nextKeys);
17518
17675
  const nextAnchor = normalizedKeys.length === 0 ? "" : anchorKey && normalizedKeys.includes(anchorKey) ? anchorKey : normalizedKeys[normalizedKeys.length - 1] ?? "";
@@ -17566,6 +17723,7 @@ function AppShellSidebarController({ viewerContextId, sidebarStore, sessionWorks
17566
17723
  selectedSessionKeys: selectedSidebarSessionKeys,
17567
17724
  activeSessionId: activeSidebarSessionId || void 0,
17568
17725
  activeSessionKey: activeSidebarSessionKey || void 0,
17726
+ pinnedSessionKeys: pinnedSidebarSessionKeys,
17569
17727
  emptyStateText: emptySidebarStateText,
17570
17728
  onCreateSession: () => {
17571
17729
  sessionWorkspaceRef.current?.createSession(void 0, { closeMobileSidebar: true });
@@ -17586,6 +17744,7 @@ function AppShellSidebarController({ viewerContextId, sidebarStore, sessionWorks
17586
17744
  onDeleteSession: (entry) => {
17587
17745
  sessionWorkspaceRef.current?.openDeleteDialog([entry]);
17588
17746
  },
17747
+ onTogglePinnedSession: togglePinnedSession,
17589
17748
  onCreateSessionInDirectory: (directory) => {
17590
17749
  sessionWorkspaceRef.current?.createSession(directory, { closeMobileSidebar: true });
17591
17750
  },
@@ -20389,6 +20548,11 @@ var AppShellSessionWorkspace = import_react.forwardRef(function AppShellSessionW
20389
20548
  sidebarStore.setSidebarSessionStatusByKey((current) => mergeSidebarSessionStatusMap(current, status));
20390
20549
  };
20391
20550
  const activeSessionId = sessionState.sessionId || (sessionState.sessionKey ? void 0 : sessionId);
20551
+ const currentSessionPinKey = sessionListEntryKey({
20552
+ path: sessionState.sessionFile,
20553
+ id: activeSessionId
20554
+ });
20555
+ const currentSessionPinned = useAppShellSidebarValue(sidebarStore, (snapshot) => currentSessionPinKey ? snapshot.state.pinnedSidebarSessionKeys.includes(currentSessionPinKey) : false);
20392
20556
  const currentSessionQueryScope = sessionScrollKey(sessionState);
20393
20557
  const contextUsageSessionScopeRef = import_react.useRef("");
20394
20558
  import_react.useLayoutEffect(() => {
@@ -21679,12 +21843,27 @@ var AppShellSessionWorkspace = import_react.forwardRef(function AppShellSessionW
21679
21843
  sessionIsStreaming: sessionStateRef.current.streaming,
21680
21844
  sidebarSessionEntriesByKey
21681
21845
  });
21846
+ const toggleCurrentSessionPinned = () => {
21847
+ const currentState = sessionStateRef.current;
21848
+ const key = sessionListEntryKey({
21849
+ path: currentState.sessionFile,
21850
+ id: currentState.sessionId
21851
+ });
21852
+ if (!key) return;
21853
+ sidebarStore.setPinnedSidebarSessionKeys((current) => {
21854
+ const currentKeys = normalizeSessionSelectionKeys(current);
21855
+ const nextKeys = currentKeys.includes(key) ? currentKeys.filter((currentKey) => currentKey !== key) : [key, ...currentKeys];
21856
+ safeLocalStorageSetItem(PINNED_SESSIONS_STORAGE_KEY, JSON.stringify(nextKeys));
21857
+ return nextKeys;
21858
+ });
21859
+ };
21682
21860
  const sessionHeaderActionsRef = useLatestRef({
21683
21861
  createSession,
21684
21862
  onDeleteCurrentSession: openDeleteDialogForCurrentSession,
21685
21863
  onForkSession: openForkDialog,
21686
21864
  onRenameSession: openRenameDialog,
21687
21865
  onRunCompact: runCompact,
21866
+ onToggleCurrentSessionPinned: toggleCurrentSessionPinned,
21688
21867
  onToggleHideThinking: toggleHideThinking,
21689
21868
  onToggleHideToolBlocks: toggleHideToolBlocks,
21690
21869
  onTreeSession: openTreeDialog
@@ -21781,6 +21960,7 @@ var AppShellSessionWorkspace = import_react.forwardRef(function AppShellSessionW
21781
21960
  displaySessionCwd,
21782
21961
  gitPanelOpen,
21783
21962
  loadingDisplaySessionTitle,
21963
+ currentSessionPinned,
21784
21964
  displaySettingsStore,
21785
21965
  isSessionViewLoading,
21786
21966
  newSessionDirectoryOptions,
@@ -21897,11 +22077,13 @@ function PicoAppShell({ sessionId, onSelectSession }) {
21897
22077
  setViewerContextId(nextContext);
21898
22078
  const nextDirectories = normalizeStoredDirectoryList(readStoredSidebarDirectories().directories);
21899
22079
  const nextBootstrapDirectories = nextDirectories.slice(0, INITIAL_SIDEBAR_BOOTSTRAP_DIRECTORY_COUNT);
22080
+ const nextPinnedSessionKeys = readStoredPinnedSessionKeys();
21900
22081
  sidebarStore.setSidebarState((current) => {
21901
- if (sameStringArray$3(current.sidebarDirectories, nextDirectories) && sameStringArray$3(current.initialSidebarBootstrapDirectories, nextBootstrapDirectories)) return current;
22082
+ if (sameStringArray$3(current.sidebarDirectories, nextDirectories) && sameStringArray$3(current.initialSidebarBootstrapDirectories, nextBootstrapDirectories) && sameStringArray$3(current.pinnedSidebarSessionKeys, nextPinnedSessionKeys)) return current;
21902
22083
  return {
21903
22084
  sidebarDirectories: nextDirectories,
21904
- initialSidebarBootstrapDirectories: nextBootstrapDirectories
22085
+ initialSidebarBootstrapDirectories: nextBootstrapDirectories,
22086
+ pinnedSidebarSessionKeys: nextPinnedSessionKeys
21905
22087
  };
21906
22088
  });
21907
22089
  }, [sidebarStore]);