@moldable-ai/ui 0.2.31 → 0.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/components/app-error-boundary.d.ts +1 -1
  2. package/dist/components/chat/chat-image-lightbox.d.ts +8 -0
  3. package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -1
  4. package/dist/components/chat/chat-image-lightbox.js +24 -2
  5. package/dist/components/chat/chat-input.d.ts +3 -2
  6. package/dist/components/chat/chat-input.d.ts.map +1 -1
  7. package/dist/components/chat/chat-input.js +3 -3
  8. package/dist/components/chat/chat-message.d.ts.map +1 -1
  9. package/dist/components/chat/chat-message.js +3 -1
  10. package/dist/components/chat/chat-panel.d.ts +3 -1
  11. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  12. package/dist/components/chat/chat-panel.js +53 -39
  13. package/dist/components/chat/conversation-history.d.ts +4 -2
  14. package/dist/components/chat/conversation-history.d.ts.map +1 -1
  15. package/dist/components/chat/conversation-history.js +20 -15
  16. package/dist/components/ui/alert.d.ts +1 -1
  17. package/dist/components/ui/button.d.ts +2 -2
  18. package/dist/components/ui/button.js +1 -1
  19. package/dist/components/ui/context-menu.d.ts.map +1 -1
  20. package/dist/components/ui/context-menu.js +1 -0
  21. package/dist/components/ui/date-field.d.ts +1 -1
  22. package/dist/components/ui/dropdown-menu.d.ts +1 -0
  23. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  24. package/dist/components/ui/dropdown-menu.js +3 -2
  25. package/dist/components/ui/material.d.ts +1 -1
  26. package/dist/components/ui/material.d.ts.map +1 -1
  27. package/dist/components/ui/menu-items.d.ts +2 -1
  28. package/dist/components/ui/menu-items.d.ts.map +1 -1
  29. package/dist/components/ui/menu-items.js +3 -2
  30. package/dist/components/ui/message-scroller-controller.d.ts +15 -17
  31. package/dist/components/ui/message-scroller-controller.d.ts.map +1 -1
  32. package/dist/components/ui/message-scroller-controller.js +106 -91
  33. package/dist/components/ui/message-scroller-primitive.d.ts +2 -0
  34. package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -1
  35. package/dist/components/ui/message-scroller-primitive.js +2 -0
  36. package/dist/components/ui/message-scroller.d.ts.map +1 -1
  37. package/dist/components/ui/message-scroller.js +2 -2
  38. package/dist/components/ui/number-input.d.ts +1 -1
  39. package/dist/components/ui/popover.js +1 -1
  40. package/dist/components/ui/search-field.d.ts +1 -1
  41. package/dist/components/ui/sidebar.d.ts +6 -2
  42. package/dist/components/ui/sidebar.d.ts.map +1 -1
  43. package/dist/components/ui/sidebar.js +26 -7
  44. package/dist/components/ui/toolbar-controls.d.ts +10 -2
  45. package/dist/components/ui/toolbar-controls.d.ts.map +1 -1
  46. package/dist/components/ui/toolbar-controls.js +25 -7
  47. package/package.json +1 -1
  48. package/src/components/ui/button.md +3 -2
  49. package/src/components/ui/dropdown-menu.md +16 -14
  50. package/src/components/ui/menu-items.md +2 -0
  51. package/src/components/ui/message-scroller.md +6 -3
  52. package/src/components/ui/sidebar.md +11 -5
  53. package/src/components/ui/toolbar-controls.md +11 -7
  54. package/src/styles/index.css +132 -1
  55. package/src/tokens/moldable/brand.css +124 -7
  56. package/src/tokens/platform-contract.test.ts +5 -1
@@ -23,7 +23,7 @@ export declare class AppErrorBoundary extends Component<AppErrorBoundaryProps, A
23
23
  private handleUnhandledRejection;
24
24
  private reload;
25
25
  private askMoldable;
26
- render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
26
+ render(): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
27
27
  }
28
28
  export {};
29
29
  //# sourceMappingURL=app-error-boundary.d.ts.map
@@ -1,9 +1,17 @@
1
+ import { type ReactNode } from 'react';
1
2
  type ChatImageLightboxProps = {
2
3
  src: string;
3
4
  alt: string;
4
5
  className?: string;
5
6
  imageClassName?: string;
6
7
  };
8
+ /**
9
+ * Owns the modal above the paged transcript so replacing or virtualizing the
10
+ * thumbnail row cannot close an image the reader is actively viewing.
11
+ */
12
+ export declare function ChatImageLightboxProvider({ children, }: {
13
+ children: ReactNode;
14
+ }): import("react/jsx-runtime").JSX.Element;
7
15
  export declare function ChatImageLightbox({ src, alt, className, imageClassName, }: ChatImageLightboxProps): import("react/jsx-runtime").JSX.Element;
8
16
  export {};
9
17
  //# sourceMappingURL=chat-image-lightbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-image-lightbox.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-image-lightbox.tsx"],"names":[],"mappings":"AAMA,KAAK,sBAAsB,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,GAAG,EACH,SAAS,EACT,cAAc,GACf,EAAE,sBAAsB,2CA6BxB"}
1
+ {"version":3,"file":"chat-image-lightbox.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-image-lightbox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,OAAO,CAAA;AAId,KAAK,sBAAsB,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAyCD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAA;CACpB,2CAeA;AAED,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,GAAG,EACH,SAAS,EACT,cAAc,GACf,EAAE,sBAAsB,2CA4BxB"}
@@ -1,9 +1,31 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState } from 'react';
3
+ import { createContext, useCallback, useContext, useState, } from 'react';
4
4
  import { cn } from '../../lib/utils.js';
5
5
  import { Dialog, DialogContent, DialogTitle } from '../ui/dialog.js';
