@humain/ui 2.2.3 → 2.2.5

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 (116) hide show
  1. package/dist/components/templates/AppShell/AppShell.d.ts +1 -1
  2. package/dist/components/templates/AppSidebar/AppSidebar.constants.d.ts +1 -1
  3. package/dist/index11.js +4 -4
  4. package/dist/index11.js.map +1 -1
  5. package/dist/index110.js +4 -4
  6. package/dist/index110.js.map +1 -1
  7. package/dist/index134.js +4 -4
  8. package/dist/index134.js.map +1 -1
  9. package/dist/index135.js +2 -2
  10. package/dist/index135.js.map +1 -1
  11. package/dist/index151.js +3 -3
  12. package/dist/index151.js.map +1 -1
  13. package/dist/index152.js +2 -2
  14. package/dist/index152.js.map +1 -1
  15. package/dist/index155.js +1 -1
  16. package/dist/index155.js.map +1 -1
  17. package/dist/index173.js +1 -1
  18. package/dist/index173.js.map +1 -1
  19. package/dist/index184.js +1 -1
  20. package/dist/index184.js.map +1 -1
  21. package/dist/index188.js +4 -4
  22. package/dist/index188.js.map +1 -1
  23. package/dist/index201.js +1 -1
  24. package/dist/index201.js.map +1 -1
  25. package/dist/index217.js +1 -1
  26. package/dist/index217.js.map +1 -1
  27. package/dist/index223.js.map +1 -1
  28. package/dist/index225.js +3 -3
  29. package/dist/index225.js.map +1 -1
  30. package/dist/index228.js +1 -1
  31. package/dist/index228.js.map +1 -1
  32. package/dist/index24.js +1 -1
  33. package/dist/index24.js.map +1 -1
  34. package/dist/index25.js +4 -4
  35. package/dist/index25.js.map +1 -1
  36. package/dist/index39.js +2 -2
  37. package/dist/index39.js.map +1 -1
  38. package/dist/index5.js +8 -8
  39. package/dist/index5.js.map +1 -1
  40. package/dist/styles.css +1 -1
  41. package/dist/wc/AIScrollButton.js +8 -8
  42. package/dist/wc/AIScrollButton.js.map +1 -1
  43. package/dist/wc/AISource.js +46 -46
  44. package/dist/wc/AISource.js.map +1 -1
  45. package/dist/wc/AIToolCall.js +9 -9
  46. package/dist/wc/AIToolCall.js.map +1 -1
  47. package/dist/wc/AppSidebar.constants.js +1 -1
  48. package/dist/wc/AppSidebar.constants.js.map +1 -1
  49. package/dist/wc/Badge.js +9 -9
  50. package/dist/wc/Badge.js.map +1 -1
  51. package/dist/wc/Checkbox.js +22 -22
  52. package/dist/wc/Checkbox.js.map +1 -1
  53. package/dist/wc/Pagination.js +4 -4
  54. package/dist/wc/Pagination.js.map +1 -1
  55. package/dist/wc/Switch.js +23 -23
  56. package/dist/wc/Switch.js.map +1 -1
  57. package/dist/wc/Tabs.js +110 -110
  58. package/dist/wc/Tabs.js.map +1 -1
  59. package/dist/wc/Tooltip.js +28 -28
  60. package/dist/wc/Tooltip.js.map +1 -1
  61. package/dist/wc/button.js +33 -33
  62. package/dist/wc/button.js.map +1 -1
  63. package/dist/wc/hf-alert.js +10 -10
  64. package/dist/wc/hf-alert.js.map +1 -1
  65. package/dist/wc/hf-app-shell.js.map +1 -1
  66. package/dist/wc/hf-app-sidebar.js +3 -3
  67. package/dist/wc/hf-app-sidebar.js.map +1 -1
  68. package/dist/wc/hf-nav-account-menu.js +8 -8
  69. package/dist/wc/hf-nav-account-menu.js.map +1 -1
  70. package/dist/wc/hf-steps.js +8 -8
  71. package/dist/wc/hf-steps.js.map +1 -1
  72. package/dist/wc/markdown-renderer.js +5 -5
  73. package/dist/wc/markdown-renderer.js.map +1 -1
  74. package/dist/wc/selection-group.js +6 -6
  75. package/dist/wc/selection-group.js.map +1 -1
  76. package/dist/wc-react/AIScrollButton.js +18 -18
  77. package/dist/wc-react/AIScrollButton.js.map +1 -1
  78. package/dist/wc-react/AISource.js +8 -8
  79. package/dist/wc-react/AISource.js.map +1 -1
  80. package/dist/wc-react/AIToolCall.js +42 -42
  81. package/dist/wc-react/AIToolCall.js.map +1 -1
  82. package/dist/wc-react/AppSidebar.constants.js +1 -1
  83. package/dist/wc-react/AppSidebar.constants.js.map +1 -1
  84. package/dist/wc-react/Badge.js +16 -16
  85. package/dist/wc-react/Badge.js.map +1 -1
  86. package/dist/wc-react/Checkbox.js +14 -14
  87. package/dist/wc-react/Checkbox.js.map +1 -1
  88. package/dist/wc-react/Pagination.js +130 -130
  89. package/dist/wc-react/Pagination.js.map +1 -1
  90. package/dist/wc-react/Switch.js +2 -2
  91. package/dist/wc-react/Switch.js.map +1 -1
  92. package/dist/wc-react/Tabs.js +38 -38
  93. package/dist/wc-react/Tabs.js.map +1 -1
  94. package/dist/wc-react/Tooltip.js +22 -22
  95. package/dist/wc-react/Tooltip.js.map +1 -1
  96. package/dist/wc-react/button.js +8 -8
  97. package/dist/wc-react/button.js.map +1 -1
  98. package/dist/wc-react/hf-alert.js +28 -28
  99. package/dist/wc-react/hf-alert.js.map +1 -1
  100. package/dist/wc-react/hf-app-shell.js.map +1 -1
  101. package/dist/wc-react/hf-app-sidebar.js +3 -3
  102. package/dist/wc-react/hf-app-sidebar.js.map +1 -1
  103. package/dist/wc-react/hf-nav-account-menu.js +7 -7
  104. package/dist/wc-react/hf-nav-account-menu.js.map +1 -1
  105. package/dist/wc-react/hf-steps.js +16 -16
  106. package/dist/wc-react/hf-steps.js.map +1 -1
  107. package/dist/wc-react/markdown-renderer.js +5 -5
  108. package/dist/wc-react/markdown-renderer.js.map +1 -1
  109. package/dist/wc-react/selection-group.js +1 -1
  110. package/dist/wc-react/selection-group.js.map +1 -1
  111. package/package.json +1 -1
  112. package/skills/humain-ui/SKILL.md +1 -1
  113. package/skills/humain-ui-wc/SKILL.md +1 -1
  114. package/skills/humain-ui-wc.skill +0 -0
  115. package/skills/humain-ui.skill +0 -0
  116. package/src/tokens.css +10 -2
@@ -1,10 +1,10 @@
1
1
  import { a as j } from "./rolldown-runtime.js";
2
2
  import { i as k, t as I } from "./vendor/react.js";
3
- import { n as y } from "./utils.js";
3
+ import { n as w } from "./utils.js";
4
4
  import { t as V } from "./arrow-down.js";
