@inf-monkeys-tech/monkeys-design 1.0.77 → 1.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18399,13 +18399,74 @@ var AgentWorkbenchSidebarContainer = React4.forwardRef(
18399
18399
  }
18400
18400
  );
18401
18401
  AgentWorkbenchSidebarContainer.displayName = "AgentWorkbenchSidebarContainer";
18402
- function ItemAvatar({ item }) {
18403
- const [failed, setFailed] = React4.useState(false);
18404
- if (item.iconUrl && !failed) {
18405
- return /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.iconUrl, alt: "", className: "size-full object-cover", onError: () => setFailed(true) });
18406
- }
18407
- const initial = item.name.trim().charAt(0).toLocaleUpperCase();
18408
- return initial ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: initial }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { className: "size-4" });
18402
+ function AgentWorkbenchSidebarSearch({
18403
+ value,
18404
+ label,
18405
+ placeholder = label,
18406
+ className,
18407
+ onChange
18408
+ }) {
18409
+ const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18410
+ const searchRef = React4.useRef(null);
18411
+ React4.useEffect(() => {
18412
+ const handleShortcut = (event) => {
18413
+ if (!(event.ctrlKey || event.metaKey) || event.key.toLocaleLowerCase() !== "k")
18414
+ return;
18415
+ event.preventDefault();
18416
+ searchRef.current?.focus();
18417
+ searchRef.current?.select();
18418
+ };
18419
+ window.addEventListener("keydown", handleShortcut);
18420
+ return () => window.removeEventListener("keydown", handleShortcut);
18421
+ }, []);
18422
+ return /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { className: cn2("h-10 rounded-lg bg-card", className), children: [
18423
+ /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4", "aria-hidden": "true" }) }),
18424
+ /* @__PURE__ */ jsxRuntime.jsx(
18425
+ InputGroupInput,
18426
+ {
18427
+ ref: searchRef,
18428
+ type: "search",
18429
+ value,
18430
+ "aria-label": label,
18431
+ placeholder,
18432
+ className: "min-w-0 [&::-webkit-search-cancel-button]:hidden",
18433
+ onChange: (event) => onChange(event.target.value),
18434
+ onKeyDown: (event) => {
18435
+ if (event.key !== "Escape") return;
18436
+ onChange("");
18437
+ event.currentTarget.blur();
18438
+ }
18439
+ }
18440
+ ),
18441
+ value ? /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxRuntime.jsx(
18442
+ InputGroupButton,
18443
+ {
18444
+ size: "icon-xs",
18445
+ "aria-label": messages.clearSearch,
18446
+ onClick: () => onChange(""),
18447
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5", "aria-hidden": "true" })
18448
+ }
18449
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "border border-border px-1.5 py-0.5 text-[10px]", children: "Ctrl K" }) })
18450
+ ] });
18451
+ }
18452
+ function AgentWorkbenchSidebarNewSessionButton({
18453
+ label,
18454
+ className,
18455
+ onClick
18456
+ }) {
18457
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18458
+ Button,
18459
+ {
18460
+ type: "button",
18461
+ variant: "ghost",
18462
+ className: cn2("h-9 w-full justify-start gap-2 px-3 text-sm", className),
18463
+ onClick,
18464
+ children: [
18465
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquarePen, { className: "size-4", "aria-hidden": "true" }),
18466
+ label
18467
+ ]
18468
+ }
18469
+ );
18409
18470
  }
18410
18471
  function SessionAvatar({ item }) {
18411
18472
  const [failed, setFailed] = React4.useState(false);
@@ -18423,13 +18484,329 @@ function SessionAvatar({ item }) {
18423
18484
  }
18424
18485
  return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { className: "size-5", "aria-hidden": "true" });
18425
18486
  }
