@invergent/agent-chat-react 1.9.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -228,13 +228,13 @@ var buttonVariants = classVarianceAuthority.cva(
228
228
  link: "text-primary underline underline-offset-4 hover:underline"
229
229
  },
230
230
  size: {
231
- default: "h-10 gap-1.5 px-6 has-data-[icon=inline-end]:pr-4 has-data-[icon=inline-start]:pl-4",
231
+ default: "h-11 md:h-10 gap-1.5 px-6 has-data-[icon=inline-end]:pr-4 has-data-[icon=inline-start]:pl-4",
232
232
  xs: "h-7 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
233
- sm: "h-9 gap-1 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
233
+ sm: "h-11 md:h-9 gap-1 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
234
234
  lg: "h-11 gap-1.5 px-8 has-data-[icon=inline-end]:pr-5 has-data-[icon=inline-start]:pl-5",
235
- icon: "size-10",
235
+ icon: "size-11 md:size-10",
236
236
  "icon-xs": "size-7 [&_svg:not([class*='size-'])]:size-3",
237
- "icon-sm": "size-9",
237
+ "icon-sm": "size-11 md:size-9",
238
238
  "icon-lg": "size-11"
239
239
  }
240
240
  },
@@ -676,7 +676,7 @@ function BrowserPane({ sessionId, state, adapter }) {
676
676
  DialogContent,
677
677
  {
678
678
  "aria-describedby": void 0,
679
- className: "flex h-screen w-screen max-w-none flex-col gap-0 overflow-hidden rounded-none border-0 bg-background p-0 shadow-none ring-0 sm:max-w-none",
679
+ className: "flex h-dvh w-screen max-w-none flex-col gap-0 overflow-hidden rounded-none border-0 bg-background p-0 shadow-none ring-0 sm:max-w-none",
680
680
  children: [
681
681
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "h-10 shrink-0 flex-row items-center gap-2 border-b border-line bg-card px-4 py-0", children: [
682
682
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZapIcon, { className: "size-3.5 text-muted-foreground", "aria-hidden": "true" }),
@@ -3418,7 +3418,7 @@ function Textarea({ className, ...props }) {
3418
3418
  {
3419
3419
  "data-slot": "textarea",
3420
3420
  className: cn(
3421
- "flex field-sizing-content min-h-16 w-full resize-none rounded-none border border-transparent border-b-input bg-transparent px-0 py-3 text-base transition-[color,border-color] outline-none placeholder:text-muted-foreground focus-visible:border-b-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-b-destructive md:text-sm dark:aria-invalid:border-b-destructive/50",
3421
+ "flex field-sizing-content min-h-16 w-full resize-none rounded-none border border-transparent border-b-input bg-transparent px-0 py-3 text-base transition-[color,border-color] outline-none placeholder:text-muted-foreground focus-visible:border-b-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-b-destructive dark:aria-invalid:border-b-destructive/50",
3422
3422
  className
3423
3423
  ),
3424
3424
  ...props
@@ -3731,7 +3731,7 @@ function Input({ className, type, ...props }) {
3731
3731
  type,
3732
3732
  "data-slot": "input",
3733
3733
  className: cn(
3734
- "h-10 w-full min-w-0 border border-transparent border-b-input bg-transparent px-0 py-1 text-base transition-[color,border-color] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-b-ring disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-b-destructive md:text-sm dark:aria-invalid:border-b-destructive/50",
3734
+ "h-11 md:h-10 w-full min-w-0 border border-transparent border-b-input bg-transparent px-0 py-1 text-base transition-[color,border-color] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-b-ring disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-b-destructive md:text-sm dark:aria-invalid:border-b-destructive/50",
3735
3735
  className
3736
3736
  ),
3737
3737
  ...props
@@ -4574,7 +4574,7 @@ function InputGroup({ className, ...props }) {
4574
4574
  "data-slot": "input-group",
4575
4575
  role: "group",
4576
4576
  className: cn(
4577
- "group/input-group relative flex h-10 w-full min-w-0 items-center rounded-none border border-transparent border-b-input bg-transparent transition-[color,border-color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-none has-data-[align=block-start]:rounded-none has-[[data-slot=input-group-control]:focus-visible]:border-b-ring has-[[data-slot][aria-invalid=true]]:border-b-destructive has-[textarea]:rounded-none has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:has-[[data-slot][aria-invalid=true]]:border-b-destructive/50 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3",
4577
+ "group/input-group relative flex h-11 md:h-10 w-full min-w-0 items-center rounded-none border border-transparent border-b-input bg-transparent transition-[color,border-color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-none has-data-[align=block-start]:rounded-none has-[[data-slot=input-group-control]:focus-visible]:border-b-ring has-[[data-slot][aria-invalid=true]]:border-b-destructive has-[textarea]:rounded-none has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:has-[[data-slot][aria-invalid=true]]:border-b-destructive/50 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3",
4578
4578
  className
4579
4579
  ),
4580
4580
  ...props
@@ -4689,7 +4689,7 @@ function CommandInput({
4689
4689
  className,
4690
4690
  ...props
4691
4691
  }) {
4692
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "command-input-wrapper", className: "p-1", children: /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { className: "border-transparent border-b-input bg-transparent px-3", children: [
4692
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "command-input-wrapper", className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { className: "rounded-lg border-transparent bg-muted px-3", children: [
4693
4693
  /* @__PURE__ */ jsxRuntime.jsx(
4694
4694
  cmdk.Command.Input,
4695
4695
  {
@@ -4733,35 +4733,6 @@ function CommandEmpty({
4733
4733
  }
4734
4734
  );
4735
4735
  }
4736
- function CommandGroup({
4737
- className,
4738
- ...props
4739
- }) {
4740
- return /* @__PURE__ */ jsxRuntime.jsx(
4741
- cmdk.Command.Group,
4742
- {
4743
- "data-slot": "command-group",
4744
- className: cn(
4745
- "overflow-hidden p-1.5 text-foreground **:[[cmdk-group-heading]]:px-3 **:[[cmdk-group-heading]]:py-2 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-semibold **:[[cmdk-group-heading]]:tracking-wider **:[[cmdk-group-heading]]:text-muted-foreground **:[[cmdk-group-heading]]:uppercase",
4746
- className
4747
- ),
4748
- ...props
4749
- }
4750
- );
4751
- }
4752
- function CommandSeparator({
4753
- className,
4754
- ...props
4755
- }) {
4756
- return /* @__PURE__ */ jsxRuntime.jsx(
4757
- cmdk.Command.Separator,
4758
- {
4759
- "data-slot": "command-separator",
4760
- className: cn("-mx-1.5 my-1.5 h-px bg-border/50", className),
4761
- ...props
4762
- }
4763
- );
4764
- }
4765
4736
  function CommandItem({
4766
4737
  className,
4767
4738
  children,
@@ -4772,7 +4743,7 @@ function CommandItem({
4772
4743
  {
4773
4744
  "data-slot": "command-item",
4774
4745
  className: cn(
4775
- "group/command-item relative flex cursor-default items-center gap-2 rounded-none px-3 py-2 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-selected:*:[svg]:text-foreground",
4746
+ "group/command-item relative flex cursor-default items-center gap-2 rounded-none px-3 py-2 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-muted data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[selected=true]:*:[svg]:text-foreground",
4776
4747
  className
4777
4748
  ),
4778
4749
  ...props,
@@ -4784,95 +4755,6 @@ function CommandItem({
4784
4755
  );
4785
4756
  }
4786
4757
 
4787
- // src/components/ui/dropdown-menu.tsx
4788
- init_utils();
4789
- function DropdownMenu({
4790
- ...props
4791
- }) {
4792
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
4793
- }
4794
- function DropdownMenuTrigger({
4795
- ...props
4796
- }) {
4797
- return /* @__PURE__ */ jsxRuntime.jsx(
4798
- radixUi.DropdownMenu.Trigger,
4799
- {
4800
- "data-slot": "dropdown-menu-trigger",
4801
- ...props
4802
- }
4803
- );
4804
- }
4805
- function DropdownMenuContent({
4806
- className,
4807
- align = "start",
4808
- sideOffset = 4,
4809
- ...props
4810
- }) {
4811
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4812
- radixUi.DropdownMenu.Content,
4813
- {
4814
- "data-slot": "dropdown-menu-content",
4815
- sideOffset,
4816
- align,
4817
- className: cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-48 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-none bg-popover p-1.5 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
4818
- ...props
4819
- }
4820
- ) });
4821
- }
4822
- function DropdownMenuItem({
4823
- className,
4824
- inset,
4825
- variant = "default",
4826
- ...props
4827
- }) {
4828
- return /* @__PURE__ */ jsxRuntime.jsx(
4829
- radixUi.DropdownMenu.Item,
4830
- {
4831
- "data-slot": "dropdown-menu-item",
4832
- "data-inset": inset,
4833
- "data-variant": variant,
4834
- className: cn(
4835
- "group/dropdown-menu-item relative flex cursor-default items-center gap-2.5 rounded-none px-3 py-2 text-xs font-medium tracking-wider uppercase outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-9.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[variant=destructive]:*:[svg]:text-destructive",
4836
- className
4837
- ),
4838
- ...props
4839
- }
4840
- );
4841
- }
4842
-
4843
- // src/components/ui/hover-card.tsx
4844
- init_utils();
4845
- function HoverCard({
4846
- ...props
4847
- }) {
4848
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Root, { "data-slot": "hover-card", ...props });
4849
- }
4850
- function HoverCardTrigger({
4851
- ...props
4852
- }) {
4853
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Trigger, { "data-slot": "hover-card-trigger", ...props });
4854
- }
4855
- function HoverCardContent({
4856
- className,
4857
- align = "center",
4858
- sideOffset = 4,
4859
- ...props
4860
- }) {
4861
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.HoverCard.Portal, { "data-slot": "hover-card-portal", children: /* @__PURE__ */ jsxRuntime.jsx(
4862
- radixUi.HoverCard.Content,
4863
- {
4864
- "data-slot": "hover-card-content",
4865
- align,
4866
- sideOffset,
4867
- className: cn(
4868
- "z-50 w-72 origin-(--radix-hover-card-content-transform-origin) bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
4869
- className
4870
- ),
4871
- ...props
4872
- }
4873
- ) });
4874
- }
4875
-
4876
4758
  // src/components/ui/spinner.tsx
4877
4759
  init_utils();
4878
4760
  function Spinner({ className, ...props }) {
@@ -5029,24 +4911,6 @@ var usePromptInputAttachments = () => {
5029
4911
  return context;
5030
4912
  };
5031
4913
  var LocalReferencedSourcesContext = react.createContext(null);
5032
- var PromptInputActionAddAttachments = ({
5033
- label = "Add photos or files",
5034
- ...props
5035
- }) => {
5036
- const attachments = usePromptInputAttachments();
5037
- const handleSelect = react.useCallback(
5038
- (e) => {
5039
- e.preventDefault();
5040
- attachments.openFileDialog();
5041
- },
5042
- [attachments]
5043
- );
5044
- return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { ...props, onSelect: handleSelect, children: [
5045
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { className: "mr-2 size-4" }),
5046
- " ",
5047
- label
5048
- ] });
5049
- };
5050
4914
  var PromptInput = ({
5051
4915
  className,
5052
4916
  accept,
@@ -5382,7 +5246,7 @@ var PromptInput = ({
5382
5246
  onSubmit: handleSubmit,
5383
5247
  ref: formRef,
5384
5248
  ...props,
5385
- children: /* @__PURE__ */ jsxRuntime.jsx(InputGroup, { className: "overflow-hidden", children })
5249
+ children: /* @__PURE__ */ jsxRuntime.jsx(InputGroup, { className: "overflow-hidden rounded-3xl border border-input bg-white px-3 py-1 shadow-sm dark:bg-card dark:shadow-none dark:ring-1 dark:ring-white/5 has-[textarea]:rounded-3xl has-[>[data-align=block-end]]:rounded-3xl has-[>[data-align=block-start]]:rounded-3xl", children })
5386
5250
  }
5387
5251
  )
5388
5252
  ] });
@@ -5472,7 +5336,7 @@ var PromptInputTextarea = ({
5472
5336
  return /* @__PURE__ */ jsxRuntime.jsx(
5473
5337
  InputGroupTextarea,
5474
5338
  {
5475
- className: cn("field-sizing-content max-h-48 min-h-16", className),
5339
+ className: cn("field-sizing-content max-h-48 min-h-16 px-1.5 py-3", className),
5476
5340
  name: "message",
5477
5341
  onCompositionEnd: handleCompositionEnd,
5478
5342
  onCompositionStart: handleCompositionStart,
@@ -5516,7 +5380,11 @@ var PromptInputButton = ({
5516
5380
  const button = /* @__PURE__ */ jsxRuntime.jsx(
5517
5381
  InputGroupButton,
5518
5382
  {
5519
- className: cn(className),
5383
+ className: cn(
5384
+ "rounded-sm border border-input/70 text-foreground hover:bg-accent",
5385
+ newSize === "icon-sm" && "size-9",
5386
+ className
5387
+ ),
5520
5388
  size: newSize,
5521
5389
  type: "button",
5522
5390
  variant,
@@ -5537,19 +5405,9 @@ var PromptInputButton = ({
5537
5405
  ] })
5538
5406
  ] });
5539
5407
  };
5540
- var PromptInputActionMenu = (props) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu, { ...props });
5541
- var PromptInputActionMenuTrigger = ({
5542
- className,
5543
- children,
5544
- ...props
5545
- }) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputButton, { className, ...props, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-4" }) }) });
5546
- var PromptInputActionMenuContent = ({
5547
- className,
5548
- ...props
5549
- }) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: cn(className), ...props });
5550
5408
  var PromptInputSubmit = ({
5551
5409
  className,
5552
- variant = "default",
5410
+ variant = "secondary",
5553
5411
  size = "icon-sm",
5554
5412
  status,
5555
5413
  onStop,
@@ -5558,11 +5416,11 @@ var PromptInputSubmit = ({
5558
5416
  ...props
5559
5417
  }) => {
5560
5418
  const isGenerating = status === "submitted" || status === "streaming";
5561
- let Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeftIcon, { className: "size-4" });
5419
+ let Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpIcon, { className: "size-4" });
5562
5420
  if (status === "submitted") {
5563
5421
  Icon = /* @__PURE__ */ jsxRuntime.jsx(Spinner, {});
5564
5422
  } else if (status === "streaming") {
5565
- Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquareIcon, { className: "size-4" });
5423
+ Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SquareIcon, { className: "size-3 fill-current" });
5566
5424
  } else if (status === "error") {
5567
5425
  Icon = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-4" });
5568
5426
  }
@@ -5581,7 +5439,7 @@ var PromptInputSubmit = ({
5581
5439
  InputGroupButton,
5582
5440
  {
5583
5441
  "aria-label": isGenerating ? "Stop" : "Submit",
5584
- className: cn(className),
5442
+ className: cn("rounded-full", className),
5585
5443
  onClick: handleClick,
5586
5444
  size,
5587
5445
  type: isGenerating && onStop ? "button" : "submit",
@@ -5592,6 +5450,44 @@ var PromptInputSubmit = ({
5592
5450
  );
5593
5451
  };
5594
5452
 
5453
+ // src/components/ui/popover.tsx
5454
+ init_utils();
5455
+ function Popover({
5456
+ ...props
5457
+ }) {
5458
+ return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Root, { "data-slot": "popover", ...props });
5459
+ }
5460
+ function PopoverTrigger({
5461
+ ...props
5462
+ }) {
5463
+ return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
5464
+ }
5465
+ function PopoverContent({
5466
+ className,
5467
+ align = "center",
5468
+ sideOffset = 4,
5469
+ ...props
5470
+ }) {
5471
+ return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
5472
+ radixUi.Popover.Content,
5473
+ {
5474
+ "data-slot": "popover-content",
5475
+ align,
5476
+ sideOffset,
5477
+ className: cn(
5478
+ "z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-4 rounded-none bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-150 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 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
5479
+ className
5480
+ ),
5481
+ ...props
5482
+ }
5483
+ ) });
5484
+ }
5485
+ function PopoverAnchor({
5486
+ ...props
5487
+ }) {
5488
+ return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
5489
+ }
5490
+
5595
5491
  // src/components/ui/progress.tsx
5596
5492
  init_utils();
5597
5493
  function Progress({
@@ -5646,7 +5542,7 @@ var Context = ({
5646
5542
  () => ({ maxTokens, modelId, usage, usedTokens }),
5647
5543
  [maxTokens, modelId, usage, usedTokens]
5648
5544
  );
5649
- return /* @__PURE__ */ jsxRuntime.jsx(ContextContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(HoverCard, { closeDelay: 100, openDelay: 0, ...props }) });
5545
+ return /* @__PURE__ */ jsxRuntime.jsx(ContextContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(Popover, { ...props }) });
5650
5546
  };
5651
5547
  var ContextIcon = () => {
5652
5548
  const { usedTokens, maxTokens } = useContextValue();
@@ -5696,13 +5592,13 @@ var ContextIcon = () => {
5696
5592
  );
5697
5593
  };
5698
5594
  var ContextTrigger = ({ children, ...props }) => {
5699
- return /* @__PURE__ */ jsxRuntime.jsx(HoverCardTrigger, { asChild: true, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ContextIcon, {}) }) });
5595
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ContextIcon, {}) }) });
5700
5596
  };
5701
5597
  var ContextContent = ({
5702
5598
  className,
5703
5599
  ...props
5704
5600
  }) => /* @__PURE__ */ jsxRuntime.jsx(
5705
- HoverCardContent,
5601
+ PopoverContent,
5706
5602
  {
5707
5603
  className: cn("min-w-60 divide-y overflow-hidden p-0", className),
5708
5604
  ...props
@@ -6008,39 +5904,6 @@ function ItemActions({ className, ...props }) {
6008
5904
  }
6009
5905
  );
6010
5906
  }
6011
-
6012
- // src/components/ui/popover.tsx
6013
- init_utils();
6014
- function Popover({
6015
- ...props
6016
- }) {
6017
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Root, { "data-slot": "popover", ...props });
6018
- }
6019
- function PopoverContent({
6020
- className,
6021
- align = "center",
6022
- sideOffset = 4,
6023
- ...props
6024
- }) {
6025
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
6026
- radixUi.Popover.Content,
6027
- {
6028
- "data-slot": "popover-content",
6029
- align,
6030
- sideOffset,
6031
- className: cn(
6032
- "z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-4 rounded-none bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
6033
- className
6034
- ),
6035
- ...props
6036
- }
6037
- ) });
6038
- }
6039
- function PopoverAnchor({
6040
- ...props
6041
- }) {
6042
- return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
6043
- }
6044
5907
  function ChatComposer(props) {
6045
5908
  return /* @__PURE__ */ jsxRuntime.jsx(PromptInputProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ChatComposerInner, { ...props }) });
