@lssm/module.ai-chat 0.0.0-canary-20251217062139 → 0.0.0-canary-20251217072406

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 (48) hide show
  1. package/dist/ai-chat.feature.js +93 -1
  2. package/dist/context/context-builder.js +147 -2
  3. package/dist/context/file-operations.js +174 -1
  4. package/dist/context/index.js +5 -1
  5. package/dist/context/workspace-context.js +123 -2
  6. package/dist/core/chat-service.js +211 -2
  7. package/dist/core/conversation-store.js +108 -1
  8. package/dist/core/index.js +4 -1
  9. package/dist/index.js +22 -1
  10. package/dist/libs/ai-providers/dist/factory.js +225 -1
  11. package/dist/libs/ai-providers/dist/index.js +4 -1
  12. package/dist/libs/ai-providers/dist/legacy.js +2 -1
  13. package/dist/libs/ai-providers/dist/models.js +299 -1
  14. package/dist/libs/ai-providers/dist/validation.js +60 -1
  15. package/dist/libs/design-system/dist/_virtual/rolldown_runtime.js +5 -1
  16. package/dist/libs/design-system/dist/components/atoms/Button.js +33 -1
  17. package/dist/libs/design-system/dist/components/atoms/Textarea.js +35 -1
  18. package/dist/libs/design-system/dist/lib/keyboard.js +193 -1
  19. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/button.js +55 -1
  20. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/textarea.js +16 -1
  21. package/dist/libs/design-system/dist/ui-kit-web/dist/ui-kit-core/dist/utils.js +13 -1
  22. package/dist/libs/ui-kit-web/dist/ui/avatar.js +25 -1
  23. package/dist/libs/ui-kit-web/dist/ui/badge.js +26 -1
  24. package/dist/libs/ui-kit-web/dist/ui/scroll-area.js +39 -1
  25. package/dist/libs/ui-kit-web/dist/ui/select.js +79 -1
  26. package/dist/libs/ui-kit-web/dist/ui/skeleton.js +14 -1
  27. package/dist/libs/ui-kit-web/dist/ui/tooltip.js +39 -1
  28. package/dist/libs/ui-kit-web/dist/ui/utils.js +10 -1
  29. package/dist/libs/ui-kit-web/dist/ui-kit-core/dist/utils.js +10 -1
  30. package/dist/presentation/components/ChatContainer.js +62 -1
  31. package/dist/presentation/components/ChatInput.d.ts +2 -2
  32. package/dist/presentation/components/ChatInput.js +149 -1
  33. package/dist/presentation/components/ChatMessage.d.ts +2 -2
  34. package/dist/presentation/components/ChatMessage.js +135 -1
  35. package/dist/presentation/components/CodePreview.d.ts +2 -2
  36. package/dist/presentation/components/CodePreview.js +126 -2
  37. package/dist/presentation/components/ContextIndicator.d.ts +2 -2
  38. package/dist/presentation/components/ContextIndicator.js +96 -1
  39. package/dist/presentation/components/ModelPicker.d.ts +2 -2
  40. package/dist/presentation/components/ModelPicker.js +197 -1
  41. package/dist/presentation/components/index.js +8 -1
  42. package/dist/presentation/hooks/index.js +4 -1
  43. package/dist/presentation/hooks/useChat.js +171 -1
  44. package/dist/presentation/hooks/useProviders.js +42 -1
  45. package/dist/presentation/index.js +12 -1
  46. package/dist/providers/chat-utilities.js +16 -1
  47. package/dist/providers/index.js +7 -1
  48. package/package.json +10 -10