18426
- function SessionMeta({ item, locale }) {
18487
+ function SessionMeta({ item }) {
18488
+ const { locale } = useMonkeysLocale();
18427
18489
  const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18428
18490
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
18429
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate text-xs text-foreground/80", children: new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(new Date(item.updatedAt)) }),
18430
- item.mode ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn2("shrink-0 rounded-full px-1.5 py-0.5 text-[10px] font-medium leading-none", item.mode === "work" ? "bg-primary/10 text-primary" : "bg-muted text-foreground"), children: item.mode === "work" ? messages.work : messages.chat }) : null
18491
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate text-xs text-foreground/80", children: new Intl.DateTimeFormat(locale, {
18492
+ dateStyle: "medium",
18493
+ timeStyle: "short"
18494
+ }).format(new Date(item.updatedAt)) }),
18495
+ item.mode ? /* @__PURE__ */ jsxRuntime.jsx(
18496
+ "span",
18497
+ {
18498
+ className: cn2(
18499
+ "shrink-0 rounded-full px-1.5 py-0.5 text-[10px] font-medium leading-none",
18500
+ item.mode === "work" ? "bg-primary/10 text-primary" : "bg-muted text-foreground"
18501
+ ),
18502
+ children: item.mode === "work" ? messages.work : messages.chat
18503
+ }
18504
+ ) : null
18505
+ ] });
18506
+ }
18507
+ function StatusIndicator({
18508
+ status
18509
+ }) {
18510
+ const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18511
+ if (status === "running") {
18512
+ return /* @__PURE__ */ jsxRuntime.jsx(
18513
+ lucideReact.Loader2,
18514
+ {
18515
+ className: "size-4 animate-spin text-primary",
18516
+ "aria-label": messages.running
18517
+ }
18518
+ );
18519
+ }
18520
+ if (status === "completed") {
18521
+ return /* @__PURE__ */ jsxRuntime.jsx(
18522
+ lucideReact.CheckCircle2,
18523
+ {
18524
+ className: "size-4 text-primary",
18525
+ "aria-label": messages.completed
18526
+ }
18527
+ );
18528
+ }
18529
+ if (status === "error") {
18530
+ return /* @__PURE__ */ jsxRuntime.jsx(
18531
+ lucideReact.AlertCircle,
18532
+ {
18533
+ className: "size-4 text-destructive-text",
18534
+ "aria-label": messages.failed
18535
+ }
18536
+ );
18537
+ }
18538
+ return null;
18539
+ }
18540
+ function AgentWorkbenchSessionList({
18541
+ sessions,
18542
+ selectedSessionId,
18543
+ status = "ready",
18544
+ error,
18545
+ query = "",
18546
+ emptyLabel,
18547
+ noResultsLabel,
18548
+ retryLabel,
18549
+ groupByMode = false,
18550
+ showHeading = false,
18551
+ className,
18552
+ itemClassName,
18553
+ capabilities,
18554
+ onSelect,
18555
+ onTogglePin,
18556
+ onRename,
18557
+ onDelete,
18558
+ onRetry
18559
+ }) {
18560
+ const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18561
+ const renameInputRef = React4.useRef(null);
18562
+ const [editingSessionId, setEditingSessionId] = React4.useState();
18563
+ const [editingTitle, setEditingTitle] = React4.useState("");
18564
+ React4.useEffect(() => {
18565
+ if (!editingSessionId) return;
18566
+ renameInputRef.current?.focus();
18567
+ renameInputRef.current?.select();
18568
+ }, [editingSessionId]);
18569
+ const cancelRename = () => {
18570
+ setEditingSessionId(void 0);
18571
+ setEditingTitle("");
18572
+ };
18573
+ const saveRename = (item) => {
18574
+ const title = editingTitle.trim();
18575
+ if (title && title !== item.title) onRename?.(item.id, title);
18576
+ cancelRename();
18577
+ };
18578
+ if (status === "loading" && sessions.length === 0) {
18579
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: messages.loading });
18580
+ }
18581
+ if (status === "error") {
18582
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3 px-3 py-8 text-center", children: [
18583
+ /* @__PURE__ */ jsxRuntime.jsx(
18584
+ "p",
18585
+ {
18586
+ className: "max-w-full break-words text-sm text-muted-foreground",
18587
+ role: "alert",
18588
+ children: error
18589
+ }
18590
+ ),
18591
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsxs(
18592
+ Button,
18593
+ {
18594
+ type: "button",
18595
+ variant: "ghost",
18596
+ size: "sm",
18597
+ className: "gap-1.5 px-0 text-sm text-primary hover:text-primary",
18598
+ onClick: onRetry,
18599
+ children: [
18600
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-3.5", "aria-hidden": "true" }),
18601
+ retryLabel ?? messages.retry
18602
+ ]
18603
+ }
18604
+ ) : null
18605
+ ] });
18606
+ }
18607
+ if (sessions.length === 0) {
18608
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: query ? noResultsLabel : emptyLabel });
18609
+ }
18610
+ const renderItems = (items) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: items.map((item) => {
18611
+ const percent = item.contextUsage && item.contextUsage.maxTokens > 0 ? Math.min(
18612
+ 100,
18613
+ Math.round(
18614
+ item.contextUsage.usedTokens / item.contextUsage.maxTokens * 100
18615
+ )
18616
+ ) : void 0;
18617
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18618
+ "div",
18619
+ {
18620
+ "aria-current": item.id === selectedSessionId ? "page" : void 0,
18621
+ className: cn2(
18622
+ "group flex w-full min-w-0 items-center gap-3 rounded-lg border border-transparent px-3 py-2 text-left hover:bg-muted aria-[current=page]:border-primary aria-[current=page]:bg-muted",
18623
+ itemClassName
18624
+ ),
18625
+ children: [
18626
+ editingSessionId === item.id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
18627
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(SessionAvatar, { item }) }),
18628
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
18629
+ /* @__PURE__ */ jsxRuntime.jsx(
18630
+ Input,
18631
+ {
18632
+ ref: renameInputRef,
18633
+ value: editingTitle,
18634
+ "aria-label": messages.rename,
18635
+ appearance: "compact",
18636
+ className: "h-6 w-full border-primary px-1.5 text-sm font-medium",
18637
+ onChange: (event) => setEditingTitle(event.target.value),
18638
+ onClick: (event) => event.stopPropagation(),
18639
+ onBlur: () => saveRename(item),
18640
+ onKeyDown: (event) => {
18641
+ event.stopPropagation();
18642
+ if (event.key === "Enter") {
18643
+ event.preventDefault();
18644
+ saveRename(item);
18645
+ } else if (event.key === "Escape") {
18646
+ event.preventDefault();
18647
+ cancelRename();
18648
+ }
18649
+ }
18650
+ }
18651
+ ),
18652
+ /* @__PURE__ */ jsxRuntime.jsx(SessionMeta, { item })
18653
+ ] })
18654
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
18655
+ "button",
18656
+ {
18657
+ type: "button",
18658
+ title: item.title,
18659
+ className: "flex min-w-0 flex-1 items-center gap-3 text-left",
18660
+ onClick: () => onSelect(item.id),
18661
+ children: [
18662
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(SessionAvatar, { item }) }),
18663
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
18664
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm font-medium", children: item.title }),
18665
+ /* @__PURE__ */ jsxRuntime.jsx(SessionMeta, { item })
18666
+ ] })
18667
+ ]
18668
+ }
18669
+ ),
18670
+ /* @__PURE__ */ jsxRuntime.jsxs(
18671
+ "span",
18672
+ {
18673
+ "data-agent-workbench-item-actions": true,
18674
+ className: "flex shrink-0 items-center gap-1",
18675
+ children: [
18676
+ percent !== void 0 && item.status === "idle" ? /* @__PURE__ */ jsxRuntime.jsxs(
18677
+ "span",
18678
+ {
18679
+ className: "text-xs text-foreground",
18680
+ "aria-label": messages.contextUsage({ percent }),
18681
+ children: [
18682
+ percent,
18683
+ "%"
18684
+ ]
18685
+ }
18686
+ ) : /* @__PURE__ */ jsxRuntime.jsx(StatusIndicator, { status: item.status }),
18687
+ capabilities?.pin ? /* @__PURE__ */ jsxRuntime.jsx(
18688
+ Button,
18689
+ {
18690
+ type: "button",
18691
+ variant: "ghost",
18692
+ size: "icon",
18693
+ "aria-label": item.pinned ? messages.unpin : messages.pin,
18694
+ className: cn2(
18695
+ "size-8 text-muted-foreground opacity-0 group-hover:opacity-100",
18696
+ item.pinned && "text-primary opacity-100"
18697
+ ),
18698
+ onClick: (event) => {
18699
+ event.stopPropagation();
18700
+ onTogglePin?.(item.id, !item.pinned);
18701
+ },
18702
+ children: /* @__PURE__ */ jsxRuntime.jsx(
18703
+ lucideReact.Pin,
18704
+ {
18705
+ className: cn2("size-4", item.pinned && "fill-current")
18706
+ }
18707
+ )
18708
+ }
18709
+ ) : null,
18710
+ capabilities?.rename || capabilities?.delete ? /* @__PURE__ */ jsxRuntime.jsx(
18711
+ "span",
18712
+ {
18713
+ onClick: (event) => event.stopPropagation(),
18714
+ onKeyDown: (event) => event.stopPropagation(),
18715
+ children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu4, { children: [
18716
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
18717
+ Button,
18718
+ {
18719
+ type: "button",
18720
+ variant: "ghost",
18721
+ size: "icon",
18722
+ className: "size-8",
18723
+ "aria-label": messages.actions,
18724
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { className: "size-4", "aria-hidden": "true" })
18725
+ }
18726
+ ) }),
18727
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [
18728
+ capabilities.rename ? /* @__PURE__ */ jsxRuntime.jsxs(
18729
+ DropdownMenuItem,
18730
+ {
18731
+ onSelect: () => {
18732
+ setEditingSessionId(item.id);
18733
+ setEditingTitle(item.title);
18734
+ },
18735
+ children: [
18736
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "mr-2 size-4", "aria-hidden": "true" }),
18737
+ messages.rename
18738
+ ]
18739
+ }
18740
+ ) : null,
18741
+ capabilities.delete ? /* @__PURE__ */ jsxRuntime.jsxs(
18742
+ DropdownMenuItem,
18743
+ {
18744
+ className: "text-destructive-text",
18745
+ onSelect: () => onDelete?.(item.id),
18746
+ children: [
18747
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "mr-2 size-4", "aria-hidden": "true" }),
18748
+ messages.delete
18749
+ ]
18750
+ }
18751
+ ) : null
18752
+ ] })
18753
+ ] })
18754
+ }
18755
+ ) : null
18756
+ ]
18757
+ }
18758
+ )
18759
+ ]
18760
+ },
18761
+ item.id
18762
+ );
18763
+ }) });
18764
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn2("space-y-2", className), children: [
18765
+ showHeading && !groupByMode ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 px-3 text-xs font-medium text-muted-foreground", children: messages.recentSessions }) : null,
18766
+ groupByMode ? [
18767
+ {
18768
+ id: "chatbot",
18769
+ label: messages.chats,
18770
+ icon: lucideReact.MessageSquare,
18771
+ items: sessions.filter((item) => item.mode !== "work")
18772
+ },
18773
+ {
18774
+ id: "agent",
18775
+ label: messages.agents,
18776
+ icon: lucideReact.Bot,
18777
+ items: sessions.filter((item) => item.mode === "work")
18778
+ }
18779
+ ].map(({ id, label, icon: Icon2, items }) => /* @__PURE__ */ jsxRuntime.jsxs("details", { open: true, "aria-label": label, children: [
18780
+ /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex h-9 cursor-pointer list-none items-center gap-2 rounded-md px-3 text-sm font-semibold hover:bg-muted", children: [
18781
+ /* @__PURE__ */ jsxRuntime.jsx(
18782
+ Icon2,
18783
+ {
18784
+ className: "size-4 shrink-0 text-muted-foreground",
18785
+ "aria-hidden": "true"
18786
+ }
18787
+ ),
18788
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: label })
18789
+ ] }),
18790
+ renderItems(items)
18791
+ ] }, id)) : renderItems(sessions)
18431
18792
  ] });