6046
5909
  }
@@ -6122,10 +5985,12 @@ function ChatComposerInner({
6122
5985
  onComposerError
6123
5986
  }) {
6124
5987
  const { adapter } = useAgentChatAdapterContext();
6125
- const { textInput } = usePromptInputController();
5988
+ const { textInput, attachments } = usePromptInputController();
6126
5989
  const status = isRunning ? "streaming" : disabled ? "error" : "ready";
6127
5990
  const [adapterCommands, setAdapterCommands] = react.useState([]);
6128
5991
  const [buttonMenuOpen, setButtonMenuOpen] = react.useState(false);
5992
+ const [menuMode, setMenuMode] = react.useState("all");
5993
+ const [addMenuOpen, setAddMenuOpen] = react.useState(false);
6129
5994
  const [menuDismissed, setMenuDismissed] = react.useState(false);
6130
5995
  const showSlashMenu = !menuDismissed && (textInput.value.startsWith("/") || buttonMenuOpen);
6131
5996
  react.useEffect(() => {
@@ -6133,17 +5998,17 @@ function ChatComposerInner({
6133
5998
  setMenuDismissed(false);
6134
5999
  }
6135
6000
  }, [buttonMenuOpen, menuDismissed, textInput.value]);
6136
- const [wasClosed, setWasClosed] = react.useState(true);
6137
6001
  react.useEffect(() => {
6138
- if (showSlashMenu && wasClosed) {
6139
- setWasClosed(false);
6002
+ if (textInput.value.startsWith("/")) {
6003
+ setMenuMode("all");
6004
+ }
6005
+ }, [textInput.value]);
6006
+ react.useEffect(() => {
6007
+ if (showSlashMenu && (menuMode === "skills" || menuMode === "all")) {
6140
6008
  adapter.listSlashCommands?.().then(setAdapterCommands).catch(() => {
6141
6009
  });
6142
6010
  }
6143
- if (!showSlashMenu && !wasClosed) {
6144
- setWasClosed(true);
6145
- }
6146
- }, [adapter, showSlashMenu, wasClosed]);
6011
+ }, [adapter, showSlashMenu, menuMode]);
6147
6012
  const builtinCommands = react.useMemo(
6148
6013
  () => [
6149
6014
  { value: "/clear", label: "/clear", description: "Clear conversation" },
@@ -6164,6 +6029,23 @@ function ChatComposerInner({
6164
6029
  ],
6165
6030
  []
6166
6031
  );
6032
+ const scheduledExamples = react.useMemo(
6033
+ () => [
6034
+ { value: "/loop list", label: "/loop list", description: "List your active scheduled tasks" },
6035
+ { value: "/loop cancel ", label: "/loop cancel <id>", description: "Cancel a scheduled task by ID" },
6036
+ { value: "/loop 5m check the deployment status and surface any failures", label: "/loop 5m deployment check", description: "Every 5 minutes: poll deployment status" },
6037
+ { value: "/loop 10m pull the build queue and report any stuck jobs", label: "/loop 10m build queue", description: "Every 10 minutes: review the build queue" },
6038
+ { value: "/loop 15m triage new PRs assigned to me", label: "/loop 15m PR triage", description: "Every 15 minutes: triage incoming PRs" },
6039
+ { value: "/loop 30m summarize new threads in support inbox", label: "/loop 30m support inbox", description: "Every 30 minutes: summarize support traffic" },
6040
+ { value: "/loop 1h review the on-call dashboard and flag anomalies", label: "/loop 1h on-call check", description: "Hourly: review the on-call dashboard" },
6041
+ { value: "/loop 2h scan production error rates and alert if elevated", label: "/loop 2h error scan", description: "Every 2 hours: production error scan" },
6042
+ { value: "/loop 1d give me a morning briefing of yesterday's activity", label: "/loop 1d daily briefing", description: "Daily: morning briefing of prior day" },
6043
+ { value: "/loop every 5 minutes check whether CI on the current branch has finished", label: "/loop every 5 minutes (verbose)", description: "Verbose interval form" },
6044
+ { value: "/loop watch the active deploy and notify me when it stabilises or rolls back", label: "/loop <prompt> (dynamic)", description: "Dynamic loop \u2014 model self-paces 1m\u20131h via loop_wait" },
6045
+ { value: "/loop babysit the long-running data migration and only ping me on errors or completion", label: "/loop migration watcher (dynamic)", description: "Dynamic loop \u2014 best when cadence is unpredictable" }
6046
+ ],
6047
+ []
6048
+ );
6167
6049
  const searchQuery = showSlashMenu ? textInput.value.slice(1) : "";
6168
6050
  const menuOpen = showSlashMenu;
6169
6051
  const textareaRef = react.useRef(null);
@@ -6178,7 +6060,7 @@ function ChatComposerInner({
6178
6060
  }, []);
6179
6061
  const handleCommandSelect = react.useCallback(
6180
6062
  (commandValue) => {
6181
- textInput.setInput(commandValue + " ");
6063
+ textInput.setInput(`${commandValue} `);
6182
6064
  setButtonMenuOpen(false);
6183
6065
  setMenuDismissed(true);
6184
6066
  focusTextareaAtEnd();
@@ -6187,7 +6069,7 @@ function ChatComposerInner({
6187
6069
  );
6188
6070
  const handleSearchChange = react.useCallback(
6189
6071
  (next) => {
6190
- textInput.setInput("/" + next);
6072
+ textInput.setInput(`/${next}`);
6191
6073
  },
6192
6074
  [textInput]
6193
6075
  );
@@ -6282,6 +6164,62 @@ function ChatComposerInner({
6282
6164
  },
6283
6165
  children: [
6284
6166
  /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreviewStrip, {}),
6167
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2 px-1 pb-2", children: [
6168
+ /* @__PURE__ */ jsxRuntime.jsxs(
6169
+ Button,
6170
+ {
6171
+ type: "button",
6172
+ variant: "secondary",
6173
+ size: "sm",
6174
+ className: "rounded-sm -uppercase font-display bg-white dark:bg-accent border-2 border-accent",
6175
+ onClick: () => {
6176
+ setMenuMode("commands");
6177
+ setMenuDismissed(false);
6178
+ setButtonMenuOpen(true);
6179
+ },
6180
+ children: [
6181
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TerminalIcon, {}),
6182
+ "Commands"
6183
+ ]
6184
+ }
6185
+ ),
6186
+ /* @__PURE__ */ jsxRuntime.jsxs(
6187
+ Button,
6188
+ {
6189
+ type: "button",
6190
+ variant: "secondary",
6191
+ size: "sm",
6192
+ className: "rounded-sm -uppercase font-display bg-white dark:bg-accent border-2 border-accent",
6193
+ onClick: () => {
6194
+ setMenuMode("skills");
6195
+ setMenuDismissed(false);
6196
+ setButtonMenuOpen(true);
6197
+ },
6198
+ children: [
6199
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparklesIcon, {}),
6200
+ "Skills"
6201
+ ]
6202
+ }
6203
+ ),
6204
+ /* @__PURE__ */ jsxRuntime.jsxs(
6205
+ Button,
6206
+ {
6207
+ type: "button",
6208
+ variant: "secondary",
6209
+ size: "sm",
6210
+ className: "rounded-sm -uppercase font-display bg-white dark:bg-accent border-2 border-accent",
6211
+ onClick: () => {
6212
+ setMenuMode("scheduled");
6213
+ setMenuDismissed(false);
6214
+ setButtonMenuOpen(true);
6215
+ },
6216
+ children: [
6217
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClockIcon, {}),
6218
+ "Scheduled Tasks"
6219
+ ]
6220
+ }
6221
+ )
6222
+ ] }),
6285
6223
  /* @__PURE__ */ jsxRuntime.jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
6286
6224
  PromptInput,
6287
6225
  {
@@ -6301,25 +6239,56 @@ function ChatComposerInner({
6301
6239
  ) }),
6302
6240
  /* @__PURE__ */ jsxRuntime.jsxs(PromptInputFooter, { children: [
6303
6241
  /* @__PURE__ */ jsxRuntime.jsxs(PromptInputTools, { children: [
6304
- /* @__PURE__ */ jsxRuntime.jsxs(PromptInputActionMenu, { children: [
6305
- /* @__PURE__ */ jsxRuntime.jsx(PromptInputActionMenuTrigger, {}),
6306
- /* @__PURE__ */ jsxRuntime.jsx(PromptInputActionMenuContent, { children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputActionAddAttachments, {}) })
6242
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: addMenuOpen, onOpenChange: setAddMenuOpen, children: [
6243
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputButton, { "aria-label": "Add", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-4" }) }) }),
6244
+ /* @__PURE__ */ jsxRuntime.jsx(
6245
+ PopoverContent,
6246
+ {
6247
+ side: "top",
6248
+ align: "start",
6249
+ className: "w-64 overflow-hidden rounded-xl p-1",
6250
+ children: /* @__PURE__ */ jsxRuntime.jsx(Command, { children: /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
6251
+ /* @__PURE__ */ jsxRuntime.jsxs(
6252
+ CommandItem,
6253
+ {
6254
+ disabled: true,
6255
+ className: "gap-3 rounded-md px-3 py-2 [&>svg:last-child]:hidden",
6256
+ children: [
6257
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CloudIcon, { className: "size-4 shrink-0 text-sky-500" }),
6258
+ "Add from OneDrive",
6259
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "ml-auto size-4 shrink-0 text-muted-foreground" })
6260
+ ]
6261
+ }
6262
+ ),
6263
+ /* @__PURE__ */ jsxRuntime.jsxs(
6264
+ CommandItem,
6265
+ {
6266
+ disabled: true,
6267
+ className: "gap-3 rounded-md px-3 py-2 [&>svg:last-child]:hidden",
6268
+ children: [
6269
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HardDriveIcon, { className: "size-4 shrink-0 text-emerald-500" }),
6270
+ "Add from Google Drive"
6271
+ ]
6272
+ }
6273
+ ),
6274
+ /* @__PURE__ */ jsxRuntime.jsxs(
6275
+ CommandItem,
6276
+ {
6277
+ onSelect: () => {
6278
+ setAddMenuOpen(false);
6279
+ attachments.openFileDialog();
6280
+ },
6281
+ className: "gap-3 rounded-md px-3 py-2 [&>svg:last-child]:hidden",
6282
+ children: [
6283
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PaperclipIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
6284
+ "Add local files"
6285
+ ]
6286
+ }
6287
+ )
6288
+ ] }) })
6289
+ }
6290
+ )
6307
6291
  ] }),
6308
- /* @__PURE__ */ jsxRuntime.jsx(
6309
- Button,
6310
- {
6311
- type: "button",
6312
- variant: "ghost",
6313
- size: "icon-xs",
6314
- className: "text-muted-foreground",
6315
- onClick: (e) => {
6316
- e.preventDefault();
6317
- setButtonMenuOpen((v) => !v);
6318
- },
6319
- "aria-label": "Slash commands",
6320
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-bold", children: "/" })
6321
- }
6322
- ),
6323
6292
  tokenUsage && tokenUsage.contextWindow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
6324
6293
  Context,
6325
6294
  {
@@ -6336,7 +6305,13 @@ function ChatComposerInner({
6336
6305
  outputTokenDetails: void 0
6337
6306
  },
6338
6307
  children: [
6339
- /* @__PURE__ */ jsxRuntime.jsx(ContextTrigger, {}),
6308
+ /* @__PURE__ */ jsxRuntime.jsx(
6309
+ ContextTrigger,
6310
+ {
6311
+ size: "icon-sm",
6312
+ className: "rounded-sm border border-input/70 text-foreground hover:bg-accent"
6313
+ }
6314
+ ),
6340
6315
  /* @__PURE__ */ jsxRuntime.jsxs(ContextContent, { children: [
6341
6316
  /* @__PURE__ */ jsxRuntime.jsx(ContextContentHeader, {}),
6342
6317
  /* @__PURE__ */ jsxRuntime.jsx(ContextContentBody, { children: tokenUsage.totalTokens > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -6381,14 +6356,14 @@ function ChatComposerInner({
6381
6356
  {
6382
6357
  side: "top",
6383
6358
  align: "start",
6384
- className: "overflow-hidden p-0",
6359
+ className: "overflow-hidden rounded-xl p-0",
6385
6360
  style: { width: "var(--radix-popover-trigger-width)" },
6386
6361
  onCloseAutoFocus: (e) => e.preventDefault(),
6387
6362
  onEscapeKeyDown: () => {
6388
6363
  focusTextareaAtEnd();
6389
6364
  },
6390
6365
  children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
6391
- /* @__PURE__ */ jsxRuntime.jsx(
6366
+ menuMode === "skills" ? /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search skills..." }) : menuMode === "scheduled" ? /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search scheduled tasks..." }) : /* @__PURE__ */ jsxRuntime.jsx(
6392
6367
  CommandInput,
6393
6368
  {
6394
6369
  placeholder: "Type a command or search...",
@@ -6397,8 +6372,36 @@ function ChatComposerInner({
6397
6372
  }
6398
6373
  ),
6399
6374
  /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
6400
- /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No commands found." }),
6401
- builtinCommands.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: "Built-in commands", children: builtinCommands.map((cmd) => /* @__PURE__ */ jsxRuntime.jsxs(
6375
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: menuMode === "skills" ? "No skills found." : menuMode === "scheduled" ? "No scheduled tasks found." : "No commands found." }),
6376
+ menuMode === "scheduled" && scheduledExamples.map((cmd) => /* @__PURE__ */ jsxRuntime.jsxs(
6377
+ CommandItem,
6378
+ {
6379
+ value: cmd.value,
6380
+ keywords: [cmd.description],
6381
+ onSelect: () => handleCommandSelect(cmd.value),
6382
+ className: "grid grid-cols-[14rem_1fr] items-baseline gap-3 [&_svg]:hidden",
6383
+ children: [
6384
+ /* @__PURE__ */ jsxRuntime.jsx(
6385
+ "span",
6386
+ {
6387
+ className: "font-mono font-semibold text-foreground truncate",
6388
+ title: cmd.label,
6389
+ children: cmd.label
6390
+ }
6391
+ ),
6392
+ /* @__PURE__ */ jsxRuntime.jsx(
6393
+ "span",
6394
+ {
6395
+ className: "min-w-0 truncate text-sm text-muted-foreground",
6396
+ title: cmd.description,
6397
+ children: cmd.description
6398
+ }
6399
+ )
6400
+ ]
6401
+ },
6402
+ cmd.value
6403
+ )),
6404
+ (menuMode === "commands" || menuMode === "all") && builtinCommands.map((cmd) => /* @__PURE__ */ jsxRuntime.jsxs(
6402
6405
  CommandItem,
6403
6406
  {
6404
6407
  value: cmd.value,
@@ -6409,7 +6412,7 @@ function ChatComposerInner({
6409
6412
  /* @__PURE__ */ jsxRuntime.jsx(
6410
6413
  "span",
6411
6414
  {
6412
- className: "font-mono text-foreground truncate",
6415
+ className: "font-mono font-semibold text-foreground truncate",
6413
6416
  title: cmd.label,
6414
6417
  children: cmd.label
6415
6418
  }
@@ -6417,7 +6420,7 @@ function ChatComposerInner({
6417
6420
  /* @__PURE__ */ jsxRuntime.jsx(
6418
6421
  "span",
6419
6422
  {
6420
- className: "min-w-0 truncate text-xs text-muted-foreground",
6423
+ className: "min-w-0 truncate text-sm text-muted-foreground",
6421
6424
  title: cmd.description,
6422
6425
  children: cmd.description
6423
6426
  }
@@ -6425,9 +6428,8 @@ function ChatComposerInner({
6425
6428
  ]
6426
6429
  },
6427
6430
  cmd.value
6428
- )) }),
6429
- builtinCommands.length > 0 && adapterCommands.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CommandSeparator, {}),
6430
- adapterCommands.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: "Skills", children: adapterCommands.map((cmd) => /* @__PURE__ */ jsxRuntime.jsxs(
6431
+ )),
6432
+ (menuMode === "skills" || menuMode === "all") && adapterCommands.map((cmd) => /* @__PURE__ */ jsxRuntime.jsxs(
6431
6433
  CommandItem,
6432
6434
  {
6433
6435
  value: cmd.value,
@@ -6438,7 +6440,7 @@ function ChatComposerInner({
6438
6440
  /* @__PURE__ */ jsxRuntime.jsx(
6439
6441
  "span",
6440
6442
  {
6441
- className: "font-mono text-foreground truncate",
6443
+ className: "font-mono font-semibold text-foreground truncate",
6442
6444
  title: cmd.label,
6443
6445
  children: cmd.label
6444
6446
  }
@@ -6446,7 +6448,7 @@ function ChatComposerInner({
6446
6448
  /* @__PURE__ */ jsxRuntime.jsx(
6447
6449
  "span",
6448
6450
  {
6449
- className: "min-w-0 truncate text-xs text-muted-foreground",
6451
+ className: "min-w-0 truncate text-sm text-muted-foreground",
6450
6452
  title: cmd.description,
6451
6453
  children: cmd.description
6452
6454
  }
@@ -6454,7 +6456,7 @@ function ChatComposerInner({
6454
6456
  ]
6455
6457
  },
6456
6458
  cmd.value
6457
- )) })
6459
+ ))
6458
6460
  ] })
6459
6461
  ] })
6460
6462
  }
@@ -7614,7 +7616,7 @@ function ChatThread({
7614
7616
  ] }) }),
7615
7617
  /* @__PURE__ */ jsxRuntime.jsx(ConversationScrollButton, {})
7616
7618
  ] }),
7617
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-4xl px-6 pb-5 pt-3", children: [
7619
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-4xl px-3 sm:px-6 pb-3 sm:pb-5 pt-3", children: [
7618
7620
  retryIndicator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(RetryBanner, { indicator: retryIndicator }) }),
7619
7621
  disabled && disabledReason ? /* @__PURE__ */ jsxRuntime.jsx(
7620
7622
  "div",
@@ -8279,7 +8281,7 @@ function RenderEntries({
8279
8281
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-4 shrink-0" }),
8280
8282
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name }),
8281
8283
  entry.size != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 shrink-0 text-xs text-muted-foreground/60", children: formatFileSize(entry.size) }),
8282
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-0 transition-opacity group-hover:opacity-100", children: [
8284
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100", children: [
8283
8285
  /* @__PURE__ */ jsxRuntime.jsx(
8284
8286
  "a",
8285
8287
  {
@@ -8714,6 +8716,9 @@ function ConfirmDialog({
8714
8716
  );
8715
8717
  }
8716
8718
 
8719
+ // src/agent-chat.tsx
8720
+ init_utils();
8721
+
8717
8722
  // src/lib/sessions.ts
8718
8723
  function isScheduledRunSession(session) {
8719
8724
  return Boolean(
@@ -9804,6 +9809,9 @@ function parseGoalDefinition(content) {
9804
9809
  const rubric = match ? args.slice(match.index + match[0].length).trim() : "";
9805
9810
  return rubric ? { description, rubric } : { description };
9806
9811
  }
9812
+ var RIGHT_STACK_STYLE = {
9813
+ ["--right-stack-w"]: "440px"
9814
+ };
9807
9815
  function AgentChat({
9808
9816
  adapter,
9809
9817
  agentId,
@@ -9815,6 +9823,7 @@ function AgentChat({
9815
9823
  onComposerError
9816
9824
  }) {
9817
9825
  const [workspacePath, setWorkspacePath] = react.useState(null);
9826
+ const [mobileView, setMobileView] = react.useState("chat");
9818
9827
  const runtime = useAgentChatRuntime({
9819
9828
  adapter,
9820
9829
  agentId,
@@ -9832,10 +9841,12 @@ function AgentChat({
9832
9841
  const handleFileSelect = react.useCallback(
9833
9842
  (path) => {
9834
9843
  setWorkspacePath(path);
9844
+ setMobileView("workspace");
9835
9845
  onFileSelect?.(path);
9836
9846
  },
9837
9847
  [onFileSelect]
9838
9848
  );
9849
+ const showMobileToggle = Boolean(sessionId);
9839
9850
  return /* @__PURE__ */ jsxRuntime.jsx(
9840
9851
  AgentChatAdapterProvider,
9841
9852
  {
@@ -9848,15 +9859,56 @@ function AgentChat({
9848
9859
  "section",
9849
9860
  {
9850
9861
  "data-testid": "agent-chat-layout",
9851
- className: hasBrowserPanel ? "relative min-h-0 flex-1 overflow-hidden bg-background text-sm text-foreground" : "flex min-h-0 flex-1 overflow-hidden bg-background text-sm text-foreground",
9852
- style: { direction: "ltr" },
9862
+ "data-mobile-view": mobileView,
9863
+ className: cn(
9864
+ // Phone: flex column, tab toggle on top, then either chat or
9865
+ // right stack visible based on `data-mobile-view`.
9866
+ "flex min-h-0 flex-1 flex-col overflow-hidden bg-background text-sm text-foreground",
9867
+ // md+: restore desktop two-pane layout.
9868
+ hasBrowserPanel ? "md:relative md:flex-row" : "md:flex-row"
9869
+ ),
9870
+ style: { direction: "ltr", ...RIGHT_STACK_STYLE },
9853
9871
  children: [
9872
+ showMobileToggle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden flex shrink-0 border-b border-line bg-card", children: [
9873
+ /* @__PURE__ */ jsxRuntime.jsx(
9874
+ "button",
9875
+ {
9876
+ type: "button",
9877
+ onClick: () => setMobileView("chat"),
9878
+ "aria-pressed": mobileView === "chat",
9879
+ className: cn(
9880
+ "flex-1 px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors",
9881
+ mobileView === "chat" ? "border-primary text-foreground" : "border-transparent text-subtle hover:text-foreground"
9882
+ ),
9883
+ children: "Chat"
9884
+ }
9885
+ ),
9886
+ /* @__PURE__ */ jsxRuntime.jsx(
9887
+ "button",
9888
+ {
9889
+ type: "button",
9890
+ onClick: () => setMobileView("workspace"),
9891
+ "aria-pressed": mobileView === "workspace",
9892
+ className: cn(
9893
+ "flex-1 px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors",
9894
+ mobileView === "workspace" ? "border-primary text-foreground" : "border-transparent text-subtle hover:text-foreground"
9895
+ ),
9896
+ children: "Workspace"
9897
+ }
9898
+ )
9899
+ ] }),
9854
9900
  /* @__PURE__ */ jsxRuntime.jsx(
9855
9901
  "div",
9856
9902
  {
9857
9903
  "data-testid": "chat-panel",
9858
- className: hasBrowserPanel ? "absolute inset-y-0 left-0 flex min-h-0 min-w-0 flex-col overflow-hidden" : "flex min-w-0 flex-1 flex-col overflow-hidden",
9859
- style: hasBrowserPanel ? { right: 440 } : void 0,
9904
+ "data-mobile-view": mobileView,
9905
+ className: cn(
9906
+ // Phone: full width column, hidden when workspace tab active.
9907
+ "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
9908
+ showMobileToggle && "data-[mobile-view=workspace]:hidden md:flex!",
9909
+ // md+: restore desktop positioning.
9910
+ hasBrowserPanel ? "md:absolute md:inset-y-0 md:left-0 md:right-(--right-stack-w,440px) md:flex" : "md:relative md:flex-1"
9911
+ ),
9860
9912
  children: /* @__PURE__ */ jsxRuntime.jsx(
9861
9913
  ChatThread,
9862
9914
  {
@@ -9881,8 +9933,16 @@ function AgentChat({
9881
9933
  "div",
9882
9934
  {
9883
9935
  "data-testid": "right-stack",
9884
- className: hasBrowserPanel ? "absolute inset-y-0 flex min-h-0 flex-col overflow-hidden" : "flex min-h-0 shrink-0 flex-col",
9885
- style: hasBrowserPanel ? { right: 0, width: 440 } : void 0,
9936
+ "data-mobile-view": mobileView,
9937
+ className: cn(
9938
+ // Phone: full width column, hidden when chat tab active.
9939
+ "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
9940
+ showMobileToggle && "data-[mobile-view=chat]:hidden md:flex!",
9941
+ // md+: restore desktop positioning. With browser panel the
9942
+ // right stack is absolutely positioned at the configured
9943
+ // width; without it the stack flows in the row.
9944
+ hasBrowserPanel ? "md:absolute md:inset-y-0 md:right-0 md:w-(--right-stack-w,440px) md:flex-none" : "md:relative md:shrink-0 md:flex-none md:w-(--right-stack-w,440px)"
9945
+ ),
9886
9946
  children: [
9887
9947
  hasBrowserPanel && /* @__PURE__ */ jsxRuntime.jsx(
9888
9948
  "div",
@@ -10869,16 +10929,16 @@ function MissionDashboard({
10869
10929
  }
10870
10930
  };
10871
10931
  const statusVariant = mission.status === "satisfied" ? "default" : mission.status === "failed" || mission.status === "cancelled" ? "destructive" : "secondary";
10872
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6 p-6 max-w-6xl mx-auto", children: [
10932
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 p-4 sm:gap-6 sm:p-6 max-w-6xl mx-auto", children: [
10873
10933
  /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
10874
- /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
10875
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
10934
+ /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-stretch gap-4 sm:flex-row sm:items-start sm:justify-between", children: [
10935
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 min-w-0 flex-1", children: [
10876
10936
  /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "wrap-break-word -uppercase text-sm", children: mission.description }),
10877
10937
  /* @__PURE__ */ jsxRuntime.jsxs(CardDescription, { className: "wrap-break-word text-foreground/70", children: [
10878
10938
  "Rubric: ",
10879
10939
  mission.rubric
10880
10940
  ] }),
10881
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 pt-2 text-xs text-foreground/70", children: [
10941
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pt-2 text-xs text-foreground/70", children: [
10882
10942
  /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant, className: "font-mono text-foreground", children: mission.status }),
10883
10943
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-primary", children: [
10884
10944
  "Iteration ",
@@ -10893,7 +10953,7 @@ function MissionDashboard({
10893
10953
  ] }) : null
10894
10954
  ] })
10895
10955
  ] }),
10896
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: ACTIVE_MISSION_STATUSES.has(mission.status) ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10956
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: ACTIVE_MISSION_STATUSES.has(mission.status) ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10897
10957
  mission.status === "active" ? /* @__PURE__ */ jsxRuntime.jsxs(
10898
10958
  Button,
10899
10959
  {
@@ -11013,7 +11073,7 @@ function MissionDashboard({
11013
11073
  return /* @__PURE__ */ jsxRuntime.jsxs(
11014
11074
  "li",
11015
11075
  {
11016
- className: "flex items-start justify-between gap-3 rounded border border-border/40 px-3 py-2 text-sm",
11076
+ className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between rounded border border-border/40 px-3 py-2 text-sm",
11017
11077
  children: [
11018
11078
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
11019
11079
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -11172,7 +11232,8 @@ function MissionRow({
11172
11232
  "div",
11173
11233
  {
11174
11234
  className: cn(
11175
- "group flex min-w-0 items-start gap-2 border-l-2 border-l-transparent px-3 py-2 text-sm transition-colors cursor-pointer hover:border-l-primary hover:bg-input"
11235
+ "group flex min-w-0 items-start gap-2 border-l-2 border-l-transparent px-3 py-2 text-sm transition-colors cursor-pointer hover:border-l-primary hover:bg-input",
11236
+ "min-h-11 md:min-h-0"
11176
11237
  ),
11177
11238
  onClick: openMission,
11178
11239
  onKeyDown: handleRowKeyDown,
@@ -11199,7 +11260,7 @@ function MissionRow({
11199
11260
  "button",
11200
11261
  {
11201
11262
  type: "button",
11202
- className: "rounded p-1 text-faint opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 group-hover:opacity-100",
11263
+ className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
11203
11264
  onClick: (e) => {
11204
11265
  stopActionClick(e);
11205
11266
  onPause(mission.id);
@@ -11214,7 +11275,7 @@ function MissionRow({
11214
11275
  "button",
11215
11276
  {
11216
11277
  type: "button",
11217
- className: "rounded p-1 text-faint opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 group-hover:opacity-100",
11278
+ className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
11218
11279
  onClick: (e) => {
11219
11280
  stopActionClick(e);
11220
11281
  onResume(mission.id);
@@ -11229,7 +11290,7 @@ function MissionRow({
11229
11290
  "button",
11230
11291
  {
11231
11292
  type: "button",
11232
- className: "rounded p-1 text-faint opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 group-hover:opacity-100",
11293
+ className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
11233
11294
  onClick: (e) => {
11234
11295
  stopActionClick(e);
11235
11296
  onCancel(mission.id);
@@ -11507,6 +11568,7 @@ function ScheduledWorkRow({
11507
11568
  {
11508
11569
  className: cn(
11509
11570
  "group flex min-w-0 items-start gap-2 border-l-2 border-l-transparent px-3 py-2 text-sm transition-colors hover:border-l-primary hover:bg-input",
11571
+ "min-h-11 md:min-h-0",
11510
11572
  lastSessionId && "cursor-pointer"
11511
11573
  ),
11512
11574
  onClick: openLastRun,
@@ -11533,7 +11595,7 @@ function ScheduledWorkRow({
11533
11595
  "button",
11534
11596
  {
11535
11597
  type: "button",
11536
- className: "rounded p-1 text-faint opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 group-hover:opacity-100",
11598
+ className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
11537
11599
  onClick: (e) => {
11538
11600
  stopActionClick(e);
11539
11601
  onRunNow(item.id);
@@ -11548,7 +11610,7 @@ function ScheduledWorkRow({
11548
11610
  "button",
11549
11611
  {
11550
11612
  type: "button",
11551
- className: "rounded p-1 text-faint opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 group-hover:opacity-100",
11613
+ className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
11552
11614
  onClick: (e) => {
11553
11615
  stopActionClick(e);
11554
11616
  onCancel(item.id);
@@ -11855,6 +11917,7 @@ function TreeNodeRow({
11855
11917
  },
11856
11918
  className: cn(
11857
11919
  "group flex items-center gap-2 w-full py-2 pr-2 text-left cursor-pointer transition-colors border-l-2",
11920
+ "min-h-11 md:min-h-0",
11858
11921
  isActive ? "bg-line text-foreground border-l-primary" : "bg-transparent text-subtle hover:bg-input hover:text-foreground border-l-transparent"
11859
11922
  ),
11860
11923
  style: { paddingLeft: `${depth * 12 + 12}px` },
@@ -11863,7 +11926,7 @@ function TreeNodeRow({
11863
11926
  "button",
11864
11927
  {
11865
11928
  type: "button",
11866
- className: "p-0.5 rounded hover:bg-line shrink-0",
11929
+ className: "p-2 md:p-0.5 rounded hover:bg-line shrink-0",
11867
11930
  onClick: (e) => {
11868
11931
  e.stopPropagation();
11869
11932
  setExpanded(!expanded);
@@ -11881,7 +11944,7 @@ function TreeNodeRow({
11881
11944
  "button",
11882
11945
  {
11883
11946
  type: "button",
11884
- className: "p-1 rounded opacity-0 group-hover:opacity-100 hover:bg-destructive/10 hover:text-destructive transition-all",
11947
+ className: "p-2 md:p-1 rounded opacity-100 md:opacity-0 md:group-hover:opacity-100 hover:bg-destructive/10 hover:text-destructive transition-all",
11885
11948
  onClick: (e) => {
11886
11949
  e.stopPropagation();
11887
11950
  onStop(entry.id);
@@ -11896,8 +11959,8 @@ function TreeNodeRow({
11896
11959
  {
11897
11960
  type: "button",
11898
11961
  className: cn(
11899
- "p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
11900
- deletingSessionId === entry.id ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"
11962
+ "p-2 md:p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
11963
+ deletingSessionId === entry.id ? "opacity-100" : "opacity-100 md:opacity-0 md:group-hover:opacity-100 md:focus-visible:opacity-100"
11901
11964
  ),
11902
11965
  onClick: (e) => {
11903
11966
  e.stopPropagation();