6
+ const ChatImageLightboxContext = createContext(null);
7
+ function ChatImageLightboxDialog({ image, onOpenChange, }) {
8
+ return (_jsx(Dialog, { open: image !== null, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { "aria-describedby": undefined, className: "h-[min(88vh,900px)] max-w-[min(92vw,1200px)] overflow-hidden border-0 bg-black/95 p-3 shadow-2xl", children: [_jsx(DialogTitle, { className: "sr-only", children: image?.alt }), image && (_jsx("img", { src: image.src, alt: image.alt, className: "size-full object-contain", draggable: false }))] }) }));
9
+ }
10
+ /**
11
+ * Owns the modal above the paged transcript so replacing or virtualizing the
12
+ * thumbnail row cannot close an image the reader is actively viewing.
13
+ */
14
+ export function ChatImageLightboxProvider({ children, }) {
15
+ const [image, setImage] = useState(null);
16
+ const openImage = useCallback((next) => setImage(next), []);
17
+ return (_jsxs(ChatImageLightboxContext.Provider, { value: { openImage }, children: [children, _jsx(ChatImageLightboxDialog, { image: image, onOpenChange: (open) => {
18
+ if (!open)
19
+ setImage(null);
20
+ } })] }));
21
+ }
6
22
  export function ChatImageLightbox({ src, alt, className, imageClassName, }) {
23
+ const lightbox = useContext(ChatImageLightboxContext);
7
24
  const [open, setOpen] = useState(false);
8
- return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: cn('focus-visible:ring-ring cursor-zoom-in overflow-hidden focus-visible:outline-none focus-visible:ring-1', className), onClick: () => setOpen(true), "aria-label": `View ${alt}`, children: _jsx("img", { src: src, alt: alt, className: imageClassName, draggable: false }) }), _jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "h-[min(88vh,900px)] max-w-[min(92vw,1200px)] overflow-hidden border-0 bg-black/95 p-3 shadow-2xl", children: [_jsx(DialogTitle, { className: "sr-only", children: alt }), _jsx("img", { src: src, alt: alt, className: "size-full object-contain", draggable: false })] }) })] }));
25
+ return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: cn('focus-visible:ring-ring cursor-zoom-in overflow-hidden focus-visible:outline-none focus-visible:ring-1', className), onClick: () => {
26
+ if (lightbox)
27
+ lightbox.openImage({ src, alt });
28
+ else
29
+ setOpen(true);
30
+ }, "aria-label": `View ${alt}`, children: _jsx("img", { src: src, alt: alt, className: imageClassName, draggable: false }) }), !lightbox && (_jsx(ChatImageLightboxDialog, { image: open ? { src, alt } : null, onOpenChange: setOpen }))] }));
9
31
  }
@@ -1,4 +1,4 @@
1
- import type { ChangeEvent, FormEvent, ReactNode, RefObject } from 'react';
1
+ import type { CSSProperties, ChangeEvent, FormEvent, ReactNode, RefObject } from 'react';
2
2
  export type ChatSubmitMode = 'send' | 'queue';