18432
18793
  }
18794
+ function ItemAvatar({ item }) {
18795
+ const [failed, setFailed] = React4.useState(false);
18796
+ if (item.iconUrl && !failed) {
18797
+ return /* @__PURE__ */ jsxRuntime.jsx(
18798
+ "img",
18799
+ {
18800
+ src: item.iconUrl,
18801
+ alt: "",
18802
+ className: "size-full object-cover",
18803
+ onError: () => setFailed(true)
18804
+ }
18805
+ );
18806
+ }
18807
+ const initial = item.name.trim().charAt(0).toLocaleUpperCase();
18808
+ return initial ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: initial }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { className: "size-4" });
18809
+ }
18433
18810
  function CollectionState({
18434
18811
  status,
18435
18812
  empty,
@@ -18445,11 +18822,28 @@ function CollectionState({
18445
18822
  }
18446
18823
  if (status === "error") {
18447
18824
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3 px-3 py-8 text-center", children: [
18448
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-full break-words text-sm text-muted-foreground", role: "alert", children: error }),
18449
- /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "gap-1.5 px-0 text-sm text-primary hover:text-primary", onClick: onRetry, children: [
18450
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-3.5", "aria-hidden": "true" }),
18451
- messages.retry
18452
- ] })
18825
+ /* @__PURE__ */ jsxRuntime.jsx(
18826
+ "p",
18827
+ {
18828
+ className: "max-w-full break-words text-sm text-muted-foreground",
18829
+ role: "alert",
18830
+ children: error
18831
+ }
18832
+ ),
18833
+ /* @__PURE__ */ jsxRuntime.jsxs(
18834
+ Button,
18835
+ {
18836
+ type: "button",
18837
+ variant: "ghost",
18838
+ size: "sm",
18839
+ className: "gap-1.5 px-0 text-sm text-primary hover:text-primary",
18840
+ onClick: onRetry,
18841
+ children: [
18842
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-3.5", "aria-hidden": "true" }),
18843
+ messages.retry
18844
+ ]
18845
+ }
18846
+ )
18453
18847
  ] });
18454
18848
  }