@@ -1 +1,55 @@
1
- import{cn as e,init_utils as t}from"../ui-kit-core/dist/utils.js";import*as n from"react";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";import{Slot as a}from"@radix-ui/react-slot";t();const o=i(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-hidden focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-2xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`}},defaultVariants:{variant:`default`,size:`default`}}),s=n.forwardRef(({className:t,variant:n,size:i,asChild:s=!1,...c},l)=>s?r(a,{"data-slot":`button`,className:e(o({variant:n,size:i,className:t})),...c}):r(`button`,{ref:l,"data-slot":`button`,className:e(o({variant:n,size:i,className:t})),...c}));s.displayName=`Button`;export{s as Button};
1
+ import { cn, init_utils } from "../ui-kit-core/dist/utils.js";
2
+ import * as React$1 from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { cva } from "class-variance-authority";
5
+ import { Slot } from "@radix-ui/react-slot";
6
+
7
+ //#region ../../libs/design-system/dist/ui-kit-web/dist/ui/button.js
8
+ init_utils();
9
+ const buttonVariants = cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-hidden focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
14
+ outline: "border bg-background shadow-2xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
15
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
16
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
17
+ link: "text-primary underline-offset-4 hover:underline"
18
+ },
19
+ size: {
20
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
21
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
22
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
23
+ icon: "size-9"
24
+ }
25
+ },
26
+ defaultVariants: {
27
+ variant: "default",
28
+ size: "default"
29
+ }
30
+ });
31
+ const Button = React$1.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
32
+ if (asChild) return /* @__PURE__ */ jsx(Slot, {
33
+ "data-slot": "button",
34
+ className: cn(buttonVariants({
35
+ variant,
36
+ size,
37
+ className
38
+ })),
39
+ ...props
40
+ });
41
+ return /* @__PURE__ */ jsx("button", {
42
+ ref,
43
+ "data-slot": "button",
44
+ className: cn(buttonVariants({
45
+ variant,
46
+ size,
47
+ className
48
+ })),
49
+ ...props
50
+ });
51
+ });
52
+ Button.displayName = "Button";
53
+
54
+ //#endregion
55
+ export { Button };
@@ -1 +1,16 @@
1
- import{cn as e,init_utils as t}from"../ui-kit-core/dist/utils.js";import"react";import{jsx as n}from"react/jsx-runtime";t();function r({className:t,...r}){return n(`textarea`,{"data-slot":`textarea`,className:e(`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-2xs outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,t),...r})}export{r as Textarea};
1
+ import { cn, init_utils } from "../ui-kit-core/dist/utils.js";
2
+ import "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region ../../libs/design-system/dist/ui-kit-web/dist/ui/textarea.js
6
+ init_utils();
7
+ function Textarea({ className, ...props }) {
8
+ return /* @__PURE__ */ jsx("textarea", {
9
+ "data-slot": "textarea",
10
+ className: cn("aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-2xs outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className),
11
+ ...props
12
+ });
13
+ }
14
+
15
+ //#endregion
16
+ export { Textarea };
@@ -1 +1,13 @@
1
- import{__esmMin as e}from"../../../../_virtual/rolldown_runtime.js";import{clsx as t}from"clsx";import{twMerge as n}from"tailwind-merge";function r(...e){return n(t(e))}var i=e((()=>{}));i();export{r as cn,i as init_utils};
1
+ import { __esmMin } from "../../../../_virtual/rolldown_runtime.js";
2
+ import { clsx } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+
5
+ //#region ../../libs/design-system/dist/ui-kit-web/dist/ui-kit-core/dist/utils.js
6
+ function cn(...inputs) {
7
+ return twMerge(clsx(inputs));
8
+ }
9
+ var init_utils = __esmMin((() => {}));
10
+ init_utils();
11
+
12
+ //#endregion
13
+ export { cn, init_utils };
@@ -1 +1,25 @@
1
- "use client";import{cn as e}from"./utils.js";import"react";import{jsx as t}from"react/jsx-runtime";import*as n from"@radix-ui/react-avatar";function r({className:r,...i}){return t(n.Root,{"data-slot":`avatar`,className:e(`relative flex size-8 shrink-0 overflow-hidden rounded-full`,r),...i})}function i({className:r,...i}){return t(n.Fallback,{"data-slot":`avatar-fallback`,className:e(`bg-muted flex size-full items-center justify-center rounded-full`,r),...i})}export{r as Avatar,i as AvatarFallback};
1
+ 'use client';
2
+
3
+ import { cn } from "./utils.js";
4
+ import "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
7
+
8
+ //#region ../../libs/ui-kit-web/dist/ui/avatar.js
9
+ function Avatar({ className, ...props }) {
10
+ return /* @__PURE__ */ jsx(AvatarPrimitive.Root, {
11
+ "data-slot": "avatar",
12
+ className: cn("relative flex size-8 shrink-0 overflow-hidden rounded-full", className),
13
+ ...props
14
+ });
15
+ }
16
+ function AvatarFallback({ className, ...props }) {
17
+ return /* @__PURE__ */ jsx(AvatarPrimitive.Fallback, {
18
+ "data-slot": "avatar-fallback",
19
+ className: cn("bg-muted flex size-full items-center justify-center rounded-full", className),
20
+ ...props
21
+ });
22
+ }
23
+
24
+ //#endregion
25
+ export { Avatar, AvatarFallback };
@@ -1 +1,26 @@
1
- import{cn as e}from"../ui-kit-core/dist/utils.js";import"react";import{jsx as t}from"react/jsx-runtime";import{cva as n}from"class-variance-authority";import{Slot as r}from"@radix-ui/react-slot";const i=n(`inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90`,secondary:`border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90`,destructive:`border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground`}},defaultVariants:{variant:`default`}});function a({className:n,variant:a,asChild:o=!1,...s}){return t(o?r:`span`,{"data-slot":`badge`,className:e(i({variant:a}),n),...s})}export{a as Badge};
1
+ import { cn } from "../ui-kit-core/dist/utils.js";
2
+ import "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { cva } from "class-variance-authority";
5
+ import { Slot } from "@radix-ui/react-slot";
6
+
7
+ //#region ../../libs/ui-kit-web/dist/ui/badge.js
8
+ const badgeVariants = cva("inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", {
9
+ variants: { variant: {
10
+ default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
11
+ secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
12
+ destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
13
+ outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
14
+ } },
15
+ defaultVariants: { variant: "default" }
16
+ });
17
+ function Badge({ className, variant, asChild = false, ...props }) {
18
+ return /* @__PURE__ */ jsx(asChild ? Slot : "span", {
19
+ "data-slot": "badge",
20
+ className: cn(badgeVariants({ variant }), className),
21
+ ...props
22
+ });
23
+ }
24
+
25
+ //#endregion
26
+ export { Badge };
@@ -1 +1,39 @@
1
- "use client";import{cn as e}from"../ui-kit-core/dist/utils.js";import"react";import{jsx as t,jsxs as n}from"react/jsx-runtime";import*as r from"@radix-ui/react-scroll-area";function i({className:i,children:o,...s}){return n(r.Root,{"data-slot":`scroll-area`,className:e(`relative`,i),...s,children:[t(r.Viewport,{"data-slot":`scroll-area-viewport`,className:`focus-visible:ring-ring/50 size-full rounded-[inherit] outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1`,children:o}),t(a,{}),t(r.Corner,{})]})}function a({className:n,orientation:i=`vertical`,...a}){return t(r.ScrollAreaScrollbar,{"data-slot":`scroll-area-scrollbar`,orientation:i,className:e(`flex touch-none p-px transition-colors select-none`,i===`vertical`&&`h-full w-2.5 border-l border-l-transparent`,i===`horizontal`&&`h-2.5 flex-col border-t border-t-transparent`,n),...a,children:t(r.ScrollAreaThumb,{"data-slot":`scroll-area-thumb`,className:`bg-border relative flex-1 rounded-full`})})}export{i as ScrollArea};
1
+ 'use client';
2
+
3
+ import { cn } from "../ui-kit-core/dist/utils.js";
4
+ import "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
7
+
8
+ //#region ../../libs/ui-kit-web/dist/ui/scroll-area.js
9
+ function ScrollArea({ className, children, ...props }) {
10
+ return /* @__PURE__ */ jsxs(ScrollAreaPrimitive.Root, {
11
+ "data-slot": "scroll-area",
12
+ className: cn("relative", className),
13
+ ...props,
14
+ children: [
15
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, {
16
+ "data-slot": "scroll-area-viewport",
17
+ className: "focus-visible:ring-ring/50 size-full rounded-[inherit] outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1",
18
+ children
19
+ }),
20
+ /* @__PURE__ */ jsx(ScrollBar, {}),
21
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
22
+ ]
23
+ });
24
+ }
25
+ function ScrollBar({ className, orientation = "vertical", ...props }) {
26
+ return /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, {
27
+ "data-slot": "scroll-area-scrollbar",
28
+ orientation,
29
+ className: cn("flex touch-none p-px transition-colors select-none", orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent", orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent", className),
30
+ ...props,
31
+ children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, {
32
+ "data-slot": "scroll-area-thumb",
33
+ className: "bg-border relative flex-1 rounded-full"
34
+ })
35
+ });
36
+ }
37
+
38
+ //#endregion
39
+ export { ScrollArea };
@@ -1 +1,79 @@
1
- "use client";import{cn as e}from"../ui-kit-core/dist/utils.js";import"react";import{jsx as t,jsxs as n}from"react/jsx-runtime";import{CheckIcon as r,ChevronDownIcon as i,ChevronUpIcon as a}from"lucide-react";import*as o from"@radix-ui/react-select";function s({...e}){return t(o.Root,{"data-slot":`select`,...e})}function c({...e}){return t(o.Value,{"data-slot":`select-value`,...e})}function l({className:r,size:a=`default`,children:s,...c}){return n(o.Trigger,{"data-slot":`select-trigger`,"data-size":a,className:e(`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border-input focus-visible:border-ring focus-visible:ring-ring/50 data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-2xs outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,r),...c,children:[s,t(o.Icon,{asChild:!0,children:t(i,{className:`size-4 opacity-50`})})]})}function u({className:r,children:i,position:a=`popper`,...s}){return t(o.Portal,{children:n(o.Content,{"data-slot":`select-content`,className:e(`bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-32 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md`,a===`popper`&&`data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,r),position:a,...s,children:[t(f,{}),t(o.Viewport,{className:e(`p-1`,a===`popper`&&`h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width) scroll-my-1`),children:i}),t(p,{})]})})}function d({className:i,children:a,...s}){return n(o.Item,{"data-slot":`select-item`,className:e(`focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-xs py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,i),...s,children:[t(`span`,{className:`absolute right-2 flex size-3.5 items-center justify-center`,children:t(o.ItemIndicator,{children:t(r,{className:`size-4`})})}),t(o.ItemText,{children:a})]})}function f({className:n,...r}){return t(o.ScrollUpButton,{"data-slot":`select-scroll-up-button`,className:e(`flex cursor-default items-center justify-center py-1`,n),...r,children:t(a,{className:`size-4`})})}function p({className:n,...r}){return t(o.ScrollDownButton,{"data-slot":`select-scroll-down-button`,className:e(`flex cursor-default items-center justify-center py-1`,n),...r,children:t(i,{className:`size-4`})})}export{s as Select,u as SelectContent,d as SelectItem,l as SelectTrigger,c as SelectValue};
1
+ 'use client';
2
+
3
+ import { cn } from "../ui-kit-core/dist/utils.js";
4
+ import "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
7
+ import * as SelectPrimitive from "@radix-ui/react-select";
8
+
9
+ //#region ../../libs/ui-kit-web/dist/ui/select.js
10
+ function Select({ ...props }) {
11
+ return /* @__PURE__ */ jsx(SelectPrimitive.Root, {
12
+ "data-slot": "select",
13
+ ...props
14
+ });
15
+ }
16
+ function SelectValue({ ...props }) {
17
+ return /* @__PURE__ */ jsx(SelectPrimitive.Value, {
18
+ "data-slot": "select-value",
19
+ ...props
20
+ });
21
+ }
22
+ function SelectTrigger({ className, size = "default", children, ...props }) {
23
+ return /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
24
+ "data-slot": "select-trigger",
25
+ "data-size": size,
26
+ className: cn("aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border-input focus-visible:border-ring focus-visible:ring-ring/50 data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-2xs outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
27
+ ...props,
28
+ children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
29
+ asChild: true,
30
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" })
31
+ })]
32
+ });
33
+ }
34
+ function SelectContent({ className, children, position = "popper", ...props }) {
35
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
36
+ "data-slot": "select-content",
37
+ className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-32 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
38
+ position,
39
+ ...props,
40
+ children: [
41
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
42
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
43
+ className: cn("p-1", position === "popper" && "h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width) scroll-my-1"),
44
+ children
45
+ }),
46
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
47
+ ]
48
+ }) });
49
+ }
50
+ function SelectItem({ className, children, ...props }) {
51
+ return /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
52
+ "data-slot": "select-item",
53
+ className: cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-xs py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
54
+ ...props,
55
+ children: [/* @__PURE__ */ jsx("span", {
56
+ className: "absolute right-2 flex size-3.5 items-center justify-center",
57
+ children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
58
+ }), /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })]
59
+ });
60
+ }
61
+ function SelectScrollUpButton({ className, ...props }) {
62
+ return /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, {
63
+ "data-slot": "select-scroll-up-button",
64
+ className: cn("flex cursor-default items-center justify-center py-1", className),
65
+ ...props,
66
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
67
+ });
68
+ }
69
+ function SelectScrollDownButton({ className, ...props }) {
70
+ return /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, {
71
+ "data-slot": "select-scroll-down-button",
72
+ className: cn("flex cursor-default items-center justify-center py-1", className),
73
+ ...props,
74
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
75
+ });
76
+ }
77
+
78
+ //#endregion
79
+ export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue };
@@ -1 +1,14 @@
1
- import{cn as e}from"./utils.js";import{jsx as t}from"react/jsx-runtime";function n({className:n,...r}){return t(`div`,{"data-slot":`skeleton`,className:e(`bg-accent animate-pulse rounded-md`,n),...r})}export{n as Skeleton};
1
+ import { cn } from "./utils.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+
4
+ //#region ../../libs/ui-kit-web/dist/ui/skeleton.js
5
+ function Skeleton({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx("div", {
7
+ "data-slot": "skeleton",
8
+ className: cn("bg-accent animate-pulse rounded-md", className),
9
+ ...props
10
+ });
11
+ }
12
+
13
+ //#endregion
14
+ export { Skeleton };
@@ -1 +1,39 @@
1
- "use client";import{cn as e}from"../ui-kit-core/dist/utils.js";import"react";import{jsx as t,jsxs as n}from"react/jsx-runtime";import*as r from"@radix-ui/react-tooltip";function i({delayDuration:e=0,...n}){return t(r.Provider,{"data-slot":`tooltip-provider`,delayDuration:e,...n})}function a({...e}){return t(i,{children:t(r.Root,{"data-slot":`tooltip`,...e})})}function o({...e}){return t(r.Trigger,{"data-slot":`tooltip-trigger`,...e})}function s({className:i,sideOffset:a=0,children:o,...s}){return t(r.Portal,{children:n(r.Content,{"data-slot":`tooltip-content`,sideOffset:a,className:e(`bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance`,i),...s,children:[o,t(r.Arrow,{className:`bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]`})]})})}export{a as Tooltip,s as TooltipContent,i as TooltipProvider,o as TooltipTrigger};
1
+ 'use client';
2
+
3
+ import { cn } from "../ui-kit-core/dist/utils.js";
4
+ import "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
7
+
8
+ //#region ../../libs/ui-kit-web/dist/ui/tooltip.js
9
+ function TooltipProvider({ delayDuration = 0, ...props }) {
10
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, {
11
+ "data-slot": "tooltip-provider",
12
+ delayDuration,
13
+ ...props
14
+ });
15
+ }
16
+ function Tooltip({ ...props }) {
17
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, {
18
+ "data-slot": "tooltip",
19
+ ...props
20
+ }) });
21
+ }
22
+ function TooltipTrigger({ ...props }) {
23
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, {
24
+ "data-slot": "tooltip-trigger",
25
+ ...props
26
+ });
27
+ }
28
+ function TooltipContent({ className, sideOffset = 0, children, ...props }) {
29
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(TooltipPrimitive.Content, {
30
+ "data-slot": "tooltip-content",
31
+ sideOffset,
32
+ className: cn("bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", className),
33
+ ...props,
34
+ children: [children, /* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]" })]
35
+ }) });
36
+ }
37
+
38
+ //#endregion
39
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
@@ -1 +1,10 @@
1
- import{clsx as e}from"clsx";import{twMerge as t}from"tailwind-merge";function n(...n){return t(e(n))}export{n as cn};
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ //#region ../../libs/ui-kit-web/dist/ui/utils.js
5
+ function cn(...inputs) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ //#endregion
10
+ export { cn };
@@ -1 +1,10 @@
1
- import{clsx as e}from"clsx";import{twMerge as t}from"tailwind-merge";function n(...n){return t(e(n))}export{n as cn};
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ //#region ../../libs/ui-kit-web/dist/ui-kit-core/dist/utils.js
5
+ function cn(...inputs) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ //#endregion
10
+ export { cn };
@@ -1 +1,62 @@
1
- "use client";import{ScrollArea as e}from"../../libs/ui-kit-web/dist/ui/scroll-area.js";import{cn as t}from"../../libs/ui-kit-web/dist/ui/utils.js";import*as n from"react";import{jsx as r,jsxs as i}from"react/jsx-runtime";function a({children:a,className:o,showScrollButton:s=!0}){let c=n.useRef(null),[l,u]=n.useState(!1);n.useEffect(()=>{let e=c.current;e&&e.scrollHeight-e.scrollTop<=e.clientHeight+100&&(e.scrollTop=e.scrollHeight)},[a]);let d=n.useCallback(e=>{let t=e.currentTarget;u(!(t.scrollHeight-t.scrollTop<=t.clientHeight+100))},[]),f=n.useCallback(()=>{let e=c.current;e&&e.scrollTo({top:e.scrollHeight,behavior:`smooth`})},[]);return i(`div`,{className:t(`relative flex flex-1 flex-col`,o),children:[r(e,{ref:c,className:`flex-1`,onScroll:d,children:r(`div`,{className:`flex flex-col gap-4 p-4`,children:a})}),s&&l&&i(`button`,{onClick:f,className:t(`absolute bottom-4 left-1/2 -translate-x-1/2`,`bg-primary text-primary-foreground`,`rounded-full px-3 py-1.5 text-sm font-medium shadow-lg`,`hover:bg-primary/90 transition-colors`,`flex items-center gap-1.5`),"aria-label":`Scroll to bottom`,children:[r(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:r(`path`,{d:`m6 9 6 6 6-6`})}),`New messages`]})]})}export{a as ChatContainer};
1
+ 'use client';
2
+
3
+ import { ScrollArea } from "../../libs/ui-kit-web/dist/ui/scroll-area.js";
4
+ import { cn } from "../../libs/ui-kit-web/dist/ui/utils.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/presentation/components/ChatContainer.tsx
9
+ /**
10
+ * Container component for chat messages with scrolling
11
+ */
12
+ function ChatContainer({ children, className, showScrollButton = true }) {
13
+ const scrollRef = React.useRef(null);
14
+ const [showScrollDown, setShowScrollDown] = React.useState(false);
15
+ React.useEffect(() => {
16
+ const container = scrollRef.current;
17
+ if (!container) return;
18
+ if (container.scrollHeight - container.scrollTop <= container.clientHeight + 100) container.scrollTop = container.scrollHeight;
19
+ }, [children]);
20
+ const handleScroll = React.useCallback((event) => {
21
+ const container = event.currentTarget;
22
+ setShowScrollDown(!(container.scrollHeight - container.scrollTop <= container.clientHeight + 100));
23
+ }, []);
24
+ const scrollToBottom = React.useCallback(() => {
25
+ const container = scrollRef.current;
26
+ if (container) container.scrollTo({
27
+ top: container.scrollHeight,
28
+ behavior: "smooth"
29
+ });
30
+ }, []);
31
+ return /* @__PURE__ */ jsxs("div", {
32
+ className: cn("relative flex flex-1 flex-col", className),
33
+ children: [/* @__PURE__ */ jsx(ScrollArea, {
34
+ ref: scrollRef,
35
+ className: "flex-1",
36
+ onScroll: handleScroll,
37
+ children: /* @__PURE__ */ jsx("div", {
38
+ className: "flex flex-col gap-4 p-4",
39
+ children
40
+ })
41
+ }), showScrollButton && showScrollDown && /* @__PURE__ */ jsxs("button", {
42
+ onClick: scrollToBottom,
43
+ className: cn("absolute bottom-4 left-1/2 -translate-x-1/2", "bg-primary text-primary-foreground", "rounded-full px-3 py-1.5 text-sm font-medium shadow-lg", "hover:bg-primary/90 transition-colors", "flex items-center gap-1.5"),
44
+ "aria-label": "Scroll to bottom",
45
+ children: [/* @__PURE__ */ jsx("svg", {
46
+ xmlns: "http://www.w3.org/2000/svg",
47
+ width: "16",
48
+ height: "16",
49
+ viewBox: "0 0 24 24",
50
+ fill: "none",
51
+ stroke: "currentColor",
52
+ strokeWidth: "2",
53
+ strokeLinecap: "round",
54
+ strokeLinejoin: "round",
55
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
56
+ }), "New messages"]
57
+ })]
58
+ });
59
+ }
60
+
61
+ //#endregion
62
+ export { ChatContainer };
@@ -1,5 +1,5 @@
1
1
  import { ChatAttachment } from "../../core/message-types.js";
2
- import * as react_jsx_runtime3 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime2 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/presentation/components/ChatInput.d.ts
5
5
  interface ChatInputProps {
@@ -29,6 +29,6 @@ declare function ChatInput({
29
29
  className,
30
30
  showAttachments,
31
31
  maxAttachments
32
- }: ChatInputProps): react_jsx_runtime3.JSX.Element;
32
+ }: ChatInputProps): react_jsx_runtime2.JSX.Element;
33
33
  //#endregion
34
34
  export { ChatInput };
@@ -1 +1,149 @@
1
- "use client";import{cn as e}from"../../libs/ui-kit-web/dist/ui/utils.js";import{Button$1 as t}from"../../libs/design-system/dist/components/atoms/Button.js";import{Textarea$1 as n}from"../../libs/design-system/dist/components/atoms/Textarea.js";import*as r from"react";import{Fragment as i,jsx as a,jsxs as o}from"react/jsx-runtime";import{Code as s,FileText as c,Loader2 as l,Paperclip as u,Send as d,X as f}from"lucide-react";function p({onSend:p,disabled:m=!1,isLoading:h=!1,placeholder:g=`Type a message...`,className:_,showAttachments:v=!0,maxAttachments:y=5}){let[b,x]=r.useState(``),[S,C]=r.useState([]),w=r.useRef(null),T=r.useRef(null),E=b.trim().length>0||S.length>0,D=r.useCallback(e=>{e?.preventDefault(),!(!E||m||h)&&(p(b.trim(),S.length>0?S:void 0),x(``),C([]),w.current?.focus())},[E,b,S,m,h,p]),O=r.useCallback(e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),D())},[D]),k=r.useCallback(async e=>{let t=e.target.files;if(!t)return;let n=[];for(let e of Array.from(t)){if(S.length+n.length>=y)break;let t=await e.text(),r=e.name.split(`.`).pop()?.toLowerCase()??``,i=[`ts`,`tsx`,`js`,`jsx`,`py`,`go`,`rs`,`java`].includes(r);n.push({id:`att_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:i?`code`:`file`,name:e.name,content:t,mimeType:e.type,size:e.size})}C(e=>[...e,...n]),e.target.value=``},[S.length,y]),A=r.useCallback(e=>{C(t=>t.filter(t=>t.id!==e))},[]);return o(`div`,{className:e(`flex flex-col gap-2`,_),children:[S.length>0&&a(`div`,{className:`flex flex-wrap gap-2`,children:S.map(t=>o(`div`,{className:e(`flex items-center gap-1.5 rounded-md px-2 py-1`,`bg-muted text-muted-foreground text-sm`),children:[t.type===`code`?a(s,{className:`h-3.5 w-3.5`}):a(c,{className:`h-3.5 w-3.5`}),a(`span`,{className:`max-w-[150px] truncate`,children:t.name}),a(`button`,{type:`button`,onClick:()=>A(t.id),className:`hover:text-foreground`,"aria-label":`Remove ${t.name}`,children:a(f,{className:`h-3.5 w-3.5`})})]},t.id))}),o(`form`,{onSubmit:D,className:`flex items-end gap-2`,children:[v&&o(i,{children:[a(`input`,{ref:T,type:`file`,multiple:!0,accept:`.ts,.tsx,.js,.jsx,.json,.md,.txt,.py,.go,.rs,.java,.yaml,.yml`,onChange:k,className:`hidden`,"aria-label":`Attach files`}),a(t,{type:`button`,variant:`ghost`,size:`sm`,onPress:()=>T.current?.click(),disabled:m||S.length>=y,"aria-label":`Attach files`,children:a(u,{className:`h-4 w-4`})})]}),a(`div`,{className:`relative flex-1`,children:a(n,{value:b,onChange:e=>x(e.target.value),onKeyDown:O,placeholder:g,disabled:m,className:e(`min-h-[44px] max-h-[200px] resize-none pr-12`,`focus-visible:ring-1`),rows:1,"aria-label":`Chat message`})}),a(t,{type:`submit`,disabled:!E||m||h,size:`sm`,"aria-label":h?`Sending...`:`Send message`,children:h?a(l,{className:`h-4 w-4 animate-spin`}):a(d,{className:`h-4 w-4`})})]}),a(`p`,{className:`text-muted-foreground text-xs`,children:`Press Enter to send, Shift+Enter for new line`})]})}export{p as ChatInput};
1
+ 'use client';
2
+
3
+ import { cn } from "../../libs/ui-kit-web/dist/ui/utils.js";
4
+ import { Button$1 } from "../../libs/design-system/dist/components/atoms/Button.js";
5
+ import { Textarea$1 } from "../../libs/design-system/dist/components/atoms/Textarea.js";
6
+ import * as React from "react";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { Code, FileText, Loader2, Paperclip, Send, X } from "lucide-react";
9
+
10
+ //#region src/presentation/components/ChatInput.tsx
11
+ /**
12
+ * Chat input component with attachment support
13
+ */
14
+ function ChatInput({ onSend, disabled = false, isLoading = false, placeholder = "Type a message...", className, showAttachments = true, maxAttachments = 5 }) {
15
+ const [content, setContent] = React.useState("");
16
+ const [attachments, setAttachments] = React.useState([]);
17
+ const textareaRef = React.useRef(null);
18
+ const fileInputRef = React.useRef(null);
19
+ const canSend = content.trim().length > 0 || attachments.length > 0;
20
+ const handleSubmit = React.useCallback((e) => {
21
+ e?.preventDefault();
22
+ if (!canSend || disabled || isLoading) return;
23
+ onSend(content.trim(), attachments.length > 0 ? attachments : void 0);
24
+ setContent("");
25
+ setAttachments([]);
26
+ textareaRef.current?.focus();
27
+ }, [
28
+ canSend,
29
+ content,
30
+ attachments,
31
+ disabled,
32
+ isLoading,
33
+ onSend
34
+ ]);
35
+ const handleKeyDown = React.useCallback((e) => {
36
+ if (e.key === "Enter" && !e.shiftKey) {
37
+ e.preventDefault();
38
+ handleSubmit();
39
+ }
40
+ }, [handleSubmit]);
41
+ const handleFileSelect = React.useCallback(async (e) => {
42
+ const files = e.target.files;
43
+ if (!files) return;
44
+ const newAttachments = [];
45
+ for (const file of Array.from(files)) {
46
+ if (attachments.length + newAttachments.length >= maxAttachments) break;
47
+ const content$1 = await file.text();
48
+ const extension = file.name.split(".").pop()?.toLowerCase() ?? "";
49
+ const isCode = [
50
+ "ts",
51
+ "tsx",
52
+ "js",
53
+ "jsx",
54
+ "py",
55
+ "go",
56
+ "rs",
57
+ "java"
58
+ ].includes(extension);
59
+ newAttachments.push({
60
+ id: `att_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
61
+ type: isCode ? "code" : "file",
62
+ name: file.name,
63
+ content: content$1,
64
+ mimeType: file.type,
65
+ size: file.size
66
+ });
67
+ }
68
+ setAttachments((prev) => [...prev, ...newAttachments]);
69
+ e.target.value = "";
70
+ }, [attachments.length, maxAttachments]);
71
+ const removeAttachment = React.useCallback((id) => {
72
+ setAttachments((prev) => prev.filter((a) => a.id !== id));
73
+ }, []);
74
+ return /* @__PURE__ */ jsxs("div", {
75
+ className: cn("flex flex-col gap-2", className),
76
+ children: [
77
+ attachments.length > 0 && /* @__PURE__ */ jsx("div", {
78
+ className: "flex flex-wrap gap-2",
79
+ children: attachments.map((attachment) => /* @__PURE__ */ jsxs("div", {
80
+ className: cn("flex items-center gap-1.5 rounded-md px-2 py-1", "bg-muted text-muted-foreground text-sm"),
81
+ children: [
82
+ attachment.type === "code" ? /* @__PURE__ */ jsx(Code, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5" }),
83
+ /* @__PURE__ */ jsx("span", {
84
+ className: "max-w-[150px] truncate",
85
+ children: attachment.name
86
+ }),
87
+ /* @__PURE__ */ jsx("button", {
88
+ type: "button",
89
+ onClick: () => removeAttachment(attachment.id),
90
+ className: "hover:text-foreground",
91
+ "aria-label": `Remove ${attachment.name}`,
92
+ children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
93
+ })
94
+ ]
95
+ }, attachment.id))
96
+ }),
97
+ /* @__PURE__ */ jsxs("form", {
98
+ onSubmit: handleSubmit,
99
+ className: "flex items-end gap-2",
100
+ children: [
101
+ showAttachments && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("input", {
102
+ ref: fileInputRef,
103
+ type: "file",
104
+ multiple: true,
105
+ accept: ".ts,.tsx,.js,.jsx,.json,.md,.txt,.py,.go,.rs,.java,.yaml,.yml",
106
+ onChange: handleFileSelect,
107
+ className: "hidden",
108
+ "aria-label": "Attach files"
109
+ }), /* @__PURE__ */ jsx(Button$1, {
110
+ type: "button",
111
+ variant: "ghost",
112
+ size: "sm",
113
+ onPress: () => fileInputRef.current?.click(),
114
+ disabled: disabled || attachments.length >= maxAttachments,
115
+ "aria-label": "Attach files",
116
+ children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
117
+ })] }),
118
+ /* @__PURE__ */ jsx("div", {
119
+ className: "relative flex-1",
120
+ children: /* @__PURE__ */ jsx(Textarea$1, {
121
+ value: content,
122
+ onChange: (e) => setContent(e.target.value),
123
+ onKeyDown: handleKeyDown,
124
+ placeholder,
125
+ disabled,
126
+ className: cn("min-h-[44px] max-h-[200px] resize-none pr-12", "focus-visible:ring-1"),
127
+ rows: 1,
128
+ "aria-label": "Chat message"
129
+ })
130
+ }),
131
+ /* @__PURE__ */ jsx(Button$1, {
132
+ type: "submit",
133
+ disabled: !canSend || disabled || isLoading,
134
+ size: "sm",
135
+ "aria-label": isLoading ? "Sending..." : "Send message",
136
+ children: isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Send, { className: "h-4 w-4" })
137
+ })
138
+ ]
139
+ }),
140
+ /* @__PURE__ */ jsx("p", {
141
+ className: "text-muted-foreground text-xs",
142
+ children: "Press Enter to send, Shift+Enter for new line"
143
+ })
144
+ ]
145
+ });
146
+ }
147
+
148
+ //#endregion
149
+ export { ChatInput };
@@ -1,5 +1,5 @@
1
1
  import { ChatMessage } from "../../core/message-types.js";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/presentation/components/ChatMessage.d.ts
5
5
  interface ChatMessageProps {
@@ -18,6 +18,6 @@ declare function ChatMessage$1({
18
18
  className,
19
19
  showCopy,
20
20
  showAvatar
21
- }: ChatMessageProps): react_jsx_runtime0.JSX.Element;
21
+ }: ChatMessageProps): react_jsx_runtime1.JSX.Element;
22
22
  //#endregion
23
23
  export { ChatMessage$1 as ChatMessage };