3
3
  export type ChatSlashCommandOption = {
4
4
  id: string;
@@ -21,6 +21,7 @@ type ChatInputProps = {
21
21
  inputRef?: RefObject<HTMLTextAreaElement | null>;
22
22
  onStop?: () => void;
23
23
  compact?: boolean;
24
+ surfaceBorderRadius?: CSSProperties['borderRadius'];
24
25
  imageAttachments?: ChatImageAttachment[];
25
26
  onRemoveImageAttachment?: (id: string) => void;
26
27
  footerStartControls?: ReactNode;
@@ -29,6 +30,6 @@ type ChatInputProps = {
29
30
  slashCommands?: ChatSlashCommandOption[];
30
31
  onSlashCommandSelect?: (command: ChatSlashCommandOption) => void;
31
32
  };
32
- export declare function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder, inputRef, onStop, compact, imageAttachments, onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled, slashCommands, onSlashCommandSelect, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
33
+ export declare function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder, inputRef, onStop, compact, surfaceBorderRadius, imageAttachments, onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled, slashCommands, onSlashCommandSelect, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
33
34
  export {};
34
35
  //# sourceMappingURL=chat-input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAGT,SAAS,EACT,SAAS,EACV,MAAM,OAAO,CAAA;AAKd,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAA;AAE7C,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IAC5D,QAAQ,EAAE,CACR,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,SAAS,EACzC,IAAI,CAAC,EAAE,cAAc,KAClB,IAAI,CAAA;IACT,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,mBAAmB,CAAC,EAAE,SAAS,CAAA;IAC/B,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAA;IACxC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACjE,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAA+B,EAC/B,QAAQ,EACR,MAAM,EACN,OAAe,EACf,gBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,cAAc,EACd,cAAsB,EACtB,aAAkB,EAClB,oBAAoB,GACrB,EAAE,cAAc,2CA4KhB"}
1
+ {"version":3,"file":"chat-input.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,SAAS,EAGT,SAAS,EACT,SAAS,EACV,MAAM,OAAO,CAAA;AAKd,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAA;AAE7C,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IAC5D,QAAQ,EAAE,CACR,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,SAAS,EACzC,IAAI,CAAC,EAAE,cAAc,KAClB,IAAI,CAAA;IACT,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,mBAAmB,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IACnD,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,mBAAmB,CAAC,EAAE,SAAS,CAAA;IAC/B,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAA;IACxC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACjE,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAA+B,EAC/B,QAAQ,EACR,MAAM,EACN,OAAe,EACf,mBAAmB,EACnB,gBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,cAAc,EACd,cAAsB,EACtB,aAAkB,EAClB,oBAAoB,GACrB,EAAE,cAAc,2CA8KhB"}
@@ -3,7 +3,7 @@ import { ArrowUp, Image as ImageIcon, Square, X } from 'lucide-react';
3
3
  import { cn } from '../../lib/utils.js';
4
4
  import { Button } from '../ui/button.js';
5
5
  import { Textarea } from '../ui/textarea.js';
6
- export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder = 'Ask anything...', inputRef, onStop, compact = false, imageAttachments = [], onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled = false, slashCommands = [], onSlashCommandSelect, }) {
6
+ export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeholder = 'Ask anything...', inputRef, onStop, compact = false, surfaceBorderRadius, imageAttachments = [], onRemoveImageAttachment, footerStartControls, footerControls, submitDisabled = false, slashCommands = [], onSlashCommandSelect, }) {
7
7
  const hasInput = input.trim().length > 0;
8
8
  const hasAttachments = imageAttachments.length > 0;
9
9
  const canSubmit = !submitDisabled && (hasInput || hasAttachments);
@@ -47,10 +47,10 @@ export function ChatInput({ input, onInputChange, onSubmit, isResponding, placeh
47
47
  return;
48
48
  }
49
49
  onSubmit(e, isResponding ? 'queue' : 'send');
50
- }, children: _jsxs("div", { className: cn('bg-background relative flex w-full flex-col border', compact ? 'rounded-pill' : 'rounded-container', compact && !hasAttachments && 'h-14'), children: [!compact && slashCommands.length > 0 && (_jsx("div", { className: "border-border bg-popover text-popover-foreground rounded-container absolute bottom-full left-4 right-4 z-20 mb-2 overflow-hidden border shadow-lg", children: slashCommands.map((command) => (_jsxs("button", { type: "button", className: "hover:bg-accent hover:text-accent-foreground flex min-h-12 w-full cursor-pointer items-center gap-3 px-3 py-2.5 text-left transition-colors", onMouseDown: (event) => {
50
+ }, children: _jsxs("div", { "data-chat-input-surface": true, style: { borderRadius: surfaceBorderRadius }, className: cn('bg-background relative flex w-full flex-col border', compact ? 'rounded-pill' : 'rounded-container', compact && !hasAttachments && 'h-14'), children: [!compact && slashCommands.length > 0 && (_jsx("div", { className: "border-border bg-popover text-popover-foreground rounded-container absolute bottom-full left-4 right-4 z-20 mb-2 overflow-hidden border shadow-lg", children: slashCommands.map((command) => (_jsxs("button", { type: "button", className: "hover:bg-accent hover:text-accent-foreground flex min-h-12 w-full cursor-pointer items-center gap-3 px-3 py-2.5 text-left transition-colors", onMouseDown: (event) => {
51
51
  event.preventDefault();
52
52
  onSlashCommandSelect?.(command);
53
- }, children: [_jsxs("span", { className: "bg-muted text-muted-foreground rounded-control text-ui-caption px-1.5 py-0.5 font-mono", children: ["/", command.name] }), _jsx("span", { className: "text-ui-caption min-w-0", children: command.description })] }, command.id))) })), !compact && hasAttachments && (_jsx("div", { className: "flex max-h-32 gap-2 overflow-x-auto px-3 pt-3", children: imageAttachments.map((attachment) => (_jsxs("div", { className: "bg-muted/70 border-border rounded-container flex max-w-48 shrink-0 items-center gap-2 border p-1.5 pr-2", children: [_jsx("div", { className: "bg-background rounded-container flex size-9 shrink-0 items-center justify-center overflow-hidden border", children: attachment.previewUrl ? (_jsx("img", { src: attachment.previewUrl, alt: "", className: "size-full object-cover", draggable: false })) : (_jsx(ImageIcon, { className: "text-muted-foreground size-4" })) }), _jsx("span", { className: "text-ui-caption min-w-0 truncate font-medium", title: attachment.path, children: attachment.name }), onRemoveImageAttachment && (_jsx("button", { type: "button", onClick: () => onRemoveImageAttachment(attachment.id), className: "text-muted-foreground hover:bg-accent hover:text-foreground rounded-control flex size-6 shrink-0 cursor-pointer items-center justify-center transition-colors", "aria-label": `Remove ${attachment.name}`, children: _jsx(X, { className: "size-3.5" }) }))] }, attachment.id))) })), _jsx("div", { className: cn('w-full px-5', compact ? 'py-4' : 'pb-2 pt-4'), children: _jsx(Textarea, { ref: inputRef, value: input, placeholder: placeholder, onChange: onInputChange, onKeyDown: handleKeyDown, className: cn('text-ui-body max-h-32 min-h-[24px] resize-none rounded-none border-0 !bg-transparent p-0 shadow-none focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 dark:!bg-transparent', compact && 'max-h-6 min-h-6') }) }), !compact && (_jsxs("div", { className: "flex min-h-11 items-center justify-between gap-3 px-3 pb-3", children: [_jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-start gap-1", children: footerStartControls }), _jsx("div", { className: "min-w-0 flex-1" }), _jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-0.5", children: footerControls }), _jsxs(Button, { type: showStopButton ? 'button' : 'submit', size: "icon", className: "bg-primary text-primary-foreground rounded-pill size-8 cursor-pointer hover:opacity-70 disabled:opacity-30", disabled: !canSubmit && !isResponding, onClick: handleButtonClick, children: [showStopButton ? (_jsx(Square, { className: "fill-primary-foreground size-4 animate-pulse" })) : (_jsx(ArrowUp, { className: "size-4" })), _jsx("span", { className: "sr-only", children: showStopButton
53
+ }, children: [_jsxs("span", { className: "bg-muted text-muted-foreground rounded-control text-ui-caption px-1.5 py-0.5 font-mono", children: ["/", command.name] }), _jsx("span", { className: "text-ui-caption min-w-0", children: command.description })] }, command.id))) })), !compact && hasAttachments && (_jsx("div", { className: "flex max-h-32 gap-2 overflow-x-auto px-3 pt-3", children: imageAttachments.map((attachment) => (_jsxs("div", { className: "bg-muted/70 border-border rounded-container flex max-w-48 shrink-0 items-center gap-2 border p-1.5 pr-2", children: [_jsx("div", { className: "bg-background rounded-container flex size-9 shrink-0 items-center justify-center overflow-hidden border", children: attachment.previewUrl ? (_jsx("img", { src: attachment.previewUrl, alt: "", className: "size-full object-cover", draggable: false })) : (_jsx(ImageIcon, { className: "text-muted-foreground size-4" })) }), _jsx("span", { className: "text-ui-caption min-w-0 truncate font-medium", title: attachment.path, children: attachment.name }), onRemoveImageAttachment && (_jsx("button", { type: "button", onClick: () => onRemoveImageAttachment(attachment.id), className: "text-muted-foreground hover:bg-accent hover:text-foreground rounded-control flex size-6 shrink-0 cursor-pointer items-center justify-center transition-colors", "aria-label": `Remove ${attachment.name}`, children: _jsx(X, { className: "size-3.5" }) }))] }, attachment.id))) })), _jsx("div", { className: cn('w-full px-5', compact ? 'py-4' : 'pb-2 pt-4'), children: _jsx(Textarea, { ref: inputRef, value: input, placeholder: placeholder, onChange: onInputChange, onKeyDown: handleKeyDown, className: cn('text-ui-body max-h-32 min-h-[24px] resize-none rounded-none border-0 !bg-transparent p-0 shadow-none focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 dark:!bg-transparent', compact && 'text-muted-foreground max-h-6 min-h-6 truncate') }) }), !compact && (_jsxs("div", { className: "flex min-h-11 items-center justify-between gap-3 px-3 pb-3", children: [_jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-start gap-1", children: footerStartControls }), _jsx("div", { className: "min-w-0 flex-1" }), _jsx("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-0.5", children: footerControls }), _jsxs(Button, { type: showStopButton ? 'button' : 'submit', size: "icon", className: "bg-primary text-primary-foreground rounded-pill size-8 cursor-pointer hover:opacity-70 disabled:opacity-30", disabled: !canSubmit && !isResponding, onClick: handleButtonClick, children: [showStopButton ? (_jsx(Square, { className: "fill-primary-foreground size-4 animate-pulse" })) : (_jsx(ArrowUp, { className: "size-4" })), _jsx("span", { className: "sr-only", children: showStopButton
54
54
  ? 'Stop generating'
55
55
  : isResponding
56
56
  ? 'Queue follow-up'
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-message.tsx"],"names":[],"mappings":"AAqCA,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;CACpC,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,CAAA;CACF,CAAA;AAEL,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8EAA8E;IAC9E,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,eAAe,EAAE,MAAM,CAAA;QACvB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,IAAI,CAAA;KACd,CAAA;IACD,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF,CAAA;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAIR;AAED,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B,CAAA;AAwwBD,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,MAAc,EACd,WAAmB,EACnB,YAAmB,EACnB,YAAY,GACb,EAAE,YAAY,2CAwmBd;AAED,eAAO,MAAM,OAAO,yDAAoB,CAAA;AAExC,wBAAgB,eAAe,4CAc9B;AAED,wBAAgB,iBAAiB,4CAkBhC"}
1
+ {"version":3,"file":"chat-message.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-message.tsx"],"names":[],"mappings":"AAqCA,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;CACpC,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,CAAA;CACF,CAAA;AAEL,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8EAA8E;IAC9E,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,eAAe,EAAE,MAAM,CAAA;QACvB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,IAAI,CAAA;KACd,CAAA;IACD,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF,CAAA;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAMR;AAED,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B,CAAA;AAwwBD,iBAAS,WAAW,CAAC,EACnB,OAAO,EACP,MAAc,EACd,WAAmB,EACnB,YAAmB,EACnB,YAAY,GACb,EAAE,YAAY,2CAwmBd;AAED,eAAO,MAAM,OAAO,yDAAoB,CAAA;AAExC,wBAAgB,eAAe,4CAc9B;AAED,wBAAgB,iBAAiB,4CAkBhC"}
@@ -17,7 +17,9 @@ const stripRedacted = (text) => text.replace(/\[REDACTED\]/g, '').trim();
17
17
  export function getChatMessageRenderKey(message, legacyIndex) {
18
18
  return typeof message.storeSequence === 'number'
19
19
  ? `stored-message-${message.storeSequence}`
20
- : `legacy-message-${message.role}-${message.id}-${legacyIndex}`;
20
+ : message.id
21
+ ? `legacy-message-${message.role}-${message.id}`
22
+ : `legacy-message-${message.role}-at-${legacyIndex}`;
21
23
  }
22
24
  function emptyActivityCounts() {
23
25
  return {
@@ -84,6 +84,8 @@ export interface ChatPanelProps {
84
84
  currentConversationId?: string | null;
85
85
  /** App scope currently visible in the desktop. */
86
86
  currentAppId?: string | null;
87
+ /** Opts into app/scope disclosure groups in conversation history. */
88
+ groupConversationHistory?: boolean;
87
89
  /** Whether another bounded metadata page is available. */
88
90
  hasMoreConversations?: boolean;
89
91
  /** Whether the next metadata page is currently loading. */
@@ -186,6 +188,6 @@ export interface ChatPanelProps {
186
188
  /**
187
189
  * Floating chat panel with model selector
188
190
  */
189
- export declare function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal, hasOlderMessages, isLoadingOlderMessages, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder, welcomeMessage, isExpanded, onExpandedChange, isFullScreen, onFullScreenChange, isMinimized, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress, onApprovalResponse, isEditingApp, onEditingAppChange, showEditingAppToggle, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments, onRemoveImageAttachment, isImageDropActive, queuedMessages, onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting, compactedHistoryStartIndex, contextUsage, planUsage, }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
191
+ export declare function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, groupConversationHistory, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal, hasOlderMessages, isLoadingOlderMessages, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder, welcomeMessage, isExpanded, onExpandedChange, isFullScreen, onFullScreenChange, isMinimized, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress, onApprovalResponse, isEditingApp, onEditingAppChange, showEditingAppToggle, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments, onRemoveImageAttachment, isImageDropActive, queuedMessages, onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting, compactedHistoryStartIndex, contextUsage, planUsage, }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
190
192
  export {};
191
193
  //# sourceMappingURL=chat-panel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-panel.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-panel.d.ts","sourceRoot":"","sources":["../../../src/components/chat/chat-panel.tsx"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover.js';
10
10
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '../ui/tooltip.js';
11
11
  import { ChatInput, } from './chat-input.js';
12
12
  import { CompactingMessage, ThinkingMessage, getChatMessageRenderKey, } from './chat-message.js';
13
+ import { ChatImageLightboxProvider } from './chat-image-lightbox.js';
13
14
  import { MessageRow, computeIsThinking, } from './chat-messages.js';
14
15
  import { ConversationHistory, ConversationSidebar, } from './conversation-history.js';
15
16
  import { ModelEffortSelector, } from './model-effort-selector.js';
@@ -113,8 +114,11 @@ function MessageNavigationTrail({ items }) {
113
114
  }), "data-message-navigation-row": true, className: "flex h-2.5 w-9 shrink-0 cursor-pointer items-center outline-none", children: _jsx("span", { className: "flex h-0.5 w-[30px] items-center", children: _jsx("span", { "data-message-navigation-marker": true, className: cn('bg-muted-foreground rounded-pill h-0.5 w-[26px] origin-left opacity-40', isCurrent && 'bg-foreground opacity-60') }) }) }) }), _jsx(TooltipContent, { side: "right", className: "max-w-72", children: anchor.label })] }, anchor.id));
114
115
  }) }) }) }) }));