18455
18849
  if (!hasItems) {
@@ -18457,40 +18851,6 @@ function CollectionState({
18457
18851
  }
18458
18852
  return null;
18459
18853
  }
18460
- function StatusIndicator({ status }) {
18461
- const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18462
- if (status === "running") {
18463
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin text-primary", "aria-label": messages.running });
18464
- }
18465
- if (status === "completed") {
18466
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "size-4 text-primary", "aria-label": messages.completed });
18467
- }
18468
- if (status === "error") {
18469
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "size-4 text-destructive-text", "aria-label": messages.failed });
18470
- }
18471
- return null;
18472
- }
18473
- function SessionActions({
18474
- item,
18475
- capabilities,
18476
- onIntent
18477
- }) {
18478
- const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18479
- if (!capabilities.renameSessions && !capabilities.deleteSessions) return null;
18480
- return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu4, { children: [
18481
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8", "aria-label": messages.actions, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { className: "size-4", "aria-hidden": "true" }) }) }),
18482
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [
18483
- capabilities.renameSessions ? /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onSelect: () => onIntent?.({ type: "rename-session", sessionId: item.id, title: item.title }), children: [
18484
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "mr-2 size-4", "aria-hidden": "true" }),
18485
- messages.rename
18486
- ] }) : null,
18487
- capabilities.deleteSessions ? /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { className: "text-destructive-text", onSelect: () => onIntent?.({ type: "delete-session", sessionId: item.id }), children: [
18488
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "mr-2 size-4", "aria-hidden": "true" }),
18489
- messages.delete
18490
- ] }) : null
18491
- ] })
18492
- ] });
18493
- }
18494
18854
  function AgentWorkbenchSidebar({
18495
18855
  viewModel,
18496
18856
  navigationMode,
@@ -18502,115 +18862,38 @@ function AgentWorkbenchSidebar({
18502
18862
  classNames,
18503
18863
  onIntent
18504
18864
  }) {
18505
- const { locale } = useMonkeysLocale();
18506
18865
  const messages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18507
- const resolvedConfig = React4.useMemo(() => monkeys.resolveAgentWorkbenchSidebarConfig(config), [config]);
18508
- const visibleSections = React4.useMemo(() => new Set(resolvedConfig.visibleSections), [resolvedConfig.visibleSections]);
18866
+ const resolvedConfig = React4.useMemo(
18867
+ () => monkeys.resolveAgentWorkbenchSidebarConfig(config),
18868
+ [config]
18869
+ );
18870
+ const visibleSections = React4.useMemo(
18871
+ () => new Set(resolvedConfig.visibleSections),
18872
+ [resolvedConfig.visibleSections]
18873
+ );
18509
18874
  const sessionsOnly = navigationMode === "sessions-only" || navigationMode === void 0 && resolvedConfig.navigationMode !== "default";
18510
18875
  const showAgents = visibleSections.has("agents") && !sessionsOnly;
18511
18876
  const showSessions = visibleSections.has("sessions");
18512
- const searchRef = React4.useRef(null);
18513
- const renameInputRef = React4.useRef(null);
18514
- const [editingSessionId, setEditingSessionId] = React4.useState();
18515
- const [editingTitle, setEditingTitle] = React4.useState("");
18516
18877
  const query = viewModel.searchQuery.trim().toLocaleLowerCase();
18517
18878
  const agents = React4.useMemo(
18518
- () => viewModel.agents.items.filter((item) => !query || `${item.name} ${item.description ?? ""}`.toLocaleLowerCase().includes(query)),
18879
+ () => viewModel.agents.items.filter(
18880
+ (item) => !query || `${item.name} ${item.description ?? ""}`.toLocaleLowerCase().includes(query)
18881
+ ),
18519
18882
  [query, viewModel.agents.items]
18520
18883
  );
18521
18884
  const sessions = React4.useMemo(
18522
- () => viewModel.sessions.items.filter((item) => !query || item.title.toLocaleLowerCase().includes(query)),
18885
+ () => viewModel.sessions.items.filter(
18886
+ (item) => !query || item.title.toLocaleLowerCase().includes(query)
18887
+ ),
18523
18888
  [query, viewModel.sessions.items]
18524
18889
  );
18525
- const chatbotSessions = React4.useMemo(() => sessions.filter((item) => item.mode !== "work"), [sessions]);
18526
- const agentSessions = React4.useMemo(() => sessions.filter((item) => item.mode === "work"), [sessions]);
18527
- React4.useEffect(() => {
18528
- const handleShortcut = (event) => {
18529
- if (!(event.ctrlKey || event.metaKey) || event.key.toLocaleLowerCase() !== "k") return;
18530
- event.preventDefault();
18531
- searchRef.current?.focus();
18532
- searchRef.current?.select();
18533
- };
18534
- window.addEventListener("keydown", handleShortcut);
18535
- return () => window.removeEventListener("keydown", handleShortcut);
18536
- }, []);
18537
- React4.useEffect(() => {
18538
- if (!editingSessionId) return;
18539
- renameInputRef.current?.focus();
18540
- renameInputRef.current?.select();
18541
- }, [editingSessionId]);
18542
- const beginRenameSession = (item) => {
18543
- setEditingSessionId(item.id);
18544
- setEditingTitle(item.title);
18545
- };
18546
- const cancelRenameSession = () => {
18547
- setEditingSessionId(void 0);
18548
- setEditingTitle("");
18549
- };
18550
- const saveRenameSession = (item) => {
18551
- const title = editingTitle.trim();
18552
- if (title && title !== item.title) {
18553
- onIntent?.({ type: "rename-session", sessionId: item.id, title });
18554
- }
18555
- cancelRenameSession();
18556
- };
18557
- const renderSessionItems = (items) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: items.map((item) => {
18558
- const percent = item.contextUsage && item.contextUsage.maxTokens > 0 ? Math.min(100, Math.round(item.contextUsage.usedTokens / item.contextUsage.maxTokens * 100)) : void 0;
18559
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-current": item.id === viewModel.selectedSessionItem ? "page" : void 0, className: cn2("group flex w-full min-w-0 items-center gap-3 rounded-lg border border-transparent px-3 py-2 text-left hover:bg-muted aria-[current=page]:border-primary aria-[current=page]:bg-muted", classNames?.item), children: [
18560
- editingSessionId === item.id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
18561
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(SessionAvatar, { item }) }),
18562
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
18563
- /* @__PURE__ */ jsxRuntime.jsx(
18564
- Input,
18565
- {
18566
- ref: renameInputRef,
18567
- value: editingTitle,
18568
- "aria-label": messages.rename,
18569
- appearance: "compact",
18570
- className: "h-6 w-full border-primary px-1.5 text-sm font-medium",
18571
- onChange: (event) => setEditingTitle(event.target.value),
18572
- onClick: (event) => event.stopPropagation(),
18573
- onBlur: () => saveRenameSession(item),
18574
- onKeyDown: (event) => {
18575
- event.stopPropagation();
18576
- if (event.key === "Enter") {
18577
- event.preventDefault();
18578
- saveRenameSession(item);
18579
- } else if (event.key === "Escape") {
18580
- event.preventDefault();
18581
- cancelRenameSession();
18582
- }
18583
- }
18584
- }
18585
- ),
18586
- /* @__PURE__ */ jsxRuntime.jsx(SessionMeta, { item, locale })
18587
- ] })
18588
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", title: item.title, className: "flex min-w-0 flex-1 items-center gap-3 text-left", onClick: () => onIntent?.({ type: "select-session", sessionId: item.id }), children: [
18589
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(SessionAvatar, { item }) }),
18590
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
18591
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm font-medium", children: item.title }),
18592
- /* @__PURE__ */ jsxRuntime.jsx(SessionMeta, { item, locale })
18593
- ] })
18594
- ] }),
18595
- /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-agent-workbench-item-actions": true, className: "flex shrink-0 items-center gap-1", children: [
18596
- percent !== void 0 && item.status === "idle" ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-foreground", "aria-label": messages.contextUsage({ percent }), children: [
18597
- percent,
18598
- "%"
18599
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(StatusIndicator, { status: item.status }),
18600
- viewModel.capabilities.pinSessions ? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": item.pinned ? messages.unpin : messages.pin, className: cn2("size-8 text-muted-foreground opacity-0 group-hover:opacity-100", item.pinned && "text-primary opacity-100"), onClick: (event) => {
18601
- event.stopPropagation();
18602
- onIntent?.({ type: "toggle-session-pin", sessionId: item.id, pinned: !item.pinned });
18603
- }, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pin, { className: cn2("size-4", item.pinned && "fill-current") }) }) : null,
18604
- /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(SessionActions, { item, capabilities: viewModel.capabilities, onIntent: (intent) => intent.type === "rename-session" ? beginRenameSession(item) : onIntent?.(intent) }) })
18605
- ] })
18606
- ] }, item.id);
18607
- }) });
18608
18890
  return /* @__PURE__ */ jsxRuntime.jsx(
18609
18891
  Tabs,
18610
18892
  {
18611
18893
  value: sessionsOnly || !showAgents ? "sessions" : viewModel.activeTab,
18612
18894
  onValueChange: (value) => {
18613
- if (!sessionsOnly && (value === "agents" || value === "sessions")) onIntent?.({ type: "change-tab", tab: value });
18895
+ if (!sessionsOnly && (value === "agents" || value === "sessions"))
18896
+ onIntent?.({ type: "change-tab", tab: value });
18614
18897
  },
18615
18898
  className: "h-full min-h-0",
18616
18899
  children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -18619,115 +18902,230 @@ function AgentWorkbenchSidebar({
18619
18902
  "data-sidebar-width-percent": resolvedConfig.widthPercent,
18620
18903
  "aria-label": messages.tabsLabel,
18621
18904
  header: visibleSections.has("header") ? header : void 0,
18622
- search: visibleSections.has("search") ? /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { className: cn2("h-10 rounded-lg bg-card", classNames?.search), children: [
18623
- /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4", "aria-hidden": "true" }) }),
18624
- /* @__PURE__ */ jsxRuntime.jsx(
18625
- InputGroupInput,
18905
+ search: visibleSections.has("search") ? /* @__PURE__ */ jsxRuntime.jsx(
18906
+ AgentWorkbenchSidebarSearch,
18907
+ {
18908
+ value: viewModel.searchQuery,
18909
+ label: sessionsOnly ? messages.searchSessions : messages.search,
18910
+ className: classNames?.search,
18911
+ onChange: (query2) => onIntent?.({ type: "change-search", query: query2 })
18912
+ }
18913
+ ) : void 0,
18914
+ actions: showAgents && showSessions || headerActions ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18915
+ showAgents && showSessions ? /* @__PURE__ */ jsxRuntime.jsxs(
18916
+ TabsList,
18626
18917
  {
18627
- ref: searchRef,
18628
- type: "search",
18629
- value: viewModel.searchQuery,
18630
- "aria-label": sessionsOnly ? messages.searchSessions : messages.search,
18631
- placeholder: sessionsOnly ? messages.searchSessions : messages.search,
18632
- className: "min-w-0 [&::-webkit-search-cancel-button]:hidden",
18633
- onChange: (event) => onIntent?.({ type: "change-search", query: event.target.value }),
18634
- onKeyDown: (event) => {
18635
- if (event.key !== "Escape") return;
18636
- onIntent?.({ type: "change-search", query: "" });
18637
- event.currentTarget.blur();
18638
- }
18918
+ className: cn2(
18919
+ "grid min-w-0 flex-1 grid-cols-2 text-foreground",
18920
+ classNames?.tabs
18921
+ ),
18922
+ "aria-label": messages.tabsLabel,
18923
+ children: [
18924
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "agents", children: messages.agents }),
18925
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "sessions", children: messages.sessions })
18926
+ ]
18639
18927
  }
18640
- ),
18641
- viewModel.searchQuery ? /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxRuntime.jsx(InputGroupButton, { size: "icon-xs", "aria-label": messages.clearSearch, onClick: () => onIntent?.({ type: "change-search", query: "" }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5", "aria-hidden": "true" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "border border-border px-1.5 py-0.5 text-[10px]", children: "Ctrl K" }) })
18642
- ] }) : void 0,
18643
- actions: showAgents && showSessions || headerActions ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18644
- showAgents && showSessions ? /* @__PURE__ */ jsxRuntime.jsxs(TabsList, { className: cn2("grid min-w-0 flex-1 grid-cols-2 text-foreground", classNames?.tabs), "aria-label": messages.tabsLabel, children: [
18645
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "agents", children: messages.agents }),
18646
- /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "sessions", children: messages.sessions })
18647
- ] }) : null,
18928
+ ) : null,
18648
18929
  headerActions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center", children: headerActions }) : null