5
5
  import { t as _ } from "./dist.js";
6
6
  import { t as N } from "./button.js";
7
- import { t as w } from "./react.js";
7
+ import { t as y } from "./react.js";
8
8
  import { t as H } from "./AnimatePresence.js";
9
9
  var e = /* @__PURE__ */ j(k(), 1), d = I(), T = _("fixed flex items-center justify-center shadow-lg transition-all", {
10
10
  variants: {
@@ -107,7 +107,7 @@ function D({ scrollRef: c, containerRef: n, threshold: m = 50, onClick: o, visib
107
107
  const a = l ?? t, s = () => {
108
108
  o ? o() : c?.current ? c.current.scrollIntoView({ behavior: "smooth" }) : n?.current && (n.current.scrollTop = n.current.scrollHeight);
109
109
  }, g = E(f);
110
- return /* @__PURE__ */ (0, d.jsx)(H, { children: a && /* @__PURE__ */ (0, d.jsxs)(w.div, {
110
+ return /* @__PURE__ */ (0, d.jsx)(H, { children: a && /* @__PURE__ */ (0, d.jsxs)(y.div, {
111
111
  "data-slot": "ai-scroll-button",
112
112
  initial: {
113
113
  opacity: 0,
@@ -133,7 +133,7 @@ function D({ scrollRef: c, containerRef: n, threshold: m = 50, onClick: o, visib
133
133
  1
134
134
  ]
135
135
  },
136
- className: y(T({
136
+ className: w(T({
137
137
  variant: b,
138
138
  size: f,
139
139
  position: p
@@ -145,8 +145,8 @@ function D({ scrollRef: c, containerRef: n, threshold: m = 50, onClick: o, visib
145
145
  onClick: s,
146
146
  className: "size-full rounded-full",
147
147
  "aria-label": h,
148
- children: /* @__PURE__ */ (0, d.jsx)(V, { className: y(g, b === "primary" ? "text-primary-foreground" : "text-muted-foreground") })
149
- }), i !== void 0 && i > 0 && /* @__PURE__ */ (0, d.jsx)(w.div, {
148
+ children: /* @__PURE__ */ (0, d.jsx)(V, { className: w(g, b === "primary" ? "text-primary-foreground" : "text-muted-foreground") })
149
+ }), i !== void 0 && i > 0 && /* @__PURE__ */ (0, d.jsx)(y.div, {
150
150
  initial: { scale: 0 },
151
151
  animate: { scale: 1 },
152
152
  transition: {
@@ -154,7 +154,7 @@ function D({ scrollRef: c, containerRef: n, threshold: m = 50, onClick: o, visib
154
154
  stiffness: 500,
155
155
  damping: 30
156
156
  },
157
- className: "absolute -top-1 -end-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-destructive text-primary-foreground text-xs font-medium motion-reduce:transition-none",
157
+ className: "absolute -top-1 -end-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-destructive text-destructive-foreground text-xs font-medium motion-reduce:transition-none",
158
158
  "aria-label": `${i > 99 ? "99+" : i} new messages`,
159
159
  children: i > 99 ? "99+" : i
160
160
  })]
@@ -163,7 +163,7 @@ function D({ scrollRef: c, containerRef: n, threshold: m = 50, onClick: o, visib
163
163
  D.displayName = "AIScrollButton";
164
164
  var L = e.forwardRef(({ className: c }, n) => /* @__PURE__ */ (0, d.jsx)("div", {
165
165
  ref: n,
166
- className: y("h-px w-full", c),
166
+ className: w("h-px w-full", c),
167
167
  "aria-hidden": !0
168
168
  }));
169
169
  L.displayName = "AIScrollAnchor";
@@ -1 +1 @@
1
- {"version":3,"file":"AIScrollButton.js","names":[],"sources":["../../src/components/organisms/ai/AIScrollButton/AIScrollButton.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { ArrowDown } from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst scrollButtonVariants = cva(\n 'fixed flex items-center justify-center shadow-lg transition-all',\n {\n variants: {\n variant: {\n default: 'bg-background hover:bg-muted border border-border',\n primary: 'bg-primary/10 hover:bg-primary/90 text-primary-foreground',\n ghost:\n 'bg-card/80 hover:bg-background supports-backdrop-filter:backdrop-blur-sm border border-border',\n },\n size: {\n sm: 'size-8 rounded-full',\n md: 'size-10 rounded-full',\n lg: 'size-12 rounded-xl',\n },\n position: {\n 'bottom-center':\n 'bottom-4 start-1/2 -translate-x-1/2 rtl:translate-x-1/2',\n 'bottom-right': 'bottom-4 end-4',\n 'bottom-left': 'bottom-4 start-4',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n position: 'bottom-center',\n },\n },\n);\n\n// =============================================================================\n// useScrollToBottom Hook\n// =============================================================================\n\nexport interface UseScrollToBottomOptions {\n /** Threshold in pixels from bottom to consider \"at bottom\" */\n threshold?: number;\n /** Scroll behavior */\n behavior?: ScrollBehavior;\n /** Enable auto-scroll mode: tracks whether auto-scroll should fire on content changes */\n autoScroll?: boolean;\n}\n\nexport interface UseScrollToBottomReturn {\n /** Whether the user is at the bottom of the container */\n isAtBottom: boolean;\n /** Scroll to bottom function */\n scrollToBottom: (behavior?: ScrollBehavior) => void;\n /** Ref to attach to the scrollable container */\n containerRef: React.RefObject<HTMLDivElement | null>;\n /** Ref to attach to the scroll anchor element */\n anchorRef: React.RefObject<HTMLDivElement | null>;\n /** Whether auto-scroll should fire (only meaningful when autoScroll option is true) */\n shouldAutoScroll: boolean;\n /** Call when user scrolls manually to disable auto-scroll (re-enables when user scrolls back to bottom) */\n handleUserScroll: () => void;\n /** Trigger an auto-scroll if shouldAutoScroll is true (uses requestAnimationFrame) */\n triggerAutoScroll: () => void;\n}\n\nexport function useScrollToBottom({\n threshold = 50,\n behavior = 'smooth',\n autoScroll: autoScrollEnabled = false,\n}: UseScrollToBottomOptions = {}): UseScrollToBottomReturn {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const anchorRef = React.useRef<HTMLDivElement>(null);\n const [isAtBottom, setIsAtBottom] = React.useState(true);\n const [shouldAutoScroll, setShouldAutoScroll] = React.useState(true);\n\n const scrollToBottom = React.useCallback(\n (overrideBehavior?: ScrollBehavior) => {\n const scrollBehavior = overrideBehavior ?? behavior;\n if (anchorRef.current) {\n anchorRef.current.scrollIntoView({ behavior: scrollBehavior });\n } else if (containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n },\n [behavior],\n );\n\n const checkIsAtBottom = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return true;\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n return distanceFromBottom <= threshold;\n }, [threshold]);\n\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n const atBottom = checkIsAtBottom();\n setIsAtBottom((prev) => (prev === atBottom ? prev : atBottom));\n if (autoScrollEnabled && atBottom) {\n setShouldAutoScroll((prev) => prev || true);\n }\n };\n\n handleScroll();\n\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => container.removeEventListener('scroll', handleScroll);\n }, [checkIsAtBottom, autoScrollEnabled]);\n\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const OwnerResizeObserver =\n container.ownerDocument.defaultView?.ResizeObserver;\n if (!OwnerResizeObserver) return;\n\n const resizeObserver = new OwnerResizeObserver(() => {\n const atBottom = checkIsAtBottom();\n setIsAtBottom((prev) => (prev === atBottom ? prev : atBottom));\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [checkIsAtBottom]);\n\n const handleUserScroll = React.useCallback(() => {\n if (!checkIsAtBottom()) {\n setShouldAutoScroll(false);\n }\n }, [checkIsAtBottom]);\n\n const triggerAutoScroll = React.useCallback(() => {\n if (autoScrollEnabled && shouldAutoScroll) {\n const ownerWindow =\n anchorRef.current?.ownerDocument.defaultView ??\n containerRef.current?.ownerDocument.defaultView;\n ownerWindow?.requestAnimationFrame(() => {\n scrollToBottom('smooth');\n });\n }\n }, [autoScrollEnabled, shouldAutoScroll, scrollToBottom]);\n\n return {\n isAtBottom,\n scrollToBottom,\n containerRef,\n anchorRef,\n shouldAutoScroll,\n handleUserScroll,\n triggerAutoScroll,\n };\n}\n\n// =============================================================================\n// Main AIScrollButton Component\n// =============================================================================\n\nexport interface AIScrollButtonProps\n extends VariantProps<typeof scrollButtonVariants> {\n /** Target scroll element ref */\n scrollRef?: React.RefObject<HTMLElement | null>;\n /** Scrollable container ref */\n containerRef?: React.RefObject<HTMLElement | null>;\n /** Threshold in pixels from bottom to show button */\n threshold?: number;\n /** Click handler (defaults to scrolling to bottom) */\n onClick?: () => void;\n /** Whether to show the button (controlled) */\n visible?: boolean;\n /** Label for accessibility */\n label?: string;\n /** Show unread count badge */\n unreadCount?: number;\n /** Additional class name */\n className?: string;\n}\n\nfunction getIconSize(size: AIScrollButtonProps['size']): string {\n switch (size) {\n case 'sm':\n return 'size-4';\n case 'lg':\n return 'size-6';\n default:\n return 'size-5';\n }\n}\n\nfunction AIScrollButton({\n scrollRef,\n containerRef,\n threshold = 50,\n onClick,\n visible: controlledVisible,\n variant,\n size,\n position,\n label = 'Scroll to bottom',\n unreadCount,\n className,\n}: AIScrollButtonProps) {\n const [internalVisible, setInternalVisible] = React.useState(false);\n\n // Track scroll position if containerRef is provided and no controlled visibility\n React.useEffect(() => {\n if (controlledVisible !== undefined) return;\n\n const container = containerRef?.current;\n if (!container) return;\n\n const handleScroll = () => {\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n setInternalVisible(distanceFromBottom > threshold);\n };\n\n handleScroll();\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => container.removeEventListener('scroll', handleScroll);\n }, [containerRef, threshold, controlledVisible]);\n\n const isVisible = controlledVisible ?? internalVisible;\n\n const handleClick = () => {\n if (onClick) {\n onClick();\n } else if (scrollRef?.current) {\n scrollRef.current.scrollIntoView({ behavior: 'smooth' });\n } else if (containerRef?.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n };\n\n const iconSize = getIconSize(size);\n\n return (\n <AnimatePresence>\n {isVisible && (\n <motion.div\n data-slot=\"ai-scroll-button\"\n initial={{ opacity: 0, y: 20, scale: 0.9 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 20, scale: 0.9 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className={cn(\n scrollButtonVariants({ variant, size, position }),\n 'motion-reduce:transition-none',\n className,\n )}\n >\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"icon\"\n onClick={handleClick}\n className=\"size-full rounded-full\"\n aria-label={label}\n >\n <ArrowDown\n className={cn(\n iconSize,\n variant === 'primary'\n ? 'text-primary-foreground'\n : 'text-muted-foreground',\n )}\n />\n </Button>\n\n {/* Unread count badge */}\n {unreadCount !== undefined && unreadCount > 0 && (\n <motion.div\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ type: 'spring', stiffness: 500, damping: 30 }}\n className=\"absolute -top-1 -end-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-destructive text-primary-foreground text-xs font-medium motion-reduce:transition-none\"\n aria-label={`${unreadCount > 99 ? '99+' : unreadCount} new messages`}\n >\n {unreadCount > 99 ? '99+' : unreadCount}\n </motion.div>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\nAIScrollButton.displayName = 'AIScrollButton';\n\n// =============================================================================\n// Scroll Anchor Component\n// =============================================================================\n\nexport interface AIScrollAnchorProps {\n /** Ref to expose for scrolling */\n ref?: React.Ref<HTMLDivElement>;\n /** Additional class name */\n className?: string;\n}\n\nconst AIScrollAnchor = React.forwardRef<HTMLDivElement, AIScrollAnchorProps>(\n ({ className }, ref) => {\n return (\n <div ref={ref} className={cn('h-px w-full', className)} aria-hidden />\n );\n },\n);\n\nAIScrollAnchor.displayName = 'AIScrollAnchor';\n\nexport { AIScrollAnchor, AIScrollButton, scrollButtonVariants };\n"],"mappings":"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"}
1
+ {"version":3,"file":"AIScrollButton.js","names":[],"sources":["../../src/components/organisms/ai/AIScrollButton/AIScrollButton.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { ArrowDown } from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst scrollButtonVariants = cva(\n 'fixed flex items-center justify-center shadow-lg transition-all',\n {\n variants: {\n variant: {\n default: 'bg-background hover:bg-muted border border-border',\n primary: 'bg-primary/10 hover:bg-primary/90 text-primary-foreground',\n ghost:\n 'bg-card/80 hover:bg-background supports-backdrop-filter:backdrop-blur-sm border border-border',\n },\n size: {\n sm: 'size-8 rounded-full',\n md: 'size-10 rounded-full',\n lg: 'size-12 rounded-xl',\n },\n position: {\n 'bottom-center':\n 'bottom-4 start-1/2 -translate-x-1/2 rtl:translate-x-1/2',\n 'bottom-right': 'bottom-4 end-4',\n 'bottom-left': 'bottom-4 start-4',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n position: 'bottom-center',\n },\n },\n);\n\n// =============================================================================\n// useScrollToBottom Hook\n// =============================================================================\n\nexport interface UseScrollToBottomOptions {\n /** Threshold in pixels from bottom to consider \"at bottom\" */\n threshold?: number;\n /** Scroll behavior */\n behavior?: ScrollBehavior;\n /** Enable auto-scroll mode: tracks whether auto-scroll should fire on content changes */\n autoScroll?: boolean;\n}\n\nexport interface UseScrollToBottomReturn {\n /** Whether the user is at the bottom of the container */\n isAtBottom: boolean;\n /** Scroll to bottom function */\n scrollToBottom: (behavior?: ScrollBehavior) => void;\n /** Ref to attach to the scrollable container */\n containerRef: React.RefObject<HTMLDivElement | null>;\n /** Ref to attach to the scroll anchor element */\n anchorRef: React.RefObject<HTMLDivElement | null>;\n /** Whether auto-scroll should fire (only meaningful when autoScroll option is true) */\n shouldAutoScroll: boolean;\n /** Call when user scrolls manually to disable auto-scroll (re-enables when user scrolls back to bottom) */\n handleUserScroll: () => void;\n /** Trigger an auto-scroll if shouldAutoScroll is true (uses requestAnimationFrame) */\n triggerAutoScroll: () => void;\n}\n\nexport function useScrollToBottom({\n threshold = 50,\n behavior = 'smooth',\n autoScroll: autoScrollEnabled = false,\n}: UseScrollToBottomOptions = {}): UseScrollToBottomReturn {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const anchorRef = React.useRef<HTMLDivElement>(null);\n const [isAtBottom, setIsAtBottom] = React.useState(true);\n const [shouldAutoScroll, setShouldAutoScroll] = React.useState(true);\n\n const scrollToBottom = React.useCallback(\n (overrideBehavior?: ScrollBehavior) => {\n const scrollBehavior = overrideBehavior ?? behavior;\n if (anchorRef.current) {\n anchorRef.current.scrollIntoView({ behavior: scrollBehavior });\n } else if (containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n },\n [behavior],\n );\n\n const checkIsAtBottom = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) return true;\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n return distanceFromBottom <= threshold;\n }, [threshold]);\n\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n const atBottom = checkIsAtBottom();\n setIsAtBottom((prev) => (prev === atBottom ? prev : atBottom));\n if (autoScrollEnabled && atBottom) {\n setShouldAutoScroll((prev) => prev || true);\n }\n };\n\n handleScroll();\n\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => container.removeEventListener('scroll', handleScroll);\n }, [checkIsAtBottom, autoScrollEnabled]);\n\n React.useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const OwnerResizeObserver =\n container.ownerDocument.defaultView?.ResizeObserver;\n if (!OwnerResizeObserver) return;\n\n const resizeObserver = new OwnerResizeObserver(() => {\n const atBottom = checkIsAtBottom();\n setIsAtBottom((prev) => (prev === atBottom ? prev : atBottom));\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [checkIsAtBottom]);\n\n const handleUserScroll = React.useCallback(() => {\n if (!checkIsAtBottom()) {\n setShouldAutoScroll(false);\n }\n }, [checkIsAtBottom]);\n\n const triggerAutoScroll = React.useCallback(() => {\n if (autoScrollEnabled && shouldAutoScroll) {\n const ownerWindow =\n anchorRef.current?.ownerDocument.defaultView ??\n containerRef.current?.ownerDocument.defaultView;\n ownerWindow?.requestAnimationFrame(() => {\n scrollToBottom('smooth');\n });\n }\n }, [autoScrollEnabled, shouldAutoScroll, scrollToBottom]);\n\n return {\n isAtBottom,\n scrollToBottom,\n containerRef,\n anchorRef,\n shouldAutoScroll,\n handleUserScroll,\n triggerAutoScroll,\n };\n}\n\n// =============================================================================\n// Main AIScrollButton Component\n// =============================================================================\n\nexport interface AIScrollButtonProps\n extends VariantProps<typeof scrollButtonVariants> {\n /** Target scroll element ref */\n scrollRef?: React.RefObject<HTMLElement | null>;\n /** Scrollable container ref */\n containerRef?: React.RefObject<HTMLElement | null>;\n /** Threshold in pixels from bottom to show button */\n threshold?: number;\n /** Click handler (defaults to scrolling to bottom) */\n onClick?: () => void;\n /** Whether to show the button (controlled) */\n visible?: boolean;\n /** Label for accessibility */\n label?: string;\n /** Show unread count badge */\n unreadCount?: number;\n /** Additional class name */\n className?: string;\n}\n\nfunction getIconSize(size: AIScrollButtonProps['size']): string {\n switch (size) {\n case 'sm':\n return 'size-4';\n case 'lg':\n return 'size-6';\n default:\n return 'size-5';\n }\n}\n\nfunction AIScrollButton({\n scrollRef,\n containerRef,\n threshold = 50,\n onClick,\n visible: controlledVisible,\n variant,\n size,\n position,\n label = 'Scroll to bottom',\n unreadCount,\n className,\n}: AIScrollButtonProps) {\n const [internalVisible, setInternalVisible] = React.useState(false);\n\n // Track scroll position if containerRef is provided and no controlled visibility\n React.useEffect(() => {\n if (controlledVisible !== undefined) return;\n\n const container = containerRef?.current;\n if (!container) return;\n\n const handleScroll = () => {\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n setInternalVisible(distanceFromBottom > threshold);\n };\n\n handleScroll();\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => container.removeEventListener('scroll', handleScroll);\n }, [containerRef, threshold, controlledVisible]);\n\n const isVisible = controlledVisible ?? internalVisible;\n\n const handleClick = () => {\n if (onClick) {\n onClick();\n } else if (scrollRef?.current) {\n scrollRef.current.scrollIntoView({ behavior: 'smooth' });\n } else if (containerRef?.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n };\n\n const iconSize = getIconSize(size);\n\n return (\n <AnimatePresence>\n {isVisible && (\n <motion.div\n data-slot=\"ai-scroll-button\"\n initial={{ opacity: 0, y: 20, scale: 0.9 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 20, scale: 0.9 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className={cn(\n scrollButtonVariants({ variant, size, position }),\n 'motion-reduce:transition-none',\n className,\n )}\n >\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"icon\"\n onClick={handleClick}\n className=\"size-full rounded-full\"\n aria-label={label}\n >\n <ArrowDown\n className={cn(\n iconSize,\n variant === 'primary'\n ? 'text-primary-foreground'\n : 'text-muted-foreground',\n )}\n />\n </Button>\n\n {/* Unread count badge */}\n {unreadCount !== undefined && unreadCount > 0 && (\n <motion.div\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={{ type: 'spring', stiffness: 500, damping: 30 }}\n className=\"absolute -top-1 -end-1 flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-destructive text-destructive-foreground text-xs font-medium motion-reduce:transition-none\"\n aria-label={`${unreadCount > 99 ? '99+' : unreadCount} new messages`}\n >\n {unreadCount > 99 ? '99+' : unreadCount}\n </motion.div>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\nAIScrollButton.displayName = 'AIScrollButton';\n\n// =============================================================================\n// Scroll Anchor Component\n// =============================================================================\n\nexport interface AIScrollAnchorProps {\n /** Ref to expose for scrolling */\n ref?: React.Ref<HTMLDivElement>;\n /** Additional class name */\n className?: string;\n}\n\nconst AIScrollAnchor = React.forwardRef<HTMLDivElement, AIScrollAnchorProps>(\n ({ className }, ref) => {\n return (\n <div ref={ref} className={cn('h-px w-full', className)} aria-hidden />\n );\n },\n);\n\nAIScrollAnchor.displayName = 'AIScrollAnchor';\n\nexport { AIScrollAnchor, AIScrollButton, scrollButtonVariants };\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { a as y } from "./rolldown-runtime.js";
2
- import { i as j, t as N } from "./vendor/react.js";
1
+ import { a as j } from "./rolldown-runtime.js";
2
+ import { i as y, t as N } from "./vendor/react.js";
3
3
  import { n as l } from "./utils.js";
4
4
  import { t as f } from "./createLucideIcon.js";
5
5
  import { t as b } from "./dist.js";
@@ -32,27 +32,27 @@ var k = [
32
32
  d: "M2 12h20",
33
33
  key: "9i4pu4"
34
34
  }]
35
- ], w = f("globe", I), u = /* @__PURE__ */ y(j(), 1), t = N(), A = b("inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", {
35
+ ], w = f("globe", I), u = /* @__PURE__ */ j(y(), 1), r = N(), A = b("inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", {
36
36
  variants: { variant: {
37
37
  default: "text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm",
38
38
  pill: "px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press",
39
- minimal: "text-xs text-text-quaternary hover:text-secondary-foreground rounded-sm"
39
+ minimal: "text-xs text-secondary-foreground hover:text-foreground rounded-sm"
40
40
  } },
41
41
  defaultVariants: { variant: "default" }
42
- }), q = 3;
43
- function E(e) {
44
- return Number.isFinite(e) && e >= 0 ? Math.floor(e) : q;
42
+ }), E = 3;
43
+ function L(e) {
44
+ return Number.isFinite(e) && e >= 0 ? Math.floor(e) : E;
45
45
  }
46
- function m({ url: e, favicon: r, className: a }) {
46
+ function m({ url: e, favicon: t, className: a }) {
47
47
  const [i, s] = u.useState(!1), n = u.useMemo(() => {
48
- if (r) return r;
48
+ if (t) return t;
49
49
  try {
50
50
  return `https://www.google.com/s2/favicons?domain=${new URL(e).hostname}&sz=32`;
51
51
  } catch {
52
52
  return null;
53
53
  }
54
- }, [e, r]);
55
- return !n || i ? /* @__PURE__ */ (0, t.jsx)(w, { className: l("size-4 text-muted-foreground", a) }) : /* @__PURE__ */ (0, t.jsx)("img", {
54
+ }, [e, t]);
55
+ return !n || i ? /* @__PURE__ */ (0, r.jsx)(w, { className: l("size-4 text-muted-foreground", a) }) : /* @__PURE__ */ (0, r.jsx)("img", {
56
56
  src: n,
57
57
  alt: "",
58
58
  className: l("size-4 rounded delight-fade-in motion-reduce:!animate-none", a),
@@ -60,29 +60,29 @@ function m({ url: e, favicon: r, className: a }) {
60
60
  });
61
61
  }
62
62
  m.displayName = "SourceFavicon";
63
- function d({ source: e, variant: r, showFavicon: a = !0, className: i, onClick: s }) {
64
- const n = e.title || e.siteName || e.url, c = l(A({ variant: r }), i), o = /* @__PURE__ */ (0, t.jsxs)(t.Fragment, { children: [
65
- a && /* @__PURE__ */ (0, t.jsx)(m, {
63
+ function d({ source: e, variant: t, showFavicon: a = !0, className: i, onClick: s }) {
64
+ const n = e.title || e.siteName || e.url, c = l(A({ variant: t }), i), o = /* @__PURE__ */ (0, r.jsxs)(r.Fragment, { children: [
65
+ a && /* @__PURE__ */ (0, r.jsx)(m, {
66
66
  url: e.url,
67
67
  favicon: e.favicon
68
68
  }),
69
- /* @__PURE__ */ (0, t.jsx)("span", {
69
+ /* @__PURE__ */ (0, r.jsx)("span", {
70
70
  className: "truncate max-w-[200px]",
71
71
  children: n
72
72
  }),
73
- r === "default" && /* @__PURE__ */ (0, t.jsx)(h, {
73
+ t === "default" && /* @__PURE__ */ (0, r.jsx)(h, {
74
74
  className: "size-3 shrink-0",
75
75
  "aria-hidden": "true"
76
76
  })
77
77
  ] });
78
- return s ? /* @__PURE__ */ (0, t.jsx)("button", {
78
+ return s ? /* @__PURE__ */ (0, r.jsx)("button", {
79
79
  type: "button",
80
80
  "data-slot": "ai-source-trigger",
81
81
  onClick: s,
82
82
  className: c,
83
83
  "aria-label": `Source: ${n}`,
84
84
  children: o
85
- }) : /* @__PURE__ */ (0, t.jsx)("a", {
85
+ }) : /* @__PURE__ */ (0, r.jsx)("a", {
86
86
  "data-slot": "ai-source-trigger",
87
87
  href: e.url,
88
88
  target: "_blank",
@@ -93,7 +93,7 @@ function d({ source: e, variant: r, showFavicon: a = !0, className: i, onClick:
93
93
  });
94
94
  }
95
95
  d.displayName = "AISourceTrigger";
96
- function g({ source: e, className: r }) {
96
+ function g({ source: e, className: t }) {
97
97
  const a = u.useMemo(() => {
98
98
  try {
99
99
  return new URL(e.url).hostname;
@@ -101,85 +101,85 @@ function g({ source: e, className: r }) {
101
101
  return e.url;
102
102
  }
103
103
  }, [e.url]);
104
- return /* @__PURE__ */ (0, t.jsxs)("div", {
105
- className: l("p-3 max-w-xs space-y-2", r),
104
+ return /* @__PURE__ */ (0, r.jsxs)("div", {
105
+ className: l("p-3 max-w-xs space-y-2", t),
106
106
  children: [
107
- /* @__PURE__ */ (0, t.jsxs)("div", {
107
+ /* @__PURE__ */ (0, r.jsxs)("div", {
108
108
  className: "flex items-start gap-2",
109
- children: [/* @__PURE__ */ (0, t.jsx)(m, {
109
+ children: [/* @__PURE__ */ (0, r.jsx)(m, {
110
110
  url: e.url,
111
111
  favicon: e.favicon,
112
112
  className: "mt-0.5"
113
- }), /* @__PURE__ */ (0, t.jsxs)("div", {
113
+ }), /* @__PURE__ */ (0, r.jsxs)("div", {
114
114
  className: "flex-1 min-w-0",
115
- children: [/* @__PURE__ */ (0, t.jsx)("p", {
115
+ children: [/* @__PURE__ */ (0, r.jsx)("p", {
116
116
  className: "text-sm font-medium text-foreground truncate",
117
117
  children: e.title || a
118
- }), /* @__PURE__ */ (0, t.jsx)("p", {
118
+ }), /* @__PURE__ */ (0, r.jsx)("p", {
119
119
  className: "text-xs text-text-quaternary truncate",
120
120
  children: a
121
121
  })]
122
122
  })]
123
123
  }),
124
- e.description && /* @__PURE__ */ (0, t.jsx)("p", {
124
+ e.description && /* @__PURE__ */ (0, r.jsx)("p", {
125
125
  className: "text-xs text-muted-foreground line-clamp-2",
126
126
  children: e.description
127
127
  }),
128
- /* @__PURE__ */ (0, t.jsxs)("a", {
128
+ /* @__PURE__ */ (0, r.jsxs)("a", {
129
129
  href: e.url,
130
130
  target: "_blank",
131
131
  rel: "noopener noreferrer",
132
132
  className: "flex items-center gap-1 text-xs text-primary hover:text-primary",
133
- children: ["Visit source", /* @__PURE__ */ (0, t.jsx)(h, { className: "size-3" })]
133
+ children: ["Visit source", /* @__PURE__ */ (0, r.jsx)(h, { className: "size-3" })]
134
134
  })
135
135
  ]
136
136
  });
137
137
  }
138
138
  g.displayName = "AISourceContent";
139
- function v({ source: e, variant: r, showFavicon: a = !0, showTooltip: i = !0, className: s }) {
140
- return i ? /* @__PURE__ */ (0, t.jsxs)(M, { children: [/* @__PURE__ */ (0, t.jsx)(_, { render: /* @__PURE__ */ (0, t.jsx)("span", {
139
+ function v({ source: e, variant: t, showFavicon: a = !0, showTooltip: i = !0, className: s }) {
140
+ return i ? /* @__PURE__ */ (0, r.jsxs)(M, { children: [/* @__PURE__ */ (0, r.jsx)(_, { render: /* @__PURE__ */ (0, r.jsx)("span", {
141
141
  "data-slot": "ai-source",
142
- children: /* @__PURE__ */ (0, t.jsx)(d, {
142
+ children: /* @__PURE__ */ (0, r.jsx)(d, {
143
143
  source: e,
144
- variant: r,
144
+ variant: t,
145
145
  showFavicon: a,
146
146
  className: s
147
147
  })
148
- }) }), /* @__PURE__ */ (0, t.jsx)(S, {
148
+ }) }), /* @__PURE__ */ (0, r.jsx)(S, {
149
149
  side: "top",
150
150
  className: "p-0",
151
- children: /* @__PURE__ */ (0, t.jsx)(g, { source: e })
152
- })] }) : /* @__PURE__ */ (0, t.jsx)("span", {
151
+ children: /* @__PURE__ */ (0, r.jsx)(g, { source: e })
152
+ })] }) : /* @__PURE__ */ (0, r.jsx)("span", {
153
153
  "data-slot": "ai-source",
154
- children: /* @__PURE__ */ (0, t.jsx)(d, {
154
+ children: /* @__PURE__ */ (0, r.jsx)(d, {
155
155
  source: e,
156
- variant: r,
156
+ variant: t,
157
157
  showFavicon: a,
158
158
  className: s
159
159
  })
160
160
  });
161
161
  }
162
162
  v.displayName = "AISource";
163
- function L({ sources: e, maxVisible: r = 3, showAll: a = !1, onShowMore: i, className: s }) {
164
- const n = E(r), c = a ? e : e.slice(0, n), o = Math.max(0, e.length - n);
165
- return /* @__PURE__ */ (0, t.jsxs)("nav", {
163
+ function T({ sources: e, maxVisible: t = 3, showAll: a = !1, onShowMore: i, className: s }) {
164
+ const n = L(t), c = a ? e : e.slice(0, n), o = Math.max(0, e.length - n);
165
+ return /* @__PURE__ */ (0, r.jsxs)("nav", {
166
166
  "data-slot": "ai-source-list",
167
167
  "aria-label": "Sources",
168
168
  className: l("flex flex-wrap items-center gap-2", s),
169
169
  children: [
170
- /* @__PURE__ */ (0, t.jsx)("span", {
170
+ /* @__PURE__ */ (0, r.jsx)("span", {
171
171
  className: "text-xs text-text-quaternary",
172
172
  children: "Sources:"
173
173
  }),
174
- c.map((x, p) => /* @__PURE__ */ (0, t.jsx)("span", {
174
+ c.map((x, p) => /* @__PURE__ */ (0, r.jsx)("span", {
175
175
  className: "delight-stagger motion-reduce:!animate-none",
176
176
  style: { "--delight-delay": `${p * 50}ms` },
177
- children: /* @__PURE__ */ (0, t.jsx)(v, {
177
+ children: /* @__PURE__ */ (0, r.jsx)(v, {
178
178
  source: x,
179
179
  variant: "pill"
180
180
  })
181
181
  }, `${x.url}-${p}`)),
182
- !a && o > 0 && /* @__PURE__ */ (0, t.jsxs)("button", {
182
+ !a && o > 0 && /* @__PURE__ */ (0, r.jsxs)("button", {
183
183
  type: "button",
184
184
  onClick: i,
185
185
  "aria-label": `Show ${o} more sources`,
@@ -193,7 +193,7 @@ function L({ sources: e, maxVisible: r = 3, showAll: a = !1, onShowMore: i, clas
193
193
  ]
194
194
  });
195
195
  }
196
- L.displayName = "AISourceList";
196
+ T.displayName = "AISourceList";
197
197
  export {
198
198
  v as t
199
199
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AISource.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/external-link.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/globe.mjs","../../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n];\nconst ExternalLink = createLucideIcon(\"external-link\", __iconNode);\n\nexport { __iconNode, ExternalLink as default };\n//# sourceMappingURL=external-link.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n];\nconst Globe = createLucideIcon(\"globe\", __iconNode);\n\nexport { __iconNode, Globe as default };\n//# sourceMappingURL=globe.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-text-quaternary hover:text-secondary-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-text-quaternary truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-text-quaternary\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"AISource.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/external-link.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/globe.mjs","../../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n];\nconst ExternalLink = createLucideIcon(\"external-link\", __iconNode);\n\nexport { __iconNode, ExternalLink as default };\n//# sourceMappingURL=external-link.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n];\nconst Globe = createLucideIcon(\"globe\", __iconNode);\n\nexport { __iconNode, Globe as default };\n//# sourceMappingURL=globe.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-secondary-foreground hover:text-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-text-quaternary truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-text-quaternary\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -2,8 +2,8 @@ import { a as _ } from "./rolldown-runtime.js";
2
2
  import { i as A, t as O } from "./vendor/react.js";
3
3
  import { n as o } from "./utils.js";
4
4
  import { t as C } from "./createLucideIcon.js";
5
- import { t as q } from "./check.js";
6
- import { t as V } from "./chevron-down.js";
5
+ import { t as V } from "./check.js";
6
+ import { t as q } from "./chevron-down.js";
7
7
  import { t as H } from "./chevron-right.js";
8
8
  import { t as b } from "./circle-alert.js";
9
9
  import { t as L } from "./clock.js";
@@ -44,7 +44,7 @@ function w({ status: e, className: a }) {
44
44
  case "running":
45
45
  return /* @__PURE__ */ (0, s.jsx)(L, { className: t });
46
46
  case "success":
47
- return /* @__PURE__ */ (0, s.jsx)(q, { className: o(t, "delight-check-bounce motion-reduce:!animate-none") });
47
+ return /* @__PURE__ */ (0, s.jsx)(V, { className: o(t, "delight-check-bounce motion-reduce:!animate-none") });
48
48
  case "error":
49
49
  return /* @__PURE__ */ (0, s.jsx)(b, { className: o(t, "delight-shake motion-reduce:!animate-none") });
50
50
  default:
@@ -69,7 +69,7 @@ function T({ toolName: e, status: a, isOpen: t, onToggle: n, className: c }) {
69
69
  className: "text-sm font-medium text-foreground",
70
70
  children: e
71
71
  }), /* @__PURE__ */ (0, s.jsx)("span", {
72
- className: "text-xs text-text-quaternary",
72
+ className: "text-xs text-secondary-foreground",
73
73
  children: {
74
74
  pending: "Pending",
75
75
  running: "Running...",
@@ -78,7 +78,7 @@ function T({ toolName: e, status: a, isOpen: t, onToggle: n, className: c }) {
78
78
  }[a]
79
79
  })]
80
80
  })]
81
- }), t ? /* @__PURE__ */ (0, s.jsx)(V, {
81
+ }), t ? /* @__PURE__ */ (0, s.jsx)(q, {
82
82
  className: "size-4 text-muted-foreground",
83
83
  "aria-hidden": "true"
84
84
  }) : /* @__PURE__ */ (0, s.jsx)(H, {
@@ -185,7 +185,7 @@ function W(e, a) {
185
185
  return e.length === a.length && e.every((t, n) => t === a[n]);
186
186
  }
187
187
  function $({ toolCalls: e, defaultAllOpen: a = !1, defaultOpenToolCallIds: t = [], openToolCallIds: n, onOpenToolCallIdsChange: c, className: d }) {
188
- const i = n !== void 0, [u, m] = N.useState(() => p(a ? e.map((r) => r.toolCallId) : t, e)), h = p(i ? n : u, e), z = new Set(h);
188
+ const i = n !== void 0, [u, m] = N.useState(() => p(a ? e.map((r) => r.toolCallId) : t, e)), g = p(i ? n : u, e), z = new Set(g);
189
189
  N.useLayoutEffect(() => {
190
190
  i || m((r) => {
191
191
  const l = p(r, e);
@@ -193,10 +193,10 @@ function $({ toolCalls: e, defaultAllOpen: a = !1, defaultOpenToolCallIds: t = [
193
193
  });
194
194
  }, [i, e]);
195
195
  const S = (r, l) => {
196
- const x = new Set(h);
196
+ const x = new Set(g);
197
197
  l ? x.add(r) : x.delete(r);
198
- const g = p([...x], e);
199
- i || m(g), c?.([...g]);
198
+ const h = p([...x], e);
199
+ i || m(h), c?.([...h]);
200
200
  };
201
201
  return /* @__PURE__ */ (0, s.jsx)("div", {
202
202
  "data-slot": "ai-tool-call-list",
@@ -1 +1 @@
1
- {"version":3,"file":"AIToolCall.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/code.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n];\nconst Code = createLucideIcon(\"code\", __iconNode);\n\nexport { __iconNode, Code as default };\n//# sourceMappingURL=code.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-text-quaternary\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":";;;;;;;;;;;;;;AASA,IAAMA,IAAa,CACjB,CAAC,QAAQ;AAAA,EAAE,GAAG;AAAA,EAAkB,KAAK;AAAQ,CAAC,GAC9C,CAAC,QAAQ;AAAA,EAAE,GAAG;AAAA,EAAgB,KAAK;AAAS,CAAC,CAC/C,GACM,IAAO,EAAiB,QAAQA,CAAU,GCJ1C,IAAa,CACjB,CACE,QACA;AAAA,EACE,GAAG;AAAA,EACH,KAAK;AACP,CACF,CACF,GACM,IAAS,EAAiB,UAAU,CAAU,2CCE9C,IAAmB,EACvB,uDACA;AAAA,EACE,UAAU,EACR,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EACT,EACF;AAAA,EACA,iBAAiB,EACf,QAAQ,UACV;AACF,CACF,GAEM,IAAqB,EAAI,UAAU;AAAA,EACvC,UAAU,EACR,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EACT,EACF;AAAA,EACA,iBAAiB,EACf,QAAQ,UACV;AACF,CAAC;AAgCD,SAAS,EAAW,EAAE,QAAA,GAAQ,WAAA,EAAA,GAA8B;AAC1D,QAAM,IAAY,EAAG,EAAmB,EAAE,QAAA,EAAO,CAAC,GAAG,CAAS;AAE9D,UAAQ,GAAR;AAAA,IACE,KAAK;AACH,aAAO,oBAAA,EAAA,KAAC,GAAD,EAAO,WAAW,EAAY,CAAA;AAAA,IACvC,KAAK;AACH,aACE,oBAAA,EAAA,KAAC,GAAD,EACE,WAAW,EACT,GACA,kDACF,EACD,CAAA;AAAA,IAEL,KAAK;AACH,aACE,oBAAA,EAAA,KAAC,GAAD,EACE,WAAW,EAAG,GAAW,2CAA2C,EACrE,CAAA;AAAA,IAEL;AACE,aAAO,oBAAA,EAAA,KAAC,GAAD,EAAQ,WAAW,EAAY,CAAA;AAAA,EAC1C;AACF;AAEA,EAAW,cAAc;AAczB,SAAS,EAAiB,EACxB,UAAA,GACA,QAAA,GACA,QAAA,GACA,UAAA,GACA,WAAA,EAAA,GACwB;AAQxB,SACE,oBAAA,EAAA,MAAC,UAAD;AAAA,IACE,MAAK;AAAA,IACL,SAAS;AAAA,IACT,iBAAe;AAAA,IACf,WAAW,EACT,qLACA,CACF;AAAA,cAPF,CASE,oBAAA,EAAA,MAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACE,oBAAA,EAAA,KAAC,GAAD;AAAA,QAAoB,QAAA;AAAA,QAAQ,eAAY;AAAA,MAAQ,CAAA,GAChD,oBAAA,EAAA,MAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf,CACE,oBAAA,EAAA,KAAC,QAAD;AAAA,UAAM,WAAU;AAAA,oBACb;AAAA,QACG,CAAA,GACN,oBAAA,EAAA,KAAC,QAAD;AAAA,UAAM,WAAU;AAAA,oBACb;AAAA,YAvBT,SAAS;AAAA,YACT,SAAS;AAAA,YACT,SAAS;AAAA,YACT,OAAO;AAAA,UAoBE,EAAY,CAAA;AAAA,QACT,CAAA,CACH;AAAA,QACF;AAAA,QACJ,IACC,oBAAA,EAAA,KAAC,GAAD;AAAA,MACE,WAAU;AAAA,MACV,eAAY;AAAA,IACb,CAAA,IAED,oBAAA,EAAA,KAAC,GAAD;AAAA,MACE,WAAU;AAAA,MACV,eAAY;AAAA,IACb,CAAA,CAEG;AAAA;AAEZ;AAEA,EAAiB,cAAc;AAa/B,SAAS,EAAgB,EACvB,OAAA,GACA,MAAA,GACA,UAAA,GACA,WAAA,EAAA,GACuB;AACvB,SACE,oBAAA,EAAA,MAAC,OAAD;AAAA,IAAK,WAAW,EAAG,aAAa,CAAS;AAAA,cAAzC,CACE,oBAAA,EAAA,MAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACG,GACA,CACE;AAAA,QACJ,CACE;AAAA;AAET;AAEA,EAAgB,cAAc;AAmB9B,SAAS,EAAY,GAAwB;AAC3C,SAAI,OAAO,KAAU,WAAiB,IAC/B,KAAK,UAAU,GAAO,MAAM,CAAC;AACtC;AAEA,SAAS,EAAW,EAClB,UAAA,GACA,aAAA,IAAc,IACd,MAAM,GACN,cAAA,GACA,WAAA,EAAA,GACkB;AAClB,QAAM,CAAC,GAAQ,CAAA,IAAa,EAAqB;AAAA,IAC/C,OAAO;AAAA,IACP,cAAc;AAAA,IACd,UAAU;AAAA,EACZ,CAAC,GAEK,IAAS,EAAS,UAAU,WAE5B,IAAA,MAAqB;AACzB,IAAA,EAAU,CAAC,CAAM;AAAA,EACnB;AAEA,SACE,oBAAA,EAAA,MAAC,OAAD;AAAA,IACE,aAAU;AAAA,IACV,WAAW,EAAG,EAAiB,EAAE,QAAA,EAAO,CAAC,GAAG,CAAS;AAAA,cAFvD,CAIE,oBAAA,EAAA,KAAC,GAAD;AAAA,MACE,UAAU,EAAS;AAAA,MACX,QAAA;AAAA,MACA,QAAA;AAAA,MACR,UAAU;AAAA,IACX,CAAA,GAED,oBAAA,EAAA,KAAC,GAAD,EAAA,UACG,KACC,oBAAA,EAAA,KAAC,EAAO,KAAR;AAAA,MACE,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MACjC,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,MAAE;AAAA,MACtC,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MAC9B,YAAY,EAAE,UAAU,IAAI;AAAA,MAC5B,WAAU;AAAA,gBAEV,oBAAA,EAAA,MAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf;AAAA,UAEE,oBAAA,EAAA,MAAC,OAAD;AAAA,YAAK,WAAU;AAAA,sBAAf,CAAyD,QAClD,EAAS,UACX;AAAA;UAGJ,EAAS,QAAQ,OAAO,KAAK,EAAS,IAAI,EAAE,SAAS,KACpD,oBAAA,EAAA,KAAC,GAAD;AAAA,YACE,OAAM;AAAA,YACN,MAAM,oBAAA,EAAA,KAAC,GAAD,EAAM,WAAU,SAAU,CAAA;AAAA,sBAEhC,oBAAA,EAAA,KAAC,GAAD;AAAA,cACE,MAAM,EAAY,EAAS,IAAI;AAAA,cAC/B,UAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,MAAK;AAAA,YACN,CAAA;AAAA,UACc,CAAA;AAAA,UAIlB,EAAS,WAAW,UACnB,oBAAA,EAAA,KAAC,GAAD;AAAA,YACE,OAAM;AAAA,YACN,MAAM,oBAAA,EAAA,KAAC,GAAD,EAAM,WAAU,SAAU,CAAA;AAAA,sBAEhC,oBAAA,EAAA,KAAC,GAAD;AAAA,cACE,MAAM,EAAY,EAAS,MAAM;AAAA,cACjC,UAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,MAAK;AAAA,YACN,CAAA;AAAA,UACc,CAAA;AAAA,UAIlB,EAAS,SACR,oBAAA,EAAA,KAAC,OAAD;AAAA,YAAK,WAAU;AAAA,sBACb,oBAAA,EAAA,MAAC,OAAD;AAAA,cAAK,WAAU;AAAA,wBAAf,CACE,oBAAA,EAAA,KAAC,GAAD,EAAa,WAAU,0CAA2C,CAAA,GAClE,oBAAA,EAAA,KAAC,KAAD;AAAA,gBAAG,WAAU;AAAA,0BAA4B,EAAS;AAAA,cAAS,CAAA,CACxD;AAAA;UACF,CAAA;AAAA,QAEJ;AAAA;IACK,CAAA,EAEC,CAAA,CACd;AAAA;AAET;AAEA,EAAW,cAAc;AAqBzB,SAAS,EACP,GACA,GACU;AACV,QAAM,IAAY,IAAI,IAAI,CAAG;AAC7B,SAAO,EAAU,QAAA,CAAS,MACxB,EAAU,IAAI,EAAS,UAAU,IAAI,CAAC,EAAS,UAAU,IAAI,CAAC,CAChE;AACF;AAEA,SAAS,EACP,GACA,GACS;AACT,SACE,EAAK,WAAW,EAAM,UACtB,EAAK,MAAA,CAAO,GAAI,MAAU,MAAO,EAAM,CAAA,CAAM;AAEjD;AAEA,SAAS,EAAe,EACtB,WAAA,GACA,gBAAA,IAAiB,IACjB,wBAAA,IAAyB,CAAC,GAC1B,iBAAiB,GACjB,yBAAA,GACA,WAAA,EAAA,GACsB;AACtB,QAAM,IAAe,MAA8B,QAC7C,CAAC,GAA6B,CAAA,IAAA,EAC5B,SAAA,MACJ,EACE,IACI,EAAU,IAAA,CAAK,MAAa,EAAS,UAAU,IAC/C,GACJ,CACF,CACF,GAII,IAAyB,EAHJ,IACvB,IACA,GAGF,CACF,GACM,IAAU,IAAI,IAAI,CAAsB;AAE9C,EAAA,EAAM,gBAAA,MAAsB;AAC1B,IAAI,KACJ,EAAA,CAAgC,MAAY;AAC1C,YAAM,IAAa,EAAyB,GAAS,CAAS;AAC9D,aAAO,EAAoB,GAAS,CAAU,IAAI,IAAU;AAAA,IAC9D,CAAC;AAAA,EACH,GAAG,CAAC,GAAc,CAAS,CAAC;AAE5B,QAAM,IAAA,CAAmB,GAAoB,MAAkB;AAC7D,UAAM,IAAO,IAAI,IAAI,CAAsB;AAC3C,IAAI,IAAM,EAAK,IAAI,CAAU,IACxB,EAAK,OAAO,CAAU;AAC3B,UAAM,IAAa,EAAyB,CAAC,GAAG,CAAI,GAAG,CAAS;AAChE,IAAK,KACH,EAA+B,CAAU,GAE3C,IAA0B,CAAC,GAAG,CAAU,CAAC;AAAA,EAC3C;AAEA,SACE,oBAAA,EAAA,KAAC,OAAD;AAAA,IAAK,aAAU;AAAA,IAAoB,WAAW,EAAG,aAAa,CAAS;AAAA,cACpE,EAAU,IAAA,CAAK,MACd,oBAAA,EAAA,KAAC,GAAD;AAAA,MAEE,UAAU;AAAA,MACV,MAAM,EAAQ,IAAI,EAAS,UAAU;AAAA,MACrC,cAAA,CAAe,MAAS,EAAgB,EAAS,YAAY,CAAI;AAAA,IAClE,GAJM,EAAS,UAIf,CACF;AAAA,EACE,CAAA;AAET;AAEA,EAAe,cAAc"}
1
+ {"version":3,"file":"AIToolCall.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/code.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n];\nconst Code = createLucideIcon(\"code\", __iconNode);\n\nexport { __iconNode, Code as default };\n//# sourceMappingURL=code.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-secondary-foreground\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -587,7 +587,7 @@ var ua = Object.assign(P, {
587
587
  Trigger: $,
588
588
  NavSkeleton: ce,
589
589
  AccountSkeleton: be
590
- }), ca = "280px", ba = "116px";
590
+ }), ca = "280px", ba = "68px";
591
591
  export {
592
592
  Ve as _,
593
593
  ee as a,