115
116
  }
116
- function ChatMessageViewport({ items, renderItem, toolProgress, onApprovalResponse, currentConversationId, scrollToBottomSignal, isBusy, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, showNavigationTrail = false, scrollAreaClassName, contentClassName, scrollButtonClassName, }) {
117
- const viewportRef = useRef(null);
117
+ function ChatMessageViewport({ currentConversationId, ...props }) {
118
+ return (_jsx(MessageScrollerProvider, { autoScroll: true, defaultScrollPosition: "end", scrollPreviousItemPeek: 64, children: _jsx(ChatImageLightboxProvider, { children: _jsx(ChatMessageViewportBody, { ...props }) }) }, currentConversationId ?? 'new-conversation'));
119
+ }
120
+ function ChatMessageViewportBody({ items, renderItem, toolProgress, onApprovalResponse, scrollToBottomSignal, isBusy, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, showNavigationTrail = false, scrollAreaClassName, contentClassName, scrollButtonClassName, }) {
121
+ const { beginHistoryLoad, finishHistoryLoad } = useMessageScroller();
118
122
  const loadingOlderRef = useRef(false);
119
123
  const handleViewportScroll = useCallback((event) => {
120
124
  const viewport = event.currentTarget;
@@ -126,27 +130,27 @@ function ChatMessageViewport({ items, renderItem, toolProgress, onApprovalRespon
126
130
  return;
127
131
  }
128
132
  loadingOlderRef.current = true;
129
- // A prepended page is position-preserved by the message scroller
130
- // itself, synchronously in the same mutation pass — compensating here
131
- // after a paint produced a visible two-step jump. Only a reset (the
132
- // cursor raced a history rewrite) still needs an explicit landing.
133
+ beginHistoryLoad();
133
134
  void onLoadOlderMessages()
134
135
  .then((outcome) => {
135
- if (outcome !== 'reset')
136
- return;
137
- window.requestAnimationFrame(() => {
138
- if (viewportRef.current !== viewport)
139
- return;
140
- viewport.scrollTop = viewport.scrollHeight;
141
- });
136
+ finishHistoryLoad(outcome !== 'unchanged');
137
+ })
138
+ .catch(() => {
139
+ finishHistoryLoad(false);
142
140
  })
143
141
  .finally(() => {
144
142
  window.requestAnimationFrame(() => {
145
143
  loadingOlderRef.current = false;
146
144
  });
147
145
  });
148
- }, [hasOlderMessages, isLoadingOlderMessages, onLoadOlderMessages]);
149
- return (_jsx(MessageScrollerProvider, { autoScroll: true, defaultScrollPosition: "end", scrollPreviousItemPeek: 64, children: _jsxs(MessageScroller, { className: "relative min-h-0 min-w-0 flex-1", children: [_jsx(MessageScrollerCommandSync, { signal: scrollToBottomSignal }), _jsx(MessageScrollerViewport, { ref: viewportRef, className: scrollAreaClassName, "data-message-scroll-fade": true, "data-has-older-messages": hasOlderMessages ? 'true' : 'false', onScroll: handleViewportScroll, children: _jsx(MessageScrollerContent, { "aria-busy": isBusy || isLoadingOlderMessages, className: contentClassName, children: _jsx(ToolProgressProvider, { value: toolProgress, children: _jsx(ToolApprovalProvider, { onApprovalResponse: onApprovalResponse ?? null, children: items.map((item) => (_jsx(MessageScrollerItem, { messageId: item.key, scrollAnchor: item.kind === 'message' && item.message.role === 'user', children: renderItem(item) }, item.key))) }) }) }) }), items.length > 0 && (_jsx(MessageScrollerButton, { className: scrollButtonClassName })), showNavigationTrail && _jsx(MessageNavigationTrail, { items: items })] }) }, currentConversationId ?? 'new-conversation'));
146
+ }, [
147
+ beginHistoryLoad,
148
+ finishHistoryLoad,
149
+ hasOlderMessages,
150
+ isLoadingOlderMessages,
151
+ onLoadOlderMessages,
152
+ ]);
153
+ return (_jsxs(MessageScroller, { className: "relative min-h-0 min-w-0 flex-1", children: [_jsx(MessageScrollerCommandSync, { signal: scrollToBottomSignal }), _jsx(MessageScrollerViewport, { className: scrollAreaClassName, "data-message-scroll-fade": true, "data-has-older-messages": hasOlderMessages ? 'true' : 'false', onScroll: handleViewportScroll, children: _jsx(MessageScrollerContent, { "aria-busy": isBusy || isLoadingOlderMessages, className: contentClassName, children: _jsx(ToolProgressProvider, { value: toolProgress, children: _jsx(ToolApprovalProvider, { onApprovalResponse: onApprovalResponse ?? null, children: items.map((item) => (_jsx(MessageScrollerItem, { messageId: item.key, scrollAnchor: item.kind === 'message' && item.message.role === 'user', children: renderItem(item) }, item.key))) }) }) }) }), items.length > 0 && (_jsx(MessageScrollerButton, { className: scrollButtonClassName })), showNavigationTrail && _jsx(MessageNavigationTrail, { items: items })] }));
150
154
  }