18649
18930
  ] }) : void 0,
18650
- footer: visibleSections.has("footer") && (!sessionsOnly && viewModel.capabilities.manageAgentSettings || footer) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn2("border-t border-border p-4", classNames?.footer), children: [
18651
- !sessionsOnly && viewModel.capabilities.manageAgentSettings ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", className: "h-10 w-full justify-start gap-2 px-3 text-sm", onClick: () => onIntent?.({ type: "open-agent-settings" }), children: [
18652
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "size-4", "aria-hidden": "true" }),
18653
- messages.settings
18654
- ] }) : null,
18655
- footer
18656
- ] }) : void 0,
18931
+ footer: visibleSections.has("footer") && (!sessionsOnly && viewModel.capabilities.manageAgentSettings || footer) ? /* @__PURE__ */ jsxRuntime.jsxs(
18932
+ "div",
18933
+ {
18934
+ className: cn2("border-t border-border p-4", classNames?.footer),
18935
+ children: [
18936
+ !sessionsOnly && viewModel.capabilities.manageAgentSettings ? /* @__PURE__ */ jsxRuntime.jsxs(
18937
+ Button,
18938
+ {
18939
+ type: "button",
18940
+ variant: "ghost",
18941
+ className: "h-10 w-full justify-start gap-2 px-3 text-sm",
18942
+ onClick: () => onIntent?.({ type: "open-agent-settings" }),
18943
+ children: [
18944
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "size-4", "aria-hidden": "true" }),
18945
+ messages.settings
18946
+ ]
18947
+ }
18948
+ ) : null,
18949
+ footer
18950
+ ]
18951
+ }
18952
+ ) : void 0,
18657
18953
  bodyScrollable: false,
18658
18954
  className,