151
155
  function clampPercent(value) {
152
156
  if (!Number.isFinite(value))
@@ -181,7 +185,7 @@ function ContextWindowIndicator({ usage, planUsage, }) {
181
185
  : 'var(--muted-foreground)';
182
186
  return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-pill flex size-8 cursor-pointer items-center justify-center bg-transparent p-0 focus-visible:outline-none focus-visible:ring-1", "aria-label": `Context window ${usedPercent}% full`, children: _jsx("span", { className: "rounded-pill relative size-4", style: {
183
187
  background: `conic-gradient(${ringColor} ${usedPercent}%, color-mix(in oklch, var(--muted-foreground) 22%, transparent) 0)`,
184
- }, children: _jsx("span", { className: "bg-background rounded-pill absolute inset-[3px]" }) }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", sideOffset: 8, className: "w-80 p-3 shadow-lg", children: [_jsxs("div", { className: "text-ui-body flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Context window" }), _jsxs("span", { children: [formatTokenCount(usage.usedTokens), " /", ' ', formatTokenCount(usage.maxTokens), " (", usedPercent, "%)"] })] }), _jsx("div", { className: "bg-muted rounded-pill mt-2 h-1.5 overflow-hidden", children: _jsx("div", { className: "bg-primary rounded-pill h-full", style: { width: `${usedPercent}%` } }) }), usage.compactsAutomatically && (_jsx("div", { className: "text-muted-foreground text-11 mt-2 leading-4", children: "Moldable automatically compacts its context" })), planUsage && planUsage.windows.length > 0 && (_jsxs("div", { className: "border-border mt-3 flex flex-col gap-3 border-t pt-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption", children: ["Plan usage limits", planUsage.planLabel ? ` · ${planUsage.planLabel}` : ''] }), planUsage.accountLabel && (_jsx("div", { className: "text-ui-caption mt-0.5 truncate font-medium", children: planUsage.accountLabel }))] }), planUsage.windows.map((window) => {
188
+ }, children: _jsx("span", { className: "bg-background rounded-pill absolute inset-[3px]" }) }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", sideOffset: 8, className: "w-80 p-3 shadow-lg", children: [_jsxs("div", { className: "text-ui-body flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Context window" }), _jsxs("span", { className: "text-ui-caption", children: [formatTokenCount(usage.usedTokens), " /", ' ', formatTokenCount(usage.maxTokens), " (", usedPercent, "%)"] })] }), _jsx("div", { className: "bg-muted rounded-pill mt-2 h-1.5 overflow-hidden", children: _jsx("div", { className: "bg-primary rounded-pill h-full", style: { width: `${usedPercent}%` } }) }), usage.compactsAutomatically && (_jsx("div", { className: "text-muted-foreground text-11 mt-2 leading-4", children: "Moldable automatically compacts its context" })), planUsage && planUsage.windows.length > 0 && (_jsxs("div", { className: "border-border mt-3 flex flex-col gap-3 border-t pt-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption", children: ["Plan usage limits", planUsage.planLabel ? ` · ${planUsage.planLabel}` : ''] }), planUsage.accountLabel && (_jsx("div", { className: "text-ui-caption mt-0.5 truncate font-medium", children: planUsage.accountLabel }))] }), planUsage.windows.map((window) => {
185
189
  const reset = formatUsageReset(window.resetAt);