18659
- classNames: { root: classNames?.root, body: "flex min-h-0 flex-1 flex-col p-0" },
18955
+ classNames: {
18956
+ root: classNames?.root,
18957
+ body: "flex min-h-0 flex-1 flex-col p-0"
18958
+ },
18660
18959
  children: [
18661
- showAgents ? /* @__PURE__ */ jsxRuntime.jsxs(TabsContent, { value: "agents", "data-agent-workbench-scroll-region": true, className: cn2("mt-0 min-h-0 flex-1 overflow-x-hidden overflow-y-auto overscroll-contain px-4 pb-4", classNames?.body), children: [
18662
- viewModel.capabilities.createAgent ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", className: "mb-3 h-9 w-full justify-start gap-2 px-3 text-sm", onClick: () => onIntent?.({ type: "create-agent" }), children: [
18663
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4", "aria-hidden": "true" }),
18664
- messages.newAgent
18665
- ] }) : null,
18666
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 px-3 text-xs font-medium text-muted-foreground", children: messages.allAgents }),
18667
- /* @__PURE__ */ jsxRuntime.jsx(CollectionState, { status: viewModel.agents.status, empty: messages.emptyAgents, noResults: messages.noResults, hasItems: agents.length > 0, query, error: viewModel.agents.error, onRetry: () => onIntent?.({ type: "retry-agents" }) }),
18668
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: agents.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
18669
- "div",
18670
- {
18671
- "aria-current": item.id === viewModel.selectedAgentItem ? "page" : void 0,
18672
- className: cn2("group flex w-full min-w-0 items-center gap-3 rounded-lg border border-transparent px-3 py-2 text-left hover:bg-muted aria-[current=page]:border-primary aria-[current=page]:bg-muted", classNames?.item),
18673
- children: [
18674
- /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", title: item.name, className: "flex min-w-0 flex-1 items-center gap-3 text-left", onClick: () => onIntent?.({ type: "select-agent", itemId: item.id }), children: [
18675
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(ItemAvatar, { item }) }),
18676
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
18677
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm font-medium", children: item.name }),
18678
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-xs text-foreground/80", children: item.description || messages.noDescription })
18679
- ] })
18680
- ] }),
18681
- item.builtIn ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded-full bg-muted px-1.5 py-1 text-[10px] text-foreground", children: messages.builtIn }) : null,
18682
- viewModel.capabilities.pinAgents ? /* @__PURE__ */ jsxRuntime.jsx(
18683
- Button,
18684
- {
18685
- type: "button",
18686
- variant: "ghost",
18687
- size: "icon",
18688
- "aria-label": item.pinned ? messages.unpin : messages.pin,
18689
- className: cn2("size-8 text-muted-foreground opacity-0 group-hover:opacity-100", item.pinned && "text-primary opacity-100"),
18690
- onClick: (event) => {
18691
- event.stopPropagation();
18692
- onIntent?.({ type: "toggle-agent-pin", itemId: item.id, pinned: !item.pinned });
18693
- },
18694
- onKeyDown: (event) => {
18695
- if (event.key === "Enter" || event.key === " ") {
18696
- event.preventDefault();
18697
- event.stopPropagation();
18698
- onIntent?.({ type: "toggle-agent-pin", itemId: item.id, pinned: !item.pinned });
18960
+ showAgents ? /* @__PURE__ */ jsxRuntime.jsxs(
18961
+ TabsContent,
18962
+ {
18963
+ value: "agents",
18964
+ "data-agent-workbench-scroll-region": true,
18965
+ className: cn2(
18966
+ "mt-0 min-h-0 flex-1 overflow-x-hidden overflow-y-auto overscroll-contain px-4 pb-4",
18967
+ classNames?.body
18968
+ ),
18969
+ children: [
18970
+ viewModel.capabilities.createAgent ? /* @__PURE__ */ jsxRuntime.jsxs(
18971
+ Button,
18972
+ {
18973
+ type: "button",
18974
+ variant: "ghost",
18975
+ className: "mb-3 h-9 w-full justify-start gap-2 px-3 text-sm",
18976
+ onClick: () => onIntent?.({ type: "create-agent" }),
18977
+ children: [
18978
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4", "aria-hidden": "true" }),
18979
+ messages.newAgent
18980
+ ]
18981
+ }
18982
+ ) : null,
18983
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 px-3 text-xs font-medium text-muted-foreground", children: messages.allAgents }),
18984
+ /* @__PURE__ */ jsxRuntime.jsx(
18985
+ CollectionState,
18986
+ {
18987
+ status: viewModel.agents.status,
18988
+ empty: messages.emptyAgents,
18989
+ noResults: messages.noResults,
18990
+ hasItems: agents.length > 0,
18991
+ query,
18992
+ error: viewModel.agents.error,
18993
+ onRetry: () => onIntent?.({ type: "retry-agents" })
18994
+ }
18995
+ ),
18996
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: agents.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
18997
+ "div",
18998
+ {
18999
+ "aria-current": item.id === viewModel.selectedAgentItem ? "page" : void 0,
19000
+ className: cn2(
19001
+ "group flex w-full min-w-0 items-center gap-3 rounded-lg border border-transparent px-3 py-2 text-left hover:bg-muted aria-[current=page]:border-primary aria-[current=page]:bg-muted",
19002
+ classNames?.item
19003
+ ),
19004
+ children: [
19005
+ /* @__PURE__ */ jsxRuntime.jsxs(
19006
+ "button",
19007
+ {
19008
+ type: "button",
19009
+ title: item.name,
19010
+ className: "flex min-w-0 flex-1 items-center gap-3 text-left",
19011
+ onClick: () => onIntent?.({ type: "select-agent", itemId: item.id }),
19012
+ children: [
19013
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(ItemAvatar, { item }) }),
19014
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
19015
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm font-medium", children: item.name }),
19016
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-xs text-foreground/80", children: item.description || messages.noDescription })
19017
+ ] })
19018
+ ]
18699
19019
  }
18700
- },
18701
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pin, { className: cn2("size-4", item.pinned && "fill-current", item.pinPending && "animate-pulse") })
18702
- }
18703
- ) : null
18704
- ]
18705
- },
18706
- item.id
18707
- )) })
18708
- ] }) : null,
18709
- showSessions ? /* @__PURE__ */ jsxRuntime.jsxs(TabsContent, { value: "sessions", "data-agent-workbench-scroll-region": true, className: cn2("mt-0 min-h-0 flex-1 overflow-x-hidden overflow-y-auto overscroll-contain px-4 pb-4", classNames?.body), children: [
18710
- visibleSections.has("new-session") && viewModel.capabilities.createSession ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", className: "h-9 w-full justify-start gap-2 px-3 text-sm", onClick: () => onIntent?.({ type: "create-session" }), children: [
18711
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquarePen, { className: "size-4", "aria-hidden": "true" }),
18712
- messages.newSession
18713
- ] }) : null,
18714
- !sessionsOnly && viewModel.capabilities.manageCapabilities ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", className: "mb-3 h-9 w-full justify-start gap-2 px-3 text-sm", onClick: () => onIntent?.({ type: "open-capabilities" }), children: [
18715
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Blocks, { className: "size-4", "aria-hidden": "true" }),
18716
- messages.capabilities
18717
- ] }) : null,
18718
- !sessionsOnly ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 px-3 text-xs font-medium text-muted-foreground", children: messages.recentSessions }) : null,
18719
- /* @__PURE__ */ jsxRuntime.jsx(CollectionState, { status: viewModel.sessions.status, empty: messages.emptySessions, noResults: messages.noResults, hasItems: sessions.length > 0, query, error: viewModel.sessions.error, onRetry: () => onIntent?.({ type: "retry-sessions" }) }),
18720
- sessionsOnly && sessions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: [
18721
- { id: "chatbot", label: messages.chats, icon: lucideReact.MessageSquare, items: chatbotSessions },
18722
- { id: "agent", label: messages.agents, icon: lucideReact.Bot, items: agentSessions }
18723
- ].map(({ id, label, icon: Icon2, items }) => /* @__PURE__ */ jsxRuntime.jsxs("details", { open: true, "aria-label": label, children: [
18724
- /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex h-9 cursor-pointer list-none items-center gap-2 rounded-md px-3 text-sm font-semibold hover:bg-muted", children: [
18725
- /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
18726
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: label })
18727
- ] }),
18728
- renderSessionItems(items)
18729
- ] }, id)) }) : !sessionsOnly ? renderSessionItems(sessions) : null
18730
- ] }) : null
19020
+ ),
19021
+ item.builtIn ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded-full bg-muted px-1.5 py-1 text-[10px] text-foreground", children: messages.builtIn }) : null,
19022
+ viewModel.capabilities.pinAgents ? /* @__PURE__ */ jsxRuntime.jsx(
19023
+ Button,
19024
+ {
19025
+ type: "button",
19026
+ variant: "ghost",
19027
+ size: "icon",
19028
+ "aria-label": item.pinned ? messages.unpin : messages.pin,
19029
+ className: cn2(
19030
+ "size-8 text-muted-foreground opacity-0 group-hover:opacity-100",
19031
+ item.pinned && "text-primary opacity-100"
19032
+ ),
19033
+ onClick: (event) => {
19034
+ event.stopPropagation();
19035
+ onIntent?.({
19036
+ type: "toggle-agent-pin",
19037
+ itemId: item.id,
19038
+ pinned: !item.pinned
19039
+ });
19040
+ },
19041
+ onKeyDown: (event) => {
19042
+ if (event.key === "Enter" || event.key === " ") {
19043
+ event.preventDefault();
19044
+ event.stopPropagation();
19045
+ onIntent?.({
19046
+ type: "toggle-agent-pin",
19047
+ itemId: item.id,
19048
+ pinned: !item.pinned
19049
+ });
19050
+ }
19051
+ },
19052
+ children: /* @__PURE__ */ jsxRuntime.jsx(
19053
+ lucideReact.Pin,
19054
+ {
19055
+ className: cn2(
19056
+ "size-4",
19057
+ item.pinned && "fill-current",
19058
+ item.pinPending && "animate-pulse"
19059
+ )
19060
+ }
19061
+ )
19062
+ }
19063
+ ) : null
19064
+ ]
19065
+ },
19066
+ item.id
19067
+ )) })
19068
+ ]
19069
+ }
19070
+ ) : null,
19071
+ showSessions ? /* @__PURE__ */ jsxRuntime.jsxs(
19072
+ TabsContent,
19073
+ {
19074
+ value: "sessions",
19075
+ "data-agent-workbench-scroll-region": true,
19076
+ className: cn2(
19077
+ "mt-0 min-h-0 flex-1 overflow-x-hidden overflow-y-auto overscroll-contain px-4 pb-4",
19078
+ classNames?.body
19079
+ ),
19080
+ children: [
19081
+ visibleSections.has("new-session") && viewModel.capabilities.createSession ? /* @__PURE__ */ jsxRuntime.jsx(
19082
+ AgentWorkbenchSidebarNewSessionButton,
19083
+ {
19084
+ label: messages.newSession,
19085
+ onClick: () => onIntent?.({ type: "create-session" })
19086
+ }
19087
+ ) : null,
19088
+ !sessionsOnly && viewModel.capabilities.manageCapabilities ? /* @__PURE__ */ jsxRuntime.jsxs(
19089
+ Button,
19090
+ {
19091
+ type: "button",
19092
+ variant: "ghost",
19093
+ className: "mb-3 h-9 w-full justify-start gap-2 px-3 text-sm",
19094
+ onClick: () => onIntent?.({ type: "open-capabilities" }),
19095
+ children: [
19096
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Blocks, { className: "size-4", "aria-hidden": "true" }),
19097
+ messages.capabilities
19098
+ ]
19099
+ }
19100
+ ) : null,
19101
+ /* @__PURE__ */ jsxRuntime.jsx(
19102
+ AgentWorkbenchSessionList,
19103
+ {
19104
+ sessions,
19105
+ selectedSessionId: viewModel.selectedSessionItem,
19106
+ status: viewModel.sessions.status,
19107
+ error: viewModel.sessions.error,
19108
+ query,
19109
+ emptyLabel: messages.emptySessions,
19110
+ noResultsLabel: messages.noResults,
19111
+ groupByMode: sessionsOnly,
19112
+ showHeading: !sessionsOnly,
19113
+ itemClassName: classNames?.item,
19114
+ capabilities: {
19115
+ pin: viewModel.capabilities.pinSessions,
19116
+ rename: viewModel.capabilities.renameSessions,
19117
+ delete: viewModel.capabilities.deleteSessions
19118
+ },
19119
+ onSelect: (sessionId) => onIntent?.({ type: "select-session", sessionId }),
19120
+ onTogglePin: (sessionId, pinned) => onIntent?.({ type: "toggle-session-pin", sessionId, pinned }),
19121
+ onRename: (sessionId, title) => onIntent?.({ type: "rename-session", sessionId, title }),
19122
+ onDelete: (sessionId) => onIntent?.({ type: "delete-session", sessionId }),
19123
+ onRetry: () => onIntent?.({ type: "retry-sessions" })
19124
+ }
19125
+ )
19126
+ ]
19127
+ }
19128
+ ) : null
18731
19129
  ]