186
190
  const percent = clampPercent(window.usedPercent);
187
191
  return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-ui-caption flex items-center justify-between gap-3", children: [_jsx("span", { children: window.label }), _jsxs("span", { className: "text-muted-foreground", children: [reset ? `Resets ${reset} · ` : '', percent, "%"] })] }), _jsx("div", { className: "bg-muted rounded-pill h-1.5 overflow-hidden", children: _jsx("div", { className: percent >= 90
@@ -217,7 +221,7 @@ function QueuedMessageRow({ message, isResponding, onRetryQueuedMessage, onSteer
217
221
  /**
218
222
  * Floating chat panel with model selector
219
223
  */
220
- export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal = 0, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder = 'Ask anything...', welcomeMessage, isExpanded, onExpandedChange, isFullScreen = false, onFullScreenChange, isMinimized = false, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress = {}, onApprovalResponse, isEditingApp = true, onEditingAppChange, showEditingAppToggle = false, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments = [], onRemoveImageAttachment, isImageDropActive = false, queuedMessages = [], onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting = false, compactedHistoryStartIndex, contextUsage, planUsage, }) {
224
+ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, groupConversationHistory = false, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal = 0, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder = 'Ask anything...', welcomeMessage, isExpanded, onExpandedChange, isFullScreen = false, onFullScreenChange, isMinimized = false, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress = {}, onApprovalResponse, isEditingApp = true, onEditingAppChange, showEditingAppToggle = false, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments = [], onRemoveImageAttachment, isImageDropActive = false, queuedMessages = [], onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting = false, compactedHistoryStartIndex, contextUsage, planUsage, }) {
221
225
  const inputRef = useRef(null);
222
226
  const fullScreenTriggerRef = useRef(null);
223
227
  const [isConnectingChatGPT, setIsConnectingChatGPT] = useState(false);
@@ -317,7 +321,7 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
317
321
  : 'Not editing app (click to enable)' }) })] }) })) : null;
318
322
  const composerStartControls = (_jsxs(_Fragment, { children: [conversations &&
319
323
  (conversations.length > 0 || onNewChat) &&
320
- onSelectConversation && (_jsx(ConversationHistory, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelectConversation, onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, disabled: false, dropdownAlign: "start", dropdownSide: "top", tooltipSide: "top", hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations })), editingAppControl] }));
324
+ onSelectConversation && (_jsx(ConversationHistory, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupConversationHistory, onSelect: onSelectConversation, onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, disabled: false, dropdownAlign: "start", dropdownSide: "top", tooltipSide: "top", hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations })), editingAppControl] }));
321
325
  // Keyboard shortcut: Cmd+Shift+O for new chat
322
326
  useEffect(() => {
323
327
  const handleKeyDown = (e) => {
@@ -439,40 +443,50 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
439
443
  window.requestAnimationFrame(() => {
440
444
  fullScreenTriggerRef.current?.focus();
441
445
  });
442
- }, size: "full", className: "rounded-container flex gap-0 overflow-hidden border-0 p-0", children: [_jsx("div", { "data-tauri-drag-region": true, className: "absolute inset-x-0 top-0 z-20 h-9", "aria-hidden": "true" }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-50 flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsxs("aside", { className: "border-border bg-muted/50 rounded-r-container relative z-10 flex w-[280px] shrink-0 flex-col overflow-hidden border-r px-3 pb-4 pt-11", children: [_jsxs("button", { type: "button", onClick: () => onFullScreenChange?.(false), className: "text-muted-foreground hover:text-foreground rounded-container text-ui-body mb-4 flex h-8 cursor-pointer items-center gap-2 px-2 transition-colors", children: [_jsx(Minimize2, { className: "size-4" }), "Back to app"] }), _jsx(ConversationSidebar, { conversations: conversations ?? [], currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelectConversation ?? (() => undefined), onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, hideScrollbar: true, disabled: false, hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations, className: "min-h-0 flex-1" })] }), _jsxs("section", { className: "relative flex min-w-0 flex-1 flex-col", children: [_jsxs("header", { className: "border-border flex h-14 shrink-0 items-center justify-between border-b px-5", children: [_jsx(DialogTitle, { className: "text-ui-body truncate font-medium", children: selectedConversation?.title ?? 'New conversation' }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => onFullScreenChange?.(false), "aria-label": "Exit full screen", className: "text-muted-foreground hover:text-foreground relative z-30 cursor-pointer", children: _jsx(Minimize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "Exit full screen" })] }) })] }), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, showNavigationTrail: true, contentClassName: "mx-auto w-full min-w-0 max-w-3xl overflow-hidden px-6 py-6", scrollButtonClassName: "absolute bottom-3 left-1/2 z-20 size-8 -translate-x-1/2 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) })), _jsxs("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border bg-muted/30 rounded-container mb-2 border p-3", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx("div", { className: "bg-background overflow-hidden rounded-[24px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.2)]", children: _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: editingAppControl, footerControls: composerControls, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect }) })] })] })] }) }));
446
+ }, size: "full", className: "rounded-container flex gap-0 overflow-hidden border-0 p-0", children: [_jsx("div", { "data-tauri-drag-region": true, className: "absolute inset-x-0 top-0 z-20 h-9", "aria-hidden": "true" }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-50 flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsxs("aside", { className: "border-border bg-muted/50 rounded-r-container relative z-10 flex w-[280px] shrink-0 flex-col overflow-hidden border-r px-3 pb-4 pt-11", children: [_jsxs("button", { type: "button", onClick: () => onFullScreenChange?.(false), className: "text-muted-foreground hover:text-foreground rounded-container text-ui-body mb-4 flex h-8 cursor-pointer items-center gap-2 px-2 transition-colors", children: [_jsx(Minimize2, { className: "size-4" }), "Back to app"] }), _jsx(ConversationSidebar, { conversations: conversations ?? [], currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupConversationHistory, onSelect: onSelectConversation ?? (() => undefined), onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, hideScrollbar: true, disabled: false, hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations, className: "min-h-0 flex-1" })] }), _jsxs("section", { className: "relative flex min-w-0 flex-1 flex-col", children: [_jsxs("header", { className: "border-border flex h-14 shrink-0 items-center justify-between border-b px-5", children: [_jsx(DialogTitle, { className: "text-ui-body truncate font-medium", children: selectedConversation?.title ?? 'New conversation' }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => onFullScreenChange?.(false), "aria-label": "Exit full screen", className: "text-muted-foreground hover:text-foreground relative z-30 cursor-pointer", children: _jsx(Minimize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "Exit full screen" })] }) })] }), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, showNavigationTrail: true, contentClassName: "mx-auto w-full min-w-0 max-w-3xl overflow-hidden px-6 py-6", scrollButtonClassName: "absolute bottom-3 left-1/2 z-20 size-8 -translate-x-1/2 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) })), _jsxs("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border bg-muted/30 rounded-container mb-2 border p-3", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx("div", { className: "bg-background overflow-hidden rounded-[24px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.2)]", children: _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: editingAppControl, footerControls: composerControls, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect }) })] })] })] }) }));
443
447
  }