18732
19130
  }
18733
19131
  )
@@ -18801,9 +19199,10 @@ function AgentWorkbenchExploreSidebar({
18801
19199
  renderItemMedia,
18802
19200
  onIntent
18803
19201
  }) {
18804
- const navigationMessages = useMonkeysLocaleMessages().agentWorkbench.navigation;
18805
- const searchRef = React4.useRef(null);
18806
- const resolvedConfig = React4.useMemo(() => monkeys.resolveAgentWorkbenchSidebarConfig(config), [config]);
19202
+ const resolvedConfig = React4.useMemo(
19203
+ () => monkeys.resolveAgentWorkbenchSidebarConfig(config),
19204
+ [config]
19205
+ );
18807
19206
  const visibleSections = React4.useMemo(
18808
19207
  () => new Set(resolvedConfig.visibleSections),
18809
19208
  [resolvedConfig.visibleSections]
@@ -18826,28 +19225,18 @@ function AgentWorkbenchExploreSidebar({
18826
19225
  if (groups.some((group) => group.id === activeGroupId)) return;
18827
19226
  setActiveGroupId(resolvedDefaultGroupId ?? groups[0]?.id ?? "");
18828
19227
  }, [activeGroupId, groups, resolvedDefaultGroupId]);
18829
- React4.useEffect(() => {
18830
- const handleShortcut = (event) => {
18831
- if (!(event.ctrlKey || event.metaKey) || event.key.toLocaleLowerCase() !== "k")
18832
- return;
18833
- event.preventDefault();
18834
- searchRef.current?.focus();
18835
- searchRef.current?.select();
18836
- };
18837
- window.addEventListener("keydown", handleShortcut);
18838
- return () => window.removeEventListener("keydown", handleShortcut);
18839
- }, []);
18840
19228
  const changeGroup = (groupId) => {
18841
19229
  setActiveGroupId(groupId);
18842
19230
  onIntent?.({ type: "change-group", groupId });
18843
19231
  };
18844
- const state = !visibleSections.has("sessions") ? "ready" : error ? "error" : loading && sessions.length === 0 ? "loading" : filteredSessions.length === 0 && !draftVisible ? "empty" : "ready";
18845
19232
  const groupNavigation = visibleSections.has("groups") && activeGroup ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border px-4 pb-4 pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { value: activeGroup.id, onValueChange: changeGroup, children: [
18846
19233
  /* @__PURE__ */ jsxRuntime.jsx(
18847
19234
  TabsList,
18848
19235
  {
18849
19236
  className: "grid h-10 w-full rounded-[var(--radius)] bg-muted p-0.5 text-foreground",
18850
- style: { gridTemplateColumns: `repeat(${groups.length}, minmax(0, 1fr))` },
19237
+ style: {
19238
+ gridTemplateColumns: `repeat(${groups.length}, minmax(0, 1fr))`
19239
+ },
18851
19240
  children: groups.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
18852
19241
  TabsTrigger,
18853
19242
  {
@@ -18866,7 +19255,11 @@ function AgentWorkbenchExploreSidebar({
18866
19255
  "aria-label": item.title,
18867
19256
  className: "group relative aspect-[1.27] overflow-hidden rounded-[var(--radius)] border border-border bg-card text-left transition hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
18868
19257
  style: Number.isFinite(group.itemAspectRatio) && Number(group.itemAspectRatio) > 0 ? { aspectRatio: group.itemAspectRatio } : void 0,
18869
- onClick: () => onIntent?.({ type: "select-item", groupId: group.id, item }),
19258
+ onClick: () => onIntent?.({
19259
+ type: "select-item",
19260
+ groupId: group.id,
19261
+ item
19262
+ }),
18870
19263
  children: renderItemMedia?.(item, group) ?? /* @__PURE__ */ jsxRuntime.jsx(AgentWorkbenchExploreCardMedia, { item })
18871
19264
  },
18872
19265
  item.id
@@ -18879,47 +19272,23 @@ function AgentWorkbenchExploreSidebar({
18879
19272
  "data-sidebar-width-percent": resolvedConfig.widthPercent,
18880
19273
  "aria-label": labels.navigation,
18881
19274
  header: visibleSections.has("header") ? header : void 0,
18882
- search: visibleSections.has("search") ? /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { className: "h-12 rounded-[var(--radius)] border-border bg-card text-foreground", children: [
18883
- /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4 text-muted-foreground", "aria-hidden": "true" }) }),
18884
- /* @__PURE__ */ jsxRuntime.jsx(
18885
- InputGroupInput,
18886
- {
18887
- ref: searchRef,
18888
- type: "search",
18889
- value: searchQuery,
18890
- "aria-label": labels.search,
18891
- placeholder: labels.search,
18892
- className: "min-w-0 text-foreground placeholder:text-muted-foreground [&::-webkit-search-cancel-button]:hidden",
18893
- onChange: (event) => onIntent?.({ type: "change-search", query: event.target.value })
18894
- }
18895
- ),
18896
- /* @__PURE__ */ jsxRuntime.jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "rounded-sm border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: "Ctrl K" }) })
18897
- ] }) : void 0,
18898
- primaryAction: visibleSections.has("new-session") ? /* @__PURE__ */ jsxRuntime.jsxs(
18899
- Button,
19275
+ search: visibleSections.has("search") ? /* @__PURE__ */ jsxRuntime.jsx(
19276
+ AgentWorkbenchSidebarSearch,
18900
19277
  {
18901
- type: "button",
18902
- className: "h-11 w-full justify-start gap-2 rounded-[var(--radius)] border border-primary/60 bg-primary px-3 font-semibold text-primary-foreground hover:bg-primary/90",
18903
- onClick: () => onIntent?.({ type: "create-session" }),
18904
- children: [
18905
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquarePen, { className: "size-4", "aria-hidden": "true" }),
18906
- labels.newSession
18907
- ]
19278
+ value: searchQuery,
19279
+ label: labels.search,
19280
+ onChange: (query) => onIntent?.({ type: "change-search", query })
19281
+ }
19282
+ ) : void 0,
19283
+ primaryAction: visibleSections.has("new-session") ? /* @__PURE__ */ jsxRuntime.jsx(
19284
+ AgentWorkbenchSidebarNewSessionButton,
19285
+ {
19286
+ label: labels.newSession,
19287
+ onClick: () => onIntent?.({ type: "create-session" })
18908
19288
  }
18909
19289
  ) : void 0,
18910
19290
  groups: groupNavigation,
18911
19291
  footer: visibleSections.has("footer") ? footer : void 0,
18912
- status: state,
18913
- loadingState: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-24 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-5 animate-spin" }) }),
18914
- emptyState: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: normalizedQuery ? labels.noResults : labels.emptySessions }),
18915
- errorState: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-24 flex-col items-center justify-center gap-2 px-3 py-6 text-center", role: "alert", children: [
18916
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "size-5 shrink-0 text-destructive-text", "aria-hidden": "true" }),
18917
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-full break-words text-sm text-muted-foreground", children: error }),
18918
- labels.retry ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "gap-1.5 text-primary", onClick: () => onIntent?.({ type: "retry-sessions" }), children: [
18919
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-3.5", "aria-hidden": "true" }),
18920
- labels.retry
18921
- ] }) : null
18922
- ] }),
18923
19292
  bodyProps: { "data-agent-workbench-session-scroll-region": "" },
18924
19293
  className,
18925
19294
  classNames: { body: "min-h-[160px] flex-[0_1_280px] px-4 pb-3" },
@@ -18934,53 +19303,24 @@ function AgentWorkbenchExploreSidebar({
18934
19303
  children: labels.draftSession
18935
19304
  }
18936
19305
  ) : null,
18937
- filteredSessions.map((session) => /* @__PURE__ */ jsxRuntime.jsxs(
18938
- "div",
19306
+ filteredSessions.length > 0 || !draftVisible || loading || error ? /* @__PURE__ */ jsxRuntime.jsx(
19307
+ AgentWorkbenchSessionList,
18939
19308
  {
18940
- "aria-current": session.id === selectedSessionId ? "page" : void 0,
18941
- className: "group flex h-10 w-full min-w-0 items-center rounded-[var(--radius)] border border-transparent bg-muted/60 text-foreground transition hover:bg-muted aria-[current=page]:border-primary aria-[current=page]:bg-primary/10",
18942
- children: [
18943
- /* @__PURE__ */ jsxRuntime.jsx(
18944
- "button",
18945
- {
18946
- type: "button",
18947
- title: session.title,
18948
- className: "h-full min-w-0 flex-1 truncate px-3 text-left text-sm font-semibold",
18949
- onClick: () => onIntent?.({ type: "select-session", sessionId: session.id }),
18950
- children: session.title
18951
- }
18952
- ),
18953
- deleteSessions ? /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu4, { children: [
18954
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
18955
- Button,
18956
- {
18957
- type: "button",
18958
- variant: "ghost",
18959
- size: "icon",
18960
- "aria-label": navigationMessages.actions,
18961
- className: "mr-1 size-8 shrink-0 text-muted-foreground opacity-0 transition-opacity group-aria-[current=page]:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 data-[state=open]:opacity-100",
18962
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { className: "size-4", "aria-hidden": "true" })
18963
- }
18964
- ) }),
18965
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs(
18966
- DropdownMenuItem,
18967
- {
18968
- className: "text-destructive-text",
18969
- onSelect: () => onIntent?.({
18970
- type: "delete-session",
18971
- sessionId: session.id
18972
- }),
18973
- children: [
18974
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "mr-2 size-4", "aria-hidden": "true" }),
18975
- navigationMessages.delete
18976
- ]
18977
- }
18978
- ) })
18979
- ] }) : null
18980
- ]
18981
- },
18982
- session.id
18983
- ))
19309
+ sessions: filteredSessions,
19310
+ selectedSessionId,
19311
+ status: error ? "error" : loading ? "loading" : "ready",
19312
+ error,
19313
+ query: normalizedQuery,
19314
+ emptyLabel: labels.emptySessions,
19315
+ noResultsLabel: labels.noResults,
19316
+ retryLabel: labels.retry,
19317
+ groupByMode: resolvedConfig.navigationMode !== "default",
19318
+ capabilities: { delete: deleteSessions },
19319
+ onSelect: (sessionId) => onIntent?.({ type: "select-session", sessionId }),
19320
+ onDelete: (sessionId) => onIntent?.({ type: "delete-session", sessionId }),
19321
+ onRetry: labels.retry ? () => onIntent?.({ type: "retry-sessions" }) : void 0
19322
+ }
19323
+ ) : null
18984
19324
  ] }) : null
18985
19325
  }
18986
19326
  );