444
448
  return (_jsxs(_Fragment, { children: [_jsx(AnimatePresence, { children: isExpanded && !isMinimized && (_jsx(motion.div, { "data-moldable-chat-backdrop": true, initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, className: "fixed inset-0 z-40 bg-black/20", onClick: () => onExpandedChange(false) })) }), _jsx(motion.div, { "data-moldable-chat-panel": true, initial: false, animate: {
445
449
  width: isExpanded ? 'min(90vw, 640px)' : '400px',
446
450
  y: isMinimized ? 'calc(100% + 24px)' : 0,
447
451
  opacity: isMinimized ? 0 : 1,
448
- }, transition: { type: 'tween', duration: 0.25, ease: 'easeOut' }, className: cn('pointer-events-none fixed bottom-6 left-[calc(50%+var(--sidebar-width,0px)/2)] z-50 flex -translate-x-1/2 justify-center', isMinimized && 'pointer-events-none', className), children: _jsxs("div", { "data-chat-drop-target": true, className: cn('bg-background/80 pointer-events-auto relative w-full shadow-[0_8px_40px_-12px_rgba(0,0,0,0.15)]', isExpanded
449
- ? 'bg-background'
450
- : 'bg-background/80 supports-[backdrop-filter]:backdrop-blur-xl', 'rounded-[28px]', isExpanded ? 'overflow-hidden' : 'overflow-visible'), children: [!isExpanded && (_jsx("div", { className: "pointer-events-none absolute inset-0 z-0 rounded-[inherit]", style: {
451
- background: 'linear-gradient(134deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.02) 50%, transparent 55%)',
452
- } })), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-[70] flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsx("div", { className: "pointer-events-none absolute inset-0 z-50 rounded-[inherit]", style: {
452
+ }, transition: { type: 'tween', duration: 0.25, ease: 'easeOut' }, className: cn('pointer-events-none fixed bottom-6 left-[calc(50%+var(--sidebar-width,0px)/2)] z-50 flex -translate-x-1/2 justify-center', isMinimized && 'pointer-events-none', className), children: _jsxs("div", { "data-chat-drop-target": true, className: cn('bg-background/80 pointer-events-auto relative isolate w-full transition-[background-color,border-radius,box-shadow] duration-200 ease-out', isExpanded
453
+ ? 'bg-background rounded-[28px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.15)]'
454
+ : 'bg-background/80 rounded-[36px] supports-[backdrop-filter]:backdrop-blur-xl', isExpanded ? 'overflow-hidden' : 'overflow-visible'), children: [_jsx(motion.div, { initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
455
+ duration: isExpanded ? 0.08 : 0.12,
456
+ delay: isExpanded ? 0 : 0.18,
457
+ ease: 'easeOut',
458
+ }, className: "pointer-events-none absolute inset-0 z-0 rounded-[inherit]", style: {
459
+ background: 'linear-gradient(135deg, color-mix(in oklch, var(--foreground) 9%, transparent) 0%, color-mix(in oklch, var(--foreground) 2%, transparent) 42%, transparent 58%)',
460
+ } }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-[70] flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsx("div", { className: "pointer-events-none absolute inset-0 z-[49] rounded-[inherit]", style: {
461
+ padding: '1px',
462
+ background: 'linear-gradient(135deg, color-mix(in oklch, var(--foreground) 20%, transparent), color-mix(in oklch, var(--border) 65%, transparent) 48%, color-mix(in oklch, var(--foreground) 12%, transparent))',
463
+ mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
464
+ WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
465
+ maskComposite: 'exclude',
466
+ WebkitMaskComposite: 'xor',
467
+ } }), _jsx(motion.div, { "data-moldable-chat-edge-treatment": true, initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
468
+ duration: isExpanded ? 0.08 : 0.12,
469
+ delay: isExpanded ? 0 : 0.18,
470
+ ease: 'easeOut',
471
+ }, className: "pointer-events-none absolute inset-0 z-50 rounded-[inherit]", style: {
453
472
  padding: '1px',
454
- background: 'linear-gradient(135deg, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0.1) 20%, rgba(255,255,255,0.05) 45%, rgba(255,255,255,0.05) 55%, rgba(255,255,255,0.1) 80%, rgba(255,255,255,0.25) 100%)',
473
+ background: 'conic-gradient(from 205deg at 50% 50%, color-mix(in oklch, var(--foreground) 16%, transparent) 0deg, color-mix(in oklch, var(--border) 72%, transparent) 72deg, color-mix(in oklch, var(--primary) 18%, transparent) 148deg, color-mix(in oklch, var(--foreground) 30%, transparent) 226deg, color-mix(in oklch, var(--border) 68%, transparent) 304deg, color-mix(in oklch, var(--foreground) 16%, transparent) 360deg)',
455
474
  mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
456
475
  WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
457
476
  maskComposite: 'exclude',
458
477
  WebkitMaskComposite: 'xor',
459
- } }), !isExpanded && (_jsx(motion.div, { className: "rounded-4xl pointer-events-none absolute inset-0 z-0", animate: {
460
- boxShadow: [
461
- '0 0 0px 0px color-mix(in oklch, var(--primary) 0%, #ff8800 00%)',
462
- '0 0 20px 0px color-mix(in oklch, var(--primary) 20%, #ff8800 30%)',
463
- '0 0 30px 2px color-mix(in oklch, var(--primary) 0%, #ff8800 00%)',
464
- ],
465
- }, transition: {
466
- duration: 4,
467
- repeat: Infinity,
468
- repeatDelay: 5,
469
- ease: [0.4, 0, 0.2, 1],
470
- } })), _jsxs("div", { className: "relative z-10 overflow-hidden rounded-[inherit]", children: [_jsxs(motion.div, { initial: false, animate: {
478
+ } }), _jsx(motion.div, { "data-moldable-chat-edge-depth": true, initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
479
+ duration: isExpanded ? 0.08 : 0.12,
480
+ delay: isExpanded ? 0 : 0.18,
481
+ ease: 'easeOut',
482
+ }, className: "pointer-events-none absolute inset-0 z-40 rounded-[inherit]", style: {
483
+ boxShadow: 'inset 0 1px 0 color-mix(in oklch, var(--foreground) 9%, transparent), inset 0 -1px 0 color-mix(in oklch, var(--background) 72%, transparent), 0 16px 38px -26px color-mix(in oklch, var(--foreground) 52%, transparent), 0 0 24px -17px color-mix(in oklch, var(--primary) 42%, transparent)',
484
+ } }), _jsxs("div", { className: "relative z-10 overflow-hidden rounded-[inherit]", children: [_jsxs(motion.div, { initial: false, animate: {
471
485
  height: isExpanded ? 'min(60vh, 480px)' : '0px',
472
486
  opacity: isExpanded ? 1 : 0,
473
- }, transition: { type: 'tween', duration: 0.2, ease: 'easeOut' }, className: "flex flex-col overflow-hidden", style: { pointerEvents: isExpanded ? 'auto' : 'none' }, children: [isExpanded && !isMinimized && (_jsxs("div", { className: "absolute right-2 top-2 z-20 grid grid-cols-1 gap-0.5", "data-moldable-chat-panel-controls": true, role: "toolbar", "aria-label": "Chat view controls", "aria-orientation": "vertical", children: [onFullScreenChange && (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { ref: fullScreenTriggerRef, "data-moldable-chat-enter-fullscreen": true, variant: "ghost", size: "icon-sm", onClick: () => onFullScreenChange(true), "aria-label": "Enter full screen", className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(Maximize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Full screen" })] }) })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: handleMinimize, className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(ChevronDown, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "bottom", children: _jsx("p", { children: "Minimize" }) })] }) })] })), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, scrollAreaClassName: "px-2", contentClassName: "w-full min-w-0 max-w-full overflow-hidden py-4 pr-12", scrollButtonClassName: "absolute bottom-3 left-auto right-4 z-20 size-8 translate-x-0 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "shrink-0 px-4 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) }))] }), _jsxs("div", { className: "relative z-10", onClick: () => {
487
+ }, transition: { type: 'tween', duration: 0.2, ease: 'easeOut' }, className: "flex flex-col overflow-hidden", style: { pointerEvents: isExpanded ? 'auto' : 'none' }, children: [isExpanded && !isMinimized && (_jsxs("div", { className: "absolute right-4 top-3 z-20 grid grid-cols-1 gap-1", "data-moldable-chat-panel-controls": true, role: "toolbar", "aria-label": "Chat view controls", "aria-orientation": "vertical", children: [onFullScreenChange && (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { ref: fullScreenTriggerRef, "data-moldable-chat-enter-fullscreen": true, variant: "ghost", size: "icon-xl", onClick: () => onFullScreenChange(true), "aria-label": "Enter full screen", className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(Maximize2, { className: "size-5" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Full screen" })] }) })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xl", onClick: handleMinimize, className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(ChevronDown, { className: "size-5" }) }) }), _jsx(TooltipContent, { side: "bottom", children: _jsx("p", { children: "Minimize" }) })] }) })] })), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, scrollAreaClassName: "px-2", contentClassName: "w-full min-w-0 max-w-full overflow-hidden py-4 pr-12", scrollButtonClassName: "absolute bottom-3 left-auto right-4 z-20 size-8 translate-x-0 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "shrink-0 px-4 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) }))] }), _jsxs("div", { className: "relative z-10", onClick: () => {
474
488
  if (!isExpanded) {
475
489
  onExpandedChange(true);
476
490
  }
477
- }, children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border/70 bg-background/95 border-t px-4 py-2", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, compact: !isExpanded, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: isExpanded ? composerStartControls : null, footerControls: isExpanded ? composerControls : null, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect })] })] })] }) })] }));
491
+ }, children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border/70 bg-background/95 border-t px-4 py-2", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, compact: !isExpanded, surfaceBorderRadius: isExpanded ? 24 : undefined, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: isExpanded ? composerStartControls : null, footerControls: isExpanded ? composerControls : null, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect })] })] })] }) })] }));
478
492
  }
@@ -26,6 +26,8 @@ interface ConversationListProps {
26
26
  conversations: ConversationMeta[];
27
27
  currentConversationId?: string | null;
28
28
  currentAppId?: string | null;
29
+ /** Opts into app/scope disclosure groups for unified conversation surfaces. */
30
+ groupByScope?: boolean;
29
31
  onSelect: (id: string) => void;
30
32
  onArchive?: (id: string) => void;
31
33
  onArchiveGroup?: (group: ConversationGroup) => void;
@@ -51,7 +53,7 @@ interface ConversationSidebarProps extends ConversationListProps {
51
53
  onLoadMoreConversations?: () => void | Promise<unknown>;
52
54
  }
53
55
  export declare function groupConversations(conversations: ConversationMeta[], currentAppId?: string | null): ConversationGroup[];
54
- export declare function ConversationSidebar({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, hideScrollbar, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, disabled, className, }: ConversationSidebarProps): import("react/jsx-runtime").JSX.Element;
55
- export declare function ConversationHistory({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
56
+ export declare function ConversationSidebar({ conversations, currentConversationId, currentAppId, groupByScope, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, hideScrollbar, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, disabled, className, }: ConversationSidebarProps): import("react/jsx-runtime").JSX.Element;
57
+ export declare function ConversationHistory({ conversations, currentConversationId, currentAppId, groupByScope, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
56
58
  export {};
57
59
  //# sourceMappingURL=conversation-history.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"AAiCA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAClC;AAOD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAIR;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI,IAAI,MAAM,CAIhB;AAED,UAAU,qBAAqB;IAC7B,aAAa,EAAE,gBAAgB,EAAE,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAC1C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,gBAAgB,EAAE,EACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAC3B,iBAAiB,EAAE,CA8CrB;AAqPD,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,YAAoB,EACpB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,aAAqB,EACrB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,EACvB,QAAgB,EAChB,SAAS,GACV,EAAE,wBAAwB,2CAwH1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,YAAoB,EACpB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,aAAuB,EACvB,YAAuB,EACvB,WAAsB,EACtB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,GACxB,EAAE,wBAAwB,kDAmG1B"}