@workerdeck/ui 1.1.0 → 1.2.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/build/{SessionPanel-I5QSLLb0.mjs → SessionPanel-DVhnUwXw.mjs} +37 -2
- package/build/SessionPanel-DVhnUwXw.mjs.map +1 -0
- package/build/format-C4h4jZL_.d.mts +25 -0
- package/build/format.d.mts +2 -2
- package/build/format.mjs +2 -2
- package/build/index.d.mts +2 -2
- package/build/index.mjs +2 -2
- package/build/scoped.css +4 -0
- package/build/{status-Dm9INVTt.mjs → status-BW2xj79g.mjs} +11 -2
- package/build/status-BW2xj79g.mjs.map +1 -0
- package/build/workspace.mjs +2 -2
- package/package.json +4 -4
- package/src/components/agent/TranscriptItemView.tsx +19 -1
- package/src/components/terminal/TerminalTranscript.tsx +4 -1
- package/src/components/terminal/height.ts +6 -1
- package/src/components/terminal/items.tsx +14 -1
- package/src/lib/format.ts +10 -0
- package/build/SessionPanel-I5QSLLb0.mjs.map +0 -1
- package/build/format-C_lpFq0l.d.mts +0 -16
- package/build/status-Dm9INVTt.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionPanel-DVhnUwXw.mjs","names":["Select","SelectPrimitive","Menu","MenuPrimitive","Dialog","DialogPrimitive","TooltipPrimitive","File","FileText","FileCard","noop","RESULT_PREVIEW_CHARS","TurnResultRow","CompactionRow","NoticeRow","Dialog","Dialog","Dialog","Dialog","Select","Select","answerFor","Box","Box","Dialog","nearestMember","LANE","LOUDNESS","KIND_NAME","MIN_MARK","doneLine","excerpt","peekContent","TurnResultRow","NoticeRow","CompactionRow","useRunStart","Dialog","Menu"],"sources":["../src/lib/utils.ts","../src/components/ui/Button.tsx","../src/components/ui/Badge.tsx","../src/components/ui/Input.tsx","../src/components/ui/PortalScope.tsx","../src/components/ui/Select.tsx","../src/components/ui/Menu.tsx","../src/components/ui/Dialog.tsx","../src/components/ui/Tooltip.tsx","../src/lib/clipboard.ts","../src/components/ui/CopyButton.tsx","../src/components/ui/Spinner.tsx","../src/components/ui/CodeBlock.tsx","../src/components/ui/Splitter.tsx","../src/components/ui/ProgressRing.tsx","../src/components/prompt-area/prompt-area-engine.ts","../src/components/prompt-area/prompt-area-list-ops.ts","../src/components/prompt-area/dom-helpers.ts","../src/components/prompt-area/cursor-helpers.ts","../src/components/prompt-area/clipboard-helpers.ts","../src/components/prompt-area/html-to-markdown.ts","../src/components/prompt-area/use-prompt-area-events.ts","../src/components/prompt-area/use-prompt-area-keydown.ts","../src/components/prompt-area/use-chip-editing.ts","../src/components/prompt-area/use-trigger-search.ts","../src/components/prompt-area/use-prompt-area.ts","../src/components/prompt-area/trigger-popover.tsx","../src/components/prompt-area/animated-placeholder.tsx","../src/components/prompt-area/remove-button.tsx","../src/components/prompt-area/image-strip.tsx","../src/components/prompt-area/file-strip.tsx","../src/components/prompt-area/prompt-area.tsx","../src/components/prompt-area/use-prompt-area-state.ts","../src/components/prompt-area/trigger-presets.ts","../src/components/agent/transcript-variant.tsx","../src/lib/tool-icon.ts","../src/components/agent/pulse.tsx","../src/components/terminal/affordances.tsx","../src/components/terminal/row.tsx","../src/components/terminal/diff.tsx","../src/components/terminal/markdown.tsx","../src/components/terminal/press.tsx","../src/components/terminal/image-box.ts","../src/components/terminal/result-preview.ts","../src/components/agent/tool-result-fetch.tsx","../src/components/agent/tool-result-image.tsx","../src/components/terminal/tool-run.ts","../src/components/terminal/todos.ts","../src/components/terminal/items.tsx","../src/components/terminal/surface.tsx","../src/components/agent/Composer.tsx","../src/lib/css.ts","../src/components/agent/ContextDialog.tsx","../src/components/agent/EntryIcon.tsx","../src/components/agent/HostFilesDialog.tsx","../src/components/agent/McpDialog.tsx","../src/components/agent/SkillsDialog.tsx","../src/components/agent/ModelSelect.tsx","../src/components/agent/PermissionModeSelect.tsx","../src/lib/plan-request.ts","../src/components/agent/Response.tsx","../src/components/agent/PermissionPrompt.tsx","../src/components/agent/SubagentStrip.tsx","../src/components/terminal/blocks.ts","../src/components/agent/use-subagent-frame.ts","../src/components/agent/QuestionPrompt.tsx","../src/components/terminal/prompt.tsx","../src/components/terminal/PermissionPrompt.tsx","../src/components/terminal/QuestionPrompt.tsx","../src/components/agent/SessionInfoDialog.tsx","../src/components/agent/status.ts","../src/components/agent/StatusBar.tsx","../src/components/agent/Conversation.tsx","../src/components/agent/Loader.tsx","../src/components/agent/SessionEmptyState.tsx","../src/components/terminal/height.ts","../src/components/terminal/scrubber.tsx","../src/components/agent/scrubber-marks.ts","../src/components/agent/Scrubber.tsx","../src/components/agent/transcript-rows.ts","../src/components/agent/use-height-epoch.ts","../src/components/agent/use-transcript-jumps.ts","../src/components/terminal/TerminalTranscript.tsx","../src/components/agent/FileCard.tsx","../src/components/agent/Message.tsx","../src/components/agent/PromptTokenText.tsx","../src/components/agent/Reasoning.tsx","../src/components/agent/ToolCallCard.tsx","../src/components/agent/TranscriptItemView.tsx","../src/components/agent/TranscriptRows.tsx","../src/components/agent/Transcript.tsx","../src/components/agent/UsageMeters.tsx","../src/components/agent/UsageDialog.tsx","../src/components/agent/SessionPanel.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { extendTailwindMerge } from 'tailwind-merge'\n\n// Register the custom text-* utilities as a font-size group, or tailwind-merge buckets a size class with a colour class and drops the size.\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-xl',\n 'display-lg',\n 'display-md',\n 'display-sm',\n 'heading-1',\n 'heading-2',\n 'heading-3',\n 'body',\n 'body-sm',\n 'label',\n 'code',\n ],\n },\n ],\n },\n },\n})\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { type ButtonHTMLAttributes, forwardRef } from 'react'\nimport { type VariantProps, cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils.ts'\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-colors outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-1 focus-visible:ring-offset-bg disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-accent-hover',\n outline: 'border-border bg-surface hover:border-border-strong hover:bg-surface-hover',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-surface-hover',\n ghost: 'text-fg-2 hover:bg-surface-hover hover:text-foreground',\n destructive: 'text-danger hover:bg-danger-bg',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-8 gap-1.5 px-3',\n xs: \"h-6 gap-1 px-2 text-xs [&_svg:not([class*='size-'])]:size-3\",\n sm: 'h-7 gap-1 px-2.5 text-xs',\n lg: 'h-9 gap-1.5 px-3.5',\n icon: 'size-8',\n 'icon-sm': 'size-7',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n)\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', type = 'button', ...props }, ref) => (\n <button ref={ref} type={type} data-slot=\"button\" className={cn(buttonVariants({ variant, size, className }))} {...props} />\n ),\n)\nButton.displayName = 'Button'\n\nexport { buttonVariants }\n","import { type HTMLAttributes } from 'react'\nimport { type VariantProps, cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils.ts'\n\nconst badgeVariants = cva('inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-label font-medium whitespace-nowrap', {\n variants: {\n variant: {\n neutral: 'border-border bg-surface text-fg-2',\n accent: 'border-transparent bg-accent-bg text-fg-1',\n success: 'border-transparent bg-success-bg text-success',\n warning: 'border-transparent bg-warning-bg text-warning',\n danger: 'border-transparent bg-danger-bg text-danger',\n info: 'border-transparent bg-info-bg text-info',\n },\n mono: {\n true: 'font-mono text-code',\n false: '',\n },\n },\n defaultVariants: { variant: 'neutral', mono: false },\n})\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {\n dot?: boolean\n}\n\nexport function Badge({ className, variant = 'neutral', mono, dot, children, ...props }: BadgeProps) {\n return (\n <span data-slot=\"badge\" className={cn(badgeVariants({ variant, mono, className }))} {...props}>\n {dot ? <span aria-hidden className=\"size-1.5 shrink-0 self-center rounded-full bg-current\" /> : null}\n {children}\n </span>\n )\n}\n\nexport { badgeVariants }\n","import { type InputHTMLAttributes, forwardRef } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport const Input = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(({ className, ...props }, ref) => (\n <input\n ref={ref}\n data-slot=\"input\"\n className={cn(\n 'h-8 w-full rounded-md border border-border bg-bg px-2.5 text-body-sm text-text',\n 'placeholder:text-fg-4 transition-colors outline-none',\n 'hover:border-border-strong focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n />\n))\nInput.displayName = 'Input'\n","import { type FunctionComponent, type ReactNode } from 'react'\n\nexport const PortalScope: FunctionComponent<{ children?: ReactNode }> = ({ children }) => (\n <div className=\"wd-root\" style={{ display: 'contents' }}>\n {children}\n </div>\n)\n","import { type FunctionComponent } from 'react'\nimport { Select as SelectPrimitive } from '@base-ui/react/select'\nimport { Check, ChevronsUpDown } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const Select = SelectPrimitive.Root\nexport const SelectValue = SelectPrimitive.Value\nexport const SelectItemText = SelectPrimitive.ItemText\n\nexport const SelectTrigger: FunctionComponent<SelectPrimitive.Trigger.Props> = ({ className, children, ...props }) => (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n className={cn(\n 'inline-flex h-7 items-center justify-between gap-1.5 rounded-md border border-border bg-bg px-2 text-body-sm text-text',\n 'transition-colors outline-none hover:border-border-strong focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40',\n 'data-popup-open:border-border-strong disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon className=\"text-fg-4\">\n <ChevronsUpDown className=\"size-3.5\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n)\n\nexport const SelectContent: FunctionComponent<\n SelectPrimitive.Popup.Props & Pick<SelectPrimitive.Positioner.Props, 'align' | 'alignItemWithTrigger' | 'side' | 'sideOffset'>\n> = ({ className, align = 'start', alignItemWithTrigger = false, side = 'bottom', sideOffset = 6, ...props }) => (\n <SelectPrimitive.Portal>\n <PortalScope>\n <SelectPrimitive.Positioner\n align={align}\n alignItemWithTrigger={alignItemWithTrigger}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-80 outline-none\"\n >\n <SelectPrimitive.Popup\n data-slot=\"select-content\"\n className={cn(\n 'max-h-[min(24rem,var(--available-height))] min-w-[var(--anchor-width)] overflow-y-auto',\n 'rounded-md border border-border bg-surface p-1 text-fg-1 shadow-(--shadow-lg) outline-none',\n className,\n )}\n {...props}\n />\n </SelectPrimitive.Positioner>\n </PortalScope>\n </SelectPrimitive.Portal>\n)\n\nexport const SelectItem: FunctionComponent<SelectPrimitive.Item.Props> = ({ className, children, ...props }) => (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n 'flex cursor-pointer items-start gap-2 rounded-sm px-2 py-1.5 text-body-sm text-text outline-none select-none',\n 'data-highlighted:bg-surface-hover',\n className,\n )}\n {...props}\n >\n <span className=\"flex min-w-0 flex-1 flex-col gap-0.5\">{children}</span>\n <SelectPrimitive.ItemIndicator className=\"mt-0.5 text-fg-1\">\n <Check className=\"size-3.5\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n)\n","import { type FunctionComponent } from 'react'\nimport { Menu as MenuPrimitive } from '@base-ui/react/menu'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const Menu = MenuPrimitive.Root\nexport const MenuTrigger = MenuPrimitive.Trigger\n\nexport const MenuContent: FunctionComponent<\n MenuPrimitive.Popup.Props & Pick<MenuPrimitive.Positioner.Props, 'align' | 'side' | 'sideOffset'>\n> = ({ className, align = 'end', side = 'bottom', sideOffset = 6, ...props }) => (\n <MenuPrimitive.Portal>\n <PortalScope>\n <MenuPrimitive.Positioner align={align} side={side} sideOffset={sideOffset} className=\"isolate z-80 outline-none\">\n <MenuPrimitive.Popup\n data-slot=\"menu-content\"\n className={cn(\n 'min-w-48 rounded-md border border-border bg-surface p-1 text-fg-1 shadow-(--shadow-lg) outline-none',\n 'transition-[opacity,transform] duration-(--motion-base)',\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </PortalScope>\n </MenuPrimitive.Portal>\n)\n\nexport const MenuItem: FunctionComponent<MenuPrimitive.Item.Props & { destructive?: boolean }> = ({ className, destructive, ...props }) => (\n <MenuPrimitive.Item\n data-slot=\"menu-item\"\n className={cn(\n 'flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-body-sm outline-none select-none',\n 'data-highlighted:bg-surface-hover',\n destructive ? 'text-danger' : 'text-text',\n className,\n )}\n {...props}\n />\n)\n\nexport const MenuSeparator: FunctionComponent<MenuPrimitive.Separator.Props> = ({ className, ...props }) => (\n <MenuPrimitive.Separator className={cn('my-1 h-px bg-border', className)} {...props} />\n)\n","import { type FunctionComponent } from 'react'\nimport { Dialog as DialogPrimitive } from '@base-ui/react/dialog'\nimport { X } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const Dialog = DialogPrimitive.Root\nexport const DialogTrigger = DialogPrimitive.Trigger\nexport const DialogClose = DialogPrimitive.Close\n\nexport const DialogContent: FunctionComponent<DialogPrimitive.Popup.Props & { size?: 'sm' | 'md' | 'lg' }> = ({\n className,\n children,\n size = 'md',\n ...props\n}) => (\n <DialogPrimitive.Portal>\n <PortalScope>\n <DialogPrimitive.Backdrop\n className={cn(\n 'fixed inset-0 z-70 bg-black/40 backdrop-blur-[1px]',\n 'transition-opacity duration-(--motion-base)',\n 'data-starting-style:opacity-0 data-ending-style:opacity-0',\n )}\n />\n <DialogPrimitive.Popup\n data-slot=\"dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-70 flex max-h-[min(42rem,calc(100dvh-3rem))] -translate-x-1/2 -translate-y-1/2 flex-col',\n size === 'sm' && 'w-[min(24rem,calc(100vw-2rem))]',\n size === 'md' && 'w-[min(32rem,calc(100vw-2rem))]',\n size === 'lg' && 'w-[min(46rem,calc(100vw-2rem))]',\n 'rounded-lg border border-border bg-surface shadow-(--shadow-lg) outline-none',\n 'transition-[opacity,transform] duration-(--motion-base)',\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n >\n {children}\n </DialogPrimitive.Popup>\n </PortalScope>\n </DialogPrimitive.Portal>\n)\n\nexport const DialogHeader: FunctionComponent<{\n title: string\n description?: string\n actions?: React.ReactNode\n}> = ({ title, description, actions }) => (\n <div className=\"flex items-start gap-2 border-b border-border px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <DialogPrimitive.Title className=\"truncate text-body-sm font-semibold text-text\">{title}</DialogPrimitive.Title>\n {description ? (\n <DialogPrimitive.Description className=\"mt-0.5 text-label text-fg-4\">{description}</DialogPrimitive.Description>\n ) : null}\n </div>\n {actions}\n <DialogPrimitive.Close\n aria-label=\"Close\"\n className=\"-mr-1 flex size-6 shrink-0 items-center justify-center rounded-md text-fg-3 transition-colors outline-none hover:bg-surface-hover hover:text-fg-1\"\n >\n <X className=\"size-3.5\" />\n </DialogPrimitive.Close>\n </div>\n)\n\nexport const DialogBody: FunctionComponent<React.HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (\n <div className={cn('min-h-0 flex-1 overflow-y-auto p-4', className)} {...props} />\n)\n\nexport const DialogRow: FunctionComponent<{\n label: string\n children: React.ReactNode\n mono?: boolean\n}> = ({ label, children, mono }) => (\n <div className=\"flex items-baseline justify-between gap-4 py-1.5\">\n <span className=\"shrink-0 text-label text-fg-3\">{label}</span>\n <span className={cn('min-w-0 truncate text-right text-body-sm text-fg-1', mono && 'font-mono text-label')}>{children}</span>\n </div>\n)\n","import { type FunctionComponent, type ReactElement, type ReactNode } from 'react'\nimport { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const TooltipProvider = TooltipPrimitive.Provider\n\nexport const TooltipContent: FunctionComponent<\n TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, 'side' | 'sideOffset'>\n> = ({ className, side = 'top', sideOffset = 6, ...props }) => (\n <TooltipPrimitive.Portal>\n <PortalScope>\n <TooltipPrimitive.Positioner side={side} sideOffset={sideOffset} className=\"isolate z-90\">\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n 'rounded-md border border-border bg-surface px-2 py-1 text-label text-fg-2 shadow-(--shadow-md) outline-none',\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Positioner>\n </PortalScope>\n </TooltipPrimitive.Portal>\n)\n\nexport function Tip({\n content,\n render,\n side,\n children,\n}: {\n content: ReactNode\n render?: ReactElement\n side?: 'top' | 'right' | 'bottom' | 'left'\n children?: ReactNode\n}) {\n return (\n <TooltipPrimitive.Root>\n <TooltipPrimitive.Trigger render={render ?? <span className=\"inline-flex\" />}>{children}</TooltipPrimitive.Trigger>\n <TooltipContent side={side}>{content}</TooltipContent>\n </TooltipPrimitive.Root>\n )\n}\n","export async function copyText(value: string): Promise<boolean> {\n // Optional-chained, not `in`-checked: some embedded webviews expose a `clipboard` object whose `writeText` rejects.\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value)\n return true\n }\n } catch {}\n return legacyCopy(value)\n}\n\nfunction legacyCopy(value: string): boolean {\n if (typeof document === 'undefined') {\n return false\n }\n const textarea = document.createElement('textarea')\n textarea.value = value\n textarea.setAttribute('readonly', '')\n textarea.style.position = 'fixed'\n textarea.style.top = '-9999px'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n const previous = document.activeElement\n try {\n textarea.select()\n textarea.setSelectionRange(0, value.length)\n return document.execCommand('copy')\n } catch {\n return false\n } finally {\n document.body.removeChild(textarea)\n if (previous instanceof HTMLElement) {\n previous.focus()\n }\n }\n}\n","import { useState } from 'react'\nimport { Check, Copy } from 'lucide-react'\nimport { Button, type ButtonProps } from './Button.tsx'\nimport { copyText } from '../../lib/clipboard.ts'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface CopyButtonProps extends Omit<ButtonProps, 'onClick' | 'children'> {\n value: string\n glyph?: boolean\n}\n\nexport function CopyButton({ value, glyph, className, variant = 'ghost', size = 'icon-sm', ...props }: CopyButtonProps) {\n const [copied, setCopied] = useState(false)\n return (\n <Button\n variant={variant}\n size={size}\n aria-label=\"Copy\"\n className={cn('text-fg-3', className)}\n onClick={() => {\n void copyText(value).then((ok) => {\n if (!ok) {\n return\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n })\n }}\n {...props}\n >\n {glyph ? (\n <span className={cn('font-mono text-body-sm leading-5', copied && 'text-success')}>{copied ? '✓' : '⧉'}</span>\n ) : copied ? (\n <Check className=\"size-3.5 text-success\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </Button>\n )\n}\n","import { LoaderCircle } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\n\nexport function Spinner({ className }: { className?: string }) {\n return <LoaderCircle aria-label=\"Loading\" className={cn('size-4 animate-spin text-fg-3', className)} />\n}\n","import type { ReactNode } from 'react'\nimport { CopyButton } from './CopyButton.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface CodeBlockProps {\n code: string\n label?: ReactNode\n copyable?: boolean\n variant?: 'panel' | 'plain'\n className?: string\n}\n\nexport function CodeBlock({ code, label, copyable = true, variant = 'panel', className }: CodeBlockProps) {\n const plain = variant === 'plain'\n const header = label !== undefined || copyable\n\n if (plain) {\n return (\n <div data-slot=\"code-block\" data-variant=\"plain\" className={cn('min-w-0', className)}>\n {header ? (\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"truncate text-label leading-5 text-fg-4\">{label}</span>\n {copyable ? <CopyButton glyph value={code} className=\"size-5 shrink-0 rounded-sm\" /> : null}\n </div>\n ) : null}\n <pre className=\"max-h-64 overflow-auto bg-code-bg px-2 font-mono text-label leading-5 whitespace-pre-wrap text-fg-2\">{code}</pre>\n </div>\n )\n }\n\n return (\n <div data-slot=\"code-block\" className={cn('overflow-hidden rounded-md border border-border bg-code-bg', className)}>\n {header ? (\n <div className=\"flex h-8 items-center justify-between border-b border-border px-2.5\">\n <span className=\"font-mono text-label text-fg-3\">{label}</span>\n {copyable ? <CopyButton value={code} /> : null}\n </div>\n ) : null}\n <pre className=\"max-h-64 overflow-auto px-3 py-2 font-mono text-label whitespace-pre-wrap text-fg-2\">{code}</pre>\n </div>\n )\n}\n","import { useCallback, useRef, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface SplitterProps {\n orientation: 'vertical' | 'horizontal'\n value: number\n onValueChange: (value: number) => void\n min: number\n max: number\n step?: number\n defaultValue?: number\n inverted?: boolean\n 'aria-label': string\n className?: string\n}\n\nexport function Splitter({\n orientation,\n value,\n onValueChange,\n min,\n max,\n step = 16,\n defaultValue,\n inverted,\n 'aria-label': label,\n className,\n}: SplitterProps) {\n const drag = useRef<{ origin: number; start: number } | null>(null)\n const vertical = orientation === 'vertical'\n\n const clamp = useCallback((next: number) => Math.min(max, Math.max(min, next)), [min, max])\n\n const onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) {\n return\n }\n event.preventDefault()\n event.currentTarget.setPointerCapture(event.pointerId)\n drag.current = { origin: vertical ? event.clientX : event.clientY, start: value }\n }\n\n const onPointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {\n const state = drag.current\n if (!state) {\n return\n }\n const delta = (vertical ? event.clientX : event.clientY) - state.origin\n onValueChange(clamp(state.start + (inverted ? -delta : delta)))\n }\n\n const endDrag = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag.current) {\n return\n }\n drag.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n }\n\n // Reached after `endDrag` — the second click of a double-click has already started a drag, and dblclick fires after pointerup.\n const onDoubleClick = () => {\n if (defaultValue !== undefined) {\n onValueChange(clamp(defaultValue))\n }\n }\n\n const onKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n const grow = vertical ? 'ArrowRight' : 'ArrowDown'\n const shrink = vertical ? 'ArrowLeft' : 'ArrowUp'\n const direction = inverted ? -1 : 1\n if (event.key === grow) {\n onValueChange(clamp(value + step * direction))\n } else if (event.key === shrink) {\n onValueChange(clamp(value - step * direction))\n } else if (event.key === 'Home') {\n onValueChange(min)\n } else if (event.key === 'End') {\n onValueChange(max)\n } else {\n return\n }\n event.preventDefault()\n }\n\n return (\n <div\n data-slot=\"splitter\"\n role=\"separator\"\n tabIndex={0}\n aria-label={label}\n aria-orientation={orientation}\n aria-valuenow={Math.round(value)}\n aria-valuemin={min}\n aria-valuemax={max}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onDoubleClick={onDoubleClick}\n onKeyDown={onKeyDown}\n className={cn(\n 'group relative shrink-0 touch-none bg-border transition-colors',\n 'hover:bg-border-strong focus-visible:bg-accent focus-visible:outline-none',\n vertical ? 'w-px cursor-col-resize' : 'h-px cursor-row-resize',\n className,\n )}\n >\n <span aria-hidden className={cn('absolute', vertical ? '-inset-x-[3px] inset-y-0' : '-inset-y-[3px] inset-x-0')} />\n </div>\n )\n}\n","import { cn } from '../../lib/utils.ts'\n\nexport interface ProgressRingProps {\n value: number\n size?: number\n strokeWidth?: number\n className?: string\n}\n\nexport function ProgressRing({ value, size = 13, strokeWidth = 2, className }: ProgressRingProps) {\n const clamped = Math.min(100, Math.max(0, value))\n const radius = (size - strokeWidth) / 2\n const circumference = 2 * Math.PI * radius\n return (\n <svg\n data-slot=\"progress-ring\"\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n role=\"img\"\n aria-label={`${Math.round(clamped)}%`}\n className={cn('shrink-0 -rotate-90', className)}\n >\n <circle cx={size / 2} cy={size / 2} r={radius} fill=\"none\" stroke=\"currentColor\" strokeOpacity={0.2} strokeWidth={strokeWidth} />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={circumference * (1 - clamped / 100)}\n />\n </svg>\n )\n}\n","/**\n * Pure logic engine for the PromptArea component.\n * No DOM dependencies - fully testable in Node.\n */\nimport type { Segment, ChipSegment, TriggerConfig, TriggerPosition, ActiveTrigger } from './types.ts'\n\n// Serialization\n\n/**\n * Converts an array of segments to a plain text string.\n * Chips are represented as `{trigger}{displayText}` (e.g., \"@Alice\").\n */\nexport function segmentsToPlainText(segments: Segment[]): string {\n return segments\n .map((seg) => {\n if (seg.type === 'text') {\n return seg.text\n }\n return `${seg.trigger}${seg.displayText}`\n })\n .join('')\n}\n\n/**\n * Converts plain text into a single text segment.\n * Used for initial value conversion from plain strings.\n */\nexport function plainTextToSegments(text: string): Segment[] {\n if (!text) {\n return []\n }\n return [{ type: 'text', text }]\n}\n\n/**\n * Truncates segments so their combined plain-text length is at most `maxLength`.\n * Whole segments are kept while they fit; a text segment that crosses the limit\n * is sliced to fit, and a chip that would cross the limit is dropped (a chip\n * can't be partially represented).\n */\nexport function truncateSegmentsToLength(segments: Segment[], maxLength: number): Segment[] {\n if (maxLength <= 0) {\n return []\n }\n const result: Segment[] = []\n let length = 0\n for (const seg of segments) {\n const segLength = seg.type === 'text' ? seg.text.length : seg.trigger.length + seg.displayText.length\n if (length + segLength <= maxLength) {\n result.push(seg)\n length += segLength\n continue\n }\n if (seg.type === 'text') {\n let remaining = maxLength - length\n if (remaining > 0) {\n // Don't split a surrogate pair: if the cut lands right after a high\n // surrogate, drop the incomplete code point instead of a lone surrogate.\n const code = seg.text.charCodeAt(remaining - 1)\n if (code >= 0xd800 && code <= 0xdbff) {\n remaining -= 1\n }\n if (remaining > 0) {\n result.push({ type: 'text', text: seg.text.slice(0, remaining) })\n }\n }\n }\n break\n }\n return result\n}\n\n// Whitespace / word boundaries\n\n/**\n * Single source of truth for what counts as an inline-whitespace word boundary\n * in the editor model: a space, newline, or tab.\n *\n * Trigger detection, paste auto-resolution, and position validation all rely\n * on the *same* notion of a boundary — keeping it here prevents the three\n * call sites from silently drifting apart (e.g. one handling tabs and the\n * others not).\n */\nexport function isInlineWhitespace(char: string | undefined): boolean {\n return char === ' ' || char === '\\n' || char === '\\t'\n}\n\n/**\n * Builds a lookup from trigger character to its config. When two triggers\n * share a character the first one wins, preserving the previous `Array.find`\n * semantics while turning the per-character scan into an O(1) map read.\n */\nfunction buildTriggerCharMap(triggers: TriggerConfig[]): Map<string, TriggerConfig> {\n const map = new Map<string, TriggerConfig>()\n for (const trigger of triggers) {\n if (!map.has(trigger.char)) {\n map.set(trigger.char, trigger)\n }\n }\n return map\n}\n\n// Trigger position validation\n\n/**\n * Checks whether a trigger character at the given position in text\n * is valid according to the position rule.\n *\n * @param text - The full text content\n * @param charIndex - The index of the trigger character in the text\n * @param position - The position rule to validate against\n */\nexport function isValidTriggerPosition(text: string, charIndex: number, position: TriggerPosition): boolean {\n if (charIndex === 0) {\n return true\n }\n\n const prevChar = text[charIndex - 1]\n\n if (position === 'start') {\n return prevChar === '\\n'\n }\n\n // position === 'any': valid after any whitespace\n return isInlineWhitespace(prevChar)\n}\n\n// Trigger detection\n\n/**\n * Scans backwards from the cursor position to detect if the user is\n * currently typing a trigger word.\n *\n * Returns the active trigger info, or null if no trigger is active.\n *\n * @param text - The full plain text content\n * @param cursorPos - The cursor position (character offset from start)\n * @param triggers - Available trigger configurations\n */\nexport function detectActiveTrigger(text: string, cursorPos: number, triggers: TriggerConfig[]): ActiveTrigger | null {\n if (!text || cursorPos === 0 || triggers.length === 0) {\n return null\n }\n\n const triggerByChar = buildTriggerCharMap(triggers)\n\n // Scan backwards from cursor to find the nearest trigger character.\n // Stop at whitespace (trigger word has ended) or start of text.\n for (let i = cursorPos - 1; i >= 0; i--) {\n const char = text[i]\n\n // If we hit whitespace before finding a trigger, check if this whitespace\n // is immediately followed by a trigger character\n if (isInlineWhitespace(char)) {\n // The character after this whitespace could be a trigger\n if (i + 1 < cursorPos) {\n const nextChar = text[i + 1]\n const matchingTrigger = triggerByChar.get(nextChar)\n if (matchingTrigger && isValidTriggerPosition(text, i + 1, matchingTrigger.position)) {\n return {\n config: matchingTrigger,\n startOffset: i + 1,\n query: text.slice(i + 2, cursorPos),\n }\n }\n }\n // No trigger found after this whitespace, stop searching\n return null\n }\n\n const matchingTrigger = triggerByChar.get(char)\n if (matchingTrigger && isValidTriggerPosition(text, i, matchingTrigger.position)) {\n return {\n config: matchingTrigger,\n startOffset: i,\n query: text.slice(i + 1, cursorPos),\n }\n }\n }\n\n return null\n}\n\n// Chip resolution\n\n/**\n * Resolves an active trigger into a chip within the segments array.\n * Replaces the trigger text (trigger char + query) with a chip segment.\n *\n * @param segments - Current document segments\n * @param activeTrigger - The active trigger to resolve\n * @param chip - The chip data (value, displayText, optional data)\n * @returns New segments array with the chip inserted, and the new cursor position\n */\nexport function resolveChip(\n segments: Segment[],\n activeTrigger: ActiveTrigger,\n chip: { value: string; displayText: string; data?: unknown; autoResolved?: boolean },\n): { segments: Segment[]; cursorOffset: number } {\n const triggerStart = activeTrigger.startOffset\n const triggerEnd = triggerStart + 1 + activeTrigger.query.length // +1 for trigger char\n\n const newSegments: Segment[] = []\n let offset = 0\n\n for (const seg of segments) {\n if (seg.type === 'chip') {\n const chipText = `${seg.trigger}${seg.displayText}`\n const chipStart = offset\n const chipEnd = offset + chipText.length\n\n // If the trigger range overlaps with this chip, something is wrong.\n // Chips should not be partially replaced.\n if (chipEnd <= triggerStart || chipStart >= triggerEnd) {\n newSegments.push(seg)\n }\n offset = chipEnd\n } else {\n const textStart = offset\n const textEnd = offset + seg.text.length\n\n if (textEnd <= triggerStart) {\n // Entirely before the trigger - keep as-is\n newSegments.push(seg)\n } else if (textStart >= triggerEnd) {\n // Entirely after the trigger - keep as-is\n newSegments.push(seg)\n } else {\n // This text segment contains (part of) the trigger range\n const beforeText = seg.text.slice(0, Math.max(0, triggerStart - textStart))\n const afterText = seg.text.slice(Math.min(seg.text.length, triggerEnd - textStart))\n\n if (beforeText) {\n newSegments.push({ type: 'text', text: beforeText })\n }\n\n const newChip: ChipSegment = {\n type: 'chip',\n trigger: activeTrigger.config.char,\n value: chip.value,\n displayText: chip.displayText,\n ...(chip.data !== undefined ? { data: chip.data } : {}),\n ...(chip.autoResolved ? { autoResolved: true } : {}),\n }\n newSegments.push(newChip)\n\n // Add trailing space after chip, then any remaining text\n if (afterText) {\n newSegments.push({ type: 'text', text: ' ' + afterText.replace(/^\\s/, '') })\n } else {\n newSegments.push({ type: 'text', text: ' ' })\n }\n }\n\n offset = textEnd\n }\n }\n\n const merged = mergeAdjacentTextSegments(newSegments)\n\n // Cursor should be placed after the chip + trailing space.\n // Find the *last* matching chip so duplicates resolve correctly.\n let lastChipEndOffset = -1\n let runningOffset = 0\n for (const seg of merged) {\n if (seg.type === 'text') {\n runningOffset += seg.text.length\n } else {\n runningOffset += seg.trigger.length + seg.displayText.length\n if (seg.value === chip.value && seg.displayText === chip.displayText && seg.trigger === activeTrigger.config.char) {\n lastChipEndOffset = runningOffset\n }\n }\n }\n // +1 accounts for the trailing space after the chip\n const cursorOffset = lastChipEndOffset === -1 ? runningOffset : lastChipEndOffset + 1\n\n return { segments: merged, cursorOffset }\n}\n\n/**\n * Replaces the active trigger's range with **plain text** instead of a chip.\n *\n * The sibling of {@link resolveChip}, for suggestions that are a typing aid\n * rather than a token: what lands in the document is ordinary editable text the\n * user is expected to finish and change, and it must not look or behave like a\n * resolved chip — no immutability, no trigger character, nothing for a consumer\n * to parse back out. The caret is left at the end of the inserted text so typing\n * continues from there.\n */\nexport function resolveText(\n segments: Segment[],\n activeTrigger: ActiveTrigger,\n text: string,\n): { segments: Segment[]; cursorOffset: number } {\n const triggerStart = activeTrigger.startOffset\n const triggerEnd = triggerStart + 1 + activeTrigger.query.length // +1 for trigger char\n\n const newSegments: Segment[] = []\n let offset = 0\n let cursorOffset = triggerStart + text.length\n\n for (const seg of segments) {\n if (seg.type === 'chip') {\n const chipEnd = offset + `${seg.trigger}${seg.displayText}`.length\n // A trigger range can never overlap a chip — chips are atomic — so a chip\n // is either wholly before or wholly after, and is kept either way.\n if (chipEnd <= triggerStart || offset >= triggerEnd) {\n newSegments.push(seg)\n }\n offset = chipEnd\n continue\n }\n const textStart = offset\n const textEnd = offset + seg.text.length\n if (textEnd <= triggerStart || textStart >= triggerEnd) {\n newSegments.push(seg)\n } else {\n const before = seg.text.slice(0, Math.max(0, triggerStart - textStart))\n const after = seg.text.slice(Math.min(seg.text.length, triggerEnd - textStart))\n if (before) {\n newSegments.push({ type: 'text', text: before })\n }\n newSegments.push({ type: 'text', text })\n if (after) {\n newSegments.push({ type: 'text', text: after })\n }\n }\n offset = textEnd\n }\n\n const merged = mergeAdjacentTextSegments(newSegments)\n // Clamp: a trigger detected against a stale document could otherwise leave the\n // caret past the end, which renders as no caret at all.\n const total = segmentsToPlainText(merged).length\n if (cursorOffset > total) {\n cursorOffset = total\n }\n return { segments: merged, cursorOffset }\n}\n\n// Chip removal\n\n/**\n * Removes a chip at the given segment index and merges adjacent text segments.\n *\n * @param segments - Current document segments\n * @param index - The segment index to remove\n * @returns New segments array with the chip removed\n */\nexport function removeChipAtIndex(segments: Segment[], index: number): Segment[] {\n if (index < 0 || index >= segments.length) {\n return segments\n }\n if (segments[index].type !== 'chip') {\n return segments\n }\n\n const result = [...segments.slice(0, index), ...segments.slice(index + 1)]\n return mergeAdjacentTextSegments(result)\n}\n\n/**\n * Reverts an auto-resolved chip at the given segment index back to plain text.\n * The text includes the trigger character + display text (e.g., \"#readme\").\n *\n * @param segments - Current document segments\n * @param index - The segment index to revert\n * @returns New segments with the chip replaced by text, or null if not applicable\n */\nexport function revertChipAtIndex(segments: Segment[], index: number): { segments: Segment[]; revertedText: string } | null {\n if (index < 0 || index >= segments.length) {\n return null\n }\n const seg = segments[index]\n if (seg.type !== 'chip' || !seg.autoResolved) {\n return null\n }\n\n const revertedText = `${seg.trigger}${seg.displayText}`\n const result = [...segments.slice(0, index), { type: 'text' as const, text: revertedText }, ...segments.slice(index + 1)]\n return { segments: mergeAdjacentTextSegments(result), revertedText }\n}\n\n// Paste: resolve trigger patterns in segments\n\n/**\n * Scans text segments for trigger patterns and auto-resolves them into chips.\n * Only resolves triggers that have `resolveOnSpace: true`.\n *\n * Trigger patterns must appear at word boundaries: start of text, after\n * whitespace, or after a newline. This avoids false positives like email\n * addresses (user@example.com).\n */\nexport function resolveTriggersInSegments(segments: Segment[], triggers: TriggerConfig[]): Segment[] {\n const autoResolveTriggers = triggers.filter((t) => t.resolveOnSpace)\n if (autoResolveTriggers.length === 0) {\n return segments\n }\n\n const triggerByChar = buildTriggerCharMap(autoResolveTriggers)\n const result: Segment[] = []\n\n for (const seg of segments) {\n if (seg.type === 'chip') {\n result.push(seg)\n continue\n }\n\n const parts = splitTextByTriggerPatterns(seg.text, triggerByChar)\n result.push(...parts)\n }\n\n return mergeAdjacentTextSegments(result)\n}\n\n/**\n * Splits a text string into text and chip segments based on trigger patterns.\n * A trigger pattern is: (start-of-string | whitespace) + trigger_char + word_chars\n * followed by whitespace or end-of-string.\n */\nfunction splitTextByTriggerPatterns(text: string, triggerByChar: Map<string, TriggerConfig>): Segment[] {\n if (!text) {\n return []\n }\n\n const segments: Segment[] = []\n let i = 0\n\n while (i < text.length) {\n const char = text[i]\n\n if (triggerByChar.has(char)) {\n const isAtBoundary = i === 0 || isInlineWhitespace(text[i - 1])\n\n if (isAtBoundary) {\n const trigger = triggerByChar.get(char)\n if (trigger && isValidTriggerPosition(text, i, trigger.position)) {\n let end = i + 1\n while (end < text.length && !isInlineWhitespace(text[end])) {\n end++\n }\n\n const query = text.slice(i + 1, end)\n if (query.length > 0) {\n // Treat both undefined and '' from onSelect as \"no custom label\"\n // and fall back to the query — an empty displayText would render\n // a blank chip.\n const displayText = trigger.onSelect?.({ value: query, label: query }) || query\n segments.push({\n type: 'chip',\n trigger: char,\n value: query,\n displayText,\n autoResolved: true,\n })\n i = end\n continue\n }\n }\n }\n }\n\n const start = i\n i++\n while (i < text.length && !(triggerByChar.has(text[i]) && isInlineWhitespace(text[i - 1]))) {\n i++\n }\n segments.push({ type: 'text', text: text.slice(start, i) })\n }\n\n return segments\n}\n\n// Text range replacement\n\n/**\n * Replaces a range of plain text within the segments array.\n * Handles segment boundaries correctly, preserving chip segments.\n *\n * @param segments - Current document segments\n * @param start - Start offset in plain text\n * @param end - End offset in plain text\n * @param replacement - The replacement text\n * @returns New segments array with the replacement applied\n */\nexport function replaceTextRange(segments: Segment[], start: number, end: number, replacement: string): Segment[] {\n const newSegments: Segment[] = []\n let offset = 0\n let inserted = false\n\n for (const seg of segments) {\n if (seg.type === 'chip') {\n const chipText = `${seg.trigger}${seg.displayText}`\n const chipStart = offset\n const chipEnd = offset + chipText.length\n\n // For insertion (start === end), insert before this chip if position matches\n if (!inserted && start === end && chipStart === start) {\n newSegments.push({ type: 'text', text: replacement })\n inserted = true\n }\n\n if (chipEnd <= start || chipStart >= end) {\n newSegments.push(seg)\n }\n offset = chipEnd\n } else {\n const textStart = offset\n const textEnd = offset + seg.text.length\n\n const isBefore = start === end ? textEnd < start : textEnd <= start\n const isAfter = start === end ? textStart > end : textStart >= end\n\n if (isBefore) {\n // Entirely before the range\n newSegments.push(seg)\n } else if (isAfter) {\n // Entirely after the range\n newSegments.push(seg)\n } else {\n // Overlaps with the range (or contains the insertion point)\n const beforeText = seg.text.slice(0, Math.max(0, start - textStart))\n const afterText = seg.text.slice(Math.min(seg.text.length, end - textStart))\n\n if (beforeText) {\n newSegments.push({ type: 'text', text: beforeText })\n }\n // Insert replacement only once (when we first enter the range)\n if (!inserted && textStart <= start) {\n newSegments.push({ type: 'text', text: replacement })\n inserted = true\n }\n if (afterText) {\n newSegments.push({ type: 'text', text: afterText })\n }\n }\n\n offset = textEnd\n }\n }\n\n // Fallback: if replacement wasn't inserted (e.g., insertion at very end)\n if (!inserted && replacement) {\n newSegments.push({ type: 'text', text: replacement })\n }\n\n return mergeAdjacentTextSegments(newSegments)\n}\n\n// Markdown formatting shortcuts\n\n/**\n * Toggles markdown wrap markers around a selected text range.\n * If the selection is already wrapped with the marker, unwraps it.\n * If not wrapped, wraps it.\n *\n * @param segments - Current document segments\n * @param selectionStart - Start offset in plain text\n * @param selectionEnd - End offset in plain text\n * @param marker - The markdown marker (e.g., '**' for bold, '*' for italic)\n * @returns New segments and selection offsets, or null if selection is collapsed\n */\nexport function toggleMarkdownWrap(\n segments: Segment[],\n selectionStart: number,\n selectionEnd: number,\n marker: string,\n): { segments: Segment[]; selectionStart: number; selectionEnd: number } | null {\n if (selectionStart === selectionEnd) {\n return null\n }\n\n const plainText = segmentsToPlainText(segments)\n const markerLen = marker.length\n\n const hasOpeningMarker = selectionStart >= markerLen && plainText.slice(selectionStart - markerLen, selectionStart) === marker\n const hasClosingMarker =\n selectionEnd + markerLen <= plainText.length && plainText.slice(selectionEnd, selectionEnd + markerLen) === marker\n\n let isWrapped = hasOpeningMarker && hasClosingMarker\n\n // For single-char markers (e.g., '*'), ensure we're not matching\n // inside a multi-char marker (e.g., '**')\n if (isWrapped && markerLen === 1) {\n const charBeforeOpening = selectionStart > markerLen ? plainText[selectionStart - markerLen - 1] : ''\n const charAfterClosing = selectionEnd + markerLen < plainText.length ? plainText[selectionEnd + markerLen] : ''\n if (charBeforeOpening === marker || charAfterClosing === marker) {\n isWrapped = false\n }\n }\n\n if (isWrapped) {\n // Unwrap: remove closing marker first (preserves start offsets), then opening\n const afterClosing = replaceTextRange(segments, selectionEnd, selectionEnd + markerLen, '')\n const afterOpening = replaceTextRange(afterClosing, selectionStart - markerLen, selectionStart, '')\n return {\n segments: afterOpening,\n selectionStart: selectionStart - markerLen,\n selectionEnd: selectionEnd - markerLen,\n }\n }\n\n // Wrap: insert closing marker first (preserves start offsets), then opening\n const afterClosing = replaceTextRange(segments, selectionEnd, selectionEnd, marker)\n const afterOpening = replaceTextRange(afterClosing, selectionStart, selectionStart, marker)\n return {\n segments: afterOpening,\n selectionStart: selectionStart + markerLen,\n selectionEnd: selectionEnd + markerLen,\n }\n}\n\n// Inline markdown parsing\n\nexport type MarkdownToken =\n | { type: 'plain'; text: string }\n | { type: 'bold'; text: string }\n | { type: 'italic'; text: string }\n | { type: 'bold-italic'; text: string }\n | { type: 'url'; text: string }\n\n/**\n * Parses text for simple inline markdown: bold, italic, bold-italic, and URLs.\n * Does NOT handle block-level markdown (lists, headings, etc.).\n */\nexport function parseInlineMarkdown(text: string): MarkdownToken[] {\n if (!text) {\n return []\n }\n\n const tokens: MarkdownToken[] = []\n // Regex patterns for inline markdown elements:\n // 1. ***text*** or ___text___ -> bold-italic\n // 2. **text** or __text__ -> bold\n // 3. *text* or _text_ -> italic\n // 4. https://... or http://... -> URL\n const pattern = /(\\*{3}(.+?)\\*{3})|(\\*{2}(.+?)\\*{2})|(\\*(.+?)\\*)|(https?:\\/\\/[^\\s),]+)/g\n\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n while ((match = pattern.exec(text)) !== null) {\n if (match.index > lastIndex) {\n tokens.push({ type: 'plain', text: text.slice(lastIndex, match.index) })\n }\n\n if (match[1] && match[2]) {\n // ***bold-italic***\n tokens.push({ type: 'bold-italic', text: match[2] })\n } else if (match[3] && match[4]) {\n // **bold**\n tokens.push({ type: 'bold', text: match[4] })\n } else if (match[5] && match[6]) {\n // *italic*\n tokens.push({ type: 'italic', text: match[6] })\n } else if (match[7]) {\n // URL\n tokens.push({ type: 'url', text: match[7] })\n }\n\n lastIndex = match.index + match[0].length\n }\n\n if (lastIndex < text.length) {\n tokens.push({ type: 'plain', text: text.slice(lastIndex) })\n }\n\n return tokens\n}\n\n// Segment comparison\n\n/**\n * Shallow equality check for two segment arrays.\n * Compares type, text, trigger, value, displayText, and autoResolved fields.\n * Avoids JSON.stringify overhead for the common case.\n */\nexport function segmentsEqual(a: Segment[], b: Segment[]): boolean {\n if (a === b) {\n return true\n }\n if (a.length !== b.length) {\n return false\n }\n\n for (let i = 0; i < a.length; i++) {\n const sa = a[i]\n const sb = b[i]\n if (sa.type !== sb.type) {\n return false\n }\n if (sa.type === 'text') {\n if (sb.type !== 'text' || sa.text !== sb.text) {\n return false\n }\n } else {\n if (\n sb.type !== 'chip' ||\n sa.trigger !== sb.trigger ||\n sa.value !== sb.value ||\n sa.displayText !== sb.displayText ||\n sa.autoResolved !== sb.autoResolved\n ) {\n return false\n }\n }\n }\n return true\n}\n\n/**\n * Content equality regardless of how text is chunked into segments: adjacent\n * text segments are merged (and empty ones dropped) on both sides before\n * comparing, so a DOM read split by decorations or per-`<br>` newlines equals\n * the merged model that rendered it.\n */\nexport function segmentsContentEqual(a: Segment[], b: Segment[]): boolean {\n return segmentsEqual(mergeAdjacentTextSegments(a), mergeAdjacentTextSegments(b))\n}\n\n/**\n * Merges adjacent text segments into single text segments.\n * Also removes empty text segments.\n */\nexport function mergeAdjacentTextSegments(segments: Segment[]): Segment[] {\n const result: Segment[] = []\n\n for (const seg of segments) {\n if (seg.type === 'text' && seg.text === '') {\n continue\n }\n\n const last = result[result.length - 1]\n if (seg.type === 'text' && last?.type === 'text') {\n result[result.length - 1] = { type: 'text', text: last.text + seg.text }\n } else {\n result.push(seg)\n }\n }\n\n return result\n}\n","/**\n * List auto-formatting logic for the PromptArea component.\n * Pure — no DOM dependencies, fully testable in Node.\n */\nimport type { Segment } from './types.ts'\nimport { replaceTextRange, segmentsToPlainText } from './prompt-area-engine.ts'\n\n/**\n * Information about a list line at a given cursor position.\n */\nexport type ListContext = {\n /** Offset in plain text where the line begins */\n lineStart: number\n /** The full prefix including indentation (e.g., \" • \") */\n prefix: string\n /** Number of indentation levels (each = 2 spaces) */\n indent: number\n /** Type of list */\n listType: 'bullet' | 'numbered'\n /** For bullet lists, the marker char actually used (`•`, `-`, or `*`) */\n marker?: string\n /** For numbered lists, the number */\n number?: number\n /** Offset in plain text where content after the prefix starts */\n contentStart: number\n}\n\n/**\n * Parsed shape of a single list line — the SINGLE source of truth for what\n * counts as a list line (both `getListContext` and the renumber engine derive\n * from this, so the bullet/number regexes live in exactly one place).\n *\n * Offsets (`numberStart`/`numberEnd`) are relative to the START of the line.\n */\ntype ParsedListLine =\n | { kind: 'bullet'; indent: number; marker: string; prefixLen: number }\n | {\n kind: 'numbered'\n indent: number\n number: number\n /** Offset of the first digit within the line. */\n numberStart: number\n /** Offset just past the last digit within the line (exclusive). */\n numberEnd: number\n prefixLen: number\n }\n\n/** Classifies a single line as a bullet/numbered list item, or null. */\nfunction parseListLine(line: string): ParsedListLine | null {\n const bulletMatch = line.match(/^(\\s*)([•\\-*]) /)\n if (bulletMatch) {\n return {\n kind: 'bullet',\n indent: Math.floor(bulletMatch[1].length / 2),\n marker: bulletMatch[2],\n prefixLen: bulletMatch[0].length,\n }\n }\n\n const numberMatch = line.match(/^(\\s*)(\\d+)\\. /)\n if (numberMatch) {\n const numberStart = numberMatch[1].length\n return {\n kind: 'numbered',\n indent: Math.floor(numberMatch[1].length / 2),\n number: parseInt(numberMatch[2], 10),\n numberStart,\n numberEnd: numberStart + numberMatch[2].length,\n prefixLen: numberMatch[0].length,\n }\n }\n\n return null\n}\n\n/**\n * Detects if the cursor is in a list line and returns context about it.\n *\n * @param text - The full plain text content\n * @param cursorPos - The cursor position (character offset from start)\n * @returns List context if the cursor is in a list line, null otherwise\n */\nexport function getListContext(text: string, cursorPos: number): ListContext | null {\n const lineStart = text.lastIndexOf('\\n', cursorPos - 1) + 1\n const lineEnd = text.indexOf('\\n', cursorPos)\n const line = text.slice(lineStart, lineEnd === -1 ? text.length : lineEnd)\n\n const parsed = parseListLine(line)\n if (!parsed) {\n return null\n }\n\n return {\n lineStart,\n prefix: line.slice(0, parsed.prefixLen),\n indent: parsed.indent,\n listType: parsed.kind,\n ...(parsed.kind === 'bullet' ? { marker: parsed.marker } : { number: parsed.number }),\n contentStart: lineStart + parsed.prefixLen,\n }\n}\n\n/**\n * Detects if the user just typed a list trigger pattern (e.g., \"- \" or \"* \")\n * and returns the segments with the replacement applied.\n */\nexport function autoFormatListPrefix(segments: Segment[], cursorPos: number): { segments: Segment[]; cursorOffset: number } | null {\n const plainText = segmentsToPlainText(segments)\n const lineStart = plainText.lastIndexOf('\\n', cursorPos - 1) + 1\n const lineText = plainText.slice(lineStart, cursorPos)\n\n const match = lineText.match(/^(\\s*)[-*] $/)\n if (!match) {\n return null\n }\n\n const indent = match[1]\n const replacement = `${indent}• `\n const rangeStart = lineStart\n const rangeEnd = lineStart + lineText.length\n\n const newSegments = replaceTextRange(segments, rangeStart, rangeEnd, replacement)\n return {\n segments: newSegments,\n cursorOffset: lineStart + replacement.length,\n }\n}\n\n/**\n * Handles Enter key in a list line — continues the list or exits.\n */\nexport function insertListContinuation(segments: Segment[], cursorPos: number): { segments: Segment[]; cursorOffset: number } | null {\n const plainText = segmentsToPlainText(segments)\n const ctx = getListContext(plainText, cursorPos)\n if (!ctx) {\n return null\n }\n\n const lineEnd = plainText.indexOf('\\n', cursorPos)\n const lineContent = plainText.slice(ctx.contentStart, lineEnd === -1 ? plainText.length : lineEnd)\n\n if (lineContent.trim() === '') {\n // Enter on an empty item: outdent one level if nested (Notion/Docs style),\n // otherwise remove the prefix and exit the list to plain text.\n if (ctx.indent > 0) {\n const newSegments = replaceTextRange(segments, ctx.lineStart, ctx.lineStart + 2, '')\n return {\n segments: newSegments,\n cursorOffset: Math.max(ctx.lineStart, cursorPos - 2),\n }\n }\n const newSegments = replaceTextRange(segments, ctx.lineStart, ctx.lineStart + ctx.prefix.length, '')\n return {\n segments: newSegments,\n cursorOffset: ctx.lineStart,\n }\n }\n\n const indent = ' '.repeat(ctx.indent)\n let nextPrefix: string\n if (ctx.listType === 'bullet') {\n nextPrefix = `${indent}${ctx.marker ?? '•'} `\n } else {\n const nextNum = (ctx.number ?? 1) + 1\n nextPrefix = `${indent}${nextNum}. `\n }\n\n const insertion = `\\n${nextPrefix}`\n const newSegments = replaceTextRange(segments, cursorPos, cursorPos, insertion)\n return {\n segments: newSegments,\n cursorOffset: cursorPos + insertion.length,\n }\n}\n\n/** Returns the indent level of the list line directly above `lineStart`, or null. */\nfunction getPrevListLineLevel(text: string, lineStart: number): number | null {\n if (lineStart === 0) {\n return null\n }\n const prevLineStart = text.lastIndexOf('\\n', lineStart - 2) + 1\n const parsed = parseListLine(text.slice(prevLineStart, lineStart - 1))\n return parsed ? parsed.indent : null\n}\n\n/**\n * Indents a list item by one level (adds 2 spaces before the prefix), capped at\n * one level deeper than the line above. An item can only nest under a preceding\n * sibling, so the first item of a list — or an item already one level below its\n * parent — cannot indent further (returns null). This keeps sub-items visually\n * connected to a parent instead of drifting arbitrarily deep.\n */\nexport function indentListItem(segments: Segment[], cursorPos: number): { segments: Segment[]; cursorOffset: number } | null {\n const plainText = segmentsToPlainText(segments)\n const ctx = getListContext(plainText, cursorPos)\n if (!ctx) {\n return null\n }\n\n const prevLevel = getPrevListLineLevel(plainText, ctx.lineStart)\n const maxLevel = prevLevel === null ? 0 : prevLevel + 1\n if (ctx.indent >= maxLevel) {\n return null\n }\n\n const newSegments = replaceTextRange(segments, ctx.lineStart, ctx.lineStart, ' ')\n return {\n segments: newSegments,\n cursorOffset: cursorPos + 2,\n }\n}\n\n/**\n * Outdents a list item by one level (removes 2 spaces from before the prefix).\n */\nexport function outdentListItem(segments: Segment[], cursorPos: number): { segments: Segment[]; cursorOffset: number } | null {\n const plainText = segmentsToPlainText(segments)\n const ctx = getListContext(plainText, cursorPos)\n if (!ctx || ctx.indent === 0) {\n return null\n }\n\n const newSegments = replaceTextRange(segments, ctx.lineStart, ctx.lineStart + 2, '')\n return {\n segments: newSegments,\n cursorOffset: Math.max(ctx.lineStart, cursorPos - 2),\n }\n}\n\n/**\n * Removes the list prefix from the current line (e.g., on Backspace).\n */\nexport function removeListPrefix(segments: Segment[], cursorPos: number): { segments: Segment[]; cursorOffset: number } | null {\n const plainText = segmentsToPlainText(segments)\n const ctx = getListContext(plainText, cursorPos)\n if (!ctx) {\n return null\n }\n\n if (cursorPos > ctx.contentStart) {\n return null\n }\n\n const newSegments = replaceTextRange(segments, ctx.lineStart, ctx.contentStart, ' '.repeat(ctx.indent))\n return {\n segments: newSegments,\n cursorOffset: ctx.lineStart + ctx.indent * 2,\n }\n}\n\n/** A line that opens or closes a fenced code block (```), optionally indented. */\nconst FENCE_LINE = /^\\s*```/\n\n/** Swaps the leading list marker on a single line (\"- \" ↔ \"• \"). */\nfunction swapListPrefixLine(line: string, markdownEnabled: boolean): string {\n return markdownEnabled ? line.replace(/^(\\s*)- /, '$1• ') : line.replace(/^(\\s*)• /, '$1- ')\n}\n\n/**\n * Returns the set of line indices that sit inside a *balanced* fenced code\n * block (a ```…``` pair), so their leading \"- \"/\"• \" markers are preserved\n * verbatim. An unterminated (unpaired) fence marker is NOT protective — its\n * following lines still normalize — so a stray \"```\" in prose does not silently\n * suppress bullet normalization for the rest of the text.\n */\nfunction fenceProtectedLineIndices(lines: string[]): Set<number> {\n const protectedLines = new Set<number>()\n let openIndex = -1\n lines.forEach((line, i) => {\n if (!FENCE_LINE.test(line)) {\n return\n }\n if (openIndex === -1) {\n openIndex = i\n } else {\n for (let k = openIndex; k <= i; k++) {\n protectedLines.add(k)\n }\n openIndex = -1\n }\n })\n return protectedLines\n}\n\n/**\n * Normalizes markdown list prefixes in a raw text string (single source of\n * truth for the bullet-glyph swap, shared by segment normalization and paste):\n * - When markdown is enabled, converts \"- \" at line starts to \"• \"\n * - When markdown is disabled, converts \"• \" at line starts to \"- \"\n *\n * Lines inside a balanced ```…``` block are preserved verbatim.\n */\nexport function normalizeListPrefixText(text: string, markdownEnabled: boolean): string {\n const lines = text.split('\\n')\n const protectedLines = fenceProtectedLineIndices(lines)\n return lines.map((line, i) => (protectedLines.has(i) ? line : swapListPrefixLine(line, markdownEnabled))).join('\\n')\n}\n\n/**\n * Normalizes markdown list prefixes across text segments. See\n * {@link normalizeListPrefixText} for the per-line rule. Fence detection spans\n * the whole document (text segments flattened to a global line sequence), so a\n * code block split into per-line text segments on paste still has its \"- \" lines\n * preserved, while an unterminated fence does not suppress later bullets.\n */\nexport function normalizeListPrefixes(segments: Segment[], markdownEnabled: boolean): Segment[] {\n const globalLines: string[] = []\n segments.forEach((seg) => {\n if (seg.type === 'text') {\n globalLines.push(...seg.text.split('\\n'))\n }\n })\n const protectedLines = fenceProtectedLineIndices(globalLines)\n\n let globalIndex = 0\n let changed = false\n const result = segments.map((seg) => {\n if (seg.type !== 'text') {\n return seg\n }\n const newText = seg.text\n .split('\\n')\n .map((line) => {\n const out = protectedLines.has(globalIndex) ? line : swapListPrefixLine(line, markdownEnabled)\n globalIndex++\n return out\n })\n .join('\\n')\n if (newText === seg.text) {\n return seg\n }\n changed = true\n return { ...seg, text: newText }\n })\n return changed ? result : segments\n}\n\n// Ordered-list renumbering\n//\n// The visible number is a projection of position (like BlockNote/ProseMirror/\n// Notion), recomputed on every structural edit rather than trusted as stored\n// text. A per-indent-level counter STACK models nested lists: descending starts\n// a fresh counter at 1, ascending continues the shallower level and clears\n// deeper ones. Every run restarts at 1, so `1. 1. 1.` rebuilds to `1. 2. 3.`\n// and Tab-indenting an item restarts its sublist at 1.\n\n/**\n * A single rewritten number's digit run, in the INPUT text's coordinates.\n * `[oldStart, oldEnd)` spans only the digits (never the indentation or `. `).\n */\nexport type NumberEdit = { oldStart: number; oldEnd: number; newText: string }\n\n/**\n * Whether the text holds a genuine ordered-list run worth renumbering — a run\n * of 2+ consecutive same-level numbered lines that either starts at 1 or is\n * already a contiguous `n, n+1, …` sequence. Used to gate the paste path so a\n * copied list fragment (`3. 4. 5.` → renumber, or a broken `1. 1. 1.`) is\n * rebuilt, while incidental numeric-leading prose that `parseListLine` would\n * otherwise treat as a list — `1985. Born / 2020. Died`, `5. / 10. / 15.` — is\n * left untouched.\n */\nexport function hasOrderedListRun(text: string): boolean {\n let runLevel: number | null = null\n let runStart = 0\n let prevNumber = 0\n let runLength = 0\n let sequential = true\n\n for (const line of text.split('\\n')) {\n const parsed = parseListLine(line)\n if (parsed?.kind === 'numbered' && parsed.indent === runLevel) {\n sequential = sequential && parsed.number === prevNumber + 1\n prevNumber = parsed.number\n runLength++\n if (runLength >= 2 && (runStart === 1 || sequential)) {\n return true\n }\n } else if (parsed?.kind === 'numbered') {\n // Start a fresh run at this line's level.\n runLevel = parsed.indent\n runStart = parsed.number\n prevNumber = parsed.number\n runLength = 1\n sequential = true\n } else {\n runLevel = null\n runLength = 0\n }\n }\n\n return false\n}\n\n/**\n * Recomputes ordered-list numbering across the whole text. Returns the new text\n * plus the list of changed digit runs (ascending by `oldStart`) for cursor\n * remapping. When nothing changes, returns the SAME text reference and an empty\n * `edits` array — the no-op guard that keeps this off the typing hot path.\n */\nexport function renumberOrderedListLines(text: string): { text: string; edits: NumberEdit[] } {\n // Cheap pre-gate: with no ordered-list line there is nothing to renumber, so\n // skip the per-line scan and throwaway rebuild. This runs on every structural\n // edit (Enter, Tab, bold/italic wrap) and each paste, most of which never\n // touch a numbered list.\n if (!/^[ \\t]*\\d+\\. /m.test(text)) {\n return { text, edits: [] }\n }\n\n const counters = new Map<number, number>()\n const edits: NumberEdit[] = []\n const lines = text.split('\\n')\n let out = ''\n let lineStart = 0\n\n const clearDeeperThan = (level: number, inclusive: boolean) => {\n for (const key of counters.keys()) {\n if (inclusive ? key >= level : key > level) {\n counters.delete(key)\n }\n }\n }\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n const parsed = parseListLine(line)\n\n if (!parsed) {\n // A blank or plain (non-list) line breaks every open list run.\n counters.clear()\n out += line\n } else if (parsed.kind === 'bullet') {\n // A bullet interrupts numbered runs at its level and deeper; a shallower\n // numbered list continues across it.\n clearDeeperThan(parsed.indent, true)\n out += line\n } else {\n const level = parsed.indent\n clearDeeperThan(level, false)\n const current = counters.get(level)\n const n = current === undefined ? 1 : current + 1\n counters.set(level, n)\n\n const newDigits = String(n)\n if (newDigits === String(parsed.number)) {\n out += line\n } else {\n edits.push({\n oldStart: lineStart + parsed.numberStart,\n oldEnd: lineStart + parsed.numberEnd,\n newText: newDigits,\n })\n out += line.slice(0, parsed.numberStart) + newDigits + line.slice(parsed.numberEnd)\n }\n }\n\n if (i < lines.length - 1) {\n out += '\\n'\n }\n lineStart += line.length + 1 // + 1 for the consumed '\\n'\n }\n\n return edits.length === 0 ? { text, edits } : { text: out, edits }\n}\n\n/**\n * Remaps a caret/selection offset (in the renumber INPUT's coordinates) across\n * the digit-run edits. A single scalar delta is wrong: many spans each change\n * width, so the shift depends on how many changed spans lie strictly before the\n * offset, with a clamp when the offset sits inside a resized number.\n */\nexport function remapOffset(old: number, edits: NumberEdit[]): number {\n let shift = 0\n for (const e of edits) {\n if (e.oldEnd <= old) {\n shift += e.newText.length - (e.oldEnd - e.oldStart) // fully before\n } else if (e.oldStart >= old) {\n break // this and every later span is after the offset\n } else {\n return e.oldStart + shift + Math.min(old - e.oldStart, e.newText.length) // inside → clamp\n }\n }\n return old + shift\n}\n\n/**\n * Segment-level renumber used by the edit-commit path. Applies the digit-run\n * edits to the segments (right-to-left so earlier offsets stay valid) and\n * returns the changed spans for {@link remapOffset}. Digit runs are pure text at\n * line starts, so chips are never touched.\n */\nexport function renumberOrderedListSegments(segments: Segment[]): {\n segments: Segment[]\n edits: NumberEdit[]\n} {\n const { edits } = renumberOrderedListLines(segmentsToPlainText(segments))\n if (edits.length === 0) {\n return { segments, edits }\n }\n\n let result = segments\n for (let i = edits.length - 1; i >= 0; i--) {\n const e = edits[i]\n result = replaceTextRange(result, e.oldStart, e.oldEnd, e.newText)\n }\n return { segments: result, edits }\n}\n","/**\n * Type-safe DOM helper functions for PromptArea.\n *\n * These replace all `as` type assertions with proper type guards,\n * following the codebase rule: \"Never use `any` or `as` assertions.\"\n */\n\nimport type { ChipSegment } from './types.ts'\n\n/** URL pattern for detecting URLs in text content. */\nconst URL_PATTERN = /https?:\\/\\/[^\\s),]+/g\n/** Matches ***bold-italic***, **bold**, and *italic* spans. */\nconst MARKDOWN_INLINE_PATTERN = /(\\*{3})(.+?)\\*{3}|(\\*{2})(.+?)\\*{2}|(\\*)(.+?)\\*/g\n/** Matches a `•` bullet glyph at the start of a line (optionally indented). */\nconst LIST_BULLET_PATTERN = /(^|\\n)([ \\t]*)•/g\n/** A list line's leading indentation; the lookahead keeps the prefix itself out of the\n * capture, so only the indentation is wrapped. */\nconst LIST_INDENT_PATTERN = /(^|\\n)([ \\t]+)(?=(?:[•\\-*] |\\d+\\. ))/g\n\n// Type Guards\n\n/**\n * Type guard: checks if a DOM node is an HTMLElement.\n */\nexport function isHTMLElement(node: Node): node is HTMLElement {\n return node instanceof HTMLElement\n}\n\n/**\n * Type guard: checks if a DOM node is a chip element\n * (an HTMLElement with data-chip-trigger attribute).\n */\nexport function isChipElement(node: Node): node is HTMLElement {\n return node instanceof HTMLElement && node.dataset.chipTrigger !== undefined\n}\n\n/**\n * Type guard: checks if a DOM node is a BR element.\n */\nexport function isBRElement(node: Node): node is HTMLBRElement {\n return node instanceof HTMLBRElement\n}\n\n/**\n * Type guard: checks if a DOM node is a Text node.\n */\nexport function isTextNode(node: Node): node is Text {\n return node instanceof Text\n}\n\n/**\n * Checks whether a chip element was auto-resolved (created by pressing space\n * on resolveOnSpace triggers, rather than explicit dropdown selection).\n */\nexport function getChipAutoResolved(node: Node): boolean {\n return isChipElement(node) && node.dataset.chipAutoResolved === 'true'\n}\n\n/**\n * Type guard: checks if a DOM node is a URL link element\n * (an HTMLAnchorElement with data-url attribute).\n */\nexport function isLinkElement(node: Node): node is HTMLAnchorElement {\n return node instanceof HTMLAnchorElement && node.dataset.url === 'true'\n}\n\n// Safe JSON\n\n/**\n * Safely parses a JSON string, returning `unknown` instead of `any`.\n * Returns `undefined` if parsing fails.\n */\nexport function safeJsonParse(json: string): unknown {\n try {\n // JSON.parse returns `any` by default. We narrow it to `unknown`\n // which is the safest pattern — callers must validate before use.\n const parsed: unknown = JSON.parse(json)\n return parsed\n } catch {\n return undefined\n }\n}\n\n/**\n * Safely serializes a value to JSON, returning undefined on failure.\n */\nexport function safeJsonStringify(value: unknown): string | undefined {\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n}\n\n// DOM reading helpers\n\n/**\n * Reads the chip trigger character from a chip element's dataset.\n * Returns undefined if the node is not a chip element.\n */\nexport function getChipTrigger(node: Node): string | undefined {\n if (!isChipElement(node)) {\n return undefined\n }\n return node.dataset.chipTrigger\n}\n\n/**\n * Reads the chip value from a chip element's dataset.\n */\nexport function getChipValue(node: Node): string | undefined {\n if (!isChipElement(node)) {\n return undefined\n }\n return node.dataset.chipValue\n}\n\n/**\n * Reads the chip display text from a chip element's dataset.\n */\nexport function getChipDisplay(node: Node): string | undefined {\n if (!isChipElement(node)) {\n return undefined\n }\n return node.dataset.chipDisplay ?? node.textContent ?? undefined\n}\n\n/**\n * Reads and safely parses the chip data from a chip element's dataset.\n */\nexport function getChipData(node: Node): unknown {\n if (!isChipElement(node)) {\n return undefined\n }\n const raw = node.dataset.chipData\n if (!raw) {\n return undefined\n }\n return safeJsonParse(raw)\n}\n\n/**\n * Length of a chip's plain-text representation (`trigger + displayText`).\n *\n * This is the single definition used wherever DOM offsets are mapped to the\n * plain-text model (cursor mapping, selection sizing). The fallbacks mirror\n * how chips are rendered: `chipDisplay` is always set, but we degrade to\n * `textContent` for resilience against externally-mutated nodes.\n */\nexport function chipNodeTextLength(node: HTMLElement): number {\n const trigger = node.dataset.chipTrigger ?? ''\n const display = node.dataset.chipDisplay ?? node.textContent ?? ''\n return trigger.length + display.length\n}\n\n/**\n * Reads a chip element into a `ChipSegment`, mirroring how chips are written\n * in `renderSegmentsToDOM`. Returns null when the node is not a chip or is\n * missing a required attribute (trigger, value, or display text).\n *\n * This is the single chip reader shared by the DOM->model sync, chip-click\n * delegation, and clipboard serialization, so they cannot diverge on which\n * fields are required or how optional `data` / `autoResolved` are attached.\n */\nexport function chipNodeToSegment(node: Node): ChipSegment | null {\n if (!isChipElement(node)) {\n return null\n }\n\n const trigger = getChipTrigger(node)\n const value = getChipValue(node)\n const displayText = getChipDisplay(node)\n if (!trigger || value === undefined || !displayText) {\n return null\n }\n\n const data = getChipData(node)\n const autoResolved = getChipAutoResolved(node)\n\n return {\n type: 'chip',\n trigger,\n value,\n displayText,\n ...(data !== undefined ? { data } : {}),\n ...(autoResolved ? { autoResolved: true } : {}),\n }\n}\n\n// DOM manipulation helpers\n\n/**\n * Finds the index of a direct child node within a parent element.\n * Returns -1 if not found.\n */\nexport function indexOfChildNode(parent: HTMLElement, child: Node): number {\n const children = parent.childNodes\n for (let i = 0; i < children.length; i++) {\n if (children[i] === child) {\n return i\n }\n }\n return -1\n}\n\n/**\n * Whether a direct editor child node produces a segment when read by\n * `readSegmentsFromDOM` in use-prompt-area.ts. This is the single predicate\n * shared with `domChildIndexToSegmentIndex` below, so a DOM child index can\n * never map to a different segment index than the one the reader actually\n * produces — decoration elements (the URL `<a>` from `decorateURLsInEditor`,\n * the markdown `<span data-md>` from `decorateMarkdownInEditor`) fall through\n * to the reader's \"unknown element\" branch and DO produce a text segment, so\n * they must count here too, not just chips/text/`<br>`. A chip element only\n * counts if `chipNodeToSegment` would actually accept it — the reader skips a\n * chip missing a required attribute (trigger/value/display), so this must too.\n */\nexport function childProducesSegment(child: Node): boolean {\n if (child.nodeType === Node.TEXT_NODE) {\n return (child.textContent ?? '') !== ''\n }\n if (isBRElement(child)) {\n return !child.dataset.sentinel\n }\n if (isChipElement(child)) {\n return chipNodeToSegment(child) !== null\n }\n if (isHTMLElement(child)) {\n return (child.textContent ?? '') !== ''\n }\n return false\n}\n\n/**\n * Maps the index of a direct child node within the editor to the index of the\n * corresponding segment in the model array, by counting `childProducesSegment`\n * matches up to (but not including) `childIndex`.\n *\n * Keeping this in one place ensures chip-removal, chip-revert, and chip\n * in-place replacement all agree on the exact same mapping rules as the reader.\n */\nexport function domChildIndexToSegmentIndex(editor: HTMLElement, childIndex: number): number {\n let segIdx = 0\n for (let i = 0; i < childIndex; i++) {\n if (childProducesSegment(editor.childNodes[i])) {\n segIdx++\n }\n }\n return segIdx\n}\n\n/**\n * Gets the direct child of `ancestor` that contains `descendant`.\n * Walks up from descendant until we find a node whose parent is ancestor.\n * Returns null if descendant is not inside ancestor.\n */\nexport function getDirectChildContaining(ancestor: HTMLElement, descendant: Node): Node | null {\n let node: Node | null = descendant\n while (node !== null) {\n if (node.parentNode === ancestor) {\n return node\n }\n node = node.parentNode\n }\n return null\n}\n\n/**\n * Unwraps a block element (div, p) by replacing it with its child nodes\n * plus a trailing BR. Used for browser DOM normalization.\n */\nexport function unwrapBlockElement(parent: HTMLElement, block: HTMLElement): void {\n const fragment = document.createDocumentFragment()\n\n while (block.firstChild) {\n fragment.appendChild(block.firstChild)\n }\n\n fragment.appendChild(document.createElement('br'))\n\n parent.replaceChild(fragment, block)\n}\n\n/**\n * Normalizes the editor DOM after browser mutations.\n *\n * Browsers insert various wrapper elements on Enter/paste:\n * - Chrome wraps new lines in <div>\n * - Safari may use <div><br></div>\n * - Some use <p> tags\n *\n * This function unwraps all non-chip block elements, leaving only:\n * - Text nodes\n * - <br> elements\n * - Chip <span> elements (with data-chip-trigger)\n */\nexport function normalizeEditorDOM(editor: HTMLElement): boolean {\n let changed = false\n const blockTags = new Set(['DIV', 'P', 'SECTION', 'ARTICLE', 'BLOCKQUOTE'])\n\n // Iterate backwards since we're modifying the DOM\n for (let i = editor.childNodes.length - 1; i >= 0; i--) {\n const child = editor.childNodes[i]\n\n if (!(child instanceof HTMLElement)) {\n continue\n }\n if (child.dataset.chipTrigger !== undefined) {\n continue\n }\n if (child instanceof HTMLBRElement) {\n continue\n }\n\n const tag = child.tagName\n if (blockTags.has(tag)) {\n unwrapBlockElement(editor, child)\n changed = true\n } else if (\n tag === 'FONT' ||\n tag === 'B' ||\n tag === 'I' ||\n tag === 'U' ||\n tag === 'STRONG' ||\n tag === 'EM' ||\n tag === 'A' ||\n tag === 'SPAN'\n ) {\n // Unwrap inline formatting/decoration elements (browser-inserted or markdown decorations)\n const text = child.textContent ?? ''\n if (text) {\n editor.replaceChild(document.createTextNode(text), child)\n } else {\n editor.removeChild(child)\n }\n changed = true\n }\n }\n\n editor.normalize()\n\n return changed\n}\n\n// URL decoration\n\n/**\n * Walks direct-child text nodes in the editor and wraps URL text in\n * `<a>` elements for visual styling and clickability.\n *\n * This is a DOM-only decoration — it does NOT modify the segment model.\n * The `<a>` elements are stripped by `normalizeEditorDOM` on every input cycle,\n * so they are re-applied fresh each time.\n *\n * @param editor - The contentEditable root element\n * @returns Whether any decorations were applied\n */\nexport function decorateURLsInEditor(editor: HTMLElement): boolean {\n let decorated = false\n\n // Collect text nodes first (avoid modifying while iterating)\n const textNodes: Text[] = []\n for (let i = 0; i < editor.childNodes.length; i++) {\n const node = editor.childNodes[i]\n if (isTextNode(node) && node.textContent) {\n textNodes.push(node)\n }\n }\n\n for (const textNode of textNodes) {\n const text = textNode.textContent ?? ''\n URL_PATTERN.lastIndex = 0\n const matches: Array<{ url: string; index: number }> = []\n let match: RegExpExecArray | null\n\n while ((match = URL_PATTERN.exec(text)) !== null) {\n // Trim trailing punctuation that's likely not part of the URL\n let url = match[0]\n while (url.length > 0 && /[.;:!?]$/.test(url)) {\n url = url.slice(0, -1)\n }\n if (url.length > 0) {\n matches.push({ url, index: match.index })\n }\n }\n\n if (matches.length === 0) {\n continue\n }\n\n const parent = textNode.parentNode\n if (!parent) {\n continue\n }\n\n // Validate URLs upfront – only keep those with safe protocols (CWE-79)\n const safeMatches: Array<{ url: string; href: string; index: number }> = []\n for (const { url, index } of matches) {\n try {\n const parsed = new URL(url)\n if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {\n safeMatches.push({ url, href: parsed.href, index })\n }\n } catch {\n // skip malformed URLs\n }\n }\n\n if (safeMatches.length === 0) {\n continue\n }\n\n decorated = true\n const fragment = document.createDocumentFragment()\n let lastIndex = 0\n\n for (const { url, href, index } of safeMatches) {\n if (index > lastIndex) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)))\n }\n\n const anchor = document.createElement('a')\n anchor.href = href\n anchor.target = '_blank'\n anchor.rel = 'noopener noreferrer'\n anchor.dataset.url = 'true'\n anchor.className = 'text-accent hover:text-accent-hover underline cursor-pointer'\n anchor.textContent = url\n fragment.appendChild(anchor)\n\n lastIndex = index + url.length\n }\n\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n parent.replaceChild(fragment, textNode)\n }\n\n return decorated\n}\n\n// Markdown inline decoration\n\n/**\n * Walks direct-child text nodes in the editor and wraps markdown-formatted\n * text (`**bold**`, `*italic*`, `***bold-italic***`) in styled `<span>` elements.\n *\n * This is a DOM-only decoration — it does NOT modify the segment model.\n * The `<span>` elements are stripped by `normalizeEditorDOM` on every input cycle,\n * so they are re-applied fresh each time.\n *\n * The `*` markers stay visible in the text; only the CSS styling changes.\n *\n * @param editor - The contentEditable root element\n * @returns Whether any decorations were applied\n */\nexport function decorateMarkdownInEditor(editor: HTMLElement): boolean {\n let decorated = false\n\n // Collect text nodes first (avoid modifying while iterating)\n const textNodes: Text[] = []\n for (let i = 0; i < editor.childNodes.length; i++) {\n const node = editor.childNodes[i]\n if (isTextNode(node) && node.textContent) {\n textNodes.push(node)\n }\n }\n\n for (const textNode of textNodes) {\n const text = textNode.textContent ?? ''\n MARKDOWN_INLINE_PATTERN.lastIndex = 0\n const matches: Array<{\n fullMatch: string\n marker: string\n content: string\n index: number\n className: string\n }> = []\n let match: RegExpExecArray | null\n\n while ((match = MARKDOWN_INLINE_PATTERN.exec(text)) !== null) {\n if (match[1] && match[2]) {\n // ***bold-italic***\n matches.push({\n fullMatch: match[0],\n marker: match[1],\n content: match[2],\n index: match.index,\n className: 'font-bold italic',\n })\n } else if (match[3] && match[4]) {\n // **bold**\n matches.push({\n fullMatch: match[0],\n marker: match[3],\n content: match[4],\n index: match.index,\n className: 'font-bold',\n })\n } else if (match[5] && match[6]) {\n // *italic*\n matches.push({\n fullMatch: match[0],\n marker: match[5],\n content: match[6],\n index: match.index,\n className: 'italic',\n })\n }\n }\n\n if (matches.length === 0) {\n continue\n }\n\n decorated = true\n const parent = textNode.parentNode\n if (!parent) {\n continue\n }\n\n const fragment = document.createDocumentFragment()\n let lastIndex = 0\n\n for (const { fullMatch, marker, content, index, className } of matches) {\n if (index > lastIndex) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)))\n }\n\n // Parent span — textContent still returns full match (e.g. \"**world**\")\n const span = document.createElement('span')\n span.dataset.md = 'true'\n\n // Opening marker (visually hidden)\n const openMarker = document.createElement('span')\n openMarker.className = 'prompt-area-md-marker'\n openMarker.textContent = marker\n\n const styledContent = document.createElement('span')\n styledContent.className = className\n styledContent.textContent = content\n\n // Closing marker (visually hidden)\n const closeMarker = document.createElement('span')\n closeMarker.className = 'prompt-area-md-marker'\n closeMarker.textContent = marker\n\n span.appendChild(openMarker)\n span.appendChild(styledContent)\n span.appendChild(closeMarker)\n fragment.appendChild(span)\n\n lastIndex = index + fullMatch.length\n }\n\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n parent.replaceChild(fragment, textNode)\n }\n\n return decorated\n}\n\n/**\n * Walks direct-child text nodes and wraps each line-leading `•` bullet glyph in\n * a `<span class=\"prompt-area-list-bullet\">` so CSS can size it up (the raw\n * U+2022 glyph renders much smaller than the surrounding text).\n *\n * Like {@link decorateMarkdownInEditor}, this is a DOM-only decoration: the span\n * is stripped by {@link normalizeEditorDOM} on every input cycle, so the `•`\n * stays a plain character in the segment model and is re-decorated each render.\n *\n * @param editor - The contentEditable root element\n * @returns Whether any decorations were applied\n */\nexport function decorateBulletsInEditor(editor: HTMLElement): boolean {\n let decorated = false\n\n const textNodes: Text[] = []\n for (let i = 0; i < editor.childNodes.length; i++) {\n const node = editor.childNodes[i]\n if (isTextNode(node) && node.textContent?.includes('•')) {\n textNodes.push(node)\n }\n }\n\n for (const textNode of textNodes) {\n const text = textNode.textContent ?? ''\n LIST_BULLET_PATTERN.lastIndex = 0\n const bulletIndices: number[] = []\n let match: RegExpExecArray | null\n while ((match = LIST_BULLET_PATTERN.exec(text)) !== null) {\n bulletIndices.push(match.index + match[1].length + match[2].length)\n }\n\n if (bulletIndices.length === 0) {\n continue\n }\n\n decorated = true\n const parent = textNode.parentNode\n if (!parent) {\n continue\n }\n\n const fragment = document.createDocumentFragment()\n let lastIndex = 0\n\n for (const index of bulletIndices) {\n if (index > lastIndex) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)))\n }\n const span = document.createElement('span')\n span.dataset.md = 'true'\n span.className = 'prompt-area-list-bullet'\n span.textContent = '•'\n fragment.appendChild(span)\n lastIndex = index + 1 // the bullet is a single character\n }\n\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n parent.replaceChild(fragment, textNode)\n }\n\n return decorated\n}\n\n/**\n * Wraps each list line's leading indentation in an inline-block\n * `<span class=\"prompt-area-list-indent\">` sized per nesting level, so nested\n * items read with a wide, Notion-like indent instead of the raw 2-space gap.\n *\n * Like the other decorations this is display-only: the span keeps the original\n * whitespace as its textContent (so plain-text length and caret offsets are\n * unchanged) and is stripped by {@link normalizeEditorDOM} each input cycle.\n * Must run BEFORE the node-splitting passes ({@link decorateURLsInEditor},\n * {@link decorateMarkdownInEditor}, {@link decorateBulletsInEditor}) so every\n * direct-child text node is still a whole line — otherwise a mid-line split\n * fragment beginning with whitespace would let the `^` anchor false-match\n * non-line-leading whitespace.\n *\n * @returns Whether any decorations were applied\n */\nexport function decorateListIndentInEditor(editor: HTMLElement): boolean {\n let decorated = false\n\n const textNodes: Text[] = []\n for (let i = 0; i < editor.childNodes.length; i++) {\n const node = editor.childNodes[i]\n if (isTextNode(node)) {\n textNodes.push(node)\n }\n }\n\n for (const textNode of textNodes) {\n const text = textNode.textContent ?? ''\n LIST_INDENT_PATTERN.lastIndex = 0\n const runs: { start: number; end: number }[] = []\n let match: RegExpExecArray | null\n while ((match = LIST_INDENT_PATTERN.exec(text)) !== null) {\n const start = match.index + match[1].length\n runs.push({ start, end: start + match[2].length })\n }\n\n if (runs.length === 0) {\n continue\n }\n\n decorated = true\n const parent = textNode.parentNode\n if (!parent) {\n continue\n }\n\n const fragment = document.createDocumentFragment()\n let lastIndex = 0\n\n for (const { start, end } of runs) {\n if (start > lastIndex) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex, start)))\n }\n const whitespace = text.slice(start, end)\n const level = Math.floor(whitespace.length / 2)\n const span = document.createElement('span')\n span.dataset.md = 'true'\n span.className = 'prompt-area-list-indent'\n span.style.width = `calc(var(--prompt-area-indent-size, 1.5em) * ${level})`\n span.textContent = whitespace\n fragment.appendChild(span)\n lastIndex = end\n }\n\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex)))\n }\n\n parent.replaceChild(fragment, textNode)\n }\n\n return decorated\n}\n\n/**\n * Applies every display-only decoration to the editor in one pass: URL links\n * always, plus markdown emphasis, list indentation, and list bullets when\n * markdown mode is on. Each decoration is stripped by {@link normalizeEditorDOM}\n * on the next input cycle and re-applied here, so the segment model is never\n * mutated.\n *\n * List indentation runs FIRST, while each direct-child text node is still a\n * whole line: the URL and markdown passes split text nodes mid-line, and a tail\n * fragment starting with whitespace would let the indent regex's `^` anchor\n * false-match non-line-leading whitespace (e.g. `see http://x 1. y`).\n */\nexport function decorateEditor(editor: HTMLElement, markdownEnabled: boolean): void {\n // Whole-line passes run FIRST, while each direct-child text node is still a\n // full line. The URL and markdown passes split text nodes mid-line, so a tail\n // fragment beginning with \"•\" would let the bullet regex's `^` anchor\n // false-match a mid-line separator (e.g. `**bold** • middle`).\n if (markdownEnabled) {\n decorateListIndentInEditor(editor)\n decorateBulletsInEditor(editor)\n }\n decorateURLsInEditor(editor)\n if (markdownEnabled) {\n decorateMarkdownInEditor(editor)\n }\n}\n\n// Selection helpers\n\n/**\n * Returns the first Range from the current window selection, or null if\n * there is no selection or it has no ranges.\n */\nexport function getSelectionRange(): Range | null {\n const sel = window.getSelection()\n if (!sel || sel.rangeCount === 0) {\n return null\n }\n return sel.getRangeAt(0)\n}\n","/**\n * Cursor/selection utilities for the PromptArea contentEditable.\n *\n * Invariants:\n * - All functions are synchronous. Never return a promise or cross a microtask\n * boundary after a DOM mutation — that can cause the browser to fire\n * `selectionchange` and reset the caret.\n * - Never cache a `Selection` or `Range` across calls. Ranges become detached\n * after DOM mutations. Each function calls `window.getSelection()` or\n * `getSelectionRange()` fresh.\n * - Chip nodes are treated atomically via `isChipElement` — we never descend\n * into a contentEditable=false subtree when mapping offsets.\n */\nimport {\n chipNodeTextLength,\n getDirectChildContaining,\n getSelectionRange,\n indexOfChildNode,\n isBRElement,\n isChipElement,\n isHTMLElement,\n} from './dom-helpers.ts'\n\nexport type SavedCursor = {\n nodeIndex: number\n offset: number\n}\n\nexport function saveCursorPosition(editor: HTMLElement): SavedCursor | null {\n const range = getSelectionRange()\n if (!range) {\n return null\n }\n if (!editor.contains(range.startContainer)) {\n return null\n }\n\n const node = range.startContainer\n if (node === editor) {\n return { nodeIndex: range.startOffset, offset: 0 }\n }\n\n const directChild = getDirectChildContaining(editor, node)\n if (!directChild) {\n return null\n }\n\n const nodeIndex = indexOfChildNode(editor, directChild)\n return { nodeIndex, offset: range.startOffset }\n}\n\nexport function restoreCursorPosition(editor: HTMLElement, saved: SavedCursor): void {\n const sel = window.getSelection()\n if (!sel) {\n return\n }\n\n const childNodes = editor.childNodes\n if (childNodes.length === 0) {\n return\n }\n\n const range = document.createRange()\n\n if (saved.nodeIndex >= childNodes.length) {\n const lastChild = childNodes[childNodes.length - 1]\n if (lastChild.nodeType === Node.TEXT_NODE) {\n range.setStart(lastChild, (lastChild.textContent ?? '').length)\n } else {\n range.setStartAfter(lastChild)\n }\n } else {\n const targetNode = childNodes[saved.nodeIndex]\n if (targetNode.nodeType === Node.TEXT_NODE) {\n const maxOffset = (targetNode.textContent ?? '').length\n range.setStart(targetNode, Math.min(saved.offset, maxOffset))\n } else {\n range.setStartAfter(targetNode)\n }\n }\n\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n}\n\nexport function getCursorOffset(editor: HTMLElement): number | null {\n const range = getSelectionRange()\n if (!range) {\n return null\n }\n if (!editor.contains(range.startContainer)) {\n return null\n }\n\n const preRange = document.createRange()\n preRange.selectNodeContents(editor)\n preRange.setEnd(range.startContainer, range.startOffset)\n\n return getTextLengthInRange(preRange)\n}\n\n/**\n * Create a collapsed Range at the given plain-text offset inside the editor.\n * Returns null if the offset can't be mapped to a DOM position.\n */\nexport function createRangeAtOffset(editor: HTMLElement, targetOffset: number): Range | null {\n const pos = findDOMPosition(editor, targetOffset)\n if (!pos) {\n return null\n }\n\n const range = document.createRange()\n range.setStart(pos.node, pos.offset)\n range.collapse(true)\n return range\n}\n\n/**\n * Where the caret is on screen, in viewport coordinates.\n *\n * A collapsed range usually measures fine, but not when it sits *between* child\n * nodes of an element — which is exactly where a freshly inserted newline puts\n * it, because this editor's content is a flat run of text nodes and `<br>`s\n * directly under the editor element. There `getBoundingClientRect()` is all\n * zeros, and the obvious fallback (measure `startContainer`'s element) resolves\n * to the editor itself, whose rect is the viewport box — so it reports the\n * caret as trivially visible and scrolls nothing.\n *\n * So measure the neighbour instead: the child the caret sits before, or failing\n * that the one it sits after. Selecting a node gives a real rect even for a\n * `<br>`, which is what the line the caret just moved to consists of.\n */\nfunction caretRect(range: Range): DOMRect | null {\n const direct = range.getBoundingClientRect()\n if (direct.height > 0) {\n return direct\n }\n\n const node = range.startContainer\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return null\n }\n const children = (node as Element).childNodes\n const neighbours = [children[range.startOffset], children[range.startOffset - 1]]\n for (const neighbour of neighbours) {\n if (!neighbour) {\n continue\n }\n const probe = document.createRange()\n probe.selectNode(neighbour)\n const rect = probe.getBoundingClientRect()\n if (rect.height > 0) {\n return rect\n }\n }\n return null\n}\n\n/**\n * Keep the caret inside the editor's visible box after a *programmatic* move.\n *\n * The editor is its own scroll container once it hits `maxHeight`\n * (`prompt-area.tsx` sets `overflowY: auto` there). Typing scrolls the caret\n * into view for free, because that is the browser's own behaviour for a native\n * edit — but every path that calls `preventDefault()` and rebuilds the DOM\n * itself (Shift+Enter, list continuation, undo/redo, the bold/italic wrap,\n * paste) places the caret with a Range instead, and setting a selection does\n * not scroll anything. The symptom is a prompt that has grown past its cap and\n * stops following what you are writing: type and it scrolls, press Shift+Enter\n * and the new line appears below the fold.\n *\n * A no-op when the caret is already visible, so it is safe on every call — it\n * corrects an off-screen caret rather than scrolling to one.\n */\nexport function scrollCaretIntoView(editor: HTMLElement): void {\n const sel = window.getSelection()\n if (!sel || sel.rangeCount === 0) {\n return\n }\n const range = sel.getRangeAt(0)\n if (!editor.contains(range.startContainer)) {\n return\n }\n\n const rect = caretRect(range)\n if (!rect) {\n return\n }\n\n const box = editor.getBoundingClientRect()\n if (rect.bottom > box.bottom) {\n editor.scrollTop += rect.bottom - box.bottom\n } else if (rect.top < box.top) {\n editor.scrollTop -= box.top - rect.top\n }\n}\n\nexport function setCursorAtOffset(editor: HTMLElement, targetOffset: number): void {\n const sel = window.getSelection()\n if (!sel) {\n return\n }\n\n const pos = findDOMPosition(editor, targetOffset)\n if (pos) {\n const range = document.createRange()\n range.setStart(pos.node, pos.offset)\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n scrollCaretIntoView(editor)\n return\n }\n\n // Fallback: place cursor at end\n const range = document.createRange()\n range.selectNodeContents(editor)\n range.collapse(false)\n sel.removeAllRanges()\n sel.addRange(range)\n scrollCaretIntoView(editor)\n}\n\nexport function getTextLengthInRange(range: Range): number {\n const fragment = range.cloneContents()\n let length = 0\n\n const walk = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n length += (node.textContent ?? '').length\n } else if (isChipElement(node)) {\n length += chipNodeTextLength(node)\n } else if (isHTMLElement(node) && node.tagName === 'BR') {\n if (node.dataset.sentinel) {\n return\n } // skip sentinel <br>\n length += 1\n } else if (isHTMLElement(node)) {\n node.childNodes.forEach(walk)\n }\n }\n\n fragment.childNodes.forEach(walk)\n return length\n}\n\n/**\n * Returns the start and end plain-text offsets of the current selection.\n * Returns null if there's no selection or it's outside the editor.\n */\nexport function getSelectionOffsets(editor: HTMLElement): { start: number; end: number } | null {\n const range = getSelectionRange()\n if (!range) {\n return null\n }\n if (!editor.contains(range.startContainer)) {\n return null\n }\n\n const startRange = document.createRange()\n startRange.selectNodeContents(editor)\n startRange.setEnd(range.startContainer, range.startOffset)\n const start = getTextLengthInRange(startRange)\n\n if (range.collapsed) {\n return { start, end: start }\n }\n\n const endRange = document.createRange()\n endRange.selectNodeContents(editor)\n endRange.setEnd(range.endContainer, range.endOffset)\n const end = getTextLengthInRange(endRange)\n\n return { start, end }\n}\n\n/**\n * Sets a (potentially non-collapsed) selection at the given plain-text offsets.\n * Used to restore selection after markdown wrap/unwrap operations.\n */\nexport function setSelectionAtOffsets(editor: HTMLElement, startOffset: number, endOffset: number): void {\n const sel = window.getSelection()\n if (!sel) {\n return\n }\n\n if (startOffset === endOffset) {\n setCursorAtOffset(editor, startOffset)\n return\n }\n\n const startPos = findDOMPosition(editor, startOffset)\n const endPos = findDOMPosition(editor, endOffset)\n if (!startPos || !endPos) {\n return\n }\n\n const range = document.createRange()\n range.setStart(startPos.node, startPos.offset)\n range.setEnd(endPos.node, endPos.offset)\n sel.removeAllRanges()\n sel.addRange(range)\n}\n\n/**\n * Maps a plain-text offset to a DOM node + offset pair.\n * Recurses into decoration elements (markdown spans, URL anchors).\n */\nexport function findDOMPosition(container: HTMLElement, targetOffset: number): { node: Node; offset: number } | null {\n let remaining = targetOffset\n\n for (let i = 0; i < container.childNodes.length; i++) {\n const child = container.childNodes[i]\n\n if (child.nodeType === Node.TEXT_NODE) {\n const len = (child.textContent ?? '').length\n if (remaining <= len) {\n return { node: child, offset: remaining }\n }\n remaining -= len\n } else if (isChipElement(child)) {\n const chipLen = chipNodeTextLength(child)\n if (remaining <= chipLen) {\n return { node: container, offset: i + 1 }\n }\n remaining -= chipLen\n } else if (isBRElement(child)) {\n if (child.dataset.sentinel) {\n continue\n } // skip sentinel <br>\n if (remaining <= 1) {\n return { node: container, offset: i + 1 }\n }\n remaining -= 1\n } else if (isHTMLElement(child)) {\n // Decoration element (markdown span, URL anchor) — recurse\n const textLen = (child.textContent ?? '').length\n if (remaining <= textLen) {\n const result = findDOMPosition(child, remaining)\n if (result) {\n return result\n }\n }\n remaining -= textLen\n }\n }\n\n // Fallback: end of container\n return { node: container, offset: container.childNodes.length }\n}\n","/**\n * Clipboard-related DOM utilities for the PromptArea component.\n * Handles serializing selections and inserting pasted segments at the cursor.\n *\n * Not merged into dom-helpers.ts to avoid overcrowding that file with\n * clipboard I/O concerns alongside its DOM traversal and chip-accessor helpers.\n */\nimport type { Segment, ChipSegment } from './types.ts'\nimport { chipNodeToSegment, getChipDisplay, getChipTrigger, getSelectionRange, isChipElement, isHTMLElement } from './dom-helpers.ts'\nimport { mergeAdjacentTextSegments } from './prompt-area-engine.ts'\nimport { getTextLengthInRange } from './cursor-helpers.ts'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Visitor callbacks for {@link walkFragmentNodes}. Each fires for the\n * corresponding node kind encountered during a depth-first walk.\n */\ntype FragmentVisitor = {\n /** A text node — receives its text content (may be empty). */\n onText: (text: string) => void\n /** A chip element (has `data-chip-trigger`). */\n onChip: (node: HTMLElement) => void\n /** A `<br>` line break. */\n onBreak: () => void\n}\n\n/**\n * Depth-first walk of a selection fragment, classifying each node as text,\n * chip, or line break and recursing into any other element (decoration spans,\n * anchors, browser-inserted wrappers).\n *\n * Both fragment serializers share this single traversal so they cannot drift\n * on which nodes count as chips/breaks or how nested decorations are unwrapped.\n */\nfunction walkFragmentNodes(fragment: DocumentFragment, visitor: FragmentVisitor): void {\n const walk = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n visitor.onText(node.textContent ?? '')\n } else if (isChipElement(node)) {\n visitor.onChip(node)\n } else if (isHTMLElement(node) && node.tagName === 'BR') {\n visitor.onBreak()\n } else {\n node.childNodes.forEach(walk)\n }\n }\n\n fragment.childNodes.forEach(walk)\n}\n\n/**\n * Serializes a DocumentFragment (from selection) to plain text,\n * converting chip elements to their `trigger + displayText` form.\n */\nexport function serializeFragmentToPlainText(fragment: DocumentFragment): string {\n let text = ''\n\n walkFragmentNodes(fragment, {\n onText: (value) => {\n text += value\n },\n onChip: (node) => {\n text += (getChipTrigger(node) ?? '') + (getChipDisplay(node) ?? '')\n },\n onBreak: () => {\n text += '\\n'\n },\n })\n\n return text\n}\n\n/**\n * Serializes a DocumentFragment to an array of Segment objects,\n * preserving chip data for internal copy/paste.\n */\nexport function serializeFragmentToSegments(fragment: DocumentFragment): Segment[] {\n const segments: Segment[] = []\n\n walkFragmentNodes(fragment, {\n onText: (value) => {\n if (value) {\n segments.push({ type: 'text', text: value })\n }\n },\n onChip: (node) => {\n const chip = chipNodeToSegment(node)\n if (chip) {\n segments.push(chip)\n }\n },\n onBreak: () => {\n segments.push({ type: 'text', text: '\\n' })\n },\n })\n\n return segments\n}\n\n/**\n * Parses segment JSON from the clipboard. Returns null if invalid.\n */\nexport function parseSegmentsFromClipboard(json: string): Segment[] | null {\n try {\n const parsed: unknown = JSON.parse(json)\n if (!Array.isArray(parsed)) {\n return null\n }\n\n const segments: Segment[] = []\n for (const item of parsed) {\n if (!isRecord(item)) {\n return null\n }\n\n if (item.type === 'text' && typeof item.text === 'string') {\n segments.push({ type: 'text', text: item.text })\n } else if (\n item.type === 'chip' &&\n typeof item.trigger === 'string' &&\n typeof item.value === 'string' &&\n typeof item.displayText === 'string'\n ) {\n const chip: ChipSegment = {\n type: 'chip',\n trigger: item.trigger,\n value: item.value,\n displayText: item.displayText,\n ...(item.data !== undefined ? { data: item.data } : {}),\n ...(item.autoResolved ? { autoResolved: true } : {}),\n }\n segments.push(chip)\n } else {\n return null\n }\n }\n\n return segments\n } catch {\n return null\n }\n}\n\n/**\n * Inserts pasted segments at the current cursor position within existing segments.\n * Splits any text segment that straddles the cursor so the pasted content lands\n * exactly at the cursor and nothing before or after is lost.\n */\nexport function insertSegmentsAtCursor(currentSegments: Segment[], pastedSegments: Segment[], editor: HTMLElement): Segment[] {\n const range = getSelectionRange()\n if (!range) {\n return [...currentSegments, ...pastedSegments]\n }\n\n const preRange = document.createRange()\n preRange.selectNodeContents(editor)\n preRange.setEnd(range.startContainer, range.startOffset)\n const cursorOffset = getTextLengthInRange(preRange)\n\n const result: Segment[] = []\n let offset = 0\n let inserted = false\n\n const insertOnce = (): void => {\n if (!inserted) {\n result.push(...pastedSegments)\n inserted = true\n }\n }\n\n for (const seg of currentSegments) {\n if (seg.type === 'chip') {\n const chipLen = seg.trigger.length + seg.displayText.length\n if (offset >= cursorOffset) {\n insertOnce()\n }\n result.push(seg)\n offset += chipLen\n continue\n }\n\n const segEnd = offset + seg.text.length\n if (segEnd <= cursorOffset) {\n // Entirely before the cursor\n result.push(seg)\n } else if (offset >= cursorOffset) {\n // Entirely after the cursor\n insertOnce()\n result.push(seg)\n } else {\n // Cursor falls inside this text segment — split it.\n const splitAt = cursorOffset - offset\n const before = seg.text.slice(0, splitAt)\n const after = seg.text.slice(splitAt)\n if (before) {\n result.push({ type: 'text', text: before })\n }\n insertOnce()\n if (after) {\n result.push({ type: 'text', text: after })\n }\n }\n offset = segEnd\n }\n\n insertOnce()\n return mergeAdjacentTextSegments(result)\n}\n","/**\n * Hand-rolled, dependency-free HTML -> Markdown converter.\n *\n * Used by the paste handler: when the editor is in markdown mode and the\n * clipboard carries rich `text/html` (web pages, Notion, Google Docs, GitHub,\n * Slack, etc.), we convert it to markdown SOURCE text so the paste keeps its\n * formatting. The resulting string flows through the same insertion path as a\n * plain-text paste, and the editor's inline decorators render `*`/`**`/`***`\n * and bare URLs automatically.\n *\n * Design constraints (see .size-limit.json): no runtime deps. Parsing uses the\n * ambient `DOMParser`, walking is a small recursive switch. Type-safe: no\n * `any`, DOM narrowed via the guards in `dom-helpers.ts`.\n */\nimport { isHTMLElement, isTextNode } from './dom-helpers.ts'\n\n// Inline style / emphasis detection\n\n/** Reads a single declaration value from an inline `style` attribute string. */\nfunction getStyleValue(style: string, prop: string): string {\n const match = new RegExp(`(?:^|;)\\\\s*${prop}\\\\s*:\\\\s*([^;]+)`, 'i').exec(style)\n return match ? match[1].trim().toLowerCase() : ''\n}\n\n/** Whether a CSS font-weight value is bold (`bold`, `bolder`, or >= 600). */\nfunction isBoldWeight(value: string): boolean {\n if (value === 'bold' || value === 'bolder') {\n return true\n }\n const numeric = Number.parseInt(value, 10)\n return !Number.isNaN(numeric) && numeric >= 600\n}\n\n/**\n * Computes the markdown emphasis markers for an element from BOTH its tag and\n * its inline style. Google Docs emits `<span style=\"font-weight:700\">` rather\n * than `<b>`, and wraps everything in `<b style=\"font-weight:normal\">`, so an\n * explicit `font-weight`/`font-style` always wins over the tag name.\n */\nfunction inlineEmphasis(node: HTMLElement): { prefix: string; suffix: string } {\n const tag = node.tagName\n const style = node.getAttribute('style') ?? ''\n\n const weight = getStyleValue(style, 'font-weight')\n const bold = weight ? isBoldWeight(weight) : tag === 'B' || tag === 'STRONG'\n\n const fontStyle = getStyleValue(style, 'font-style')\n const italic = fontStyle ? fontStyle === 'italic' || fontStyle === 'oblique' : tag === 'I' || tag === 'EM'\n\n const decoration = getStyleValue(style, 'text-decoration')\n const strike = tag === 'S' || tag === 'DEL' || tag === 'STRIKE' || decoration.includes('line-through')\n\n const prefix = (strike ? '~~' : '') + (bold ? '**' : '') + (italic ? '*' : '')\n const suffix = (italic ? '*' : '') + (bold ? '**' : '') + (strike ? '~~' : '')\n return { prefix, suffix }\n}\n\n// Text handling\n\n/** Collapses HTML whitespace runs (incl. ` ` -> U+00A0) to single spaces. */\nfunction collapseWhitespace(text: string): string {\n return text.replace(/\\s+/g, ' ')\n}\n\n/** Escapes literal `*` from HTML text so prose isn't re-read as emphasis. */\nfunction escapeText(text: string): string {\n return text.replace(/\\*/g, '\\\\*')\n}\n\n// Block serializers\n\n/** Derives a fenced-block language from `class=\"language-ts\"` or `lang=\"ts\"`. */\nfunction detectCodeLang(pre: HTMLElement): string {\n const code = pre.querySelector('code')\n const classNames = `${pre.className} ${code?.className ?? ''}`\n const fromClass = /(?:language|lang)-([\\w-]+)/.exec(classNames)\n if (fromClass) {\n return fromClass[1]\n }\n return pre.getAttribute('lang') ?? code?.getAttribute('lang') ?? ''\n}\n\nfunction serializePre(pre: HTMLElement): string {\n const lang = detectCodeLang(pre)\n const raw = (pre.textContent ?? '').replace(/\\n$/, '')\n return `\\n\\n\\`\\`\\`${lang}\\n${raw}\\n\\`\\`\\`\\n\\n`\n}\n\nfunction serializeInlineCode(node: HTMLElement): string {\n const content = node.textContent ?? ''\n if (content.includes('`')) {\n return `\\`\\` ${content} \\`\\``\n }\n return `\\`${content}\\``\n}\n\n/** http(s)/mailto only; drops `#`, empty, and `javascript:` hrefs. */\nfunction isSafeHref(href: string): boolean {\n return /^(https?:|mailto:)/i.test(href)\n}\n\nfunction serializeAnchor(node: HTMLElement, depth: number): string {\n const href = node.getAttribute('href') ?? ''\n const label = serializeChildren(node, depth).trim()\n if (!isSafeHref(href)) {\n return label\n }\n if (!label || label === href) {\n return href\n }\n return `[${label}](${href})`\n}\n\nfunction serializeImage(node: HTMLElement): string {\n const src = node.getAttribute('src') ?? ''\n // Gate the src through the same allow-list as anchors: only http(s)/mailto\n // survive, so a `javascript:`/`vbscript:`/`data:` src never reaches the\n // emitted markdown (defense-in-depth for consumers that render it as HTML).\n if (!src || !isSafeHref(src)) {\n return ''\n }\n return ``\n}\n\nfunction serializeBlockquote(node: HTMLElement, depth: number): string {\n const inner = serializeChildren(node, depth).trim()\n const quoted = inner\n .split('\\n')\n .map((line) => (line ? `> ${line}` : '>'))\n .join('\\n')\n return `\\n\\n${quoted}\\n\\n`\n}\n\n/**\n * Serializes a `<ul>`/`<ol>` at nesting `depth` (0 = top level). Each `<li>`'s\n * own inline content becomes the marker line; a nested `<ul>`/`<ol>` child is\n * serialized at `depth + 1` and appended indented below its parent item.\n */\nfunction serializeList(list: HTMLElement, depth: number): string {\n const ordered = list.tagName === 'OL'\n const start = Number.parseInt(list.getAttribute('start') ?? '', 10)\n let index = Number.isNaN(start) ? 1 : start\n const indent = ' '.repeat(depth)\n const lines: string[] = []\n\n for (const child of Array.from(list.childNodes)) {\n if (!isHTMLElement(child) || child.tagName !== 'LI') {\n continue\n }\n\n const marker = ordered ? `${index}. ` : '- '\n index++\n\n let label = ''\n let nested = ''\n for (const liChild of Array.from(child.childNodes)) {\n if (isHTMLElement(liChild) && (liChild.tagName === 'UL' || liChild.tagName === 'OL')) {\n nested += `\\n${serializeList(liChild, depth + 1)}`\n } else {\n label += serializeNode(liChild, depth)\n }\n }\n lines.push(`${indent}${marker}${label.trim()}${nested}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction serializeTable(table: HTMLElement, depth: number): string {\n const rows = Array.from(table.querySelectorAll('tr'))\n if (rows.length === 0) {\n return ''\n }\n\n const cells = rows.map((row) =>\n Array.from(row.children)\n .filter((cell) => cell.tagName === 'TD' || cell.tagName === 'TH')\n .map((cell) => serializeChildren(cell, depth).replace(/\\n+/g, ' ').replace(/\\|/g, '\\\\|').trim()),\n )\n\n const header = cells[0]\n const separator = header.map(() => '---')\n const toRow = (row: string[]): string => `| ${row.join(' | ')} |`\n\n return [toRow(header), toRow(separator), ...cells.slice(1).map(toRow)].join('\\n')\n}\n\n// Recursive walker\n\nfunction serializeChildren(node: Node, depth: number): string {\n let out = ''\n node.childNodes.forEach((child) => {\n out += serializeNode(child, depth)\n })\n return out\n}\n\nfunction serializeNode(node: Node, depth: number): string {\n if (isTextNode(node)) {\n return escapeText(collapseWhitespace(node.textContent ?? ''))\n }\n if (!isHTMLElement(node)) {\n return ''\n }\n\n const tag = node.tagName\n switch (tag) {\n case 'SCRIPT':\n case 'STYLE':\n case 'NOSCRIPT':\n case 'HEAD':\n case 'TITLE': {\n return ''\n }\n case 'BR': {\n return '\\n'\n }\n case 'HR': {\n return '\\n\\n---\\n\\n'\n }\n case 'H1':\n case 'H2':\n case 'H3':\n case 'H4':\n case 'H5':\n case 'H6': {\n return `\\n\\n${'#'.repeat(Number(tag[1]))} ${serializeChildren(node, depth).trim()}\\n\\n`\n }\n case 'P': {\n return `\\n\\n${serializeChildren(node, depth).trim()}\\n\\n`\n }\n case 'DIV': {\n return `\\n${serializeChildren(node, depth).trim()}\\n`\n }\n case 'BLOCKQUOTE': {\n return serializeBlockquote(node, depth)\n }\n case 'UL':\n case 'OL': {\n return `\\n\\n${serializeList(node, depth)}\\n\\n`\n }\n case 'LI': {\n // A stray <li> outside a list wrapper — emit its content as a line.\n return `${serializeChildren(node, depth).trim()}\\n`\n }\n case 'PRE': {\n return serializePre(node)\n }\n case 'CODE': {\n // Inline code only: <pre> handles its own <code> via textContent.\n return serializeInlineCode(node)\n }\n case 'A': {\n return serializeAnchor(node, depth)\n }\n case 'IMG': {\n return serializeImage(node)\n }\n case 'TABLE': {\n return `\\n\\n${serializeTable(node, depth)}\\n\\n`\n }\n default: {\n // Inline emphasis (B/STRONG/I/EM/S/DEL + styled SPAN/FONT) and the\n // \"span soup\" unwrap case both resolve here: emphasis markers when the\n // tag or inline style is meaningful, otherwise a bare unwrap.\n const { prefix, suffix } = inlineEmphasis(node)\n return prefix + serializeChildren(node, depth) + suffix\n }\n }\n}\n\n// Output normalization\n\n/** Trims trailing spaces and caps consecutive blank lines at one. */\nfunction normalizeOutput(markdown: string): string {\n return markdown\n .replace(/[ \\t]+\\n/g, '\\n')\n .replace(/\\n[ \\t]*\\n[ \\t\\n]*/g, '\\n\\n')\n .trim()\n}\n\n// Public API\n\n/**\n * Converts an HTML string to markdown source text. Returns '' for empty or\n * body-less input. Block markdown (headings, lists, quotes, fences, tables,\n * links) is emitted as literal markdown text — that is the editor's intended\n * display; only `*`/`**`/`***` and bare URLs get visually decorated inline.\n */\nexport function htmlToMarkdown(html: string): string {\n if (!html) {\n return ''\n }\n const doc = new DOMParser().parseFromString(html, 'text/html')\n if (!doc.body) {\n return ''\n }\n return normalizeOutput(serializeChildren(doc.body, 0))\n}\n","'use client'\n\nimport { useCallback, useMemo, useRef } from 'react'\nimport type { Segment, ChipSegment, TriggerConfig } from './types.ts'\nimport { resolveTriggersInSegments } from './prompt-area-engine.ts'\nimport { normalizeEditorDOM, safeJsonStringify, getSelectionRange } from './dom-helpers.ts'\nimport {\n serializeFragmentToPlainText,\n serializeFragmentToSegments,\n parseSegmentsFromClipboard,\n insertSegmentsAtCursor,\n} from './clipboard-helpers.ts'\nimport { htmlToMarkdown } from './html-to-markdown.ts'\nimport { normalizeListPrefixText, renumberOrderedListLines, hasOrderedListRun } from './prompt-area-list-ops.ts'\n\ntype EventHandlerDeps = {\n editorRef: React.RefObject<HTMLDivElement | null>\n readSegmentsFromDOM: () => Segment[]\n onChange: (segments: Segment[]) => void\n renderSegmentsToDOM: (segments: Segment[]) => void\n runTriggerDetection: () => void\n dismissTrigger: () => void\n triggers: TriggerConfig[]\n /** When true, rich `text/html` on the clipboard is converted to markdown. */\n markdownEnabled: boolean\n /** When true, pasted list markers (\"- \") are normalized to the \"•\" glyph. */\n normalizeBullets: boolean\n onPaste?: (data: { segments: Segment[]; source: 'internal' | 'external' }) => void\n onUndo?: (segments: Segment[]) => void\n onRedo?: (segments: Segment[]) => void\n onChipAdd?: (chip: ChipSegment) => void\n onImagePaste?: (file: File) => void\n onRawPaste?: (e: React.ClipboardEvent<HTMLDivElement>) => void\n}\n\ntype PromptAreaEventHandlers = {\n handlePaste: (e: React.ClipboardEvent<HTMLDivElement>) => void\n handleCopy: (e: React.ClipboardEvent<HTMLDivElement>) => void\n handleCut: (e: React.ClipboardEvent<HTMLDivElement>) => void\n handleDrop: (e: React.DragEvent<HTMLDivElement>) => void\n handleDragOver: (e: React.DragEvent<HTMLDivElement>) => void\n handleCompositionStart: () => void\n handleCompositionEnd: () => void\n handleBlur: () => void\n handleKeyDownForUndoRedo: (e: React.KeyboardEvent<HTMLDivElement>) => boolean\n pushUndo: (segments: Segment[]) => void\n resetUndoHistory: () => void\n isComposing: React.RefObject<boolean>\n}\n\nconst MAX_UNDO_HISTORY = 100\n\n/** Delay before dismissing trigger on blur, so popover clicks register first */\nexport const BLUR_DELAY_MS = 150\n\ntype UndoState = {\n undoStack: Segment[][]\n redoStack: Segment[][]\n}\n\n/**\n * Encapsulates all edge-case event handlers for the prompt area component:\n * paste, copy, cut, drag/drop, IME composition, blur, and undo/redo.\n */\nexport function usePromptAreaEvents(deps: EventHandlerDeps): PromptAreaEventHandlers {\n const {\n editorRef,\n readSegmentsFromDOM,\n onChange,\n renderSegmentsToDOM,\n runTriggerDetection,\n dismissTrigger,\n triggers,\n markdownEnabled,\n normalizeBullets,\n onPaste: onPasteCallback,\n onUndo,\n onRedo,\n onChipAdd,\n onImagePaste,\n onRawPaste,\n } = deps\n\n const isComposing = useRef(false)\n\n // Undo/redo stack (MAX_UNDO_HISTORY entries; clears redo on new push).\n // Invariants: stacks live in refs (not useState) so pushUndo /\n // resetUndoHistory / handleKeyDownForUndoRedo keep stable identity.\n // Destabilizing this would re-create handleInput / handleKeyDown /\n // imperative handle on every render and silently regress IME + debounced\n // undo in the parent hook.\n const undoState = useRef<UndoState>({ undoStack: [], redoStack: [] })\n\n const pushUndo = useCallback((segments: Segment[]) => {\n const state = undoState.current\n state.undoStack.push(segments)\n if (state.undoStack.length > MAX_UNDO_HISTORY) {\n state.undoStack.shift()\n }\n state.redoStack = []\n }, [])\n\n const resetUndoHistory = useCallback(() => {\n undoState.current = { undoStack: [], redoStack: [] }\n }, [])\n\n // Paste: strip HTML, insert plain text only\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLDivElement>) => {\n // Let a consumer take over the paste entirely (e.g. divert large text or\n // arbitrary files to an upload pipeline) by calling preventDefault().\n onRawPaste?.(e)\n if (e.defaultPrevented) {\n return\n }\n e.preventDefault()\n\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n // Some browsers/OSes provide pasted images via `items` instead of `files` (e.g. screenshots)\n const imageFile =\n Array.from(e.clipboardData.files).find((f) => f.type.startsWith('image/')) ??\n (() => {\n const item = Array.from(e.clipboardData.items).find((i) => i.type.startsWith('image/'))\n return item?.getAsFile() ?? null\n })()\n if (imageFile) {\n onImagePaste?.(imageFile)\n return\n }\n\n const currentSegments = readSegmentsFromDOM()\n pushUndo(currentSegments)\n\n const segmentJson = e.clipboardData.getData('text/prompt-area-segments')\n if (segmentJson) {\n const parsed = parseSegmentsFromClipboard(segmentJson)\n if (parsed && parsed.length > 0) {\n const range = getSelectionRange()\n if (!range) {\n return\n }\n\n range.deleteContents()\n\n const beforePaste = readSegmentsFromDOM()\n const merged = insertSegmentsAtCursor(beforePaste, parsed, editor)\n onChange(merged)\n renderSegmentsToDOM(merged)\n\n onPasteCallback?.({ segments: merged, source: 'internal' })\n for (const seg of parsed) {\n if (seg.type === 'chip') {\n onChipAdd?.(seg)\n }\n }\n\n runTriggerDetection()\n return\n }\n }\n\n // When markdown mode is on, prefer the richest clipboard flavor:\n // 1. text/markdown — some apps (e.g. Slack) hand out markdown directly,\n // preserving nested lists that their text/plain flattens.\n // 2. text/html — convert web/Notion/Docs/GitHub HTML to markdown.\n // Otherwise (markdown off, or neither present) fall back to plain text.\n let text = ''\n if (markdownEnabled) {\n text = e.clipboardData.getData('text/markdown')\n if (text) {\n // Slack over-escapes inert punctuation (e.g. `\\(` `\\)`); unescape\n // parentheses so the source reads cleanly. They carry no markdown\n // meaning, unlike `\\*` / `\\.` / `\\-` which are left intact.\n text = text.replace(/\\\\([()])/g, '$1')\n } else {\n const html = e.clipboardData.getData('text/html')\n // A converter failure (e.g. stack overflow on pathologically deep\n // nesting) must not drop the paste — leave text empty so the\n // text/plain fallback below still runs.\n if (html) {\n try {\n text = htmlToMarkdown(html)\n } catch {\n text = ''\n }\n }\n }\n }\n if (!text) {\n text = e.clipboardData.getData('text/plain')\n }\n if (!text) {\n return\n }\n\n // Normalize pasted list markers (\"- \" → \"•\") so pasted bullets match\n // typed input. Applies to both the HTML→markdown and plain-text paths.\n if (markdownEnabled && normalizeBullets) {\n text = normalizeListPrefixText(text, true)\n }\n\n // Rebuild ordered-list numbering in the pasted block so a copied list with\n // stale numbers lands sequential. Gated on `hasOrderedListRun` so incidental\n // numeric-leading prose (e.g. `1985. Born / 2020. Died`) is left untouched.\n // Done at the raw-string level (the caret collapses to end-of-content after\n // insertion, so no offset remap needed).\n if (markdownEnabled && hasOrderedListRun(text)) {\n text = renumberOrderedListLines(text).text\n }\n\n const range = getSelectionRange()\n if (!range) {\n return\n }\n\n range.deleteContents()\n\n // Handle multi-line paste: split into lines with BR elements\n const lines = text.split('\\n')\n const fragment = document.createDocumentFragment()\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i]) {\n fragment.appendChild(document.createTextNode(lines[i]))\n }\n if (i < lines.length - 1) {\n fragment.appendChild(document.createElement('br'))\n }\n }\n\n range.insertNode(fragment)\n\n range.collapse(false)\n const sel = window.getSelection()\n sel?.removeAllRanges()\n sel?.addRange(range)\n\n normalizeEditorDOM(editor)\n const newSegments = readSegmentsFromDOM()\n\n // Auto-resolve trigger patterns in pasted text (e.g., #readme -> chip)\n const resolvedSegments = resolveTriggersInSegments(newSegments, triggers)\n\n if (resolvedSegments !== newSegments) {\n onChange(resolvedSegments)\n renderSegmentsToDOM(resolvedSegments)\n\n for (const seg of resolvedSegments) {\n if (\n seg.type === 'chip' &&\n !newSegments.some(\n (s) => s.type === 'chip' && s.trigger === seg.trigger && s.value === seg.value && s.displayText === seg.displayText,\n )\n ) {\n onChipAdd?.(seg)\n }\n }\n } else {\n onChange(newSegments)\n }\n\n onPasteCallback?.({ segments: resolvedSegments, source: 'external' })\n runTriggerDetection()\n },\n [\n editorRef,\n readSegmentsFromDOM,\n onChange,\n pushUndo,\n runTriggerDetection,\n renderSegmentsToDOM,\n triggers,\n markdownEnabled,\n normalizeBullets,\n onPasteCallback,\n onChipAdd,\n onImagePaste,\n onRawPaste,\n ],\n )\n\n // Copy: serialize chips into plain text\n\n const handleCopy = useCallback((e: React.ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault()\n\n const range = getSelectionRange()\n if (!range) {\n return\n }\n\n const fragment = range.cloneContents()\n\n const plainText = serializeFragmentToPlainText(fragment)\n e.clipboardData.setData('text/plain', plainText)\n\n const fragmentSegments = serializeFragmentToSegments(fragment)\n const hasChips = fragmentSegments.some((s) => s.type === 'chip')\n if (hasChips) {\n const json = safeJsonStringify(fragmentSegments)\n if (json) {\n e.clipboardData.setData('text/prompt-area-segments', json)\n }\n }\n }, [])\n\n // Cut: copy + delete\n\n const handleCut = useCallback(\n (e: React.ClipboardEvent<HTMLDivElement>) => {\n handleCopy(e)\n\n const range = getSelectionRange()\n if (!range) {\n return\n }\n\n const currentSegments = readSegmentsFromDOM()\n pushUndo(currentSegments)\n\n range.deleteContents()\n\n const editor = editorRef.current\n if (editor) {\n normalizeEditorDOM(editor)\n }\n\n const newSegments = readSegmentsFromDOM()\n onChange(newSegments)\n runTriggerDetection()\n },\n [handleCopy, editorRef, readSegmentsFromDOM, onChange, pushUndo, runTriggerDetection],\n )\n\n // Drag & Drop: prevent to avoid unpredictable DOM mutations\n\n const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }, [])\n\n const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }, [])\n\n // IME Composition: track state, defer trigger detection\n\n const handleCompositionStart = useCallback(() => {\n isComposing.current = true\n }, [])\n\n const handleCompositionEnd = useCallback(() => {\n isComposing.current = false\n runTriggerDetection()\n }, [runTriggerDetection])\n\n // Blur: dismiss trigger dropdown with delay (so popover clicks work)\n\n const handleBlur = useCallback(() => {\n setTimeout(() => {\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n // Only dismiss if focus didn't move to an element within the editor container\n const activeEl = document.activeElement\n if (activeEl && editor.parentElement?.contains(activeEl)) {\n return\n }\n\n dismissTrigger()\n }, BLUR_DELAY_MS)\n }, [editorRef, dismissTrigger])\n\n // Undo/Redo: intercept Ctrl+Z / Ctrl+Shift+Z\n\n const handleKeyDownForUndoRedo = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>): boolean => {\n const isMeta = e.metaKey || e.ctrlKey\n\n if (!isMeta || e.key !== 'z') {\n return false\n }\n\n e.preventDefault()\n const state = undoState.current\n\n if (e.shiftKey) {\n if (state.redoStack.length === 0) {\n return true\n }\n\n const segments = state.redoStack.pop()\n if (!segments) {\n return true\n }\n\n const current = readSegmentsFromDOM()\n state.undoStack.push(current)\n\n onChange(segments)\n renderSegmentsToDOM(segments)\n onRedo?.(segments)\n } else {\n if (state.undoStack.length === 0) {\n return true\n }\n\n const segments = state.undoStack.pop()\n if (!segments) {\n return true\n }\n\n const current = readSegmentsFromDOM()\n state.redoStack.push(current)\n\n onChange(segments)\n renderSegmentsToDOM(segments)\n onUndo?.(segments)\n }\n\n return true\n },\n [readSegmentsFromDOM, onChange, renderSegmentsToDOM, onUndo, onRedo],\n )\n\n // Memoized so the container is only as unstable as its members: the parent\n // hook keys handleInput and the imperative handle on this object, and a fresh\n // literal per render would re-create both on every render.\n return useMemo(\n () => ({\n handlePaste,\n handleCopy,\n handleCut,\n handleDrop,\n handleDragOver,\n handleCompositionStart,\n handleCompositionEnd,\n handleBlur,\n handleKeyDownForUndoRedo,\n pushUndo,\n resetUndoHistory,\n isComposing,\n }),\n [\n handlePaste,\n handleCopy,\n handleCut,\n handleDrop,\n handleDragOver,\n handleCompositionStart,\n handleCompositionEnd,\n handleBlur,\n handleKeyDownForUndoRedo,\n pushUndo,\n resetUndoHistory,\n ],\n )\n}\n","'use client'\n\nimport { useCallback } from 'react'\nimport type { Segment, TriggerConfig, ActiveTrigger, TriggerSuggestion, ChipSegment } from './types.ts'\nimport {\n isValidTriggerPosition,\n segmentsToPlainText,\n resolveChip,\n removeChipAtIndex,\n revertChipAtIndex,\n replaceTextRange,\n toggleMarkdownWrap,\n} from './prompt-area-engine.ts'\nimport {\n getListContext,\n insertListContinuation,\n indentListItem,\n outdentListItem,\n removeListPrefix,\n renumberOrderedListSegments,\n remapOffset,\n} from './prompt-area-list-ops.ts'\nimport {\n isChipElement,\n getChipAutoResolved,\n getDirectChildContaining,\n indexOfChildNode,\n domChildIndexToSegmentIndex,\n getSelectionRange,\n} from './dom-helpers.ts'\nimport { getCursorOffset, setCursorAtOffset, getSelectionOffsets, setSelectionAtOffsets } from './cursor-helpers.ts'\n\ntype UsePromptAreaKeydownOptions = {\n editorRef: React.RefObject<HTMLDivElement | null>\n triggers: TriggerConfig[]\n markdownEnabled: boolean\n submitOnEnter: boolean\n onSubmit?: (segments: Segment[]) => void\n onEscape?: () => void\n onChange: (segments: Segment[]) => void\n onChipAdd?: (chip: ChipSegment) => void\n onChipDelete?: (chip: ChipSegment) => void\n readSegmentsFromDOM: () => Segment[]\n renderSegmentsToDOM: (segments: Segment[]) => void\n runTriggerDetection: () => void\n dismissTrigger: () => void\n buildInsertChip: (segments: Segment[], trigger: ActiveTrigger) => (chip: Omit<ChipSegment, 'type'>) => void\n selectSuggestionInternal: (suggestion: TriggerSuggestion) => void\n activeTrigger: ActiveTrigger | null\n suggestions: TriggerSuggestion[]\n suggestionsLoading: boolean\n suggestionsError: string | null\n selectedSuggestionIndex: number\n setSelectedSuggestionIndex: React.Dispatch<React.SetStateAction<number>>\n pushUndo: (segments: Segment[]) => void\n handleKeyDownForUndoRedo: (e: React.KeyboardEvent<HTMLDivElement>) => boolean\n lastRenderedValue: React.RefObject<Segment[]>\n undoTimer: React.RefObject<ReturnType<typeof setTimeout> | null>\n undoBaseState: React.RefObject<Segment[] | null>\n}\n\n// The numbered keydown router (branches 1 through 6) and the chip-deletion helpers only it\n// calls, moved whole from use-prompt-area.ts. The numbering is load-bearing documentation:\n// branch order IS the precedence order.\nexport function usePromptAreaKeydown({\n editorRef,\n triggers,\n markdownEnabled,\n submitOnEnter,\n onSubmit,\n onEscape,\n onChange,\n onChipAdd,\n onChipDelete,\n readSegmentsFromDOM,\n renderSegmentsToDOM,\n runTriggerDetection,\n dismissTrigger,\n buildInsertChip,\n selectSuggestionInternal,\n activeTrigger,\n suggestions,\n suggestionsLoading,\n suggestionsError,\n selectedSuggestionIndex,\n setSelectedSuggestionIndex,\n pushUndo,\n handleKeyDownForUndoRedo,\n lastRenderedValue,\n undoTimer,\n undoBaseState,\n}: UsePromptAreaKeydownOptions): (e: React.KeyboardEvent<HTMLDivElement>) => void {\n // Remove a chip node from DOM and sync model\n\n const removeChipNodeFromDOM = useCallback(\n (editor: HTMLElement, chipNode: HTMLElement): boolean => {\n const segments = readSegmentsFromDOM()\n const chipIdx = indexOfChildNode(editor, chipNode)\n if (chipIdx === -1) {\n return false\n }\n\n const segIdx = domChildIndexToSegmentIndex(editor, chipIdx)\n const deletedChip = segments[segIdx]\n const newSegments = removeChipAtIndex(segments, segIdx)\n onChange(newSegments)\n renderSegmentsToDOM(newSegments)\n\n if (deletedChip?.type === 'chip') {\n onChipDelete?.(deletedChip)\n }\n\n return true\n },\n [readSegmentsFromDOM, onChange, renderSegmentsToDOM, onChipDelete],\n )\n\n // Revert an auto-resolved chip back to plain text\n\n const revertChipNodeToText = useCallback(\n (editor: HTMLElement, chipNode: HTMLElement): boolean => {\n const segments = readSegmentsFromDOM()\n const chipIdx = indexOfChildNode(editor, chipNode)\n if (chipIdx === -1) {\n return false\n }\n\n const segIdx = domChildIndexToSegmentIndex(editor, chipIdx)\n const revertedChip = segments[segIdx]\n const result = revertChipAtIndex(segments, segIdx)\n if (!result) {\n return false\n }\n\n let targetOffset = 0\n for (let i = 0; i < segIdx; i++) {\n const s = segments[i]\n if (s.type === 'text') {\n targetOffset += s.text.length\n } else {\n targetOffset += s.trigger.length + s.displayText.length\n }\n }\n targetOffset += result.revertedText.length\n\n onChange(result.segments)\n renderSegmentsToDOM(result.segments)\n setCursorAtOffset(editor, targetOffset)\n\n if (revertedChip?.type === 'chip') {\n onChipDelete?.(revertedChip)\n }\n\n return true\n },\n [readSegmentsFromDOM, onChange, renderSegmentsToDOM, onChipDelete],\n )\n\n // Chip backspace (delete chip behind cursor as whole unit)\n\n const handleChipBackspace = useCallback((): boolean => {\n const editor = editorRef.current\n if (!editor) {\n return false\n }\n\n const range = getSelectionRange()\n if (!range || !range.collapsed) {\n return false\n }\n\n const node = range.startContainer\n const offset = range.startOffset\n\n // Case 1: cursor is at the editor level (between child nodes)\n if (node === editor && offset > 0) {\n const prevChild = editor.childNodes[offset - 1]\n if (prevChild && isChipElement(prevChild)) {\n if (getChipAutoResolved(prevChild)) {\n return revertChipNodeToText(editor, prevChild)\n }\n return removeChipNodeFromDOM(editor, prevChild)\n }\n }\n\n // Case 2: cursor is at start of a text node, check previous sibling\n if (node.nodeType === Node.TEXT_NODE && offset === 0) {\n const directChild = getDirectChildContaining(editor, node)\n if (!directChild) {\n return false\n }\n\n let prevSibling = directChild.previousSibling\n while (prevSibling && prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent === '') {\n prevSibling = prevSibling.previousSibling\n }\n if (prevSibling && isChipElement(prevSibling)) {\n if (getChipAutoResolved(prevSibling)) {\n return revertChipNodeToText(editor, prevSibling)\n }\n return removeChipNodeFromDOM(editor, prevSibling)\n }\n }\n\n return false\n }, [removeChipNodeFromDOM, revertChipNodeToText])\n\n // Chip forward delete (delete chip in front of cursor)\n\n const handleChipForwardDelete = useCallback((): boolean => {\n const editor = editorRef.current\n if (!editor) {\n return false\n }\n\n const range = getSelectionRange()\n if (!range || !range.collapsed) {\n return false\n }\n\n const node = range.startContainer\n const offset = range.startOffset\n\n // Case 1: cursor at the editor level\n if (node === editor && offset < editor.childNodes.length) {\n const nextChild = editor.childNodes[offset]\n if (nextChild && isChipElement(nextChild)) {\n return removeChipNodeFromDOM(editor, nextChild)\n }\n }\n\n // Case 2: cursor at end of a text node, check next sibling\n if (node.nodeType === Node.TEXT_NODE && offset === (node.textContent ?? '').length) {\n const directChild = getDirectChildContaining(editor, node)\n if (!directChild) {\n return false\n }\n\n let nextSibling = directChild.nextSibling\n while (nextSibling && nextSibling.nodeType === Node.TEXT_NODE && nextSibling.textContent === '') {\n nextSibling = nextSibling.nextSibling\n }\n if (nextSibling && isChipElement(nextSibling)) {\n return removeChipNodeFromDOM(editor, nextSibling)\n }\n }\n\n return false\n }, [removeChipNodeFromDOM])\n\n // Auto-resolve active trigger on space\n\n const autoResolveActiveTrigger = useCallback(\n (trigger: ActiveTrigger) => {\n const segments = readSegmentsFromDOM()\n const query = trigger.query\n\n const syntheticSuggestion: TriggerSuggestion = {\n value: query,\n label: query,\n }\n\n const displayText = trigger.config.onSelect?.(syntheticSuggestion) ?? query\n\n const chipData = {\n value: query,\n displayText: displayText || query,\n autoResolved: true,\n }\n const result = resolveChip(segments, trigger, chipData)\n\n onChange(result.segments)\n renderSegmentsToDOM(result.segments)\n\n onChipAdd?.({\n type: 'chip',\n trigger: trigger.config.char,\n ...chipData,\n })\n\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, result.cursorOffset)\n }\n\n dismissTrigger()\n },\n [readSegmentsFromDOM, onChange, renderSegmentsToDOM, dismissTrigger, onChipAdd],\n )\n\n // Handle key events\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const applyEditResult = (editor: HTMLDivElement, result: { segments: Segment[]; cursorOffset: number }) => {\n // Ordered-list numbers are a projection of position: rebuild them on\n // every structural edit and remap the caret across any digit-run width\n // changes. No-op (same reference) when there are no ordered lists.\n let { segments, cursorOffset } = result\n if (markdownEnabled) {\n const renumbered = renumberOrderedListSegments(segments)\n segments = renumbered.segments\n cursorOffset = remapOffset(cursorOffset, renumbered.edits)\n }\n lastRenderedValue.current = segments\n onChange(segments)\n renderSegmentsToDOM(segments)\n setCursorAtOffset(editor, cursorOffset)\n }\n\n const tryListContinuation = (editor: HTMLDivElement): boolean => {\n if (!markdownEnabled) {\n return false\n }\n const segments = readSegmentsFromDOM()\n const cursorPos = getCursorOffset(editor)\n if (cursorPos === null) {\n return false\n }\n const plainText = segmentsToPlainText(segments)\n if (!getListContext(plainText, cursorPos)) {\n return false\n }\n const result = insertListContinuation(segments, cursorPos)\n if (result) {\n applyEditResult(editor, result)\n }\n return true\n }\n\n // 1. Flush pending undo debounce so Cmd+Z has the latest checkpoint\n if ((e.metaKey || e.ctrlKey) && e.key === 'z' && undoBaseState.current) {\n if (undoTimer.current) {\n clearTimeout(undoTimer.current)\n undoTimer.current = null\n }\n pushUndo(undoBaseState.current)\n undoBaseState.current = null\n }\n\n // 1a. Undo/redo intercept\n if (handleKeyDownForUndoRedo(e)) {\n return\n }\n\n // 1.5 Markdown formatting shortcuts (Cmd+B bold, Cmd+I italic)\n if (markdownEnabled && (e.metaKey || e.ctrlKey) && !e.shiftKey && (e.key === 'b' || e.key === 'i')) {\n e.preventDefault()\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n const offsets = getSelectionOffsets(editor)\n if (!offsets || offsets.start === offsets.end) {\n return\n }\n\n const marker = e.key === 'b' ? '**' : '*'\n const currentSegments = readSegmentsFromDOM()\n pushUndo(currentSegments)\n\n const result = toggleMarkdownWrap(currentSegments, offsets.start, offsets.end, marker)\n if (!result) {\n return\n }\n\n lastRenderedValue.current = result.segments\n onChange(result.segments)\n renderSegmentsToDOM(result.segments)\n setSelectionAtOffsets(editor, result.selectionStart, result.selectionEnd)\n return\n }\n\n // 1.75 Launch triggers: a trigger with mode 'launch' fires onActivate on\n // keydown and suppresses the char so it never enters the editor — for\n // opening an external surface (dialog, palette). The DOM read is gated on\n // the typed key actually matching a launch char, so it stays off the hot\n // path. insertChip still inserts a chip at the cursor if the consumer\n // wants one after the external selection.\n if (!e.metaKey && !e.ctrlKey && !e.altKey && !e.nativeEvent.isComposing && e.key.length === 1) {\n const launcher = triggers.find((t) => t.mode === 'launch' && t.char === e.key)\n const editor = editorRef.current\n if (launcher?.onActivate && editor) {\n const cursorPos = getCursorOffset(editor)\n if (cursorPos !== null) {\n const segments = readSegmentsFromDOM()\n const plainText = segmentsToPlainText(segments)\n if (isValidTriggerPosition(plainText, cursorPos, launcher.position)) {\n e.preventDefault()\n launcher.onActivate({\n text: plainText,\n cursorPosition: cursorPos,\n insertChip: buildInsertChip(replaceTextRange(segments, cursorPos, cursorPos, launcher.char), {\n config: launcher,\n startOffset: cursorPos,\n query: '',\n }),\n })\n return\n }\n }\n }\n }\n\n // 2. Trigger dropdown navigation. Gated on the dropdown actually being\n // ON SCREEN, which matches TriggerPopover's own render condition\n // (non-empty suggestions, OR loading/error/emptyMessage) rather than\n // just `suggestions.length > 0` — otherwise a popover left open in a\n // loading/empty state (e.g. right after a chip-click reopen, before its\n // empty-query search resolves) lets Enter fall through to onSubmit and\n // Escape fall through to onEscape while still visibly on screen.\n const dropdownVisible =\n activeTrigger &&\n activeTrigger.config.mode === 'dropdown' &&\n (suggestions.length > 0 || suggestionsLoading || suggestionsError !== null || !!activeTrigger.config.emptyMessage)\n if (dropdownVisible) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n if (suggestions.length > 0) {\n setSelectedSuggestionIndex((prev) => Math.min(prev + 1, suggestions.length - 1))\n }\n return\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n if (suggestions.length > 0) {\n setSelectedSuggestionIndex((prev) => Math.max(prev - 1, 0))\n }\n return\n }\n if (e.key === 'Enter' || e.key === 'Tab') {\n e.preventDefault()\n const selected = suggestions[selectedSuggestionIndex]\n if (selected) {\n selectSuggestionInternal(selected)\n }\n return\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n dismissTrigger()\n return\n }\n }\n\n // 2.5. Auto-resolve on Space when trigger has resolveOnSpace\n if (e.key === ' ' && activeTrigger && activeTrigger.config.resolveOnSpace) {\n const query = activeTrigger.query.trim()\n if (query.length > 0) {\n e.preventDefault()\n autoResolveActiveTrigger(activeTrigger)\n return\n }\n }\n\n // 2.6. Tab/Shift+Tab for list indentation (only when trigger dropdown is NOT open)\n if (markdownEnabled && e.key === 'Tab' && !activeTrigger) {\n const editor = editorRef.current\n if (editor) {\n const segments = readSegmentsFromDOM()\n const plainText = segmentsToPlainText(segments)\n const cursorPos = getCursorOffset(editor)\n if (cursorPos !== null) {\n const ctx = getListContext(plainText, cursorPos)\n if (ctx) {\n e.preventDefault()\n const result = e.shiftKey ? outdentListItem(segments, cursorPos) : indentListItem(segments, cursorPos)\n if (result) {\n applyEditResult(editor, result)\n }\n return\n }\n }\n }\n }\n\n // Insert a newline at the model level (avoids the browser's broken\n // contentEditable behaviour near <a> elements).\n const insertPlainNewline = (editor: HTMLDivElement): void => {\n const offsets = getSelectionOffsets(editor)\n if (!offsets) {\n return\n }\n const currentSegments = readSegmentsFromDOM()\n pushUndo(currentSegments)\n const newSegments = replaceTextRange(currentSegments, offsets.start, offsets.end, '\\n')\n applyEditResult(editor, { segments: newSegments, cursorOffset: offsets.start + 1 })\n }\n\n // 2.8 Shift+Enter always inserts a newline (after a list-continuation check).\n if (e.key === 'Enter' && e.shiftKey && !e.nativeEvent.isComposing) {\n e.preventDefault()\n const editor = editorRef.current\n if (editor && !tryListContinuation(editor)) {\n insertPlainNewline(editor)\n }\n return\n }\n\n // 3. Enter without Shift (skipping IME): under `submitOnEnter` it submits\n // *unconditionally* — the send key must not turn into \"another bullet\" because\n // of what the line above starts with; list continuation lives on Shift+Enter\n // (branch 2.8). Without `submitOnEnter`, Enter is the newline key and continues.\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {\n e.preventDefault()\n if (submitOnEnter) {\n onSubmit?.(readSegmentsFromDOM())\n return\n }\n const editor = editorRef.current\n if (editor && !tryListContinuation(editor)) {\n insertPlainNewline(editor)\n }\n return\n }\n\n // 4. Escape\n if (e.key === 'Escape' && onEscape) {\n onEscape()\n return\n }\n\n // 4.5 Non-collapsed selection delete (Backspace/Delete across <a> boundaries)\n if ((e.key === 'Backspace' || e.key === 'Delete') && !e.nativeEvent.isComposing) {\n const editor = editorRef.current\n if (editor) {\n const offsets = getSelectionOffsets(editor)\n if (offsets && offsets.start !== offsets.end) {\n e.preventDefault()\n const currentSegments = readSegmentsFromDOM()\n pushUndo(currentSegments)\n const newSegments = replaceTextRange(currentSegments, offsets.start, offsets.end, '')\n applyEditResult(editor, { segments: newSegments, cursorOffset: offsets.start })\n runTriggerDetection()\n return\n }\n }\n }\n\n // 5. Backspace: check list prefix removal, then chip deletion\n if (e.key === 'Backspace') {\n const editor = editorRef.current\n if (editor) {\n const segments = readSegmentsFromDOM()\n const cursorPos = getCursorOffset(editor)\n if (markdownEnabled && cursorPos !== null) {\n const result = removeListPrefix(segments, cursorPos)\n if (result) {\n e.preventDefault()\n applyEditResult(editor, result)\n runTriggerDetection()\n return\n }\n }\n }\n if (handleChipBackspace()) {\n e.preventDefault()\n runTriggerDetection()\n return\n }\n }\n\n // 6. Delete (forward): delete chip as whole unit\n if (e.key === 'Delete' && handleChipForwardDelete()) {\n e.preventDefault()\n runTriggerDetection()\n return\n }\n },\n [\n activeTrigger,\n suggestions,\n suggestionsLoading,\n suggestionsError,\n selectedSuggestionIndex,\n onSubmit,\n submitOnEnter,\n onEscape,\n readSegmentsFromDOM,\n onChange,\n renderSegmentsToDOM,\n markdownEnabled,\n dismissTrigger,\n handleChipBackspace,\n handleChipForwardDelete,\n autoResolveActiveTrigger,\n runTriggerDetection,\n selectSuggestionInternal,\n pushUndo,\n handleKeyDownForUndoRedo,\n triggers,\n buildInsertChip,\n ],\n )\n\n return handleKeyDown\n}\n","'use client'\n\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport type { Segment, TriggerConfig, ActiveTrigger, TriggerSuggestion, ChipSegment } from './types.ts'\nimport { segmentsToPlainText } from './prompt-area-engine.ts'\nimport {\n isChipElement,\n isLinkElement,\n chipNodeToSegment,\n indexOfChildNode,\n domChildIndexToSegmentIndex,\n safeJsonStringify,\n} from './dom-helpers.ts'\nimport { setCursorAtOffset } from './cursor-helpers.ts'\n\ntype UseChipEditingOptions = {\n editorRef: React.RefObject<HTMLDivElement | null>\n triggers: TriggerConfig[]\n disabled: boolean\n onChange: (segments: Segment[]) => void\n renderSegmentsToDOM: (segments: Segment[]) => void\n onChipClick?: (chip: ChipSegment) => void\n onChipAdd?: (chip: ChipSegment) => void\n onChipDelete?: (chip: ChipSegment) => void\n onLinkClick?: (url: string) => void\n setActiveTrigger: React.Dispatch<React.SetStateAction<ActiveTrigger | null>>\n setSelectedSuggestionIndex: React.Dispatch<React.SetStateAction<number>>\n setTriggerRect: React.Dispatch<React.SetStateAction<DOMRect | null>>\n runSearch: (query: string, config: TriggerConfig) => void\n activeTrigger: ActiveTrigger | null\n suggestions: TriggerSuggestion[]\n}\n\ntype UseChipEditingReturn = {\n handleClick: (e: React.MouseEvent<HTMLDivElement>) => void\n handleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void\n /** Forget the clicked chip: typing or a dismiss supersedes the chip-click dropdown. */\n clear: () => void\n /**\n * The `reopenOnChipClick` selection path: when a chip-click dropdown is open, replace the\n * clicked chip in place and return true (the caller dismisses and refocuses); return false\n * when no chip edit is in flight so the caller resolves typed trigger text as usual.\n * `pushUndo` arrives per call because the undo stack lives in usePromptAreaEvents, which is\n * wired up after this hook.\n */\n trySelectEditingChip: (\n segments: Segment[],\n chipData: Omit<ChipSegment, 'type' | 'trigger'>,\n triggerChar: string,\n pushUndo: (segments: Segment[]) => void,\n ) => boolean\n}\n\n// The chip-click editing path (`reopenOnChipClick`), moved whole from use-prompt-area.ts:\n// the three refs and their anti-loop choreography, the mousedown/click delegation, and the\n// re-verify-on-select recovery.\nexport function useChipEditing({\n editorRef,\n triggers,\n disabled,\n onChange,\n renderSegmentsToDOM,\n onChipClick,\n onChipAdd,\n onChipDelete,\n onLinkClick,\n setActiveTrigger,\n setSelectedSuggestionIndex,\n setTriggerRect,\n runSearch,\n activeTrigger,\n suggestions,\n}: UseChipEditingOptions): UseChipEditingReturn {\n // Chip whose dropdown was reopened via `reopenOnChipClick`: while set, the active\n // dropdown edits this chip in place instead of resolving typed text. `segIndex` is\n // the segment index at CLICK time, not the DOM node, which can detach if\n // `renderSegmentsToDOM` re-renders while the dropdown is open; selection re-verifies\n // it and falls back to a trigger+value search if the model shifted underneath.\n const editingChip = useRef<{ chip: ChipSegment; segIndex: number } | null>(null)\n\n // The chip node currently edited via `reopenOnChipClick`, kept in lockstep with\n // `editingChip`/`activeTrigger`. Answers \"is THIS exact element the open one\" by\n // reference identity — trigger+value cannot distinguish two chips sharing a value.\n const openChipNode = useRef<HTMLElement | null>(null)\n\n // Set by `handleMouseDown` when the mousedown landed on `openChipNode.current`;\n // read and cleared by the following `handleClick` to tell \"reopen\" from\n // \"toggle closed\". A real mousedown on the editor root rather than a\n // `dismissTrigger` flag: bubbling reaches the root before `document`, where\n // TriggerPopover's outside-click dismiss listens and would clear `openChipNode`\n // first — and it stays scoped to this node, so an unrelated dismiss cannot poison\n // a later click on the same chip.\n const suppressReopenChip = useRef<HTMLElement | null>(null)\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n const target = e.target\n if (!(target instanceof Node)) {\n return\n }\n\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n let node: Node | null = target\n while (node && node !== editor) {\n // Check for URL link click — only navigate on Cmd/Ctrl+Click;\n // plain click just positions the cursor for editing.\n if (isLinkElement(node)) {\n if (e.metaKey || e.ctrlKey) {\n e.preventDefault()\n onLinkClick?.(node.href)\n window.open(node.href, '_blank', 'noopener,noreferrer')\n return\n }\n // Plain click: let the browser place the cursor inside the link text\n break\n }\n\n if (isChipElement(node)) {\n // Spawn ripple effect. `isChipElement` has already narrowed `node`\n // to HTMLElement, so no cast is needed.\n const rect = node.getBoundingClientRect()\n const ripple = document.createElement('span')\n ripple.className = 'prompt-area-chip-ripple'\n const size = Math.max(rect.width, rect.height)\n ripple.style.width = `${size}px`\n ripple.style.height = `${size}px`\n ripple.style.left = `${e.clientX - rect.left - size / 2}px`\n ripple.style.top = `${e.clientY - rect.top - size / 2}px`\n node.appendChild(ripple)\n ripple.addEventListener('animationend', () => ripple.remove())\n\n const chip = chipNodeToSegment(node)\n if (chip) {\n // Native chip-click dropdown: reopen this trigger's suggestions\n // anchored to the chip so the selection can replace it in place.\n // Gated on `!disabled` — a disabled composer must not accept edits\n // through any path, including this one.\n const config = triggers.find((t) => t.char === chip.trigger)\n // A click on THIS exact chip element while its own dropdown was\n // open just closed it (see `suppressReopenChip` and\n // `handleMouseDown`) — treat that as a toggle-close, not a reopen.\n const wasOpenForThisChip = suppressReopenChip.current === node\n suppressReopenChip.current = null\n if (!disabled && !wasOpenForThisChip && config?.reopenOnChipClick && config.mode === 'dropdown' && config.onSearch) {\n const childIdx = indexOfChildNode(editor, node)\n editingChip.current = {\n chip,\n segIndex: domChildIndexToSegmentIndex(editor, childIdx),\n }\n openChipNode.current = node\n setActiveTrigger({ config, startOffset: 0, query: '' })\n setSelectedSuggestionIndex(0)\n setTriggerRect(rect)\n runSearch('', config)\n }\n onChipClick?.(chip)\n }\n return\n }\n node = node.parentNode\n }\n },\n [onChipClick, onLinkClick, triggers, runSearch, disabled],\n )\n\n // Feeds `suppressReopenChip` for handleClick's toggle-close detection.\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n const target = e.target\n const editor = editorRef.current\n if (!editor || !(target instanceof Node)) {\n suppressReopenChip.current = null\n return\n }\n\n let node: Node | null = target\n while (node && node !== editor) {\n if (isChipElement(node)) {\n suppressReopenChip.current = openChipNode.current === node ? node : null\n return\n }\n node = node.parentNode\n }\n suppressReopenChip.current = null\n }, [])\n\n // Select a suggestion from the dropdown\n\n const clear = useCallback(() => {\n editingChip.current = null\n openChipNode.current = null\n }, [])\n\n // Chip-click dropdown (`reopenOnChipClick`): replace the clicked chip in\n // place instead of resolving typed trigger text at the caret. Disabled\n // is re-checked here (not just at open time) in case the composer\n // became disabled while the popover was still open.\n const trySelectEditingChip = useCallback(\n (\n segments: Segment[],\n chipData: Omit<ChipSegment, 'type' | 'trigger'>,\n triggerChar: string,\n pushUndo: (segments: Segment[]) => void,\n ): boolean => {\n const editing = editingChip.current\n if (!editing) {\n return false\n }\n const editor = editorRef.current\n if (editor && !disabled) {\n // Re-verify the click-time index still holds the same chip — the\n // model may have shifted (external value update, undo/redo) while\n // the dropdown was open. If it moved, recover ONLY when exactly one\n // chip in the document now matches trigger+value: with duplicates,\n // guessing risks silently editing the wrong instance, which is\n // worse than the no-op this falls back to.\n const atIndex = segments[editing.segIndex]\n const stillThere = atIndex?.type === 'chip' && atIndex.trigger === editing.chip.trigger && atIndex.value === editing.chip.value\n const segIdx = stillThere\n ? editing.segIndex\n : (() => {\n const matches: number[] = []\n segments.forEach((seg, i) => {\n if (seg.type === 'chip' && seg.trigger === editing.chip.trigger && seg.value === editing.chip.value) {\n matches.push(i)\n }\n })\n return matches.length === 1 ? matches[0] : -1\n })()\n const oldChip = segIdx !== -1 ? segments[segIdx] : undefined\n\n if (oldChip?.type === 'chip') {\n const newChip: ChipSegment = {\n type: 'chip',\n trigger: triggerChar,\n ...chipData,\n }\n let newSegments = segments.map((seg, i) => (i === segIdx ? newChip : seg))\n\n // Guarantee a real landing spot after the replaced chip, mirroring\n // resolveChip's trailing-space convention (prompt-area-engine.ts):\n // if the new chip is now the last segment (or directly followed by\n // another chip), the caret would land at a bare element boundary\n // with no text node, which some engines fail to render/snap a\n // visible caret at.\n const nextSeg = newSegments[segIdx + 1]\n const insertedSpace = !nextSeg || nextSeg.type !== 'text' || nextSeg.text.length === 0\n if (insertedSpace) {\n newSegments = [...newSegments.slice(0, segIdx + 1), { type: 'text', text: ' ' }, ...newSegments.slice(segIdx + 1)]\n }\n\n pushUndo(segments)\n onChange(newSegments)\n renderSegmentsToDOM(newSegments)\n\n // Same value + display text + data: treat as a no-op confirmation\n // rather than a destructive delete+add — onChipDelete is\n // documented as firing on backspace/forward-delete, not on\n // re-confirming the already-selected suggestion.\n const unchanged =\n oldChip.value === newChip.value &&\n oldChip.displayText === newChip.displayText &&\n safeJsonStringify(oldChip.data) === safeJsonStringify(newChip.data)\n if (!unchanged) {\n onChipDelete?.(oldChip)\n onChipAdd?.(newChip)\n }\n\n // +1 when a space was inserted, matching resolveChip's own\n // \"+1 accounts for the trailing space after the chip\" placement —\n // landing exactly at the chip's end would put the caret at the\n // same bare element boundary the inserted space exists to avoid.\n const caretOffset = segmentsToPlainText(newSegments.slice(0, segIdx + 1)).length + (insertedSpace ? 1 : 0)\n setCursorAtOffset(editor, caretOffset)\n }\n }\n return true\n },\n [disabled, onChange, renderSegmentsToDOM, onChipAdd, onChipDelete],\n )\n\n // Chip-click dropdown: once the empty-query suggestions arrive, preselect\n // the chip's current value so the list opens \"on\" the existing choice.\n useEffect(() => {\n const editing = editingChip.current\n if (!editing || !activeTrigger?.config.reopenOnChipClick) {\n return\n }\n const idx = suggestions.findIndex((s) => s.value === editing.chip.value)\n if (idx > 0) {\n setSelectedSuggestionIndex(idx)\n }\n }, [suggestions, activeTrigger])\n\n // Memoized so consumers can put the hook's result in dependency arrays without\n // re-creating their callbacks every render.\n return useMemo(\n () => ({ handleClick, handleMouseDown, clear, trySelectEditingChip }),\n [handleClick, handleMouseDown, clear, trySelectEditingChip],\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { TriggerConfig, TriggerSuggestion } from './types.ts'\n\ntype UseTriggerSearchReturn = {\n suggestions: TriggerSuggestion[]\n suggestionsLoading: boolean\n suggestionsError: string | null\n /** Run a search for the given query using the trigger's onSearch config. */\n search: (query: string, config: TriggerConfig) => void\n /** Cancel any in-flight search and reset state. */\n reset: () => void\n}\n\n/**\n * Manages async trigger search lifecycle: debouncing, AbortController\n * cancellation, race-condition prevention, loading/error state.\n *\n * Extracted from `usePromptArea` so the main hook stays focused on\n * editing concerns while this hook owns the data-fetching side.\n */\nexport function useTriggerSearch(): UseTriggerSearchReturn {\n const [suggestions, setSuggestions] = useState<TriggerSuggestion[]>([])\n const [suggestionsLoading, setSuggestionsLoading] = useState(false)\n const [suggestionsError, setSuggestionsError] = useState<string | null>(null)\n\n // Version counter – belt-and-suspenders alongside AbortController\n const searchVersion = useRef(0)\n const abortController = useRef<AbortController | null>(null)\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const reset = useCallback(() => {\n abortController.current?.abort()\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n setSuggestions([])\n setSuggestionsLoading(false)\n setSuggestionsError(null)\n }, [])\n\n const search = useCallback((query: string, config: TriggerConfig) => {\n if (!config.onSearch) {\n return\n }\n\n abortController.current?.abort()\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n\n setSuggestionsLoading(true)\n setSuggestionsError(null)\n searchVersion.current++\n const version = searchVersion.current\n\n const controller = new AbortController()\n abortController.current = controller\n const { onSearch, onSearchError, searchDebounceMs } = config\n\n const executeSearch = () => {\n const result = onSearch(query, { signal: controller.signal })\n\n if (result instanceof Promise) {\n void result.then(\n (items) => {\n if (controller.signal.aborted || searchVersion.current !== version) {\n return\n }\n setSuggestions(items)\n setSuggestionsLoading(false)\n },\n (error: unknown) => {\n if (controller.signal.aborted || searchVersion.current !== version) {\n return\n }\n // Silently ignore AbortError (expected when superseded)\n if (error instanceof DOMException && error.name === 'AbortError') {\n return\n }\n setSuggestionsError(error instanceof Error ? error.message : 'Search failed')\n setSuggestionsLoading(false)\n onSearchError?.(error)\n },\n )\n } else {\n setSuggestions(result)\n setSuggestionsLoading(false)\n }\n }\n\n // Debounce subsequent searches but fire immediately for the initial empty query\n if (searchDebounceMs && searchDebounceMs > 0 && query.length > 0) {\n debounceTimer.current = setTimeout(executeSearch, searchDebounceMs)\n } else {\n executeSearch()\n }\n }, [])\n\n useEffect(() => {\n return () => {\n abortController.current?.abort()\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n }\n }, [])\n\n return {\n suggestions,\n suggestionsLoading,\n suggestionsError,\n search,\n reset,\n }\n}\n","'use client'\n\nimport { cn } from '../../lib/utils.ts'\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport type { Segment, TriggerConfig, ActiveTrigger, TriggerSuggestion, ChipSegment, PromptAreaHandle } from './types.ts'\nimport {\n detectActiveTrigger,\n segmentsToPlainText,\n plainTextToSegments,\n segmentsContentEqual,\n segmentsEqual,\n resolveChip,\n resolveText,\n truncateSegmentsToLength,\n} from './prompt-area-engine.ts'\nimport {\n autoFormatListPrefix,\n normalizeListPrefixes,\n renumberOrderedListSegments,\n remapOffset,\n hasOrderedListRun,\n} from './prompt-area-list-ops.ts'\nimport {\n isHTMLElement,\n isChipElement,\n isBRElement,\n chipNodeToSegment,\n normalizeEditorDOM,\n decorateEditor,\n safeJsonStringify,\n} from './dom-helpers.ts'\nimport { getCursorOffset, setCursorAtOffset, createRangeAtOffset, getSelectionOffsets, setSelectionAtOffsets } from './cursor-helpers.ts'\nimport { usePromptAreaEvents } from './use-prompt-area-events.ts'\nimport { usePromptAreaKeydown } from './use-prompt-area-keydown.ts'\nimport { useChipEditing } from './use-chip-editing.ts'\nimport { useTriggerSearch } from './use-trigger-search.ts'\n\ntype UsePromptAreaOptions = {\n value: Segment[]\n onChange: (segments: Segment[]) => void\n triggers?: TriggerConfig[]\n disabled?: boolean\n onSubmit?: (segments: Segment[]) => void\n onEscape?: () => void\n onChipClick?: (chip: ChipSegment) => void\n onChipAdd?: (chip: ChipSegment) => void\n onChipDelete?: (chip: ChipSegment) => void\n onLinkClick?: (url: string) => void\n onPaste?: (data: { segments: Segment[]; source: 'internal' | 'external' }) => void\n onRawPaste?: (e: React.ClipboardEvent<HTMLDivElement>) => void\n onUndo?: (segments: Segment[]) => void\n onRedo?: (segments: Segment[]) => void\n onImagePaste?: (file: File) => void\n markdown?: boolean\n normalizeBullets?: boolean\n submitOnEnter?: boolean\n maxLength?: number\n}\n\ntype UsePromptAreaReturn = {\n editorRef: React.RefObject<HTMLDivElement | null>\n activeTrigger: ActiveTrigger | null\n suggestions: TriggerSuggestion[]\n suggestionsLoading: boolean\n suggestionsError: string | null\n selectedSuggestionIndex: number\n handleInput: () => void\n handleKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void\n handleClick: (e: React.MouseEvent<HTMLDivElement>) => void\n handleMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void\n selectSuggestion: (suggestion: TriggerSuggestion) => void\n dismissTrigger: () => void\n handle: PromptAreaHandle\n triggerRect: DOMRect | null\n eventHandlers: {\n onPaste: (e: React.ClipboardEvent<HTMLDivElement>) => void\n onCopy: (e: React.ClipboardEvent<HTMLDivElement>) => void\n onCut: (e: React.ClipboardEvent<HTMLDivElement>) => void\n onDrop: (e: React.DragEvent<HTMLDivElement>) => void\n onDragOver: (e: React.DragEvent<HTMLDivElement>) => void\n onCompositionStart: () => void\n onCompositionEnd: () => void\n onBlur: () => void\n }\n}\n\n/** Debounce interval for grouping typed characters into a single undo snapshot */\nconst UNDO_DEBOUNCE_MS = 300\n\n// Shared default so an omitted `triggers` prop keeps a stable identity across\n// renders — a fresh [] would re-create renderSegmentsToDOM (and everything\n// keyed on it) on every parent render.\nconst NO_TRIGGERS: TriggerConfig[] = []\n\nexport function usePromptArea({\n value,\n onChange,\n triggers = NO_TRIGGERS,\n disabled = false,\n onSubmit,\n onEscape,\n onChipClick,\n onChipAdd,\n onChipDelete,\n onLinkClick,\n onPaste,\n onRawPaste,\n onUndo,\n onRedo,\n onImagePaste,\n markdown: markdownEnabled = true,\n normalizeBullets = true,\n submitOnEnter = true,\n maxLength,\n}: UsePromptAreaOptions): UsePromptAreaReturn {\n const editorRef = useRef<HTMLDivElement | null>(null)\n const [activeTrigger, setActiveTrigger] = useState<ActiveTrigger | null>(null)\n const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(0)\n const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null)\n\n const { suggestions, suggestionsLoading, suggestionsError, search: runSearch, reset: resetSearch } = useTriggerSearch()\n\n // Guard against circular DOM <-> model syncs\n const isSyncing = useRef(false)\n const lastRenderedValue = useRef<Segment[]>([])\n\n // Debounced undo: groups consecutive keystrokes into a single undo snapshot\n const undoTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n const undoBaseState = useRef<Segment[] | null>(null)\n\n // DOM -> Model: read segments from the contentEditable DOM\n\n const readSegmentsFromDOM = useCallback((): Segment[] => {\n const editor = editorRef.current\n if (!editor) {\n return []\n }\n\n const segments: Segment[] = []\n // Track whether the editor holds any real content (text/chip) or a sentinel\n // <br> that renderSegmentsToDOM added. When it holds neither, any <br> nodes\n // present are the browser's filler <br> (see the empty-editor check below).\n let hasRealContent = false\n let hasSentinel = false\n\n for (let i = 0; i < editor.childNodes.length; i++) {\n const node = editor.childNodes[i]\n\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent ?? ''\n if (text) {\n segments.push({ type: 'text', text })\n hasRealContent = true\n }\n } else if (isChipElement(node)) {\n const chip = chipNodeToSegment(node)\n if (chip) {\n segments.push(chip)\n hasRealContent = true\n }\n } else if (isBRElement(node)) {\n if (node.dataset.sentinel) {\n hasSentinel = true\n continue // skip sentinel <br>\n }\n segments.push({ type: 'text', text: '\\n' })\n } else if (isHTMLElement(node)) {\n const text = node.textContent ?? ''\n if (text) {\n segments.push({ type: 'text', text })\n hasRealContent = true\n }\n }\n }\n\n // An emptied editor keeps a lone browser filler <br>; reading it as \"\\n\" would\n // make `value` permanently non-empty and hide the placeholder forever. A newline\n // we rendered always carries surrounding content or a trailing sentinel <br>, so\n // with neither present every <br> is filler and the editor is genuinely empty.\n if (!hasRealContent && !hasSentinel) {\n return []\n }\n\n return segments\n }, [])\n\n // Model -> DOM: render segments into the contentEditable div\n\n const renderSegmentsToDOM = useCallback(\n (segments: Segment[]) => {\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n isSyncing.current = true\n\n // Save the caret as a plain-text offset, not a {nodeIndex, offset} pair:\n // the rebuild plus decorateEditor re-chunk the child nodes, so a node\n // index recorded against the old tree lands in the wrong node and its\n // clamped offset silently moves the caret.\n const savedCursorOffset = getCursorOffset(editor)\n\n // Clear DOM safely (no innerHTML assignment)\n while (editor.firstChild) {\n editor.removeChild(editor.firstChild)\n }\n\n for (const seg of segments) {\n if (seg.type === 'text') {\n const lines = seg.text.split('\\n')\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n if (lines[lineIdx]) {\n editor.appendChild(document.createTextNode(lines[lineIdx]))\n }\n if (lineIdx < lines.length - 1) {\n editor.appendChild(document.createElement('br'))\n }\n }\n } else {\n const chip = document.createElement('span')\n chip.contentEditable = 'false'\n chip.dataset.chipTrigger = seg.trigger\n chip.dataset.chipValue = seg.value\n chip.dataset.chipDisplay = seg.displayText\n if (seg.data !== undefined) {\n const json = safeJsonStringify(seg.data)\n if (json) {\n chip.dataset.chipData = json\n }\n }\n if (seg.autoResolved) {\n chip.dataset.chipAutoResolved = 'true'\n }\n const triggerConfig = triggers.find((t) => t.char === seg.trigger)\n const chipStyle = triggerConfig?.chipStyle ?? 'pill'\n chip.dataset.chipStyle = chipStyle\n chip.className = cn('prompt-area-chip', chipStyle === 'inline' && 'prompt-area-chip--inline', triggerConfig?.chipClassName)\n chip.textContent = `${seg.trigger}${seg.displayText}`\n chip.setAttribute('role', 'button')\n chip.setAttribute('tabindex', '-1')\n editor.appendChild(chip)\n }\n }\n\n // Append sentinel <br> so trailing newlines are visible in contentEditable\n if (editor.lastChild && isBRElement(editor.lastChild)) {\n const sentinel = document.createElement('br')\n sentinel.dataset.sentinel = 'true'\n editor.appendChild(sentinel)\n }\n\n // Decorate URLs, markdown formatting, and list bullets in text nodes\n decorateEditor(editor, markdownEnabled)\n\n if (savedCursorOffset !== null) {\n setCursorAtOffset(editor, savedCursorOffset)\n }\n\n lastRenderedValue.current = segments\n isSyncing.current = false\n },\n [triggers, markdownEnabled],\n )\n\n // The chip-click editing path (`reopenOnChipClick`) lives in use-chip-editing.ts.\n\n const chipEditing = useChipEditing({\n editorRef,\n triggers,\n disabled,\n onChange,\n renderSegmentsToDOM,\n onChipClick,\n onChipAdd,\n onChipDelete,\n onLinkClick,\n setActiveTrigger,\n setSelectedSuggestionIndex,\n setTriggerRect,\n runSearch,\n activeTrigger,\n suggestions,\n })\n\n // Trigger detection (extracted so events module can call it)\n\n // Builds the insertChip handed to callback/launch activations: replaces the\n // trigger's range with a chip and notifies onChipAdd.\n const buildInsertChip = useCallback(\n (segments: Segment[], trigger: ActiveTrigger) => (chip: Omit<ChipSegment, 'type'>) => {\n const chipResult = resolveChip(segments, trigger, {\n value: chip.value,\n displayText: chip.displayText,\n data: chip.data,\n })\n onChange(chipResult.segments)\n renderSegmentsToDOM(chipResult.segments)\n onChipAdd?.({\n type: 'chip',\n trigger: trigger.config.char,\n value: chip.value,\n displayText: chip.displayText,\n ...(chip.data !== undefined ? { data: chip.data } : {}),\n })\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, chipResult.cursorOffset)\n }\n },\n [onChange, renderSegmentsToDOM, onChipAdd],\n )\n\n const runTriggerDetection = useCallback(() => {\n const editor = editorRef.current\n if (!editor) {\n return\n }\n\n const segments = readSegmentsFromDOM()\n const plainText = segmentsToPlainText(segments)\n const cursorPos = getCursorOffset(editor)\n\n if (cursorPos === null) {\n return\n }\n\n const detected = detectActiveTrigger(plainText, cursorPos, triggers)\n\n // Typing supersedes a chip-click dropdown: whichever branch we take next,\n // the popover no longer edits the clicked chip.\n chipEditing.clear()\n\n if (detected) {\n setActiveTrigger(detected)\n setSelectedSuggestionIndex(0)\n\n // Position the popover at the trigger character, not the cursor.\n // Build a range at detected.startOffset so the dropdown anchors to\n // the trigger char even when the cursor has moved past it.\n const triggerRange = createRangeAtOffset(editor, detected.startOffset)\n if (triggerRange) {\n const rect = triggerRange.getBoundingClientRect()\n // A zero rect means the range couldn't be mapped (e.g. after DOM\n // re-render). Skip updating triggerRect so we keep the last valid one.\n if (rect.height > 0 || rect.left > 0 || rect.top > 0) {\n setTriggerRect(rect)\n }\n }\n\n if (detected.config.mode === 'dropdown' && detected.config.onSearch) {\n runSearch(detected.query, detected.config)\n }\n\n if (detected.config.mode === 'callback' && detected.config.onActivate) {\n detected.config.onActivate({\n text: plainText,\n cursorPosition: cursorPos,\n insertChip: buildInsertChip(segments, detected),\n })\n }\n } else {\n setActiveTrigger(null)\n resetSearch()\n }\n }, [triggers, readSegmentsFromDOM, buildInsertChip, resetSearch, runSearch, chipEditing])\n\n // Dismiss trigger\n\n const dismissTrigger = useCallback(() => {\n chipEditing.clear()\n setActiveTrigger(null)\n setSelectedSuggestionIndex(0)\n resetSearch()\n }, [resetSearch, chipEditing])\n\n // Wire up edge-case event handlers\n\n const events = usePromptAreaEvents({\n editorRef,\n readSegmentsFromDOM,\n onChange,\n renderSegmentsToDOM,\n runTriggerDetection,\n dismissTrigger,\n triggers,\n markdownEnabled,\n normalizeBullets,\n onPaste,\n onRawPaste,\n onUndo,\n onRedo,\n onChipAdd,\n onImagePaste,\n })\n\n // Sync value prop -> DOM on external changes\n\n // Layout effect, not passive: a passive copy of this effect can still be\n // queued when the next keystroke's input event arrives, and React flushes\n // pending passive effects before rendering that keystroke's onChange. The\n // stale flush would compare an older render's `value` against the\n // lastRenderedValue that handleInput just advanced, read its own echo lag as\n // an external change, and rewrite the editor to pre-keystroke content —\n // leaving the caret behind the character once the echo re-rendered it.\n // Inside the commit, `value` can never be older than lastRenderedValue.\n useLayoutEffect(() => {\n if (isSyncing.current) {\n return\n }\n if (segmentsEqual(value, lastRenderedValue.current)) {\n return\n }\n\n // Normalize list prefixes (e.g., \"- \" → \"• \" when markdown is on)\n // so externally-provided segments render bullet characters correctly.\n if (markdownEnabled && normalizeBullets) {\n const normalized = normalizeListPrefixes(value, true)\n if (normalized !== value) {\n onChange(normalized)\n return // onChange will trigger a re-render with the normalized value\n }\n }\n\n // A rebuild churns the caret and the decorations, so skip it when the\n // editor already shows exactly this content — e.g. a consumer echoed our\n // onChange back re-chunked, or the DOM is split by decorations. Adopt the\n // value so the equality guard above short-circuits from here on.\n if (segmentsContentEqual(readSegmentsFromDOM(), value)) {\n lastRenderedValue.current = value\n return\n }\n\n renderSegmentsToDOM(value)\n }, [value, readSegmentsFromDOM, renderSegmentsToDOM, markdownEnabled, normalizeBullets, onChange])\n\n // Re-render when markdown mode changes to apply/strip decorations\n // Also convert bullet characters: • ↔ - in text segments\n // Layout for the same reason as the value sync above: a queued passive copy\n // could flush mid-typing and render a stale `value`.\n const prevMarkdown = useRef(markdownEnabled)\n useLayoutEffect(() => {\n if (prevMarkdown.current === markdownEnabled) {\n return\n }\n prevMarkdown.current = markdownEnabled\n\n const converted = normalizeBullets ? normalizeListPrefixes(value, markdownEnabled) : value\n if (converted !== value) {\n onChange(converted)\n } else {\n renderSegmentsToDOM(value)\n }\n }, [markdownEnabled, normalizeBullets, renderSegmentsToDOM, value, onChange])\n\n // Clean up undo debounce timer on unmount\n useEffect(() => {\n return () => {\n if (undoTimer.current) {\n clearTimeout(undoTimer.current)\n }\n }\n }, [])\n\n // Handle input events\n\n const handleInput = useCallback(() => {\n if (isSyncing.current) {\n return\n }\n\n // During IME composition, sync model but skip trigger detection\n if (events.isComposing.current) {\n const segments = readSegmentsFromDOM()\n lastRenderedValue.current = segments\n onChange(segments)\n return\n }\n\n const editor = editorRef.current\n\n // Capture cursor offset BEFORE normalizeEditorDOM strips <a> elements,\n // otherwise the anchor node becomes detached and we lose the position.\n const savedCursorOffset = editor ? getCursorOffset(editor) : null\n\n if (editor) {\n // Normalize browser-inserted block elements (div, p, font, a, etc.)\n normalizeEditorDOM(editor)\n }\n\n const segments = readSegmentsFromDOM()\n\n // Enforce maxLength: if the edit pushed the editor past the cap, truncate\n // back to maxLength characters and keep the caret where the user was\n // editing (clamped to the cap) rather than forcing it to the end.\n if (maxLength != null && editor && segmentsToPlainText(segments).length > maxLength) {\n const caret = getCursorOffset(editor)\n const truncated = truncateSegmentsToLength(segments, maxLength)\n lastRenderedValue.current = truncated\n onChange(truncated)\n renderSegmentsToDOM(truncated)\n setCursorAtOffset(editor, caret != null ? Math.min(caret, maxLength) : maxLength)\n runTriggerDetection()\n return\n }\n\n // Check for list auto-formatting (e.g., \"- \" -> \"bullet \")\n if (markdownEnabled && normalizeBullets && editor && savedCursorOffset !== null) {\n const formatted = autoFormatListPrefix(segments, savedCursorOffset)\n if (formatted) {\n lastRenderedValue.current = formatted.segments\n onChange(formatted.segments)\n renderSegmentsToDOM(formatted.segments)\n setCursorAtOffset(editor, formatted.cursorOffset)\n runTriggerDetection()\n return\n }\n }\n\n // Native structural edits (e.g. a Backspace that deleted or merged a list\n // row) bypass applyEditResult, so rebuild ordered-list numbering here too.\n // handleInput fires on every keystroke, so gate on a genuine ordered-list\n // run — this renumbers a real list (1,2,4 → 1,2,3) but leaves incidental\n // numeric prose (\"1985. Born / 2020. Died\") untouched.\n let nextSegments = segments\n let renumberedCursor: number | null = null\n if (markdownEnabled && savedCursorOffset !== null && hasOrderedListRun(segmentsToPlainText(segments))) {\n const renumbered = renumberOrderedListSegments(segments)\n if (renumbered.edits.length > 0) {\n nextSegments = renumbered.segments\n renumberedCursor = remapOffset(savedCursorOffset, renumbered.edits)\n }\n }\n\n // Debounced undo: capture the pre-edit state at the start of a typing\n // session and push it to the undo stack after UNDO_DEBOUNCE_MS of idle.\n if (!undoBaseState.current) {\n undoBaseState.current = lastRenderedValue.current\n }\n\n lastRenderedValue.current = nextSegments\n onChange(nextSegments)\n if (undoTimer.current) {\n clearTimeout(undoTimer.current)\n }\n undoTimer.current = setTimeout(() => {\n if (undoBaseState.current) {\n events.pushUndo(undoBaseState.current)\n undoBaseState.current = null\n }\n undoTimer.current = null\n }, UNDO_DEBOUNCE_MS)\n\n // Apply the recomputed model to the DOM. A renumber rewrites text nodes, so\n // it needs a full re-render (which also re-decorates); otherwise just\n // re-decorate the existing DOM in place.\n if (editor) {\n if (renumberedCursor !== null) {\n renderSegmentsToDOM(nextSegments)\n setCursorAtOffset(editor, renumberedCursor)\n } else {\n decorateEditor(editor, markdownEnabled)\n if (savedCursorOffset !== null) {\n setCursorAtOffset(editor, savedCursorOffset)\n }\n }\n }\n\n runTriggerDetection()\n }, [onChange, readSegmentsFromDOM, runTriggerDetection, renderSegmentsToDOM, markdownEnabled, normalizeBullets, maxLength, events])\n\n const selectSuggestionInternal = useCallback(\n (suggestion: TriggerSuggestion) => {\n if (!activeTrigger) {\n return\n }\n\n const segments = readSegmentsFromDOM()\n\n // Text-resolved suggestions leave before any chip machinery runs: there\n // is no chip, so there is nothing for the chip-click editing path or the\n // onChipAdd callback below to be about.\n const asText = activeTrigger.config.insertAsText?.(suggestion)\n if (asText !== undefined) {\n const inserted = resolveText(segments, activeTrigger, asText)\n events.pushUndo(segments)\n onChange(inserted.segments)\n renderSegmentsToDOM(inserted.segments)\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, inserted.cursorOffset)\n }\n dismissTrigger()\n setTimeout(() => {\n editorRef.current?.focus()\n }, 0)\n return\n }\n\n const displayText = activeTrigger.config.onSelect?.(suggestion) ?? suggestion.label\n\n const chipData = {\n value: suggestion.value,\n displayText: displayText || suggestion.label,\n data: suggestion.data,\n }\n\n // Chip-click dropdown (`reopenOnChipClick`): the whole path lives in\n // use-chip-editing.ts; on true the chip was replaced in place (or the edit\n // was refused because the composer went disabled) and we only dismiss and\n // refocus here.\n if (chipEditing.trySelectEditingChip(segments, chipData, activeTrigger.config.char, events.pushUndo)) {\n dismissTrigger()\n setTimeout(() => {\n editorRef.current?.focus()\n }, 0)\n return\n }\n const result = resolveChip(segments, activeTrigger, chipData)\n\n onChange(result.segments)\n renderSegmentsToDOM(result.segments)\n\n onChipAdd?.({\n type: 'chip',\n trigger: activeTrigger.config.char,\n ...chipData,\n })\n\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, result.cursorOffset)\n }\n\n dismissTrigger()\n\n setTimeout(() => {\n editorRef.current?.focus()\n }, 0)\n },\n [activeTrigger, readSegmentsFromDOM, onChange, renderSegmentsToDOM, dismissTrigger, onChipAdd, events, chipEditing],\n )\n\n const selectSuggestion = selectSuggestionInternal\n\n // Handle key events — the numbered router and its chip-deletion helpers live in\n // use-prompt-area-keydown.ts.\n\n const handleKeyDown = usePromptAreaKeydown({\n editorRef,\n triggers,\n markdownEnabled,\n submitOnEnter,\n onSubmit,\n onEscape,\n onChange,\n onChipAdd,\n onChipDelete,\n readSegmentsFromDOM,\n renderSegmentsToDOM,\n runTriggerDetection,\n dismissTrigger,\n buildInsertChip,\n selectSuggestionInternal,\n activeTrigger,\n suggestions,\n suggestionsLoading,\n suggestionsError,\n selectedSuggestionIndex,\n setSelectedSuggestionIndex,\n pushUndo: events.pushUndo,\n handleKeyDownForUndoRedo: events.handleKeyDownForUndoRedo,\n lastRenderedValue,\n undoTimer,\n undoBaseState,\n })\n\n // Imperative handle (memoized to avoid identity changes)\n\n const handle: PromptAreaHandle = useMemo(\n () => ({\n focus: () => editorRef.current?.focus(),\n blur: () => editorRef.current?.blur(),\n insertChip: (chip) => {\n const segments = readSegmentsFromDOM()\n const newChip: ChipSegment = { type: 'chip', ...chip }\n const newSegments: Segment[] = [...segments, newChip, { type: 'text', text: ' ' }]\n onChange(newSegments)\n renderSegmentsToDOM(newSegments)\n onChipAdd?.(newChip)\n },\n getPlainText: () => segmentsToPlainText(readSegmentsFromDOM()),\n clear: () => {\n onChange([])\n const editor = editorRef.current\n if (editor) {\n while (editor.firstChild) {\n editor.removeChild(editor.firstChild)\n }\n }\n events.resetUndoHistory()\n if (undoTimer.current) {\n clearTimeout(undoTimer.current)\n undoTimer.current = null\n }\n undoBaseState.current = null\n },\n setText: (text) => {\n events.pushUndo(readSegmentsFromDOM())\n const segments = plainTextToSegments(text)\n onChange(segments)\n renderSegmentsToDOM(segments)\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, text.length)\n }\n },\n appendText: (text) => {\n const segments = readSegmentsFromDOM()\n events.pushUndo(segments)\n // Merge into the trailing text segment so the onChange value doesn't\n // carry two adjacent un-merged text segments.\n const last = segments[segments.length - 1]\n const next: Segment[] =\n last?.type === 'text'\n ? [...segments.slice(0, -1), { type: 'text', text: last.text + text }]\n : [...segments, { type: 'text', text }]\n onChange(next)\n renderSegmentsToDOM(next)\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, segmentsToPlainText(next).length)\n }\n },\n getCursorPosition: () => {\n const editor = editorRef.current\n return editor ? getCursorOffset(editor) : null\n },\n setCursorPosition: (offset) => {\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, offset)\n }\n },\n setCursorToEnd: () => {\n const editor = editorRef.current\n if (editor) {\n setCursorAtOffset(editor, segmentsToPlainText(readSegmentsFromDOM()).length)\n }\n },\n getSelection: () => {\n const editor = editorRef.current\n return editor ? getSelectionOffsets(editor) : null\n },\n setSelection: (start, end) => {\n const editor = editorRef.current\n if (editor) {\n setSelectionAtOffsets(editor, start, end)\n }\n },\n }),\n [readSegmentsFromDOM, onChange, renderSegmentsToDOM, onChipAdd, events],\n )\n\n // Compose event handlers\n\n const eventHandlers = useMemo(\n () => ({\n onPaste: events.handlePaste,\n onCopy: events.handleCopy,\n onCut: events.handleCut,\n onDrop: events.handleDrop,\n onDragOver: events.handleDragOver,\n onCompositionStart: events.handleCompositionStart,\n onCompositionEnd: events.handleCompositionEnd,\n onBlur: events.handleBlur,\n }),\n [\n events.handlePaste,\n events.handleCopy,\n events.handleCut,\n events.handleDrop,\n events.handleDragOver,\n events.handleCompositionStart,\n events.handleCompositionEnd,\n events.handleBlur,\n ],\n )\n\n return {\n editorRef,\n activeTrigger,\n suggestions,\n suggestionsLoading,\n suggestionsError,\n selectedSuggestionIndex,\n handleInput,\n handleKeyDown,\n handleClick: chipEditing.handleClick,\n handleMouseDown: chipEditing.handleMouseDown,\n selectSuggestion,\n dismissTrigger,\n handle,\n triggerRect,\n eventHandlers,\n }\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { cn } from '../../lib/utils.ts'\nimport type { TriggerSuggestion } from './types.ts'\n\ntype TriggerPopoverProps = {\n suggestions: TriggerSuggestion[]\n loading: boolean\n error?: string | null\n emptyMessage?: string\n selectedIndex: number\n onSelect: (suggestion: TriggerSuggestion) => void\n onDismiss: () => void\n triggerRect: DOMRect | null\n triggerChar: string\n}\n\n// Single source of truth for the popover height: drives both the flip-above\n// calculation and the maxHeight style.\nconst POPOVER_MAX_HEIGHT = 240\n\n/**\n * Floating popover that displays trigger suggestions.\n * Positioned relative to the trigger character location in the editor.\n */\nexport function TriggerPopover({\n suggestions,\n loading,\n error,\n emptyMessage,\n selectedIndex,\n onSelect,\n onDismiss,\n triggerRect,\n triggerChar,\n}: TriggerPopoverProps) {\n const popoverRef = useRef<HTMLDivElement>(null)\n const selectedRef = useRef<HTMLButtonElement>(null)\n\n useEffect(() => {\n selectedRef.current?.scrollIntoView({ block: 'nearest' })\n }, [selectedIndex])\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n const target = e.target\n if (popoverRef.current && target instanceof Node && !popoverRef.current.contains(target)) {\n onDismiss()\n }\n }\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [onDismiss])\n\n if (!triggerRect) {\n return null\n }\n if (suggestions.length === 0 && !loading && !error && !emptyMessage) {\n return null\n }\n\n // Position the popover relative to the trigger character, clamped to the\n // viewport. Flip above the trigger when there isn't enough room below, so the\n // suggestion list stays on-screen near the bottom edge.\n const popoverMaxWidth = Math.min(320, window.innerWidth - 16)\n const left = Math.min(triggerRect.left, window.innerWidth - popoverMaxWidth - 8)\n const spaceBelow = window.innerHeight - triggerRect.bottom\n const positionAbove = spaceBelow < POPOVER_MAX_HEIGHT && triggerRect.top > spaceBelow\n const style: React.CSSProperties = {\n position: 'fixed',\n left: `${Math.max(8, left)}px`,\n zIndex: 50,\n maxWidth: `${popoverMaxWidth}px`,\n maxHeight: `${POPOVER_MAX_HEIGHT}px`,\n ...(positionAbove ? { bottom: `${window.innerHeight - triggerRect.top + 4}px` } : { top: `${triggerRect.bottom + 4}px` }),\n }\n\n return (\n <div\n ref={popoverRef}\n className={cn('min-w-[200px] overflow-y-auto', 'bg-surface rounded-xl border p-2 shadow-md', 'animate-in fade-in-0 zoom-in-95')}\n style={style}\n role=\"listbox\"\n aria-label={`${triggerChar} suggestions`}\n >\n {loading ? (\n <div role=\"option\" aria-selected={false} className=\"text-muted-foreground px-3 py-2 text-sm\">\n Loading suggestions...\n </div>\n ) : error ? (\n <div role=\"option\" aria-selected={false} className=\"text-destructive px-3 py-2 text-sm\">\n {error}\n </div>\n ) : suggestions.length === 0 && emptyMessage ? (\n <div role=\"option\" aria-selected={false} className=\"text-muted-foreground px-3 py-2 text-sm\">\n {emptyMessage}\n </div>\n ) : (\n suggestions.map((suggestion, index) => (\n <button\n key={suggestion.value}\n ref={index === selectedIndex ? selectedRef : undefined}\n type=\"button\"\n role=\"option\"\n aria-selected={index === selectedIndex}\n className={cn(\n 'text-foreground flex w-full items-start gap-2 rounded-lg px-3 py-2 text-left text-sm',\n 'hover:bg-surface-hover cursor-pointer transition-colors',\n index === selectedIndex && 'bg-surface-hover',\n )}\n onMouseDown={(e) => {\n e.preventDefault() // Prevent blur on the editor\n onSelect(suggestion)\n }}\n >\n {suggestion.icon && <span className=\"mt-0.5 shrink-0\">{suggestion.icon}</span>}\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate font-medium\">{suggestion.label}</div>\n {suggestion.description && <div className=\"text-muted-foreground truncate text-xs\">{suggestion.description}</div>}\n </div>\n </button>\n ))\n )}\n </div>\n )\n}\n","'use client'\n\nimport { useEffect, useState } from 'react'\n\ntype AnimatedPlaceholderProps = {\n texts: string[]\n interval?: number\n}\n\n/**\n * Cross-fading placeholder that rotates through `texts`.\n *\n * Each text is keyed so React remounts it on change, replaying the\n * `tw-animate-css` enter animation (slide down + fade in). No animation\n * library is required.\n */\nexport function AnimatedPlaceholder({ texts, interval = 3000 }: AnimatedPlaceholderProps) {\n const [index, setIndex] = useState(0)\n\n useEffect(() => {\n if (texts.length <= 1) {\n return\n }\n\n const id = setInterval(() => {\n setIndex((prev) => (prev + 1) % texts.length)\n }, interval)\n\n return () => clearInterval(id)\n }, [texts.length, interval])\n\n return (\n <div\n className=\"pointer-events-none absolute top-0 left-0 overflow-hidden select-none\"\n style={{ color: 'var(--prompt-area-placeholder, var(--muted-foreground))' }}\n aria-hidden=\"true\"\n >\n <div key={index} className=\"animate-in fade-in-0 slide-in-from-top-4 duration-300 ease-in-out\">\n {texts[index]}\n </div>\n </div>\n )\n}\n","import { cn } from '../../lib/utils.ts'\n\ntype RemoveButtonProps = {\n onClick: () => void\n label: string\n className?: string\n}\n\nexport function RemoveButton({ onClick, label, className }: RemoveButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onClick()\n }}\n className={cn(\n 'absolute top-0.5 right-0.5 grid h-3.5 w-3.5 cursor-pointer place-items-center',\n 'rounded-full bg-black/60 text-white hover:bg-black/80 dark:bg-white/60 dark:text-black dark:hover:bg-white/80',\n 'transition-colors',\n className,\n )}\n aria-label={label}\n >\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 10 10\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\">\n <line x1=\"2.75\" y1=\"2.75\" x2=\"7.25\" y2=\"7.25\" />\n <line x1=\"7.25\" y1=\"2.75\" x2=\"2.75\" y2=\"7.25\" />\n </svg>\n </button>\n )\n}\n","'use client'\n\nimport { cn } from '../../lib/utils.ts'\nimport { RemoveButton } from './remove-button.tsx'\nimport type { PromptAreaImage } from './types.ts'\n\ntype ImageStripProps = {\n images: PromptAreaImage[]\n onRemove?: (image: PromptAreaImage) => void\n onClick?: (image: PromptAreaImage) => void\n className?: string\n}\n\nexport function ImageStrip({ images, onRemove, onClick, className }: ImageStripProps) {\n if (images.length === 0) {\n return null\n }\n\n return (\n <div className={cn('flex flex-wrap gap-2', className)} role=\"list\" aria-label=\"Attached images\">\n {images.map((image) => (\n <div\n key={image.id}\n role=\"listitem\"\n className={cn('border-border relative h-16 w-16 flex-shrink-0 overflow-hidden rounded-md border', onClick && 'cursor-pointer')}\n onClick={() => onClick?.(image)}\n >\n <img src={image.url} alt={image.alt ?? 'Attached image'} className=\"h-full w-full object-cover\" />\n {image.loading && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-black/40\">\n <div className=\"h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent\" />\n </div>\n )}\n {onRemove && <RemoveButton onClick={() => onRemove(image)} label={`Remove ${image.alt ?? 'image'}`} />}\n </div>\n ))}\n </div>\n )\n}\n","'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport { cn } from '../../lib/utils.ts'\nimport { RemoveButton } from './remove-button.tsx'\nimport type { PromptAreaFile } from './types.ts'\n\ntype IconProps = { className?: string }\n\n/** Shared SVG wrapper matching the lucide icon defaults (no dependency). */\nfunction Svg({ className, children }: IconProps & { children: React.ReactNode }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={className}\n >\n {children}\n </svg>\n )\n}\n\nconst FileBody = (\n <>\n <path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" />\n <path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />\n </>\n)\n\nfunction File({ className }: IconProps) {\n return <Svg className={className}>{FileBody}</Svg>\n}\nfunction FileText({ className }: IconProps) {\n return (\n <Svg className={className}>\n {FileBody}\n <path d=\"M10 9H8\" />\n <path d=\"M16 13H8\" />\n <path d=\"M16 17H8\" />\n </Svg>\n )\n}\nfunction FileSpreadsheet({ className }: IconProps) {\n return (\n <Svg className={className}>\n {FileBody}\n <path d=\"M8 13h2\" />\n <path d=\"M14 13h2\" />\n <path d=\"M8 17h2\" />\n <path d=\"M14 17h2\" />\n </Svg>\n )\n}\nfunction FileCode({ className }: IconProps) {\n return (\n <Svg className={className}>\n {FileBody}\n <path d=\"M10 12.5 8 15l2 2.5\" />\n <path d=\"m14 12.5 2 2.5-2 2.5\" />\n </Svg>\n )\n}\nfunction ImageIcon({ className }: IconProps) {\n return (\n <Svg className={className}>\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\" />\n </Svg>\n )\n}\n\ntype FileStripProps = {\n files: PromptAreaFile[]\n onRemove?: (file: PromptAreaFile) => void\n onClick?: (file: PromptAreaFile) => void\n className?: string\n}\n\n/** Threshold above which collapse activates automatically. */\nconst COLLAPSE_THRESHOLD = 3\n\n/** Pick a lucide icon key based on MIME type. */\nfunction getFileIconKey(type?: string): 'pdf' | 'spreadsheet' | 'code' | 'image' | 'default' {\n if (!type) {\n return 'default'\n }\n if (type === 'application/pdf') {\n return 'pdf'\n }\n if (type.includes('spreadsheet') || type === 'text/csv') {\n return 'spreadsheet'\n }\n if (type.startsWith('text/') || type.includes('javascript') || type.includes('json') || type.includes('xml')) {\n return 'code'\n }\n if (type.startsWith('image/')) {\n return 'image'\n }\n return 'default'\n}\n\nconst FILE_ICONS = {\n pdf: FileText,\n spreadsheet: FileSpreadsheet,\n code: FileCode,\n image: ImageIcon,\n default: File,\n} as const\n\n/** Format bytes into a human-readable string. */\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`\n }\n if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)} KB`\n }\n if (bytes < 1024 * 1024 * 1024) {\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n }\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`\n}\n\n/** Extract a short extension label from a filename (e.g., \"PDF\", \"CSV\"). */\nfunction getExtensionLabel(name: string): string | null {\n const dot = name.lastIndexOf('.')\n if (dot === -1 || dot === name.length - 1) {\n return null\n }\n return name.slice(dot + 1).toUpperCase()\n}\n\nfunction FileCard({\n file,\n compact,\n onRemove,\n onClick,\n}: {\n file: PromptAreaFile\n compact: boolean\n onRemove?: (file: PromptAreaFile) => void\n onClick?: (file: PromptAreaFile) => void\n}) {\n const ext = getExtensionLabel(file.name)\n const sizeStr = file.size != null ? formatFileSize(file.size) : null\n const meta = [ext, sizeStr].filter(Boolean).join(' · ')\n\n return (\n <div\n role=\"listitem\"\n className={cn(\n 'border-border relative flex flex-shrink-0 items-center gap-2 overflow-hidden rounded-lg border transition-colors',\n 'hover:bg-surface-hover',\n compact ? 'h-10 w-36 px-2' : 'h-14 w-48 px-3',\n onClick && 'cursor-pointer',\n )}\n onClick={() => onClick?.(file)}\n >\n {(() => {\n const Icon = FILE_ICONS[getFileIconKey(file.type)]\n return <Icon className={cn('text-muted-foreground flex-shrink-0', compact ? 'h-4 w-4' : 'h-5 w-5')} />\n })()}\n <div className=\"min-w-0 flex-1\">\n <div className={cn('truncate font-medium', compact ? 'text-xs' : 'text-sm')} title={file.name}>\n {file.name}\n </div>\n {!compact && meta && <div className=\"text-muted-foreground truncate text-xs\">{meta}</div>}\n </div>\n\n {file.loading && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-black/40\">\n <div className=\"h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent\" />\n </div>\n )}\n\n {onRemove && <RemoveButton onClick={() => onRemove(file)} label={`Remove ${file.name}`} />}\n </div>\n )\n}\n\nexport function FileStrip({ files, onRemove, onClick, className }: FileStripProps) {\n const [expanded, setExpanded] = useState(false)\n const popoverRef = useRef<HTMLDivElement>(null)\n const toggleRef = useRef<HTMLButtonElement>(null)\n\n useEffect(() => {\n if (!expanded) {\n return\n }\n const handleClick = (e: MouseEvent) => {\n const target = e.target\n if (!(target instanceof Node)) {\n return\n }\n if (popoverRef.current && !popoverRef.current.contains(target) && !toggleRef.current?.contains(target)) {\n setExpanded(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [expanded])\n\n if (files.length === 0) {\n return null\n }\n\n const collapsible = files.length > COLLAPSE_THRESHOLD\n const compact = collapsible\n const hiddenCount = files.length - COLLAPSE_THRESHOLD\n const visibleFiles = files.slice(0, COLLAPSE_THRESHOLD)\n\n return (\n <div className={cn('relative', className)}>\n <div className=\"flex flex-wrap gap-2\" role=\"list\" aria-label=\"Attached files\">\n {(collapsible ? visibleFiles : files).map((file) => (\n <FileCard key={file.id} file={file} compact={compact} onRemove={onRemove} onClick={onClick} />\n ))}\n {collapsible && (\n <div role=\"listitem\">\n <button\n ref={toggleRef}\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className={cn(\n 'border-border text-muted-foreground hover:bg-surface-hover flex flex-shrink-0 cursor-pointer items-center justify-center rounded-lg border transition-colors',\n compact ? 'h-10 px-3 text-xs' : 'h-14 px-4 text-sm',\n )}\n >\n {expanded ? 'Show less' : `+${hiddenCount} more`}\n </button>\n </div>\n )}\n </div>\n\n {expanded && (\n <div\n ref={popoverRef}\n className={cn(\n 'bg-surface border-border absolute bottom-full left-0 z-10 mb-2 max-h-48 overflow-y-auto rounded-lg border p-2 shadow-lg',\n )}\n >\n <div className=\"flex flex-wrap gap-2\" role=\"list\" aria-label=\"More attached files\">\n {files.slice(COLLAPSE_THRESHOLD).map((file) => (\n <FileCard key={file.id} file={file} compact={compact} onRemove={onRemove} onClick={onClick} />\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'\nimport { cn } from '../../lib/utils.ts'\nimport type { PromptAreaProps, PromptAreaHandle } from './types.ts'\nimport { usePromptArea } from './use-prompt-area.ts'\nimport { BLUR_DELAY_MS } from './use-prompt-area-events.ts'\nimport { TriggerPopover } from './trigger-popover.tsx'\nimport { AnimatedPlaceholder } from './animated-placeholder.tsx'\nimport { ImageStrip } from './image-strip.tsx'\nimport { FileStrip } from './file-strip.tsx'\n\n/**\n * PromptArea - A lightweight rich text input with trigger support.\n *\n * Uses contentEditable to support inline chips (immutable pills) for\n * mentions, commands, and other triggered tokens. Each trigger character\n * can be configured to show a dropdown or fire a callback.\n *\n * @example\n * ```tsx\n * const [segments, setSegments] = useState<Segment[]>([])\n *\n * <PromptArea\n * value={segments}\n * onChange={setSegments}\n * triggers={[\n * { char: '@', position: 'any', mode: 'dropdown', onSearch: searchUsers },\n * { char: '/', position: 'start', mode: 'dropdown', onSearch: searchCommands },\n * { char: '#', position: 'any', mode: 'dropdown', onSearch: searchTags },\n * ]}\n * placeholder=\"Type a message...\"\n * onSubmit={handleSubmit}\n * autoGrow\n * />\n * ```\n */\nexport function PromptArea({\n value,\n onChange,\n triggers,\n placeholder,\n className,\n disabled = false,\n markdown,\n normalizeBullets,\n onSubmit,\n onEscape,\n onChipClick,\n onChipAdd,\n onChipDelete,\n onLinkClick,\n onPaste,\n onUndo,\n onRedo,\n minHeight = 80,\n maxHeight,\n autoFocus = false,\n autoGrow = false,\n 'aria-label': ariaLabel,\n 'data-test-id': dataTestId,\n images = [],\n imagePosition = 'above',\n onImagePaste,\n onImageRemove,\n onImageClick,\n files = [],\n filePosition = 'above',\n onFileRemove,\n onFileClick,\n onKeyDown,\n onBlur,\n onRawPaste,\n submitOnEnter,\n spellCheck,\n maxLength,\n 'aria-describedby': ariaDescribedBy,\n ref,\n}: PromptAreaProps & { ref?: React.Ref<PromptAreaHandle> }) {\n const {\n editorRef,\n activeTrigger,\n suggestions,\n suggestionsLoading,\n suggestionsError,\n selectedSuggestionIndex,\n handleInput,\n handleKeyDown,\n handleClick,\n handleMouseDown,\n selectSuggestion,\n dismissTrigger,\n handle,\n triggerRect,\n eventHandlers,\n } = usePromptArea({\n value,\n onChange,\n triggers,\n disabled,\n onSubmit,\n onEscape,\n onChipClick,\n onChipAdd,\n onChipDelete,\n onLinkClick,\n onPaste,\n onRawPaste,\n onUndo,\n onRedo,\n onImagePaste,\n markdown,\n normalizeBullets,\n submitOnEnter,\n maxLength,\n })\n\n useImperativeHandle(ref, () => handle, [handle])\n\n useEffect(() => {\n if (autoFocus) {\n editorRef.current?.focus()\n }\n }, [autoFocus, editorRef])\n\n // Auto-grow: expand on focus/input, shrink on blur\n\n const [isFocused, setIsFocused] = useState(false)\n const [editorHeight, setEditorHeight] = useState<number | undefined>(undefined)\n\n const syncHeight = useCallback(() => {\n const el = editorRef.current\n if (!el) {\n return\n }\n // Temporarily set height to auto so scrollHeight reflects true content height\n el.style.height = 'auto'\n const contentHeight = el.scrollHeight\n el.style.height = `${contentHeight}px`\n setEditorHeight(contentHeight)\n }, [editorRef])\n\n const handleFocus = useCallback(() => {\n if (!autoGrow) {\n return\n }\n setIsFocused(true)\n syncHeight()\n }, [autoGrow, syncHeight])\n\n const handleBlurWithShrink = useCallback(() => {\n eventHandlers.onBlur()\n if (!autoGrow) {\n return\n }\n setTimeout(() => {\n const editor = editorRef.current\n if (!editor) {\n return\n }\n // Only shrink if focus truly left the component\n const activeEl = document.activeElement\n if (activeEl && editor.parentElement?.contains(activeEl)) {\n return\n }\n setIsFocused(false)\n setEditorHeight(undefined)\n }, BLUR_DELAY_MS)\n }, [eventHandlers, autoGrow, editorRef])\n\n const handleInputWithGrow = useCallback(() => {\n handleInput()\n if (autoGrow && isFocused) {\n syncHeight()\n }\n }, [handleInput, autoGrow, isFocused, syncHeight])\n\n // Re-measure on value changes (chip insertion, undo/redo, programmatic updates)\n useEffect(() => {\n if (autoGrow && isFocused) {\n requestAnimationFrame(() => syncHeight())\n }\n }, [value, autoGrow, isFocused, syncHeight])\n\n // Overflow indicator: detect when collapsed content is clipped\n\n const [hasOverflow, setHasOverflow] = useState(false)\n const overflowTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(() => {\n if (!autoGrow) {\n return\n }\n\n const checkOverflow = () => {\n if (isFocused) {\n setHasOverflow(false)\n return\n }\n const el = editorRef.current\n if (!el) {\n return\n }\n setHasOverflow(el.scrollHeight > el.clientHeight)\n }\n\n // Delay the check so the CSS height transition (150ms) finishes first;\n // on initial mount there is no transition so the check still runs quickly.\n const delay = isFocused ? 0 : 160\n overflowTimerRef.current = setTimeout(checkOverflow, delay)\n return () => {\n if (overflowTimerRef.current !== null) {\n clearTimeout(overflowTimerRef.current)\n }\n }\n }, [autoGrow, isFocused, value, editorRef])\n\n // Compute editor style\n\n const editorStyle = useMemo((): React.CSSProperties => {\n if (!autoGrow) {\n const style: React.CSSProperties = { minHeight: `${minHeight}px` }\n if (maxHeight) {\n style.maxHeight = `${maxHeight}px`\n style.overflowY = 'auto'\n }\n return style\n }\n return {\n height: isFocused && editorHeight ? `${editorHeight}px` : `${minHeight}px`,\n minHeight: `${minHeight}px`,\n // Respect an explicit maxHeight; otherwise fall back to a viewport-relative\n // cap so the editor never grows past the screen.\n maxHeight: maxHeight ? `${maxHeight}px` : '70dvh',\n overflowY: isFocused ? 'auto' : 'hidden',\n // `min-height` is eased so consumers that animate it (e.g. the compact\n // prompt area's collapse/expand) morph smoothly instead of snapping.\n transition: 'height 150ms ease-out, min-height 240ms cubic-bezier(0.33, 1, 0.68, 1)',\n }\n }, [autoGrow, minHeight, maxHeight, isFocused, editorHeight])\n\n // Run a consumer's onKeyDown first; if it calls preventDefault, skip all of\n // PromptArea's built-in key handling (submit, trigger nav, etc.).\n const handleKeyDownCombined = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented) {\n return\n }\n handleKeyDown(e)\n },\n [onKeyDown, handleKeyDown],\n )\n\n // Forward blur to the consumer (with relatedTarget) alongside the internal\n // trigger-dismiss / auto-grow-shrink handling.\n const handleBlurCombined = useCallback(\n (e: React.FocusEvent<HTMLDivElement>) => {\n onBlur?.(e)\n // handleBlurWithShrink already calls eventHandlers.onBlur() and only\n // shrinks when autoGrow is on, so it covers both modes.\n handleBlurWithShrink()\n },\n [onBlur, handleBlurWithShrink],\n )\n\n const isEmpty = value.length === 0 || (value.length === 1 && value[0].type === 'text' && value[0].text === '')\n\n const imageStrip =\n images.length > 0 ? (\n <ImageStrip images={images} onRemove={onImageRemove} onClick={onImageClick} className={imagePosition === 'above' ? 'pb-2' : 'pt-2'} />\n ) : null\n\n const fileStrip =\n files.length > 0 ? (\n <FileStrip files={files} onRemove={onFileRemove} onClick={onFileClick} className={filePosition === 'above' ? 'pb-2' : 'pt-2'} />\n ) : null\n\n // Typography (font-size/line-height) lives on the container, not the editor, so\n // it cascades to the editor AND the placeholder overlays — and a consumer can\n // override all three at once via `className` (e.g. `text-base leading-6`).\n return (\n <div className={cn('prompt-area-container relative text-sm leading-relaxed', className)}>\n {imagePosition === 'above' && imageStrip}\n {filePosition === 'above' && fileStrip}\n <div className=\"relative\">\n <div\n ref={editorRef}\n contentEditable={!disabled}\n suppressContentEditableWarning\n role=\"textbox\"\n aria-label={ariaLabel ?? 'Text input'}\n aria-multiline=\"true\"\n aria-disabled={disabled || undefined}\n aria-describedby={ariaDescribedBy}\n data-test-id={dataTestId}\n spellCheck={spellCheck}\n className={cn(\n 'prompt-area-editor',\n 'w-full min-w-0 break-words whitespace-pre-wrap outline-none',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n style={editorStyle}\n onFocus={handleFocus}\n onInput={autoGrow ? handleInputWithGrow : handleInput}\n onKeyDown={handleKeyDownCombined}\n onMouseDown={handleMouseDown}\n onClick={handleClick}\n onPaste={eventHandlers.onPaste}\n onCopy={eventHandlers.onCopy}\n onCut={eventHandlers.onCut}\n onDrop={eventHandlers.onDrop}\n onDragOver={eventHandlers.onDragOver}\n onCompositionStart={eventHandlers.onCompositionStart}\n onCompositionEnd={eventHandlers.onCompositionEnd}\n onBlur={handleBlurCombined}\n />\n\n {/* Overflow gradient indicator – visible when auto-grow is collapsed and content is clipped */}\n {autoGrow && hasOverflow && !isFocused && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-auto absolute right-0 bottom-0 left-0 cursor-pointer\"\n style={{ height: '32px' }}\n onClick={() => editorRef.current?.focus()}\n >\n <div\n className=\"h-full w-full\"\n style={{\n background:\n 'linear-gradient(to bottom, transparent, color-mix(in srgb, var(--prompt-area-surface, var(--background)) 80%, transparent), var(--prompt-area-surface, var(--background)))',\n }}\n />\n </div>\n )}\n {isEmpty &&\n placeholder &&\n (Array.isArray(placeholder) ? (\n <AnimatedPlaceholder texts={placeholder} />\n ) : (\n <div\n className=\"pointer-events-none absolute top-0 left-0 select-none\"\n style={{ color: 'var(--prompt-area-placeholder, var(--muted-foreground))' }}\n aria-hidden=\"true\"\n >\n {placeholder}\n </div>\n ))}\n </div>\n\n {filePosition === 'below' && fileStrip}\n {imagePosition === 'below' && imageStrip}\n {activeTrigger && activeTrigger.config.mode === 'dropdown' && (\n <TriggerPopover\n suggestions={suggestions}\n loading={suggestionsLoading}\n error={suggestionsError}\n emptyMessage={activeTrigger.config.emptyMessage}\n selectedIndex={selectedSuggestionIndex}\n onSelect={selectSuggestion}\n onDismiss={dismissTrigger}\n triggerRect={triggerRect}\n triggerChar={activeTrigger.config.char}\n />\n )}\n </div>\n )\n}\n","/**\n * Convenience hook that wires up all the boilerplate state for a PromptArea.\n *\n * Instead of manually managing `useState<Segment[]>`, `useRef<PromptAreaHandle>`,\n * and computing derived values, call `usePromptAreaState()` once and spread\n * `bind` into your `<PromptArea>`.\n *\n * @example\n * ```tsx\n * function ChatInput() {\n * const { bind, plainText, isEmpty, chips, clear, focus } = usePromptAreaState()\n *\n * return (\n * <PromptArea\n * {...bind}\n * onSubmit={() => {\n * sendMessage(plainText)\n * clear()\n * }}\n * />\n * )\n * }\n * ```\n */\n\n'use client'\n\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport type { Segment, ChipSegment, PromptAreaHandle } from './types.ts'\nimport { segmentsToPlainText } from './prompt-area-engine.ts'\n\nexport type UsePromptAreaStateOptions = {\n /** Initial segment value. Defaults to `[]`. */\n initialValue?: Segment[]\n}\n\nexport type PromptAreaBind = {\n /** Ref to attach to PromptArea — gives access to imperative methods. */\n ref: React.RefObject<PromptAreaHandle | null>\n /** Current segment array — pass as `value` prop. */\n value: Segment[]\n /** Setter — pass as `onChange` prop. */\n onChange: (segments: Segment[]) => void\n}\n\nexport type PromptAreaState = {\n /** Props to spread directly onto `<PromptArea {...bind} />`. Contains ref, value, and onChange. */\n bind: PromptAreaBind\n /** Derived plain text representation of the current value. */\n plainText: string\n /** `true` when the value is empty or whitespace-only. */\n isEmpty: boolean\n /** `true` when the value contains at least one chip. */\n hasChips: boolean\n /** All chip segments in the current value. */\n chips: ChipSegment[]\n /** Clear all content (both state and the editor DOM). */\n clear: () => void\n /** Focus the editor. */\n focus: () => void\n /** Blur the editor. */\n blur: () => void\n /** Insert a chip at the current cursor position. */\n insertChip: (chip: Omit<ChipSegment, 'type'>) => void\n}\n\nexport function usePromptAreaState(options: UsePromptAreaStateOptions = {}): PromptAreaState {\n const { initialValue = [] } = options\n\n const [value, setValue] = useState<Segment[]>(initialValue)\n const ref = useRef<PromptAreaHandle>(null)\n\n const plainText = useMemo(() => segmentsToPlainText(value), [value])\n\n const isEmpty = useMemo(() => {\n if (value.length === 0) {\n return true\n }\n return value.every((seg) => seg.type === 'text' && seg.text.trim() === '')\n }, [value])\n\n const hasChips = useMemo(() => value.some((seg) => seg.type === 'chip'), [value])\n\n const chips = useMemo(() => value.filter((seg): seg is ChipSegment => seg.type === 'chip'), [value])\n\n // Bind object — safe to spread onto <PromptArea>\n const bind = useMemo<PromptAreaBind>(() => ({ ref, value, onChange: setValue }), [value])\n\n const clear = useCallback(() => {\n if (ref.current) {\n ref.current.clear()\n } else {\n setValue([])\n }\n }, [])\n\n const focus = useCallback(() => ref.current?.focus(), [])\n const blur = useCallback(() => ref.current?.blur(), [])\n\n const insertChip = useCallback((chip: Omit<ChipSegment, 'type'>) => ref.current?.insertChip(chip), [])\n\n return {\n bind,\n plainText,\n isEmpty,\n hasChips,\n chips,\n clear,\n focus,\n blur,\n insertChip,\n }\n}\n","/**\n * Pre-built trigger configuration factories for common AI chat patterns.\n *\n * Each factory returns a full `TriggerConfig` with sensible defaults.\n * Pass only what you need to override.\n *\n * @example\n * ```tsx\n * <PromptArea\n * triggers={[\n * mentionTrigger({ onSearch: searchUsers }),\n * commandTrigger({ onSearch: searchCommands }),\n * hashtagTrigger(),\n * ]}\n * />\n * ```\n */\n\nimport type { TriggerConfig, TriggerPosition } from './types.ts'\n\n// Shared option type — everything in TriggerConfig except the keys each\n// factory sets by default.\n\ntype TriggerPresetOptions = Omit<Partial<TriggerConfig>, 'char' | 'position' | 'mode'>\n\n// @mention — dropdown at any position\n\nexport type MentionTriggerOptions = TriggerPresetOptions & {\n /** Override the trigger character. Defaults to `'@'`. */\n char?: string\n}\n\n/**\n * Creates a **mention** trigger (`@`).\n *\n * Defaults: `position: 'any'`, `mode: 'dropdown'`, `chipStyle: 'pill'`,\n * accessible label `\"mention\"`.\n */\nexport function mentionTrigger(opts: MentionTriggerOptions = {}): TriggerConfig {\n const { char = '@', ...rest } = opts\n return {\n char,\n position: 'any',\n mode: 'dropdown',\n chipStyle: 'pill',\n accessibilityLabel: 'mention',\n ...rest,\n }\n}\n\n// /command — dropdown anywhere (opt into line-start-only with `position`)\n\nexport type CommandTriggerOptions = TriggerPresetOptions & {\n /** Override the trigger character. Defaults to `'/'`. */\n char?: string\n /**\n * Where the command trigger is valid. Defaults to `'any'`, so commands fire\n * anywhere a `/` follows whitespace — not just at the start of a line.\n * Set to `'start'` to restrict the dropdown to the very start of the input\n * or immediately after a newline (the classic slash-command behavior).\n */\n position?: TriggerPosition\n}\n\n/**\n * Creates a **command** trigger (`/`).\n *\n * Defaults: `position: 'any'`, `mode: 'dropdown'`, `chipStyle: 'inline'`,\n * accessible label `\"command\"`.\n *\n * By default commands work everywhere in the input. Pass `position: 'start'`\n * to limit them to the start of a line.\n */\nexport function commandTrigger(opts: CommandTriggerOptions = {}): TriggerConfig {\n const { char = '/', position = 'any', ...rest } = opts\n return {\n char,\n position,\n mode: 'dropdown',\n chipStyle: 'inline',\n accessibilityLabel: 'command',\n ...rest,\n }\n}\n\n// #hashtag — dropdown at any position, auto-resolve on space\n\nexport type HashtagTriggerOptions = TriggerPresetOptions & {\n /** Override the trigger character. Defaults to `'#'`. */\n char?: string\n}\n\n/**\n * Creates a **hashtag / tag** trigger (`#`).\n *\n * Defaults: `position: 'any'`, `mode: 'dropdown'`, `chipStyle: 'pill'`,\n * `resolveOnSpace: true`, accessible label `\"tag\"`.\n */\nexport function hashtagTrigger(opts: HashtagTriggerOptions = {}): TriggerConfig {\n const { char = '#', ...rest } = opts\n return {\n char,\n position: 'any',\n mode: 'dropdown',\n chipStyle: 'pill',\n resolveOnSpace: true,\n accessibilityLabel: 'tag',\n ...rest,\n }\n}\n\n// Generic callback trigger (e.g., for file pickers, model selectors)\n\nexport type CallbackTriggerOptions = Omit<Partial<TriggerConfig>, 'mode'> & {\n /** The trigger character. Required. */\n char: string\n}\n\n/**\n * Creates a **callback** trigger that fires `onActivate` instead of showing\n * a dropdown. Useful for opening file pickers, model selectors, etc.\n *\n * Defaults: `position: 'start'`, `mode: 'callback'`.\n */\nexport function callbackTrigger(opts: CallbackTriggerOptions): TriggerConfig {\n const { char, ...rest } = opts\n return {\n char,\n position: 'start',\n mode: 'callback',\n ...rest,\n }\n}\n","import { createContext, useContext, type ReactNode } from 'react'\n\nexport type TranscriptVariant = 'cards' | 'terminal'\n\nconst VariantContext = createContext<TranscriptVariant>('cards')\n\nexport function TranscriptVariantProvider({ value, children }: { value: TranscriptVariant; children: ReactNode }) {\n return <VariantContext.Provider value={value}>{children}</VariantContext.Provider>\n}\n\nexport function useTranscriptVariant(): TranscriptVariant {\n return useContext(VariantContext)\n}\n\nexport type TranscriptDensity = 'comfortable' | 'compact'\n\nconst DensityContext = createContext<TranscriptDensity>('comfortable')\n\nexport function TranscriptDensityProvider({ value, children }: { value: TranscriptDensity; children: ReactNode }) {\n return <DensityContext.Provider value={value}>{children}</DensityContext.Provider>\n}\n\nexport function useTranscriptDensity(): TranscriptDensity {\n return useContext(DensityContext)\n}\n\nexport type TranscriptFont = 'sans' | 'mono'\n\nexport const ROW_GAP: Record<TranscriptVariant, Record<TranscriptDensity, { className?: string; px: number }>> = {\n terminal: {\n comfortable: { className: 'term-row-gap', px: 18 },\n compact: { className: 'term-row-gap', px: 18 },\n },\n cards: {\n comfortable: { className: 'pt-4', px: 16 },\n compact: { className: 'pt-2', px: 8 },\n },\n}\n","import {\n ArrowDownCircle,\n CheckSquare,\n FileDiff,\n FileText,\n FolderSearch,\n Globe,\n Image,\n type LucideIcon,\n MessageCircleQuestion,\n PencilLine,\n Puzzle,\n Search,\n Sparkles,\n SquarePen,\n Terminal,\n UsersRound,\n Wrench,\n} from 'lucide-react'\n\nexport function toolIcon(toolName: string): LucideIcon {\n switch (toolName) {\n case 'Bash':\n case 'BashOutput':\n case 'KillShell': {\n return Terminal\n }\n case 'Read': {\n return FileText\n }\n case 'Write': {\n return SquarePen\n }\n case 'Edit':\n case 'MultiEdit':\n case 'NotebookEdit': {\n return PencilLine\n }\n case 'Glob': {\n return FolderSearch\n }\n case 'Grep': {\n return Search\n }\n case 'WebFetch': {\n return ArrowDownCircle\n }\n case 'WebSearch': {\n return Globe\n }\n case 'Task':\n case 'Agent': {\n return UsersRound\n }\n case 'TodoWrite': {\n return CheckSquare\n }\n case 'Skill': {\n return Sparkles\n }\n case 'AskUserQuestion': {\n return MessageCircleQuestion\n }\n case 'CodexCommand': {\n return Terminal\n }\n case 'CodexFileChange': {\n return FileDiff\n }\n case 'CodexWebSearch': {\n return Globe\n }\n case 'CodexImageGeneration':\n case 'CodexImageView': {\n return Image\n }\n default: {\n return toolName.startsWith('mcp__') ? Puzzle : Wrench\n }\n }\n}\n\n// `BashOutput`/`KillShell` are excluded on purpose: they manage a background shell rather than run one.\nexport function isShellTool(toolName: string): boolean {\n return toolName === 'Bash' || toolName === 'CodexCommand'\n}\n\nexport function isMutatingTool(toolName: string): boolean {\n switch (toolName) {\n case 'Write':\n case 'Edit':\n case 'MultiEdit':\n case 'NotebookEdit':\n case 'Update':\n case 'CodexFileChange': {\n return true\n }\n default: {\n return false\n }\n }\n}\n","import { useEffect, useState } from 'react'\n\nexport const PULSE_FRAMES = ['⋄', '◇', '◈', '◆'] as const\nexport const PULSE_MS = 150\n\nexport const PULSE_REST = PULSE_FRAMES[PULSE_FRAMES.length - 1]\n\nexport function usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false)\n useEffect(() => {\n const query = window.matchMedia?.('(prefers-reduced-motion: reduce)')\n if (!query) {\n return\n }\n setReduced(query.matches)\n const onChange = () => setReduced(query.matches)\n query.addEventListener('change', onChange)\n return () => query.removeEventListener('change', onChange)\n }, [])\n return reduced\n}\n\nexport function usePulse(animated: boolean): string {\n const reduced = usePrefersReducedMotion()\n const running = animated && !reduced\n const [frame, setFrame] = useState(0)\n useEffect(() => {\n if (!running) {\n return\n }\n const timer = setInterval(() => setFrame((f) => f + 1), PULSE_MS)\n return () => clearInterval(timer)\n }, [running])\n if (!running) {\n return PULSE_REST\n }\n return PULSE_FRAMES[frame % PULSE_FRAMES.length]!\n}\n","import { createContext, useContext, useState, type ReactNode } from 'react'\nimport { copyText } from '../../lib/clipboard.ts'\nimport { cn } from '../../lib/utils.ts'\n\nexport type TerminalAffordances = {\n hover?: boolean\n actions?: boolean\n}\n\nconst DEFAULTS: Required<TerminalAffordances> = { hover: true, actions: true }\n\nconst AffordanceContext = createContext<Required<TerminalAffordances>>(DEFAULTS)\n\nexport function useAffordances(): Required<TerminalAffordances> {\n return useContext(AffordanceContext)\n}\n\nexport function resolveAffordances(value: TerminalAffordances | boolean | undefined): Required<TerminalAffordances> {\n if (value === false) {\n return { hover: false, actions: false }\n }\n if (value === true || value === undefined) {\n return DEFAULTS\n }\n return { ...DEFAULTS, ...value }\n}\n\nexport function AffordanceProvider({ value, children }: { value: Required<TerminalAffordances>; children: ReactNode }) {\n return <AffordanceContext.Provider value={value}>{children}</AffordanceContext.Provider>\n}\n\nexport function WithActions({ actions, children, className }: { actions: ReactNode; children: ReactNode; className?: string }) {\n const { actions: enabled } = useAffordances()\n if (!enabled) {\n return <>{children}</>\n }\n return (\n <div className={cn('term-hoverable', className)}>\n {children}\n <div className=\"term-actions\">{actions}</div>\n </div>\n )\n}\n\n// Bookmarks are a host concern (which items, where they persist); the transcript only needs\n// membership and a toggle. A missing provider renders no action at all, so embeddings that\n// never wire bookmarks pay nothing — the same contract AffordanceContext has.\nexport type BookmarkHandle = {\n has: (itemId: string) => boolean\n toggle: (itemId: string) => void\n}\n\nconst BookmarkContext = createContext<BookmarkHandle | undefined>(undefined)\n\nexport function BookmarkProvider({ value, children }: { value: BookmarkHandle | undefined; children: ReactNode }) {\n return <BookmarkContext.Provider value={value}>{children}</BookmarkContext.Provider>\n}\n\nexport function BookmarkAction({ id }: { id: string }) {\n const handle = useContext(BookmarkContext)\n if (!handle) {\n return null\n }\n const active = handle.has(id)\n const label = active ? 'Remove bookmark' : 'Bookmark'\n return (\n <button\n type=\"button\"\n className=\"term-action\"\n title={label}\n aria-label={label}\n aria-pressed={active}\n onClick={(event) => {\n event.stopPropagation()\n handle.toggle(id)\n }}\n >\n {active ? '★' : '☆'}\n </button>\n )\n}\n\nexport function OpenSubagentAction({ onOpen, label = 'Open sub-agent' }: { onOpen: () => void; label?: string }) {\n return (\n <button\n type=\"button\"\n className=\"term-action\"\n title={label}\n aria-label={label}\n onClick={(event) => {\n event.stopPropagation()\n onOpen()\n }}\n >\n ⤢\n </button>\n )\n}\n\nexport function CopyAction({ text, label = 'Copy' }: { text: string; label?: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <button\n type=\"button\"\n className=\"term-action\"\n title={label}\n aria-label={label}\n onClick={(event) => {\n event.stopPropagation()\n void copyText(text).then((ok) => {\n if (!ok) {\n return\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1200)\n })\n }}\n >\n {copied ? '✓' : '⧉'}\n </button>\n )\n}\n","import type { CSSProperties, HTMLAttributes, ReactNode } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport type Tone = 'fg' | 'bright' | 'dim' | 'faint' | 'mark' | 'blue' | 'green' | 'red' | 'yellow' | 'magenta'\n\nexport interface RowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n glyph?: ReactNode\n glyphTone?: Tone\n tone?: Tone\n bold?: boolean\n indent?: 0 | 1 | 2 | 3\n columns?: number\n children?: ReactNode\n}\n\nexport function Row({ glyph, glyphTone, tone, bold, indent, columns, className, children, style, ...props }: RowProps) {\n return (\n <div\n className={cn('term-row', className)}\n data-indent={indent ? String(indent) : undefined}\n data-tone={tone}\n data-weight={bold ? 'bold' : undefined}\n // `!== undefined`, not truthiness: `columns={0}` is a real request for a gutterless row.\n style={columns === undefined ? style : ({ ...style, '--term-cell': `${columns}ch` } as CSSProperties)}\n {...props}\n >\n <span className=\"term-gutter\" data-tone={glyphTone} aria-hidden>\n {glyph ?? ' '}\n </span>\n <div className=\"term-body\">{children}</div>\n </div>\n )\n}\n\nexport function Blank() {\n return <div className=\"term-blank\" aria-hidden />\n}\n\nexport function Band({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('term-band', className)} {...props} />\n}\n\nexport function Ink({ tone, bold, className, ...props }: HTMLAttributes<HTMLSpanElement> & { tone?: Tone; bold?: boolean }) {\n return <span data-tone={tone} data-weight={bold ? 'bold' : undefined} className={className} {...props} />\n}\n","import type { FilePatch, PatchHunk } from '@workerdeck/protocol'\nimport { Row } from './row.tsx'\n\ntype LineKind = 'context' | 'add' | 'remove'\n\nfunction kindOf(line: string): LineKind {\n return line.startsWith('+') ? 'add' : line.startsWith('-') ? 'remove' : 'context'\n}\n\nfunction hunkRows(hunk: PatchHunk): { kind: LineKind; number: number; text: string }[] {\n let oldLine = hunk.oldStart\n let newLine = hunk.newStart\n const rows = []\n for (const line of hunk.lines) {\n const kind = kindOf(line)\n const text = line.slice(1)\n if (kind === 'add') {\n rows.push({ kind, number: newLine++, text })\n } else if (kind === 'remove') {\n rows.push({ kind, number: oldLine++, text })\n } else {\n rows.push({ kind, number: newLine, text })\n oldLine++\n newLine++\n }\n }\n return rows\n}\n\nconst MARKER = { context: ' ', add: '+', remove: '-' } as const\n\nexport function previewPatch(input: unknown): FilePatch | undefined {\n const edit = input as { file_path?: unknown; old_string?: unknown; new_string?: unknown } | null\n const before = typeof edit?.old_string === 'string' ? edit.old_string : undefined\n const after = typeof edit?.new_string === 'string' ? edit.new_string : undefined\n if (before === undefined && after === undefined) {\n return undefined\n }\n const lines = [\n ...(before ? before.split('\\n').map((line) => `-${line}`) : []),\n ...(after ? after.split('\\n').map((line) => `+${line}`) : []),\n ]\n if (lines.length === 0) {\n return undefined\n }\n return {\n ...(typeof edit?.file_path === 'string' && { path: edit.file_path }),\n hunks: [{ oldStart: 0, oldLines: 0, newStart: 0, newLines: 0, lines }],\n }\n}\n\nexport function TerminalDiff({ patch }: { patch: FilePatch }) {\n const rows = patch.hunks.map(hunkRows)\n const numbered = patch.hunks.some((hunk) => hunk.newStart > 0)\n const width = numbered ? String(Math.max(...rows.flat().map((row) => row.number), 1)).length : 0\n const columns = numbered ? width + 3 : 2\n\n return (\n <div className=\"term-diff\">\n {rows.map((hunk, index) => (\n <div key={index}>\n {index > 0 ? <Row columns={columns} glyph={' '.repeat(width) + ' ⋮'} tone=\"faint\" /> : null}\n {hunk.map((row, line) => (\n <Row\n key={line}\n columns={columns}\n data-diff={row.kind}\n glyph={numbered ? `${String(row.number).padStart(width)} ${MARKER[row.kind]}` : MARKER[row.kind]}\n >\n {row.text || ' '}\n </Row>\n ))}\n </div>\n ))}\n {patch.truncated ? (\n <Row columns={columns} tone=\"faint\">\n … diff truncated\n </Row>\n ) : null}\n </div>\n )\n}\n","import { memo, type ReactNode } from 'react'\nimport { Streamdown, type Components } from 'streamdown'\nimport { cn } from '../../lib/utils.ts'\nimport { CopyAction, WithActions } from './affordances.tsx'\nimport { Band } from './row.tsx'\n\nfunction codeText(node: ReactNode): string {\n if (node === null || node === undefined || typeof node === 'boolean') {\n return ''\n }\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node)\n }\n if (Array.isArray(node)) {\n return node.map(codeText).join('')\n }\n const element = node as { props?: { children?: ReactNode } }\n return element.props ? codeText(element.props.children) : ''\n}\n\nfunction fenceLanguage(node: ReactNode): string | undefined {\n const child = Array.isArray(node) ? node.find(Boolean) : node\n const className = (child as { props?: { className?: string } } | undefined)?.props?.className\n const match = /language-([\\w-]+)/.exec(className ?? '')\n return match?.[1]\n}\n\nfunction CodeBand({ code, language }: { code: string; language?: string }) {\n return (\n <WithActions className=\"term-block\" actions={<CopyAction text={code} label=\"Copy code\" />}>\n <Band className=\"term-code\" data-language={language}>\n <pre className=\"term-pre\">{code}</pre>\n </Band>\n </WithActions>\n )\n}\n\nfunction heading(tone: 'bright' | 'fg'): Components['h1'] {\n return function Heading({ children }) {\n return (\n <div className=\"term-block\" data-tone={tone} data-weight=\"bold\">\n {children}\n </div>\n )\n }\n}\n\nconst TERMINAL_COMPONENTS: Components = {\n p: ({ children }) => <div className=\"term-block\">{children}</div>,\n\n h1: heading('bright'),\n h2: heading('bright'),\n h3: heading('bright'),\n h4: heading('fg'),\n h5: heading('fg'),\n h6: heading('fg'),\n\n ul: ({ children }) => <ul className=\"term-block term-list\">{children}</ul>,\n ol: ({ children }) => <ol className=\"term-block term-list term-list-ordered\">{children}</ol>,\n li: ({ children }) => (\n <li className=\"term-row term-li\">\n <span className=\"term-gutter\" aria-hidden />\n <div className=\"term-body\">{children}</div>\n </li>\n ),\n\n blockquote: ({ children }) => (\n <blockquote className=\"term-block term-quote\" data-tone=\"dim\">\n {children}\n </blockquote>\n ),\n\n hr: () => <div className=\"term-block term-rule\" aria-hidden />,\n\n pre: ({ children }) => <CodeBand code={codeText(children)} language={fenceLanguage(children)} />,\n code: ({ children }) => (\n <code className=\"term-inline-code\" data-tone=\"blue\">\n {children}\n </code>\n ),\n\n strong: ({ children }) => (\n <strong data-tone=\"bright\" data-weight=\"bold\">\n {children}\n </strong>\n ),\n em: ({ children }) => <em className=\"term-em\">{children}</em>,\n a: ({ children, href }) => (\n <a className=\"term-link\" data-tone=\"blue\" href={href} target=\"_blank\" rel=\"noreferrer\">\n {children}\n </a>\n ),\n\n table: ({ children }) => (\n <div className=\"term-block term-table-wrap\">\n <table className=\"term-table\">{children}</table>\n </div>\n ),\n // Every table element must be mapped: an unmapped `td` keeps its `py-2` and puts rows off the line grid (23px in an 18px theme).\n thead: ({ children }) => <thead className=\"term-thead\">{children}</thead>,\n tbody: ({ children }) => <tbody>{children}</tbody>,\n tr: ({ children }) => <tr>{children}</tr>,\n th: ({ children }) => (\n <th data-tone=\"bright\" data-weight=\"bold\">\n {children}\n </th>\n ),\n td: ({ children }) => <td>{children}</td>,\n}\n\nexport interface TerminalMarkdownProps {\n children: string\n streaming?: boolean\n className?: string\n}\n\nexport const TerminalMarkdown = memo(\n function TerminalMarkdown({ children, streaming, className }: TerminalMarkdownProps) {\n return (\n <Streamdown\n mode={streaming ? 'streaming' : 'static'}\n parseIncompleteMarkdown={streaming}\n controls={false}\n components={TERMINAL_COMPONENTS}\n className={cn('term-md', className)}\n >\n {children}\n </Streamdown>\n )\n },\n (prev, next) => prev.children === next.children && prev.streaming === next.streaming && prev.className === next.className,\n)\n","import { useEffect, useRef, type ReactNode } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nconst DRAG_SLOP = 4\n\nexport function Pressable({\n onPress,\n expanded,\n className,\n children,\n}: {\n onPress: () => void\n expanded?: boolean\n className?: string\n children: ReactNode\n}) {\n const origin = useRef<{ x: number; y: number } | null>(null)\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-expanded={expanded}\n className={cn('term-press', className)}\n onPointerDown={(event) => {\n origin.current = { x: event.clientX, y: event.clientY }\n }}\n onClick={(event) => {\n const from = origin.current\n origin.current = null\n if (from && Math.abs(event.clientX - from.x) + Math.abs(event.clientY - from.y) > DRAG_SLOP) {\n return\n }\n const selection = window.getSelection?.()\n if (selection && !selection.isCollapsed && selection.containsNode(event.currentTarget, true)) {\n return\n }\n onPress()\n }}\n onKeyDown={(event) => {\n if (event.key !== 'Enter' && event.key !== ' ') {\n return\n }\n event.preventDefault()\n onPress()\n }}\n >\n {children}\n </div>\n )\n}\n\nexport function useRevealOnOpen(open: boolean) {\n const ref = useRef<HTMLDivElement>(null)\n const previous = useRef(open)\n useEffect(() => {\n const opened = open && !previous.current\n previous.current = open\n if (!opened) {\n return\n }\n const element = ref.current\n if (!element) {\n return\n }\n // After paint: the new rows must be laid out and the virtualizer's size-change correction run before an offset read means anything.\n const frame = requestAnimationFrame(() => {\n const scroller = scrollParent(element)\n if (!scroller) {\n return\n }\n const top = element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop\n if (top >= scroller.scrollTop) {\n return\n }\n const line = Number.parseFloat(getComputedStyle(element).lineHeight) || 0\n scroller.scrollTop = Math.max(0, top - line)\n })\n return () => cancelAnimationFrame(frame)\n }, [open])\n return ref\n}\n\nfunction scrollParent(from: HTMLElement): HTMLElement | null {\n let node = from.parentElement\n while (node) {\n const overflow = getComputedStyle(node).overflowY\n if ((overflow === 'auto' || overflow === 'scroll') && node.scrollHeight > node.clientHeight) {\n return node\n }\n node = node.parentElement\n }\n return null\n}\n","import { formatBytes } from '../../lib/format.ts'\n\nexport const IMAGE_BOX_LINES = 12\n\nexport function imagePlaceholder(image: { bytes: number }): string {\n return `image · ${formatBytes(image.bytes)}`\n}\n\nexport const IMAGE_UNAVAILABLE = 'image unavailable'\n","const PREVIEW_LINES = 4\nconst PREVIEW_CHARS = 400\n\nexport type CollapsedResult = {\n shown: string[]\n more?: string\n}\n\nexport function collapsedResult(lines: string[], totalChars?: number): CollapsedResult {\n const shown: string[] = []\n let chars = 0\n let cut = false\n\n for (const line of lines.slice(0, PREVIEW_LINES)) {\n if (shown.length === 0 && line.length > PREVIEW_CHARS) {\n shown.push(`${line.slice(0, PREVIEW_CHARS)}…`)\n chars = PREVIEW_CHARS\n cut = true\n break\n }\n if (shown.length > 0 && chars + line.length > PREVIEW_CHARS) {\n break\n }\n shown.push(line)\n chars += line.length + 1\n }\n\n const held = lines.join('\\n').length\n const total = totalChars ?? held\n if (cut) {\n return { shown, more: `… +${(total - chars).toLocaleString()} chars` }\n }\n if (totalChars !== undefined && total > held) {\n return { shown, more: `… +${(total - chars).toLocaleString()} chars` }\n }\n const hidden = lines.length - shown.length\n return { shown, more: hidden > 0 ? `… +${hidden} line${hidden === 1 ? '' : 's'}` : undefined }\n}\n","import { createContext, useContext, type ReactNode } from 'react'\n\nexport type ToolResultFetcher = (toolUseId: string) => Promise<boolean>\n\nconst noop: ToolResultFetcher = async () => false\nconst FetchContext = createContext<ToolResultFetcher>(noop)\n\nexport function ToolResultFetchProvider({ value, children }: { value: ToolResultFetcher | undefined; children: ReactNode }) {\n return <FetchContext.Provider value={value ?? noop}>{children}</FetchContext.Provider>\n}\n\nexport function useToolResultFetcher(): ToolResultFetcher {\n return useContext(FetchContext)\n}\n","import { createContext, useCallback, useContext, useEffect, useRef, useState, type ReactNode } from 'react'\nimport type { WorkerDeckClient } from '@workerdeck/client'\n\nexport type ToolResultImageRef = {\n toolUseId: string\n sourceSeq: number\n partIndex: number\n mediaType: string\n bytes: number\n}\n\nexport type ToolResultImageLoader = (ref: ToolResultImageRef) => Promise<string | undefined>\n\nconst noop: ToolResultImageLoader = async () => undefined\n\nconst ImageContext = createContext<ToolResultImageLoader>(noop)\n\nexport function ToolResultImageProvider({ value, children }: { value: ToolResultImageLoader | undefined; children: ReactNode }) {\n return <ImageContext.Provider value={value ?? noop}>{children}</ImageContext.Provider>\n}\n\nexport function useToolResultImageLoader(): ToolResultImageLoader {\n return useContext(ImageContext)\n}\n\nconst MOUNT_SETTLE_MS = 150\n\nexport type ToolResultImageState = { src?: string; failed: boolean }\n\nexport function useToolResultImageSrc(ref: ToolResultImageRef): ToolResultImageState {\n const load = useToolResultImageLoader()\n const [state, setState] = useState<ToolResultImageState>({ failed: false })\n const { toolUseId, sourceSeq, partIndex, mediaType, bytes } = ref\n useEffect(() => {\n let live = true\n setState({ failed: false })\n const timer = setTimeout(() => {\n load({ toolUseId, sourceSeq, partIndex, mediaType, bytes })\n .then((src) => {\n if (live) {\n setState({ src, failed: src === undefined })\n }\n })\n .catch(() => {\n if (live) {\n setState({ failed: true })\n }\n })\n }, MOUNT_SETTLE_MS)\n return () => {\n live = false\n clearTimeout(timer)\n }\n }, [load, toolUseId, sourceSeq, partIndex, mediaType, bytes])\n return state\n}\n\nconst CACHE_BUDGET_BYTES = 64 * 1024 * 1024\n\ntype Entry = { pending: Promise<string | undefined>; url?: string; bytes: number }\n\nexport function useToolResultImages(client: WorkerDeckClient, sessionId: string | undefined): ToolResultImageLoader {\n const cache = useRef(new Map<string, Entry>())\n useEffect(\n () => () => {\n for (const entry of cache.current.values()) {\n if (entry.url) {\n URL.revokeObjectURL(entry.url)\n }\n }\n cache.current.clear()\n },\n [],\n )\n return useCallback(\n (ref: ToolResultImageRef) => {\n if (!sessionId) {\n return Promise.resolve(undefined)\n }\n const key = `${sessionId}:${ref.sourceSeq}:${ref.toolUseId}:${ref.partIndex}`\n const hit = cache.current.get(key)\n if (hit) {\n cache.current.delete(key)\n cache.current.set(key, hit)\n return hit.pending\n }\n const pending = client\n .toolResultImage(sessionId, ref.sourceSeq, ref.toolUseId, ref.partIndex)\n .then((blob) => {\n if (blob.size === 0) {\n return undefined\n }\n const url = URL.createObjectURL(blob)\n const entry = cache.current.get(key)\n if (entry) {\n entry.url = url\n entry.bytes = blob.size\n evict(cache.current, key)\n } else {\n URL.revokeObjectURL(url)\n }\n return url\n })\n .catch(() => undefined)\n cache.current.set(key, { pending, bytes: ref.bytes })\n return pending\n },\n [client, sessionId],\n )\n}\n\nfunction evict(cache: Map<string, Entry>, keep: string): void {\n let held = 0\n for (const entry of cache.values()) {\n held += entry.bytes\n }\n for (const [key, entry] of cache) {\n if (held <= CACHE_BUDGET_BYTES) {\n return\n }\n if (key === keep) {\n continue\n }\n if (entry.url) {\n URL.revokeObjectURL(entry.url)\n }\n cache.delete(key)\n held -= entry.bytes\n }\n}\n","import type { TranscriptItem } from '@workerdeck/react'\nimport { toolInputPreview } from '../../lib/format.ts'\nimport { isShellTool } from '../../lib/tool-icon.ts'\n\ntype ToolCallItem = Extract<TranscriptItem, { kind: 'tool_call' }>\n\nexport function foldsTogether(a: ToolCallItem, b: ToolCallItem): boolean {\n return a.parentToolUseId === b.parentToolUseId\n}\n\nexport function toolFamily(name: string): string {\n if (isShellTool(name)) {\n return 'shell'\n }\n const mcp = /^mcp__([^_]+(?:_[^_]+)*?)__/.exec(name)\n if (mcp?.[1]) {\n return mcp[1].replace(/_/g, '-')\n }\n return name.toLowerCase()\n}\n\nexport function runSummary(items: readonly ToolCallItem[], busy: boolean): string {\n const verb = busy ? 'Running ' : 'Ran '\n const tail = busy ? '…' : ''\n const n = items.length\n\n const counts = new Map<string, number>()\n for (const item of items) {\n const family = toolFamily(item.name)\n counts.set(family, (counts.get(family) ?? 0) + 1)\n }\n if (counts.size === 1 && counts.has('shell')) {\n return `${verb}${n} shell command${n === 1 ? '' : 's'}${tail}`\n }\n const breakdown = [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .map(([family, count]) => `${count} ${family}`)\n .join(', ')\n return `${verb}${n} tool${n === 1 ? '' : 's'} · ${breakdown}${tail}`\n}\n\nfunction clip(text: string, max = 80): string {\n return text.length > max ? text.slice(0, max - 1) + '…' : text\n}\n\nfunction trimmed(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined\n}\n\nexport function taskLabel(task: ToolCallItem): string {\n return `${task.name}(${taskIdentity(task)})`\n}\n\nexport function taskIdentity(task: ToolCallItem): string {\n const input = task.input as { description?: unknown; subagent_type?: unknown } | null\n const description = trimmed(input?.description)\n const agent = trimmed(input?.subagent_type)\n return agent && description\n ? `${agent} · ${clip(description)}`\n : (agent ?? (description ? clip(description) : toolInputPreview(task.input)))\n}\n\nexport function taskBrief(task: ToolCallItem): string | undefined {\n const input = task.input as { prompt?: unknown } | null\n return trimmed(input?.prompt)\n}\n\nfunction callBusy(call: ToolCallItem): boolean {\n return call.status === 'running' || call.status === 'pending'\n}\n\nexport function callFailed(call: ToolCallItem): boolean {\n return call.status === 'failed' || call.result?.isError === true\n}\n\nexport function runFailed(items: readonly ToolCallItem[]): boolean {\n const last = items[items.length - 1]\n return last !== undefined && callFailed(last)\n}\n\nexport function taskBusy(task: ToolCallItem, children: readonly TranscriptItem[]): boolean {\n return callBusy(task) || children.some((child) => child.kind === 'tool_call' && callBusy(child))\n}\n\nexport function taskFailed(task: ToolCallItem): boolean {\n return callFailed(task)\n}\n\nexport function taskSummary(task: ToolCallItem, children: readonly TranscriptItem[]): string {\n const busy = taskBusy(task, children)\n const calls = children.reduce((n, child) => n + (child.kind === 'tool_call' ? 1 : 0), 0)\n const label = taskLabel(task)\n if (calls === 0) {\n return busy ? `${label} · working…` : `${label} · done`\n }\n return `${label} · ${calls} tool${calls === 1 ? '' : 's'}${busy ? '…' : ''}`\n}\n","export type TodoStatus = 'pending' | 'in_progress' | 'completed'\n\nexport type TodoEntry = { status: TodoStatus; text: string }\n\nexport type TodoPreview = { summary: string; shown: TodoEntry[]; more?: string }\n\nconst PREVIEW_TODOS = 8\n\nconst GLYPH: Record<TodoStatus, string> = { pending: '☐', in_progress: '◐', completed: '☒' }\n\nfunction todoEntry(value: unknown): TodoEntry | undefined {\n if (typeof value !== 'object' || value === null) {\n return undefined\n }\n const raw = value as { content?: unknown; status?: unknown; activeForm?: unknown }\n const status = raw.status\n if (status !== 'pending' && status !== 'in_progress' && status !== 'completed') {\n return undefined\n }\n const content = typeof raw.content === 'string' ? raw.content.trim() : ''\n if (content === '') {\n return undefined\n }\n const active = typeof raw.activeForm === 'string' ? raw.activeForm.trim() : ''\n return { status, text: status === 'in_progress' && active !== '' ? active : content }\n}\n\n// Whole-or-nothing: a malformed entry (streaming, partial input) falls back to the generic preview rather than a half-drawn checklist.\nexport function parseTodos(input: unknown): TodoEntry[] | undefined {\n const todos = (input as { todos?: unknown } | null)?.todos\n if (!Array.isArray(todos) || todos.length === 0) {\n return undefined\n }\n const out: TodoEntry[] = []\n for (const value of todos) {\n const entry = todoEntry(value)\n if (entry === undefined) {\n return undefined\n }\n out.push(entry)\n }\n return out\n}\n\nexport function todoPreview(name: string, input: unknown): TodoPreview | undefined {\n if (name !== 'TodoWrite') {\n return undefined\n }\n const todos = parseTodos(input)\n if (todos === undefined) {\n return undefined\n }\n const done = todos.reduce((n, todo) => n + (todo.status === 'completed' ? 1 : 0), 0)\n const shown = todos.slice(0, PREVIEW_TODOS)\n const hidden = todos.length - shown.length\n return {\n summary: `${done}/${todos.length} done`,\n shown,\n more: hidden > 0 ? `… +${hidden} more` : undefined,\n }\n}\n\n// Height and render both draw this exact string — `toolRowHeight` counts what `TerminalTodos` paints.\nexport function todoLine(todo: TodoEntry): string {\n return `${GLYPH[todo.status]} ${todo.text}`\n}\n","import { useEffect, useState } from 'react'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { COMPACTION_TEXT, formatBytes, formatCost, formatDuration, toolInputPreview } from '../../lib/format.ts'\nimport { isMutatingTool } from '../../lib/tool-icon.ts'\nimport { usePulse } from '../agent/pulse.tsx'\nimport { BookmarkAction, CopyAction, WithActions } from './affordances.tsx'\nimport { TerminalDiff } from './diff.tsx'\nimport { TerminalMarkdown } from './markdown.tsx'\nimport { Pressable, useRevealOnOpen } from './press.tsx'\nimport { IMAGE_BOX_LINES, IMAGE_UNAVAILABLE, imagePlaceholder } from './image-box.ts'\nimport { collapsedResult } from './result-preview.ts'\nimport { useToolResultFetcher } from '../agent/tool-result-fetch.tsx'\nimport { useToolResultImageSrc } from '../agent/tool-result-image.tsx'\nimport { runFailed, runSummary } from './tool-run.ts'\nimport { todoLine, todoPreview, type TodoPreview, type TodoStatus } from './todos.ts'\nimport { type ToolCallItem } from './blocks.ts'\nimport { Band, Blank, Ink, Row, type Tone } from './row.tsx'\n\nexport const PROMPT_GLYPH = '❯'\n\nexport const RESULT_PREVIEW_CHARS = 2000\n\nfunction clipToChars(lines: string[], maxChars: number): string[] {\n const out: string[] = []\n let chars = 0\n for (const line of lines) {\n if (out.length > 0 && chars + line.length > maxChars) {\n break\n }\n out.push(line)\n chars += line.length + 1\n }\n return out\n}\n\nexport function UserRow({ item }: { item: Extract<TranscriptItem, { kind: 'user' }> }) {\n return (\n <WithActions actions={<BookmarkAction id={item.id} />}>\n <div className=\"term-user\">\n {item.attachments?.length ? (\n <Row glyph={PROMPT_GLYPH} glyphTone=\"dim\" tone=\"dim\">\n {item.attachments.map((attachment) => attachment.name).join(', ')}\n </Row>\n ) : null}\n {item.text\n ? item.text.split('\\n').map((line, index) => (\n <Row key={index} glyph={index === 0 ? PROMPT_GLYPH : undefined} glyphTone=\"dim\" tone=\"fg\">\n {line || ' '}\n </Row>\n ))\n : null}\n </div>\n </WithActions>\n )\n}\n\nexport function AssistantRow({ item }: { item: Extract<TranscriptItem, { kind: 'assistant_text' }> }) {\n return (\n <WithActions\n actions={\n <>\n <BookmarkAction id={item.id} />\n {item.streaming ? null : <CopyAction text={item.text} label=\"Copy message\" />}\n </>\n }\n >\n <Row glyph=\"●\" glyphTone=\"fg\" tone=\"fg\">\n <TerminalMarkdown streaming={item.streaming}>{item.text}</TerminalMarkdown>\n </Row>\n </WithActions>\n )\n}\n\nexport function ThinkingRow({ item }: { item: Extract<TranscriptItem, { kind: 'thinking' }> }) {\n return (\n <Row glyph=\"✻\" glyphTone=\"dim\" tone=\"dim\">\n <span className=\"term-em\">{item.text}</span>\n </Row>\n )\n}\n\nconst TOOL_TONE: Record<string, Tone> = {\n running: 'blue',\n pending: 'blue',\n deferred: 'yellow',\n settled: 'dim',\n failed: 'red',\n}\n\nexport function ToolRow({ item }: { item: ToolCallItem }) {\n const [open, setOpen] = useState(false)\n const [full, setFull] = useState(false)\n const [fetching, setFetching] = useState(false)\n const fetchResult = useToolResultFetcher()\n const reveal = useRevealOnOpen(open)\n const status = item.status ?? (item.result === undefined ? 'running' : 'settled')\n const busy = status === 'running' || status === 'pending'\n const isError = status === 'failed' || item.result?.isError === true\n const pulse = usePulse(busy)\n\n const text = item.result?.text ?? ''\n const lines = text.trimEnd().split('\\n')\n const collapsed = collapsedResult(lines, item.result?.totalChars)\n const preview = open ? (full ? lines : clipToChars(lines, RESULT_PREVIEW_CHARS)) : collapsed.shown\n const hidden = lines.length - preview.length\n const clipped = open && !full && hidden > 0\n const truncated = item.result?.truncated === true\n const missing = truncated ? (item.result?.totalChars ?? 0) - text.length : 0\n\n const tone: Tone = isError ? 'red' : status === 'settled' && isMutatingTool(item.name) ? 'green' : (TOOL_TONE[status] ?? 'dim')\n\n const command = (item.input as { command?: unknown } | null)?.command\n const copyable = typeof command === 'string' ? command : text\n const todos = todoPreview(item.name, item.input)\n\n return (\n <div ref={reveal} className={open ? 'term-open' : undefined}>\n <WithActions\n actions={\n <>\n <BookmarkAction id={item.id} />\n {copyable ? <CopyAction text={copyable} label=\"Copy\" /> : null}\n </>\n }\n >\n <Pressable onPress={() => setOpen((v) => !v)} expanded={open}>\n <Row glyph={busy ? pulse : '●'} glyphTone={tone} tone=\"fg\">\n <Ink bold tone=\"bright\">\n {item.name}\n </Ink>\n <Ink tone=\"dim\">({todos ? todos.summary : toolInputPreview(item.input)})</Ink>\n {item.backend && item.backend !== 'server' ? <Ink tone=\"faint\"> · {item.backend}</Ink> : null}\n </Row>\n </Pressable>\n {item.result?.images?.map((image) => (\n <TerminalImage key={image.partIndex} toolUseId={item.id} image={image} />\n ))}\n {item.patch && !open ? (\n <TerminalDiff patch={item.patch} />\n ) : todos && !open ? (\n <TerminalTodos preview={todos} />\n ) : text ? (\n <>\n {preview.map((line, index) => (\n <Row key={index} indent={1} columns={3} glyph={index === 0 ? '⎿' : undefined} tone={isError ? 'red' : 'dim'}>\n {line || ' '}\n </Row>\n ))}\n {!open ? (\n collapsed.more ? (\n <Row indent={1} columns={3} tone=\"faint\">\n {collapsed.more}\n </Row>\n ) : null\n ) : clipped || truncated ? (\n <Row indent={1} columns={3} tone=\"faint\">\n {fetching ? (\n <>… fetching {(item.result?.totalChars ?? 0).toLocaleString()} chars</>\n ) : clipped || truncated ? (\n <button\n type=\"button\"\n className=\"term-press term-link\"\n onClick={() => {\n setFull(true)\n if (!truncated) {\n return\n }\n setFetching(true)\n void fetchResult(item.id).finally(() => setFetching(false))\n }}\n >\n {truncated\n ? `… +${missing.toLocaleString()} chars — fetch the rest`\n : `… +${hidden} line${hidden === 1 ? '' : 's'} — show all ${text.length.toLocaleString()} chars`}\n </button>\n ) : (\n <>\n … +{hidden} line{hidden === 1 ? '' : 's'}\n </>\n )}\n </Row>\n ) : hidden > 0 ? (\n <Row indent={1} columns={3} tone=\"faint\">\n … +{hidden} line{hidden === 1 ? '' : 's'}\n </Row>\n ) : null}\n </>\n ) : null}\n </WithActions>\n </div>\n )\n}\n\nconst TODO_TONE: Record<TodoStatus, Tone> = {\n pending: 'dim',\n in_progress: 'blue',\n completed: 'faint',\n}\n\nfunction TerminalTodos({ preview }: { preview: TodoPreview }) {\n return (\n <>\n {preview.shown.map((todo, index) => (\n <Row key={index} indent={1} columns={3} glyph={index === 0 ? '⎿' : undefined} tone={TODO_TONE[todo.status]}>\n {todoLine(todo)}\n </Row>\n ))}\n {preview.more ? (\n <Row indent={1} columns={3} tone=\"faint\">\n {preview.more}\n </Row>\n ) : null}\n </>\n )\n}\n\ntype ToolResultImage = NonNullable<NonNullable<ToolCallItem['result']>['images']>[number]\n\nfunction TerminalImage({ toolUseId, image }: { toolUseId: string; image: ToolResultImage }) {\n const { src, failed } = useToolResultImageSrc({ toolUseId, ...image })\n return (\n <Row indent={1} columns={3}>\n <div\n className=\"term-image\"\n data-state={src ? 'loaded' : failed ? 'failed' : 'pending'}\n style={{ height: `calc(var(--term-line) * ${IMAGE_BOX_LINES})` }}\n >\n {src ? (\n <img src={src} alt={imagePlaceholder(image)} />\n ) : (\n <Ink tone=\"faint\">{failed ? IMAGE_UNAVAILABLE : imagePlaceholder(image)}</Ink>\n )}\n </div>\n </Row>\n )\n}\n\nexport function ToolRunRow({ items }: { items: ToolCallItem[] }) {\n const [open, setOpen] = useState(false)\n const reveal = useRevealOnOpen(open)\n const busy = items.some((item) => {\n const status = item.status ?? (item.result === undefined ? 'running' : 'settled')\n return status === 'running' || status === 'pending'\n })\n const failed = runFailed(items)\n const pulse = usePulse(busy)\n\n return (\n <div ref={reveal} className={open ? 'term-open' : undefined}>\n <Pressable onPress={() => setOpen((v) => !v)} expanded={open}>\n <Row glyph={busy ? pulse : undefined} glyphTone={busy ? 'mark' : undefined} tone={failed ? 'red' : 'dim'}>\n {runSummary(items, busy)}\n </Row>\n </Pressable>\n {open ? (\n <div>\n {items.map((item) => (\n <ToolRow key={item.id} item={item} />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport function TurnResultRow({ item }: { item: Extract<TranscriptItem, { kind: 'turn_result' }> }) {\n return (\n <div>\n <Row tone={item.isError ? 'red' : 'faint'}>\n {item.isError ? item.subtype : 'done'} · {formatDuration(item.durationMs)} · {formatCost(item.totalCostUsd)}\n </Row>\n {item.errors?.map((message, index) => (\n <Row key={index} tone=\"red\">\n {message}\n </Row>\n ))}\n </div>\n )\n}\n\n/**\n * One row, deliberately. A rule with a centred label reads better and costs the height book a\n * second measurement for a row that carries no content — and the point here is only that the\n * boundary is *visible*, so the ring dropping 90% → 15% stops reading as a bug.\n */\nexport function CompactionRow() {\n return (\n <Row glyph=\"≡\" glyphTone=\"yellow\" tone=\"faint\">\n {COMPACTION_TEXT}\n </Row>\n )\n}\n\nexport function NoticeRow({ item }: { item: Extract<TranscriptItem, { kind: 'notice' }> }) {\n const error = item.level === 'error'\n return (\n <Row glyph=\"!\" glyphTone={error ? 'red' : 'yellow'} tone={error ? 'red' : 'dim'}>\n {item.text}\n </Row>\n )\n}\n\nexport function FileRow({ item, href }: { item: Extract<TranscriptItem, { kind: 'file_delivered' }>; href?: string }) {\n return (\n <Row glyph=\"⤓\" glyphTone=\"blue\" tone=\"dim\">\n {href ? (\n <a className=\"term-link\" data-tone=\"blue\" href={href} download>\n {item.path}\n </a>\n ) : (\n <Ink tone=\"blue\">{item.path}</Ink>\n )}\n <Ink tone=\"faint\"> · {formatBytes(item.bytes)}</Ink>\n {item.description ? <Ink tone=\"faint\"> · {item.description}</Ink> : null}\n </Row>\n )\n}\n\nexport function useTicker(on: boolean): number {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n if (!on) {\n return\n }\n const timer = setInterval(() => setNow(Date.now()), 1000)\n return () => clearInterval(timer)\n }, [on])\n return now\n}\n\nexport function WorkingRow({ label, startedAt, tokens }: { label: string; startedAt?: number; tokens?: number }) {\n const pulse = usePulse(true)\n const now = useTicker(startedAt !== undefined)\n const elapsed = startedAt === undefined ? undefined : formatDuration(now - startedAt)\n const readings = [elapsed, tokens ? `↓ ${(tokens / 1000).toFixed(1)}k tokens` : undefined].filter(Boolean)\n return (\n <Row glyph={pulse} glyphTone=\"mark\" tone=\"mark\">\n {label}\n {readings.length ? <Ink tone=\"faint\"> ({readings.join(' · ')})</Ink> : null}\n </Row>\n )\n}\n\nexport { Band, Blank }\n","import type { CSSProperties, HTMLAttributes } from 'react'\nimport { cn } from '../../lib/utils.ts'\nimport { AffordanceProvider, resolveAffordances, type TerminalAffordances } from './affordances.tsx'\n\nexport interface TerminalSurfaceProps extends HTMLAttributes<HTMLDivElement> {\n fontSize?: number\n lineHeight?: number\n bleed?: string\n affordances?: TerminalAffordances | boolean\n}\n\nexport function TerminalSurface({ fontSize, lineHeight, bleed, affordances, className, style, children, ...props }: TerminalSurfaceProps) {\n const resolved = resolveAffordances(affordances)\n return (\n <div\n data-terminal=\"\"\n data-affordances={[resolved.hover && 'hover', resolved.actions && 'actions'].filter(Boolean).join(' ') || undefined}\n className={cn('min-w-0', className)}\n style={\n {\n ...(fontSize !== undefined && { '--term-font-size': `${Math.round(fontSize)}px` }),\n ...(lineHeight !== undefined && { '--term-line': `${Math.round(lineHeight)}px` }),\n ...(bleed !== undefined && { '--term-bleed': bleed }),\n ...style,\n } as CSSProperties\n }\n {...props}\n >\n <AffordanceProvider value={resolved}>{children}</AffordanceProvider>\n </div>\n )\n}\n","import { useEffect, useImperativeHandle, useMemo, useRef, useState, type DragEvent, type ReactNode, type Ref } from 'react'\nimport type { SkillInfo, SlashCommandInfo } from '@workerdeck/protocol'\nimport type { StagedAttachment, UseAttachmentsResult } from '@workerdeck/react'\nimport { ArrowUp, FileText, Paperclip, RotateCw, Sparkles, Square, TriangleAlert, X } from 'lucide-react'\nimport { Button } from '../ui/Button.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { PromptArea } from '../prompt-area/prompt-area.tsx'\nimport { usePromptAreaState } from '../prompt-area/use-prompt-area-state.ts'\nimport { plainTextToSegments } from '../prompt-area/prompt-area-engine.ts'\nimport { commandTrigger, mentionTrigger } from '../prompt-area/trigger-presets.ts'\nimport { useTranscriptVariant } from './transcript-variant.tsx'\nimport type { TerminalAffordances } from '../terminal/affordances.tsx'\nimport { PROMPT_GLYPH } from '../terminal/items.tsx'\nimport { TerminalSurface } from '../terminal/surface.tsx'\nimport type { TriggerSuggestion } from '../prompt-area/types.ts'\nimport { cn } from '../../lib/utils.ts'\nimport { formatBytes } from '../../lib/format.ts'\n\nexport type ComposerFileMatch = { path: string; relative: string }\n\nexport type ComposerHandle = {\n insertText: (text: string) => void\n focus: () => void\n}\n\nexport interface ComposerProps {\n onSend: (text: string, attachmentIds: string[]) => void\n onInterrupt: () => void\n busy: boolean\n disabled?: boolean\n placeholder?: string\n commands?: SlashCommandInfo[]\n skills?: SkillInfo[]\n onSearchFiles?: (query: string, options: { signal: AbortSignal }) => Promise<ComposerFileMatch[]>\n attachments?: UseAttachmentsResult\n toolbar?: ReactNode\n layout?: 'stacked' | 'inline'\n fontSize?: number\n lineHeight?: number\n affordances?: TerminalAffordances | boolean\n /**\n * Where unsent text is remembered between mounts. The composer is remounted on every session switch, so without\n * this a half-written prompt dies with the switch. Omit to keep the composer stateless across mounts.\n */\n draft?: { initialText: string; save: (text: string) => void; clear: () => void }\n className?: string\n ref?: Ref<ComposerHandle>\n}\n\nfunction cleanName(name: string) {\n return name.replace(/\\s*\\(MCP\\)$/i, '')\n}\n\nexport function skillPrompt(skill: SkillInfo): string {\n const base = skill.defaultPrompt?.trim() || `$${skill.name}`\n return /\\s$/.test(base) ? base : base + ' '\n}\n\nfunction matchScore(query: string, haystacks: string[]): number {\n const needle = query.toLowerCase()\n const lowered = haystacks.map((s) => s.toLowerCase())\n if (lowered.some((h) => h.startsWith(needle))) {\n return 2\n }\n return lowered.some((h) => h.includes(needle)) ? 1 : 0\n}\n\nexport function Composer({\n onSend,\n onInterrupt,\n busy,\n disabled,\n placeholder = 'Message the agent…',\n commands,\n skills,\n onSearchFiles,\n attachments,\n toolbar,\n layout = 'stacked',\n fontSize,\n lineHeight,\n affordances,\n draft,\n className,\n ref,\n}: ComposerProps) {\n const inline = layout === 'inline'\n const terminal = useTranscriptVariant() === 'terminal'\n // Read once, on mount: re-seeding mid-session would fight whatever is being typed.\n const [initialDraft] = useState(() => draft?.initialText ?? '')\n const { bind, plainText, isEmpty, clear, focus } = usePromptAreaState(\n initialDraft === '' ? undefined : { initialValue: plainTextToSegments(initialDraft) },\n )\n const fileInput = useRef<HTMLInputElement>(null)\n const [dragging, setDragging] = useState(false)\n\n useImperativeHandle(\n ref,\n () => ({\n insertText: (text: string) => {\n const prefix = plainText.length > 0 && !/\\s$/.test(plainText) ? ' ' : ''\n bind.ref.current?.appendText(prefix + text)\n focus()\n },\n focus,\n }),\n [bind.ref, plainText, focus],\n )\n\n const triggers = useMemo(() => {\n const configured = []\n const usableSkills = (skills ?? []).filter((s) => s.enabled)\n if (commands && commands.length > 0) {\n const seen = new Set<string>()\n const unique = commands.flatMap((c) => {\n const name = cleanName(c.name)\n if (seen.has(name)) {\n return []\n }\n seen.add(name)\n return [{ ...c, name }]\n })\n configured.push(\n commandTrigger({\n onSearch: (query: string): TriggerSuggestion[] => {\n const scored: Array<{ score: number; suggestion: TriggerSuggestion }> = []\n for (const c of unique) {\n const score = matchScore(query, [c.name, ...(c.aliases ?? []), ...c.name.split(':')])\n if (score === 0) {\n continue\n }\n scored.push({\n score,\n suggestion: {\n value: c.name,\n label: `/${c.name}${c.argumentHint ? ` ${c.argumentHint}` : ''}`,\n description: c.description,\n },\n })\n }\n scored.sort((a, b) => b.score - a.score)\n return scored.map(({ suggestion }) => suggestion)\n },\n onSelect: (suggestion) => suggestion.value,\n chipClassName: 'font-mono',\n }),\n )\n }\n if (usableSkills.length > 0) {\n configured.push(\n commandTrigger({\n char: '$',\n accessibilityLabel: 'skill',\n onSearch: (query: string): TriggerSuggestion[] => {\n const scored: Array<{ score: number; suggestion: TriggerSuggestion }> = []\n for (const skill of usableSkills) {\n const score = matchScore(query, [skill.name, ...skill.name.split(/[-:_]/)])\n if (score === 0) {\n continue\n }\n const summary = skill.shortDescription ?? skill.description\n scored.push({\n score,\n suggestion: {\n value: skill.name,\n label: skill.displayName ?? skill.name,\n description: summary ? `Skill · ${summary}` : 'Skill · inserts a message you can edit',\n icon: <Sparkles className=\"size-3.5 text-fg-3\" />,\n },\n })\n }\n scored.sort((a, b) => b.score - a.score)\n return scored.map(({ suggestion }) => suggestion)\n },\n insertAsText: (suggestion) => {\n const skill = usableSkills.find((s) => s.name === suggestion.value)\n return skill ? skillPrompt(skill) : `$${suggestion.value} `\n },\n }),\n )\n }\n if (onSearchFiles) {\n configured.push(\n mentionTrigger({\n searchDebounceMs: 150,\n onSearch: async (query, options) => {\n const matches = await onSearchFiles(query, options)\n return matches.map((match) => ({\n value: match.relative,\n label: match.relative,\n description: match.path,\n }))\n },\n onSelect: (suggestion) => suggestion.value,\n chipStyle: 'inline',\n chipClassName: 'font-mono',\n emptyMessage: 'No matching files',\n }),\n )\n }\n return configured.length > 0 ? configured : undefined\n }, [commands, skills, onSearchFiles])\n\n const saveDraft = draft?.save\n useEffect(() => {\n saveDraft?.(plainText)\n }, [plainText, saveDraft])\n\n const staged = attachments?.items ?? []\n const canSend = !disabled && (!isEmpty || staged.length > 0) && !attachments?.uploading && !attachments?.hasFailure\n\n const submit = () => {\n if (!canSend) {\n return\n }\n onSend(plainText.trim(), attachments?.readyIds ?? [])\n attachments?.clear()\n draft?.clear()\n clear()\n focus()\n }\n\n const pick = (files: FileList | null) => {\n if (files && files.length > 0) {\n attachments?.add(files)\n }\n }\n\n const fileField =\n attachments && !attachments.disabled ? (\n <input\n ref={fileInput}\n type=\"file\"\n multiple\n accept={attachments.accept || undefined}\n className=\"hidden\"\n onChange={(e) => {\n pick(e.target.files)\n // Re-picking the same file must fire `change` again.\n e.target.value = ''\n }}\n />\n ) : null\n const canAttach = !!attachments && !attachments.disabled\n\n const attach = canAttach ? (\n <>\n {fileField}\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Attach files\" disabled={disabled} onClick={() => fileInput.current?.click()}>\n <Paperclip className=\"size-4\" />\n </Button>\n </>\n ) : null\n\n const gutter = busy ? (\n <GlyphButton gutter label=\"Interrupt\" tone=\"yellow\" onClick={onInterrupt}>\n ✕\n </GlyphButton>\n ) : canAttach ? (\n <GlyphButton gutter label=\"Attach files\" disabled={disabled} onClick={() => fileInput.current?.click()}>\n +\n </GlyphButton>\n ) : (\n <span aria-hidden className=\"term-gutter\" data-tone=\"blue\">\n {PROMPT_GLYPH}\n </span>\n )\n\n const interrupting = busy && !canSend\n const submitButton = terminal ? (\n <GlyphButton label=\"Send\" disabled={!canSend} onClick={submit} tone={canSend ? 'blue' : undefined}>\n ↵\n </GlyphButton>\n ) : interrupting ? (\n <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Interrupt\" className=\"rounded-full\" onClick={onInterrupt}>\n <Square className=\"size-3\" />\n </Button>\n ) : (\n <Button size=\"icon-sm\" aria-label=\"Send\" className=\"rounded-full\" disabled={!canSend} onClick={submit}>\n <ArrowUp className=\"size-4\" />\n </Button>\n )\n\n const dropHandlers = {\n onDragOver: (e: DragEvent) => {\n if (attachments && !attachments.disabled) {\n e.preventDefault()\n setDragging(true)\n }\n },\n onDragLeave: () => setDragging(false),\n onDrop: (e: DragEvent) => {\n if (!attachments || attachments.disabled) {\n return\n }\n e.preventDefault()\n setDragging(false)\n pick(e.dataTransfer.files)\n },\n }\n\n const errorRow = attachments?.error ? (\n <div className={cn('mx-auto mt-1 flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 text-label text-danger')}>\n <TriangleAlert className=\"size-3 shrink-0\" />\n <span className=\"min-w-0 flex-1\">{attachments.error}</span>\n <button type=\"button\" onClick={attachments.dismissError} aria-label=\"Dismiss\" className=\"shrink-0 opacity-70 hover:opacity-100\">\n <X className=\"size-3\" />\n </button>\n </div>\n ) : null\n\n if (terminal) {\n const line = lineHeight ?? 18\n return (\n <div data-slot=\"composer\" className={cn('shrink-0', className)}>\n <TerminalSurface\n {...dropHandlers}\n fontSize={fontSize}\n lineHeight={lineHeight}\n affordances={affordances}\n bleed=\"1ch\"\n data-dragging={dragging || undefined}\n className={cn('term-composer', disabled && 'opacity-60')}\n >\n <div className=\"term-composer-body\">\n {staged.length > 0 && attachments ? <AttachmentStrip attachments={attachments} /> : null}\n <div className=\"term-row\">\n {canAttach ? fileField : null}\n {gutter}\n <div className=\"flex min-w-0 items-start\">\n <PromptArea\n {...bind}\n triggers={triggers}\n markdown={false}\n normalizeBullets={false}\n onSubmit={submit}\n disabled={disabled}\n placeholder={disabled ? 'Session ended' : placeholder}\n minHeight={line}\n maxHeight={line * 10}\n aria-label=\"Message the agent\"\n className=\"term-composer-field min-w-0 flex-1\"\n onImagePaste={(file) => attachments?.add([file])}\n />\n {submitButton}\n </div>\n </div>\n {toolbar ? (\n <div className=\"term-row\">\n <span aria-hidden className=\"term-gutter\" />\n <div className=\"flex min-w-0 items-center gap-[1ch]\">{toolbar}</div>\n </div>\n ) : null}\n </div>\n </TerminalSurface>\n {errorRow}\n </div>\n )\n }\n\n return (\n <div data-slot=\"composer\" className={cn('px-[var(--wd-composer-padding)] pb-[var(--wd-composer-padding)]', className)}>\n <div\n {...dropHandlers}\n className={cn(\n 'mx-auto w-full max-w-[var(--wd-transcript-max-width)] overflow-hidden border border-border bg-bg',\n 'transition-colors rounded-lg shadow-(--shadow-xs)',\n 'focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30',\n dragging && 'border-ring ring-2 ring-ring/30',\n disabled && 'opacity-60',\n )}\n >\n {staged.length > 0 && attachments ? <AttachmentStrip attachments={attachments} /> : null}\n {inline ? (\n <div className=\"flex items-end gap-1 p-1\">\n {attach}\n <PromptArea\n {...bind}\n triggers={triggers}\n markdown={false}\n normalizeBullets={false}\n onSubmit={submit}\n disabled={disabled}\n placeholder={disabled ? 'Session ended' : placeholder}\n minHeight={20}\n maxHeight={192}\n aria-label=\"Message the agent\"\n className=\"min-w-0 flex-1 py-1 text-body-sm text-text\"\n onImagePaste={(file) => attachments?.add([file])}\n />\n {submitButton}\n </div>\n ) : (\n <>\n <PromptArea\n {...bind}\n triggers={triggers}\n markdown={false}\n normalizeBullets={false}\n onSubmit={submit}\n disabled={disabled}\n placeholder={disabled ? 'Session ended' : placeholder}\n minHeight={28}\n maxHeight={192}\n aria-label=\"Message the agent\"\n className=\"px-3 pt-2.5 pb-0 text-body-sm text-text\"\n onImagePaste={(file) => attachments?.add([file])}\n />\n <div className=\"flex items-center justify-between gap-2 px-2 pb-2\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {attach}\n {toolbar}\n </div>\n {submitButton}\n </div>\n </>\n )}\n </div>\n {errorRow}\n </div>\n )\n}\n\nfunction GlyphButton({\n tone,\n label,\n disabled,\n onClick,\n gutter,\n className,\n children,\n}: {\n tone?: 'blue' | 'yellow'\n label: string\n disabled?: boolean\n onClick: () => void\n gutter?: boolean\n className?: string\n children: ReactNode\n}) {\n return (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n disabled={disabled}\n onClick={onClick}\n data-tone={tone}\n data-gutter={gutter || undefined}\n className={cn('term-glyph', className)}\n >\n {children}\n </button>\n )\n}\n\nfunction AttachmentStrip({ attachments }: { attachments: UseAttachmentsResult }) {\n const terminal = useTranscriptVariant() === 'terminal'\n return (\n <div className={cn('flex gap-2 overflow-x-auto', terminal ? 'term-attachments' : 'border-b border-border px-2 py-2')}>\n {attachments.items.map((item) => (\n <AttachmentChip\n key={item.key}\n item={item}\n onRetry={() => attachments.retry(item.key)}\n onRemove={() => attachments.remove(item.key)}\n />\n ))}\n </div>\n )\n}\n\nfunction AttachmentChip({ item, onRetry, onRemove }: { item: StagedAttachment; onRetry: () => void; onRemove: () => void }) {\n const failed = item.status === 'failed'\n const terminal = useTranscriptVariant() === 'terminal'\n const round = terminal ? '' : 'rounded-md'\n return (\n <div className=\"group relative shrink-0\" title={failed ? `${item.name} — ${item.error}` : `${item.name} · ${formatBytes(item.bytes)}`}>\n <div\n className={cn(\n 'flex size-14 items-center justify-center overflow-hidden bg-surface',\n round,\n terminal ? 'term-attachment' : 'border border-border',\n failed && 'border-danger/50',\n )}\n data-failed={terminal && failed ? '' : undefined}\n >\n {item.previewUrl ? (\n <img src={item.previewUrl} alt={item.name} className=\"size-full object-cover\" />\n ) : (\n <div className=\"flex flex-col items-center gap-0.5 text-fg-3\">\n <FileText className=\"size-4\" />\n <span className=\"max-w-12 truncate text-[9px] font-semibold uppercase\">{extensionOf(item.name)}</span>\n </div>\n )}\n </div>\n {item.status === 'uploading' ? (\n <div className={cn('absolute inset-0 flex items-center justify-center bg-black/35', round)}>\n <Spinner className=\"size-4 text-white\" />\n </div>\n ) : null}\n {failed ? (\n <button\n type=\"button\"\n onClick={onRetry}\n aria-label={`Retry ${item.name}`}\n className={cn('absolute inset-0 flex items-center justify-center bg-black/45 text-warning', round)}\n >\n <RotateCw className=\"size-4\" />\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label={`Remove ${item.name}`}\n className={cn(\n 'absolute flex size-4 items-center justify-center bg-surface text-fg-3 hover:text-fg-1',\n terminal ? 'term-attachment-remove' : '-top-1 -right-1 rounded-full border border-border shadow-(--shadow-xs)',\n )}\n >\n <X className=\"size-2.5\" />\n </button>\n </div>\n )\n}\n\nfunction extensionOf(name: string) {\n const dot = name.lastIndexOf('.')\n return dot > 0 ? name.slice(dot + 1).toUpperCase() : 'FILE'\n}\n","/**\n * Pass a colour through only if this engine can actually parse it. Category colours arrive\n * from the CLI as untrusted strings, and an unparseable one must fall back to the token\n * colour rather than reaching the DOM.\n */\nexport function cssColor(color: string): string | undefined {\n return typeof CSS !== 'undefined' && CSS.supports('color', color) ? color : undefined\n}\n","import type { ContextUsage } from '@workerdeck/protocol'\nimport { Dialog, DialogBody, DialogContent, DialogHeader } from '../ui/Dialog.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatTokens } from '../../lib/format.ts'\nimport { cssColor } from '../../lib/css.ts'\nimport { meterTintClass } from '../../lib/status.ts'\n\nexport interface ContextDialogProps {\n usage?: ContextUsage\n open: boolean\n onOpenChange: (open: boolean) => void\n className?: string\n}\n\nexport function ContextDialog({ usage, open, onOpenChange, className }: ContextDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className={className}>\n <DialogHeader title=\"Context\" description={usage?.model} />\n <DialogBody>\n {!usage ? (\n <p className=\"py-6 text-center text-body-sm text-fg-4\">\n No reading yet — the context window is measured after a turn completes.\n </p>\n ) : (\n <>\n <div className=\"flex items-baseline justify-between gap-4\">\n <span className=\"text-label text-fg-3\">Used</span>\n <span className=\"font-mono text-body-sm text-fg-1\">\n {formatTokens(usage.totalTokens)} / {formatTokens(usage.maxTokens)} · {usage.percentage.toFixed(0)}%\n </span>\n </div>\n <div className=\"mt-2 h-2 overflow-hidden rounded-full bg-border\">\n <div\n className={cn('h-full rounded-full', meterTintClass(usage.percentage))}\n style={{ width: `${Math.min(100, Math.max(2, usage.percentage))}%` }}\n />\n </div>\n {usage.categories.length > 0 ? (\n <div className=\"mt-5\">\n <h3 className=\"text-label font-medium text-fg-3\">Breakdown</h3>\n <div className=\"mt-2 flex flex-col gap-3\">\n {usage.categories.map((category) => {\n const share = (category.tokens / Math.max(usage.maxTokens, 1)) * 100\n const color = cssColor(category.color)\n return (\n <div key={category.name}>\n <div className=\"flex items-baseline justify-between gap-3\">\n <span className=\"flex min-w-0 items-center gap-2\">\n <span\n className=\"size-2 shrink-0 rounded-full bg-fg-4\"\n style={color ? { backgroundColor: color } : undefined}\n />\n <span className=\"truncate text-body-sm text-fg-1\">{category.name}</span>\n </span>\n <span className=\"shrink-0 font-mono text-label text-fg-3\">{formatTokens(category.tokens)}</span>\n </div>\n <div className=\"mt-1 h-1 overflow-hidden rounded-full bg-border\">\n <div\n className=\"h-full rounded-full bg-fg-4\"\n style={{\n width: `${Math.min(100, share)}%`,\n backgroundColor: color,\n }}\n />\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : null}\n </>\n )}\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n","import { File, Folder, Link2 } from 'lucide-react'\nimport type { HostDirEntry } from '@workerdeck/protocol'\n\n/**\n * The icon for one host directory entry. A symlink is drawn as a link and never silently\n * resolved — the caller decides what a symlink means, the tree only says it is one.\n */\nexport function EntryIcon({ type }: { type: HostDirEntry['type'] }) {\n if (type === 'dir') {\n return <Folder className=\"size-3.5 shrink-0 text-accent\" />\n }\n if (type === 'symlink') {\n return <Link2 className=\"size-3.5 shrink-0 text-fg-4\" />\n }\n return <File className=\"size-3.5 shrink-0 text-fg-4\" />\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { WorkerDeckClient } from '@workerdeck/client'\nimport type { HostDirEntry, HostFileMatch } from '@workerdeck/protocol'\nimport { ChevronLeft, File, Search } from 'lucide-react'\nimport { Button } from '../ui/Button.tsx'\nimport { CodeBlock } from '../ui/CodeBlock.tsx'\nimport { Dialog, DialogBody, DialogContent, DialogHeader } from '../ui/Dialog.tsx'\nimport { Input } from '../ui/Input.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { formatBytes } from '../../lib/format.ts'\nimport { EntryIcon } from './EntryIcon.tsx'\n\nexport interface HostFilesDialogProps {\n client: WorkerDeckClient\n cwd: string | undefined\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nexport function HostFilesDialog({ client, cwd, open, onOpenChange }: HostFilesDialogProps) {\n const [path, setPath] = useState<string | undefined>(cwd)\n const [entries, setEntries] = useState<HostDirEntry[]>([])\n const [truncated, setTruncated] = useState(false)\n const [query, setQuery] = useState('')\n const [matches, setMatches] = useState<HostFileMatch[] | undefined>()\n const [file, setFile] = useState<{ path: string; content: string; bytes: number } | undefined>()\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | undefined>()\n\n const list = useCallback(\n async (target: string) => {\n setLoading(true)\n setError(undefined)\n try {\n const response = await client.listHostDir(target)\n setPath(response.path)\n setEntries(response.entries)\n setTruncated(response.truncated ?? false)\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Could not read that directory')\n } finally {\n setLoading(false)\n }\n },\n [client],\n )\n\n useEffect(() => {\n if (!open) {\n return\n }\n setFile(undefined)\n setQuery('')\n setMatches(undefined)\n setError(undefined)\n if (cwd) {\n void list(cwd)\n }\n }, [open, cwd, list])\n\n useEffect(() => {\n if (!open || !cwd) {\n return\n }\n const q = query.trim()\n if (!q) {\n setMatches(undefined)\n return\n }\n const timer = setTimeout(() => {\n client\n .findHostFiles(cwd, q, 40)\n .then((response) => setMatches(response.matches))\n .catch(() => setMatches([]))\n }, 150)\n return () => clearTimeout(timer)\n }, [client, cwd, query, open])\n\n const openFile = async (target: string) => {\n setLoading(true)\n setError(undefined)\n try {\n const response = await client.readHostFile(target)\n setFile({\n path: response.path,\n bytes: response.bytes,\n content: response.encoding === 'utf8' ? response.content : '(binary file — not shown)',\n })\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Could not read that file')\n } finally {\n setLoading(false)\n }\n }\n\n const parent = path && cwd && path !== cwd ? path.slice(0, path.lastIndexOf('/')) || '/' : undefined\n const shown = matches ?? entries\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent size=\"lg\">\n <DialogHeader\n title={file ? file.path.split('/').pop()! : 'Files'}\n description={file ? file.path : path}\n actions={\n file ? (\n <Button variant=\"ghost\" size=\"xs\" onClick={() => setFile(undefined)}>\n <ChevronLeft className=\"size-3.5\" />\n Back\n </Button>\n ) : parent ? (\n <Button variant=\"ghost\" size=\"xs\" onClick={() => void list(parent)}>\n <ChevronLeft className=\"size-3.5\" />\n Up\n </Button>\n ) : null\n }\n />\n <DialogBody className=\"flex flex-col gap-3\">\n {error ? <div className=\"rounded-md bg-danger-bg px-3 py-2 text-body-sm text-danger\">{error}</div> : null}\n\n {file ? (\n <>\n <p className=\"text-label text-fg-4\">{formatBytes(file.bytes)}</p>\n <CodeBlock code={file.content} label={file.path.split('/').pop()} />\n </>\n ) : (\n <>\n <div className=\"relative\">\n <Search className=\"absolute top-1/2 left-2 size-3.5 -translate-y-1/2 text-fg-4\" />\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search this project…\"\n className=\"pl-7\"\n spellCheck={false}\n />\n </div>\n {loading && shown.length === 0 ? (\n <div className=\"py-6 text-center\">\n <Spinner className=\"size-4 text-fg-4\" />\n </div>\n ) : shown.length === 0 ? (\n <p className=\"py-6 text-center text-body-sm text-fg-4\">{matches ? 'No matching files.' : 'This directory is empty.'}</p>\n ) : (\n <ul className=\"flex flex-col\">\n {matches\n ? matches.map((match) => (\n <li key={match.path}>\n <button\n type=\"button\"\n onClick={() => void openFile(match.path)}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-surface-hover\"\n >\n <File className=\"size-3.5 shrink-0 text-fg-4\" />\n <span className=\"min-w-0 flex-1 truncate font-mono text-label text-fg-1\">{match.relative}</span>\n </button>\n </li>\n ))\n : entries.map((entry) => (\n <li key={entry.path}>\n <button\n type=\"button\"\n onClick={() => (entry.type === 'dir' ? void list(entry.path) : void openFile(entry.path))}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-surface-hover\"\n >\n <EntryIcon type={entry.type} />\n <span className=\"min-w-0 flex-1 truncate font-mono text-label text-fg-1\">\n {entry.name}\n {entry.type === 'dir' ? '/' : ''}\n </span>\n {entry.bytes !== undefined ? (\n <span className=\"shrink-0 text-label text-fg-4\">{formatBytes(entry.bytes)}</span>\n ) : null}\n </button>\n </li>\n ))}\n </ul>\n )}\n {truncated && !matches ? (\n <p className=\"text-label text-fg-4\">More entries than the server will return — use the search box.</p>\n ) : null}\n </>\n )}\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { WorkerDeckClient } from '@workerdeck/client'\nimport type { McpServerActionRequest, McpServerStatusInfo, McpServerToolInfo } from '@workerdeck/protocol'\nimport { ChevronLeft, ChevronRight, Power, PowerOff, RotateCw } from 'lucide-react'\nimport { Badge, type BadgeProps } from '../ui/Badge.tsx'\nimport { Button } from '../ui/Button.tsx'\nimport { Dialog, DialogBody, DialogContent, DialogHeader, DialogRow } from '../ui/Dialog.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface McpDialogProps {\n client: WorkerDeckClient\n sessionId: string | undefined\n open: boolean\n onOpenChange: (open: boolean) => void\n canManageServers?: boolean\n className?: string\n}\n\nconst STATUS_VARIANT: Record<string, NonNullable<BadgeProps['variant']>> = {\n connected: 'success',\n failed: 'danger',\n 'needs-auth': 'warning',\n pending: 'info',\n disabled: 'neutral',\n}\n\nexport function McpDialog({ client, sessionId, open, onOpenChange, canManageServers = true, className }: McpDialogProps) {\n const [servers, setServers] = useState<McpServerStatusInfo[] | undefined>()\n const [error, setError] = useState<string | undefined>()\n const [loading, setLoading] = useState(false)\n const [busyServer, setBusyServer] = useState<string | undefined>()\n const [selectedServer, setSelectedServer] = useState<string | undefined>()\n const [selectedTool, setSelectedTool] = useState<string | undefined>()\n\n const load = useCallback(async () => {\n if (!sessionId) {\n return\n }\n setLoading(true)\n setError(undefined)\n try {\n setServers(await client.listMcpServers(sessionId))\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Could not read MCP status')\n } finally {\n setLoading(false)\n }\n }, [client, sessionId])\n\n useEffect(() => {\n if (!open) {\n return\n }\n setSelectedServer(undefined)\n setSelectedTool(undefined)\n void load()\n }, [open, load])\n\n const act = async (name: string, action: McpServerActionRequest['action']) => {\n if (!sessionId) {\n return\n }\n setBusyServer(name)\n setError(undefined)\n try {\n setServers(await client.mcpServerAction(sessionId, name, action))\n } catch (e) {\n setError(e instanceof Error ? e.message : `Could not ${action} ${name}`)\n } finally {\n setBusyServer(undefined)\n }\n }\n\n const server = servers?.find((s) => s.name === selectedServer)\n const tool = server?.tools?.find((t) => t.name === selectedTool)\n const title = tool?.name ?? server?.name ?? 'MCP servers'\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className={className}>\n <DialogHeader\n title={title}\n description={tool ? `${server?.name} tool` : server ? server.serverInfo?.name : undefined}\n actions={\n selectedServer ? (\n <Button variant=\"ghost\" size=\"xs\" onClick={() => (selectedTool ? setSelectedTool(undefined) : setSelectedServer(undefined))}>\n <ChevronLeft className=\"size-3.5\" />\n Back\n </Button>\n ) : (\n <Button variant=\"ghost\" size=\"xs\" onClick={() => void load()} disabled={loading}>\n {loading ? <Spinner className=\"size-3 text-current\" /> : <RotateCw className=\"size-3\" />}\n Refresh\n </Button>\n )\n }\n />\n <DialogBody>\n {error ? <div className=\"mb-3 rounded-md bg-danger-bg px-3 py-2 text-body-sm text-danger\">{error}</div> : null}\n {tool ? (\n <ToolView tool={tool} />\n ) : server ? (\n <ServerView\n server={server}\n busy={busyServer === server.name}\n canManage={canManageServers}\n onAct={(action) => void act(server.name, action)}\n onSelectTool={setSelectedTool}\n />\n ) : error && !servers ? null : (\n <ServerList servers={servers} loading={loading} onSelect={setSelectedServer} />\n )}\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction ServerList({\n servers,\n loading,\n onSelect,\n}: {\n servers: McpServerStatusInfo[] | undefined\n loading: boolean\n onSelect: (name: string) => void\n}) {\n if (loading && !servers) {\n return (\n <div className=\"py-6 text-center\">\n <Spinner className=\"size-4 text-fg-4\" />\n </div>\n )\n }\n if (!servers?.length) {\n return <p className=\"py-6 text-center text-body-sm text-fg-4\">No MCP servers configured for this session.</p>\n }\n const scopes = [...new Set(servers.map((s) => s.scope ?? 'other'))]\n return (\n <div className=\"flex flex-col gap-4\">\n {scopes.map((scope) => (\n <div key={scope}>\n <h3 className=\"text-label font-medium text-fg-3 capitalize\">{scope}</h3>\n <ul className=\"mt-1 flex flex-col\">\n {servers\n .filter((s) => (s.scope ?? 'other') === scope)\n .map((s) => (\n <li key={s.name}>\n <button\n type=\"button\"\n onClick={() => onSelect(s.name)}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-2 text-left transition-colors hover:bg-surface-hover\"\n >\n <span className=\"min-w-0 flex-1 truncate text-body-sm text-fg-1\">{s.name}</span>\n {s.tools?.length ? <span className=\"shrink-0 text-label text-fg-4\">{s.tools.length} tools</span> : null}\n <Badge variant={STATUS_VARIANT[s.status] ?? 'neutral'} dot className=\"shrink-0\">\n {s.status}\n </Badge>\n <ChevronRight className=\"size-3.5 shrink-0 text-fg-4\" />\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n )\n}\n\nfunction ServerView({\n server,\n busy,\n canManage,\n onAct,\n onSelectTool,\n}: {\n server: McpServerStatusInfo\n busy: boolean\n canManage: boolean\n onAct: (action: McpServerActionRequest['action']) => void\n onSelectTool: (name: string) => void\n}) {\n const disabled = server.status === 'disabled'\n return (\n <div className=\"flex flex-col gap-4\">\n <div>\n <DialogRow label=\"Status\">\n <Badge variant={STATUS_VARIANT[server.status] ?? 'neutral'} dot>\n {server.status}\n </Badge>\n </DialogRow>\n {server.transport ? <DialogRow label=\"Transport\">{server.transport}</DialogRow> : null}\n {server.scope ? <DialogRow label=\"Scope\">{server.scope}</DialogRow> : null}\n {server.serverInfo ? (\n <DialogRow label=\"Server\">\n {server.serverInfo.name} {server.serverInfo.version}\n </DialogRow>\n ) : null}\n {server.command ? (\n <DialogRow label=\"Command\" mono>\n {[server.command, ...(server.args ?? [])].join(' ')}\n </DialogRow>\n ) : null}\n {server.url ? (\n <DialogRow label=\"URL\" mono>\n {server.url}\n </DialogRow>\n ) : null}\n </div>\n\n {server.error ? <div className=\"rounded-md bg-danger-bg px-3 py-2 text-body-sm break-words text-danger\">{server.error}</div> : null}\n\n {canManage ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => onAct('reconnect')}>\n {busy ? <Spinner className=\"size-3 text-current\" /> : <RotateCw className=\"size-3\" />}\n Reconnect\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={busy} onClick={() => onAct(disabled ? 'enable' : 'disable')}>\n {disabled ? <Power className=\"size-3\" /> : <PowerOff className=\"size-3\" />}\n {disabled ? 'Enable' : 'Disable'}\n </Button>\n </div>\n ) : null}\n\n <div>\n <h3 className=\"text-label font-medium text-fg-3\">Tools</h3>\n {!server.tools?.length ? (\n <p className=\"py-2 text-body-sm text-fg-4\">\n {server.status === 'connected' ? 'This server exposes no tools.' : 'Tools are listed once the server connects.'}\n </p>\n ) : (\n <ul className=\"mt-1 flex flex-col\">\n {server.tools.map((t) => (\n <li key={t.name}>\n <button\n type=\"button\"\n onClick={() => onSelectTool(t.name)}\n className=\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-surface-hover\"\n >\n <span className=\"min-w-0 flex-1 truncate font-mono text-label text-fg-1\">{t.name}</span>\n <ChevronRight className=\"size-3.5 shrink-0 text-fg-4\" />\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n )\n}\n\nfunction ToolView({ tool }: { tool: McpServerToolInfo }) {\n const annotations = tool.annotations\n return (\n <div className=\"flex flex-col gap-3\">\n {tool.description ? (\n <p className=\"text-body-sm whitespace-pre-wrap text-fg-2\">{tool.description}</p>\n ) : (\n <p className=\"text-body-sm text-fg-4\">This tool carries no description.</p>\n )}\n {annotations ? (\n <div className=\"flex flex-wrap gap-1.5\">\n {annotations.readOnly ? <Badge variant=\"success\">read-only</Badge> : null}\n {annotations.destructive ? <Badge variant=\"danger\">destructive</Badge> : null}\n {annotations.openWorld ? <Badge variant=\"warning\">open world</Badge> : null}\n </div>\n ) : null}\n {tool.inputSchema !== undefined ? (\n <div>\n <h3 className=\"text-label font-medium text-fg-3\">Parameters</h3>\n <pre className=\"mt-1 max-h-64 overflow-auto rounded-md bg-surface px-3 py-2 text-label text-fg-2\">\n {safeSchema(tool.inputSchema)}\n </pre>\n </div>\n ) : (\n <p className={cn('text-label text-fg-4')}>\n Parameters aren’t available: this engine names and describes each tool but reports no input schema.\n </p>\n )}\n </div>\n )\n}\n\nfunction safeSchema(schema: unknown): string {\n try {\n return JSON.stringify(schema, null, 2)\n } catch {\n return String(schema)\n }\n}\n","import { useState } from 'react'\nimport type { SkillInfo } from '@workerdeck/protocol'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { Button } from '../ui/Button.tsx'\nimport { Dialog, DialogBody, DialogContent, DialogHeader, DialogRow } from '../ui/Dialog.tsx'\n\nexport interface SkillsDialogProps {\n skills: SkillInfo[] | undefined\n open: boolean\n onOpenChange: (open: boolean) => void\n onUse?: (skill: SkillInfo) => void\n className?: string\n}\n\nconst SCOPE_LABEL: Record<string, string> = {\n user: 'Personal',\n repo: 'This project',\n system: 'System',\n admin: 'Managed',\n}\n\nexport function SkillsDialog({ skills, open, onOpenChange, onUse, className }: SkillsDialogProps) {\n const [selected, setSelected] = useState<string | undefined>()\n const skill = skills?.find((s) => s.name === selected)\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next) {\n setSelected(undefined)\n }\n onOpenChange(next)\n }}\n >\n <DialogContent className={className}>\n <DialogHeader\n title={skill ? (skill.displayName ?? skill.name) : 'Skills'}\n description={\n skill\n ? skill.name !== (skill.displayName ?? skill.name)\n ? skill.name\n : undefined\n : 'Capabilities the agent can choose to use. Not commands — the model picks them from their descriptions.'\n }\n actions={\n skill ? (\n <Button variant=\"ghost\" size=\"xs\" onClick={() => setSelected(undefined)}>\n <ChevronLeft className=\"size-3.5\" />\n Back\n </Button>\n ) : undefined\n }\n />\n <DialogBody>\n {skill ? (\n <SkillView skill={skill} onUse={onUse} onUsed={() => onOpenChange(false)} />\n ) : (\n <SkillList skills={skills} onSelect={setSelected} />\n )}\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction SkillList({ skills, onSelect }: { skills: SkillInfo[] | undefined; onSelect: (name: string) => void }) {\n if (!skills) {\n return <p className=\"py-6 text-center text-body-sm text-fg-4\">Skills are listed once the session connects — send a message first.</p>\n }\n if (skills.length === 0) {\n return <p className=\"py-6 text-center text-body-sm text-fg-4\">This session found no skills.</p>\n }\n const scopes = [...new Set(skills.map((s) => s.scope ?? 'other'))]\n return (\n <div className=\"flex flex-col gap-4\">\n {scopes.map((scope) => (\n <div key={scope}>\n <h3 className=\"text-label font-medium text-fg-3\">{SCOPE_LABEL[scope] ?? scope}</h3>\n <ul className=\"mt-1 flex flex-col\">\n {skills\n .filter((s) => (s.scope ?? 'other') === scope)\n .map((s) => (\n <li key={s.name}>\n <button\n type=\"button\"\n onClick={() => onSelect(s.name)}\n className=\"flex w-full items-start gap-2 rounded-md px-2 py-2 text-left transition-colors hover:bg-surface-hover\"\n >\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-body-sm text-fg-1\">{s.displayName ?? s.name}</span>\n {(s.shortDescription ?? s.description) ? (\n <span className=\"block truncate text-label text-fg-4\">{s.shortDescription ?? s.description}</span>\n ) : null}\n </span>\n {!s.enabled ? (\n <Badge variant=\"neutral\" className=\"mt-0.5 shrink-0\">\n off\n </Badge>\n ) : null}\n <ChevronRight className=\"mt-0.5 size-3.5 shrink-0 text-fg-4\" />\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n )\n}\n\nfunction SkillView({ skill, onUse, onUsed }: { skill: SkillInfo; onUse?: (skill: SkillInfo) => void; onUsed: () => void }) {\n return (\n <div className=\"flex flex-col gap-4\">\n <div>\n {skill.scope ? <DialogRow label=\"Scope\">{SCOPE_LABEL[skill.scope] ?? skill.scope}</DialogRow> : null}\n <DialogRow label=\"Status\">\n <Badge variant={skill.enabled ? 'success' : 'neutral'} dot>\n {skill.enabled ? 'enabled' : 'disabled'}\n </Badge>\n </DialogRow>\n </div>\n {skill.description ? (\n <div>\n <h3 className=\"text-label font-medium text-fg-3\">Description</h3>\n <p className=\"mt-1 text-body-sm whitespace-pre-wrap text-fg-2\">{skill.description}</p>\n </div>\n ) : (\n <p className=\"text-body-sm text-fg-4\">This skill carries no description.</p>\n )}\n {onUse && skill.enabled ? (\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n onUse(skill)\n onUsed()\n }}\n >\n Use this skill\n </Button>\n <p className=\"mt-1.5 text-label text-fg-4\">\n Writes an opening message into the composer for you to edit — it isn’t sent, and there is no command that runs a skill directly.\n </p>\n </div>\n ) : null}\n </div>\n )\n}\n","import type { ModelOption } from '@workerdeck/protocol'\nimport { Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue } from '../ui/Select.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface ModelSelectProps {\n models: ModelOption[]\n model?: string\n onModelChange: (model?: string) => void\n variant?: 'toolbar' | 'form'\n disabled?: boolean\n className?: string\n}\n\nfunction isDefaultOption(value: string) {\n return value === 'default'\n}\n\nfunction dropVariant(id: string) {\n return id.replace(/\\[.*\\]$/, '')\n}\n\nfunction family(id: string): string {\n const parts = id.toLowerCase().split('-')\n if (parts[0] === 'claude') {\n parts.shift()\n }\n return parts[0] ?? ''\n}\n\nfunction optionMatches(option: ModelOption, model: string): boolean {\n if (model === option.value || model === option.resolvedModel) {\n return true\n }\n const stripped = dropVariant(model)\n if (option.resolvedModel) {\n return stripped === dropVariant(option.resolvedModel)\n }\n const token = family(stripped)\n return token !== '' && token === family(dropVariant(option.value))\n}\n\nfunction matchModel(models: ModelOption[], model?: string): ModelOption | undefined {\n if (!model) {\n return undefined\n }\n return models.filter((m) => !isDefaultOption(m.value)).find((m) => optionMatches(m, model))\n}\n\nexport function ModelSelect({ models, model, onModelChange, variant = 'toolbar', disabled, className }: ModelSelectProps) {\n const selected = matchModel(models, model) ?? (model ? undefined : models.find((m) => isDefaultOption(m.value)))\n return (\n <Select\n items={models.map((m) => ({ value: m.value, label: m.displayName }))}\n value={selected?.value ?? null}\n onValueChange={(value) => {\n if (typeof value !== 'string' || value === selected?.value) {\n return\n }\n onModelChange(isDefaultOption(value) ? undefined : value)\n }}\n disabled={disabled}\n >\n <SelectTrigger\n aria-label=\"Model\"\n className={cn(\n variant === 'toolbar' && 'h-6 max-w-56 border-transparent bg-transparent text-fg-3 hover:bg-surface-hover',\n className,\n )}\n >\n <span className={cn('truncate', variant === 'toolbar' && 'font-mono text-label')}>\n <SelectValue placeholder={model ?? 'model'} />\n </span>\n </SelectTrigger>\n <SelectContent className=\"min-w-72\">\n {models.map((m) => (\n <SelectItem key={m.value} value={m.value}>\n <SelectItemText>\n <span className=\"font-medium\">{m.displayName}</span>\n </SelectItemText>\n {m.description ? <span className=\"text-label text-fg-4\">{m.description}</span> : null}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n","import type { LucideIcon } from 'lucide-react'\nimport type { PermissionMode } from '@workerdeck/protocol'\nimport { ClipboardList, Code, Hand, ShieldCheck, TriangleAlert, Zap } from 'lucide-react'\nimport { Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue } from '../ui/Select.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport type PermissionModeMeta = {\n value: PermissionMode\n label: string\n shortLabel: string\n description: string\n icon: LucideIcon\n dangerous?: boolean\n}\n\nexport const PERMISSION_MODES: PermissionModeMeta[] = [\n {\n value: 'default',\n label: 'Manual',\n shortLabel: 'Manual',\n description: 'Always ask before making changes',\n icon: Hand,\n },\n {\n value: 'acceptEdits',\n label: 'Accept edits',\n shortLabel: 'Edits',\n description: 'Automatically accept all file edits',\n icon: Code,\n },\n {\n value: 'plan',\n label: 'Plan',\n shortLabel: 'Plan',\n description: 'Create a plan before making changes',\n icon: ClipboardList,\n },\n {\n value: 'auto',\n label: 'Auto',\n shortLabel: 'Auto',\n description: 'The agent handles permission decisions',\n icon: Zap,\n },\n {\n value: 'dontAsk',\n label: \"Don't ask\",\n shortLabel: \"Don't ask\",\n description: 'Never ask — deny anything not pre-approved',\n icon: ShieldCheck,\n },\n {\n value: 'bypassPermissions',\n label: 'Bypass permissions',\n shortLabel: 'Bypass',\n description: 'Skip every approval — the agent is unsupervised',\n icon: TriangleAlert,\n dangerous: true,\n },\n]\n\nexport function permissionModeMeta(mode: PermissionMode): PermissionModeMeta | undefined {\n return PERMISSION_MODES.find((m) => m.value === mode)\n}\n\nexport type PermissionModeChoice = {\n value: PermissionMode\n label: string\n description: string\n dangerous?: boolean\n disabled?: boolean\n}\n\nexport function permissionModeChoices(modes?: readonly PermissionMode[], canBypass?: boolean): PermissionModeChoice[] {\n const offered = modes ? PERMISSION_MODES.filter((m) => modes.includes(m.value)) : PERMISSION_MODES\n return offered.map((m) => ({\n value: m.value,\n label: m.label,\n description:\n m.value === 'bypassPermissions' && canBypass === false ? 'Only available to a session started in this mode' : m.description,\n dangerous: m.dangerous,\n disabled: m.value === 'bypassPermissions' && canBypass === false,\n }))\n}\n\nexport interface PermissionModeSelectProps {\n mode?: PermissionMode\n onModeChange: (mode: PermissionMode) => void\n modes?: readonly PermissionMode[]\n canBypass?: boolean\n variant?: 'toolbar' | 'form'\n disabled?: boolean\n className?: string\n}\n\nexport function PermissionModeSelect({\n mode,\n onModeChange,\n modes,\n canBypass,\n variant = 'toolbar',\n disabled,\n className,\n}: PermissionModeSelectProps) {\n const dangerous = mode === 'bypassPermissions'\n const offered = modes ? PERMISSION_MODES.filter((m) => modes.includes(m.value)) : PERMISSION_MODES\n const unavailable = (meta: PermissionModeMeta) => meta.value === 'bypassPermissions' && canBypass === false\n return (\n <Select\n items={offered.map((m) => ({ value: m.value, label: m.label }))}\n value={mode ?? null}\n onValueChange={(value) => {\n if (typeof value === 'string' && value !== mode) {\n onModeChange(value as PermissionMode)\n }\n }}\n disabled={disabled}\n >\n <SelectTrigger\n aria-label=\"Permission mode\"\n className={cn(\n variant === 'toolbar' && 'h-6 max-w-44 border-transparent bg-transparent hover:bg-surface-hover',\n dangerous ? 'text-danger' : variant === 'toolbar' ? 'text-fg-3' : undefined,\n className,\n )}\n >\n <span className={cn('truncate', variant === 'toolbar' && 'text-label')}>\n <SelectValue placeholder=\"permissions\" />\n </span>\n </SelectTrigger>\n <SelectContent className=\"min-w-64\">\n {offered.map((m) => {\n const blocked = unavailable(m)\n return (\n <SelectItem key={m.value} value={m.value} disabled={blocked}>\n <SelectItemText>\n <span className=\"flex items-center gap-2\">\n <m.icon className={cn('size-3.5 shrink-0', m.dangerous ? 'text-danger' : 'text-fg-3')} />\n <span className={cn('font-medium', m.dangerous && 'text-danger')}>{m.label}</span>\n </span>\n </SelectItemText>\n <span className={cn('pl-5.5 text-label', blocked ? 'text-fg-4' : m.dangerous ? 'text-danger/80' : 'text-fg-4')}>\n {blocked ? 'Only available to a session started in this mode' : m.description}\n </span>\n </SelectItem>\n )\n })}\n </SelectContent>\n </Select>\n )\n}\n","type PlanRequestLike = { toolName?: unknown; input?: unknown }\n\nexport function planFromRequest(request: PlanRequestLike | null | undefined): string | undefined {\n if (request?.toolName !== 'ExitPlanMode') {\n return undefined\n }\n const input = request.input\n if (input === null || typeof input !== 'object') {\n return undefined\n }\n const plan = (input as { plan?: unknown }).plan\n if (typeof plan !== 'string' || plan.trim().length === 0) {\n return undefined\n }\n return plan\n}\n","import { memo } from 'react'\nimport { Streamdown } from 'streamdown'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface ResponseProps {\n children: string\n streaming?: boolean\n className?: string\n}\n\nexport const Response = memo(\n function Response({ children, streaming, className }: ResponseProps) {\n return (\n <Streamdown\n mode={streaming ? 'streaming' : 'static'}\n parseIncompleteMarkdown={streaming}\n shikiTheme={['github-light', 'github-dark']}\n linkSafety={{ enabled: false }}\n className={cn('size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0', className)}\n >\n {children}\n </Streamdown>\n )\n },\n (prev, next) => prev.children === next.children && prev.streaming === next.streaming && prev.className === next.className,\n)\n","import { useState } from 'react'\nimport type { PermissionRequest } from '@workerdeck/protocol'\nimport { Hand } from 'lucide-react'\nimport { Button } from '../ui/Button.tsx'\nimport { Input } from '../ui/Input.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { toolInputPreview } from '../../lib/format.ts'\nimport { planFromRequest } from '../../lib/plan-request.ts'\nimport { toolIcon } from '../../lib/tool-icon.ts'\nimport { Response } from './Response.tsx'\n\nexport interface PermissionPromptProps {\n request: PermissionRequest\n onApprove: (requestId: string) => void\n onDeny: (requestId: string, message?: string, interrupt?: boolean) => void\n className?: string\n}\n\nexport function PermissionPrompt({ request, onApprove, onDeny, className }: PermissionPromptProps) {\n const [showInput, setShowInput] = useState(false)\n const [denying, setDenying] = useState(false)\n const [reason, setReason] = useState('')\n\n const deny = (interrupt: boolean) => {\n const message = reason.trim()\n onDeny(request.id, message || undefined, interrupt || undefined)\n setReason('')\n setDenying(false)\n }\n\n const plan = planFromRequest(request)\n const summary = toolInputPreview(request.input)\n const ToolIcon = toolIcon(request.toolName)\n\n return (\n <div data-slot=\"permission-prompt\" className={cn('rounded-lg border border-warning/40 bg-warning-bg p-3', className)}>\n <div className=\"flex items-start gap-2.5\">\n <Hand className=\"mt-0.5 size-4 shrink-0 text-warning\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-body-sm font-medium text-fg-1\">\n {plan ? 'Plan ready for review' : (request.title ?? request.displayName ?? 'Permission needed')}\n </div>\n {request.description ? <div className=\"mt-0.5 text-label text-fg-3\">{request.description}</div> : null}\n {request.decisionReason ? <div className=\"mt-0.5 text-label text-fg-4\">{request.decisionReason}</div> : null}\n {plan ? (\n <div className=\"mt-1.5 max-h-72 overflow-y-auto rounded-md bg-code-bg px-2.5 py-2 text-body-sm text-fg-2\">\n <Response>{plan}</Response>\n </div>\n ) : (\n <>\n <div className=\"mt-1.5 flex min-w-0 items-center gap-2\">\n <ToolIcon className=\"size-3 shrink-0 text-fg-3\" />\n <span className=\"shrink-0 font-mono text-label font-medium text-fg-2\">{request.toolName}</span>\n {summary ? <span className=\"min-w-0 truncate font-mono text-label text-fg-4\">{summary}</span> : null}\n </div>\n <button\n type=\"button\"\n className=\"mt-1 font-mono text-label text-fg-3 underline-offset-2 hover:underline\"\n onClick={() => setShowInput((v) => !v)}\n >\n {showInput ? 'Hide' : 'Show'} {request.toolName} input\n </button>\n {showInput ? (\n <pre className=\"mt-1.5 max-h-48 overflow-auto rounded-md bg-code-bg px-2.5 py-1.5 font-mono text-label whitespace-pre-wrap text-fg-2\">\n {JSON.stringify(request.input, null, 2)}\n </pre>\n ) : null}\n </>\n )}\n </div>\n <div className=\"flex shrink-0 flex-wrap justify-end gap-1.5\">\n <Button size=\"sm\" onClick={() => onApprove(request.id)}>\n {plan ? 'Approve plan' : 'Allow'}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setDenying((v) => !v)}>\n {plan ? 'Keep planning' : 'Deny'}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => deny(true)}>\n {plan ? 'Stop the turn' : 'Deny & stop'}\n </Button>\n </div>\n </div>\n {denying ? (\n <div className=\"mt-2.5 flex items-center gap-2 border-t border-warning/30 pt-2.5\">\n <Input\n autoFocus\n value={reason}\n onChange={(e) => setReason(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n deny(false)\n }\n if (e.key === 'Escape') {\n setDenying(false)\n }\n }}\n placeholder={\n plan\n ? 'What should change? (optional) — the agent keeps planning and reads this'\n : 'Reason (optional) — the agent reads this and can try something else'\n }\n className=\"h-7 flex-1\"\n />\n <Button size=\"sm\" variant=\"outline\" onClick={() => setDenying(false)}>\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"destructive\" onClick={() => deny(false)}>\n {plan ? 'Keep planning' : 'Deny'}\n </Button>\n </div>\n ) : null}\n </div>\n )\n}\n","import { ArrowLeft } from 'lucide-react'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\nimport { formatDuration } from '../../lib/format.ts'\nimport { Button } from '../ui/Button.tsx'\nimport { Ink, Row } from '../terminal/row.tsx'\nimport { TerminalSurface } from '../terminal/surface.tsx'\nimport { taskBusy, taskFailed, taskIdentity } from '../terminal/tool-run.ts'\nimport type { ToolCallItem } from '../terminal/blocks.ts'\nimport { usePulse } from './pulse.tsx'\nimport { useTicker } from '../terminal/items.tsx'\n\nexport function SubagentStrip({\n task,\n items,\n label,\n onBack,\n terminal,\n fontSize,\n lineHeight,\n}: {\n task: ToolCallItem | undefined\n items: readonly TranscriptItem[]\n label: string\n onBack: () => void\n terminal: boolean\n fontSize?: number\n lineHeight?: number\n}) {\n const busy = task ? taskBusy(task, items) : false\n const failed = task ? taskFailed(task) : false\n const pulse = usePulse(busy)\n const tools = items.reduce((n, item) => n + (item.kind === 'tool_call' ? 1 : 0), 0)\n const startedAt = busy ? task?.ts : undefined\n const now = useTicker(startedAt !== undefined)\n const elapsed = startedAt === undefined ? undefined : formatDuration(now - startedAt)\n\n const name = task ? taskIdentity(task) : label\n const status = !task ? undefined : failed ? 'failed' : busy ? `${pulse} working…` : 'done'\n const detail = [tools > 0 ? `${tools} tool${tools === 1 ? '' : 's'}` : undefined, elapsed].filter(Boolean).join(' · ')\n\n if (terminal) {\n return (\n <TerminalSurface fontSize={fontSize} lineHeight={lineHeight} className=\"shrink-0\">\n <button type=\"button\" onClick={onBack} aria-label=\"Back to the session\" className=\"block w-full cursor-pointer text-left\">\n <Row glyph=\"←\" glyphTone=\"dim\" indent={1} tone={failed ? 'red' : 'green'}>\n {name}\n {status ? <Ink tone={failed ? 'red' : busy ? 'mark' : 'dim'}> · {status}</Ink> : null}\n {detail ? <Ink tone=\"faint\"> · {detail}</Ink> : null}\n </Row>\n </button>\n </TerminalSurface>\n )\n }\n\n return (\n <div className=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-1.5\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack} className=\"h-6 gap-1 px-1.5\">\n <ArrowLeft className=\"size-3.5\" />\n Back\n </Button>\n <span className={cn('min-w-0 flex-1 truncate text-body-sm', failed ? 'text-danger' : 'text-fg-2')}>{name}</span>\n {status ? (\n <span className={cn('shrink-0 text-label', failed ? 'text-danger' : busy ? 'text-accent' : 'text-fg-3')}>{status}</span>\n ) : null}\n {detail ? <span className=\"shrink-0 text-label text-fg-4\">{detail}</span> : null}\n </div>\n )\n}\n","import type { TranscriptItem } from '@workerdeck/react'\nimport { foldsTogether } from './tool-run.ts'\n\nexport type ToolCallItem = Extract<TranscriptItem, { kind: 'tool_call' }>\n\n// `user` items carry `parentToolUseId` only optionally (only a subagent's brief has the key); the other kinds carry it as `string | null`.\nexport function parentOf(item: TranscriptItem): string | undefined {\n const parent = 'parentToolUseId' in item ? item.parentToolUseId : undefined\n return parent ?? undefined\n}\n\nexport function subagentItems(items: readonly TranscriptItem[], parentToolUseId: string): TranscriptItem[] {\n return items.filter((item) => parentOf(item) === parentToolUseId)\n}\n\nexport function isRunCall(item: TranscriptItem): item is ToolCallItem {\n return item.kind === 'tool_call'\n}\n\nexport type ItemBlock = { key: string; item: TranscriptItem; index: number }\nexport type RunBlock = {\n key: string\n run: ToolCallItem[]\n indices: number[]\n index: number\n}\nexport type LeafBlock = ItemBlock | RunBlock\n\nexport type TaskBlock = {\n key: string\n task: ToolCallItem\n children: LeafBlock[]\n childIndices: number[]\n index: number\n}\n\nexport type TerminalBlock = ItemBlock | RunBlock | TaskBlock\n\nexport function taskChildItems(block: TaskBlock): TranscriptItem[] {\n return block.children.flatMap((child) => ('run' in child ? child.run : [child.item]))\n}\n\nfunction pushLeaf(out: LeafBlock[], item: TranscriptItem, index: number): void {\n const previous = out.at(-1)\n if (isRunCall(item)) {\n if (previous && 'run' in previous && foldsTogether(previous.run[0]!, item)) {\n previous.run.push(item)\n previous.indices.push(index)\n } else {\n out.push({ key: `run:${item.id}`, run: [item], indices: [index], index })\n }\n return\n }\n out.push({ key: `${item.kind}:${item.id}`, item, index })\n}\n\nexport function terminalBlocks(items: readonly TranscriptItem[], offset = 0, fold = true): TerminalBlock[] {\n if (!fold) {\n return items.map((item, position) => ({\n key: `${item.kind}:${item.id}`,\n item,\n index: offset + position,\n }))\n }\n\n const topLevelCalls = new Set<string>()\n for (const item of items) {\n if (item.kind === 'tool_call' && parentOf(item) === undefined) {\n topLevelCalls.add(item.id)\n }\n }\n const childrenOf = new Map<string, { item: TranscriptItem; index: number }[]>()\n items.forEach((item, position) => {\n const parent = parentOf(item)\n if (parent !== undefined && topLevelCalls.has(parent)) {\n const list = childrenOf.get(parent)\n if (list) {\n list.push({ item, index: offset + position })\n } else {\n childrenOf.set(parent, [{ item, index: offset + position }])\n }\n }\n })\n\n const out: TerminalBlock[] = []\n for (const [position, item] of items.entries()) {\n const index = offset + position\n const parent = parentOf(item)\n if (parent !== undefined && childrenOf.has(parent)) {\n continue\n }\n if (item.kind === 'tool_call') {\n const children = childrenOf.get(item.id)\n if (children) {\n const folded: LeafBlock[] = []\n for (const child of children) {\n pushLeaf(folded, child.item, child.index)\n }\n out.push({\n key: `task:${item.id}`,\n task: item,\n children: folded,\n childIndices: children.map((child) => child.index),\n index,\n })\n continue\n }\n }\n pushLeaf(out as LeafBlock[], item, index)\n }\n return out\n}\n\nexport function needsBlank(previous: TranscriptItem, next: TranscriptItem): boolean {\n if (previous.kind === 'tool_call' && next.kind === 'tool_call') {\n return false\n }\n return true\n}\n\nexport function blockNeedsBlank(previous: TerminalBlock, next: TerminalBlock): boolean {\n const kind = (block: TerminalBlock) => ('item' in block ? block.item.kind : 'tool_call')\n return !(kind(previous) === 'tool_call' && kind(next) === 'tool_call')\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { subagentLabel, type SessionInfo } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { subagentItems, type ToolCallItem } from '../terminal/blocks.ts'\n\n/**\n * The sub-agent frame machine: which agent frame is on screen, how it is entered (a host\n * `openSubagent` request or a Task row in the transcript), how it is left (Escape, the strip's\n * Back, or the host withdrawing), and what the transcript reveals on the way out. The frame\n * round-trips through the host's URL — the anti-loop rules live in GOTCHAS (\"The sub-agent\n * frame round-trips through the URL\"); here they mean: entry keys on the nonce alone, and the\n * report is deduped through a ref, so an echo of our own report is inert on arrival.\n */\nexport function useSubagentFrame(options: {\n sessionId: string | undefined\n items: TranscriptItem[]\n session: SessionInfo | undefined\n /** Host request to reveal a transcript row; entering a frame must not eat a pending one. */\n reveal?: { toolUseId: string; nonce: number }\n /** Host request to enter a frame; `toolUseId: undefined` withdraws it (Back/Forward). */\n openSubagent?: { toolUseId: string; nonce: number }\n onSubagentChange?: (toolUseId: string | undefined) => void\n}) {\n const { sessionId, items, session, reveal, openSubagent, onSubagentChange } = options\n\n const [subagentId, setSubagentId] = useState<string | undefined>(undefined)\n const [returnReveal, setReturnReveal] = useState<{ toolUseId: string; nonce: number } | undefined>(undefined)\n useEffect(() => {\n setSubagentId(undefined)\n setReturnReveal(undefined)\n }, [sessionId])\n\n // Leaving a frame reveals the Task row it came from, so the reader lands where they left.\n const leaveSubagent = useCallback(() => {\n setSubagentId((current) => {\n if (current !== undefined) {\n setReturnReveal({ toolUseId: current, nonce: Date.now() })\n }\n return undefined\n })\n }, [])\n\n const openSubagentNonce = openSubagent?.nonce\n const openSubagentId = openSubagent?.toolUseId\n useEffect(() => {\n if (openSubagentId === undefined) {\n leaveSubagent()\n } else {\n setSubagentId(openSubagentId)\n }\n // Keyed on the nonce alone: an unchanged nonce is the host echoing our own report, and\n // acting on it starts the URL → panel → URL cycle.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [openSubagentNonce])\n\n // A reveal targets the root transcript, so it closes whatever frame is open — without the\n // return reveal, which would fight the requested one.\n const revealNonce = reveal?.nonce\n useEffect(() => {\n if (revealNonce === undefined) {\n return\n }\n setSubagentId(undefined)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [revealNonce])\n\n useEffect(() => {\n if (subagentId === undefined) {\n return\n }\n const onKey = (event: KeyboardEvent) => {\n if (event.key !== 'Escape' || event.defaultPrevented) {\n return\n }\n leaveSubagent()\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [subagentId, leaveSubagent])\n\n const onSubagentChangeRef = useRef(onSubagentChange)\n onSubagentChangeRef.current = onSubagentChange\n const reportedSubagentId = useRef<string | undefined>(undefined)\n useEffect(() => {\n if (reportedSubagentId.current === subagentId) {\n return\n }\n reportedSubagentId.current = subagentId\n onSubagentChangeRef.current?.(subagentId)\n }, [subagentId])\n\n const frameItems = useMemo(() => (subagentId === undefined ? [] : subagentItems(items, subagentId)), [items, subagentId])\n const task = useMemo(\n () =>\n subagentId === undefined\n ? undefined\n : items.find((item): item is ToolCallItem => item.kind === 'tool_call' && item.id === subagentId),\n [items, subagentId],\n )\n const fallbackLabel = useMemo(() => {\n const record = session?.subagents?.find((sub) => sub.toolUseId === subagentId)\n return record ? subagentLabel(record) : 'Sub-agent'\n }, [session, subagentId])\n\n return { subagentId, enterSubagent: setSubagentId, leaveSubagent, returnReveal, frameItems, task, fallbackLabel }\n}\n","import { useState } from 'react'\nimport type { PermissionRequest, QuestionBehavior, UserQuestion, UserQuestionOption } from '@workerdeck/protocol'\nimport { MessageCircleQuestion, X } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { Button } from '../ui/Button.tsx'\nimport { Input } from '../ui/Input.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport type QuestionBehaviorMeta = {\n value: QuestionBehavior\n label: string\n description: string\n}\n\nexport const QUESTION_BEHAVIORS: QuestionBehaviorMeta[] = [\n { value: 'auto', label: 'Auto-answer', description: 'pick each question’s recommended option' },\n { value: 'ask', label: 'Ask', description: 'wait for a watcher or webhook controller to answer' },\n { value: 'deny', label: 'Disabled', description: 'the agent is told to decide on its own' },\n]\n\nexport function parseUserQuestions(input: Record<string, unknown>): UserQuestion[] {\n const raw = Array.isArray(input.questions) ? input.questions : []\n return raw.flatMap((entry): UserQuestion[] => {\n const q = entry as Partial<UserQuestion>\n if (typeof q.question !== 'string' || !Array.isArray(q.options)) {\n return []\n }\n const options = q.options.filter((o): o is UserQuestionOption => typeof (o as UserQuestionOption | undefined)?.label === 'string')\n if (options.length === 0) {\n return []\n }\n return [\n {\n question: q.question,\n header: typeof q.header === 'string' ? q.header : '',\n options,\n multiSelect: q.multiSelect === true,\n },\n ]\n })\n}\n\ntype Selection = { labels: string[]; other: string; otherActive: boolean }\n\nconst EMPTY_SELECTION: Selection = { labels: [], other: '', otherActive: false }\n\nfunction answerFor(selection: Selection): string {\n const parts = [...selection.labels]\n if (selection.otherActive && selection.other.trim()) {\n parts.push(selection.other.trim())\n }\n return parts.join(', ')\n}\n\nexport interface QuestionPromptProps {\n request: PermissionRequest\n onAnswer: (requestId: string, updatedInput: Record<string, unknown>) => void\n onDismiss: (requestId: string, message?: string) => void\n className?: string\n}\n\nexport function QuestionPrompt({ request, onAnswer, onDismiss, className }: QuestionPromptProps) {\n const questions = parseUserQuestions(request.input)\n const [selections, setSelections] = useState<Selection[]>(() => questions.map(() => EMPTY_SELECTION))\n\n const update = (index: number, patch: Partial<Selection>) => {\n setSelections((prev) => prev.map((s, i) => (i === index ? { ...s, ...patch } : s)))\n }\n\n const toggle = (index: number, label: string, multiSelect: boolean) => {\n const current = selections[index] ?? EMPTY_SELECTION\n if (multiSelect) {\n update(index, {\n labels: current.labels.includes(label) ? current.labels.filter((l) => l !== label) : [...current.labels, label],\n })\n } else {\n update(index, { labels: current.labels[0] === label ? [] : [label], otherActive: false })\n }\n }\n\n const complete = questions.every((_, i) => answerFor(selections[i] ?? EMPTY_SELECTION) !== '')\n\n const submit = () => {\n const answers: Record<string, string> = {}\n questions.forEach((q, i) => {\n answers[q.question] = answerFor(selections[i] ?? EMPTY_SELECTION)\n })\n onAnswer(request.id, { ...request.input, answers })\n }\n\n return (\n <div data-slot=\"question-prompt\" className={cn('rounded-lg border border-info/40 bg-info-bg p-3', className)}>\n <div className=\"flex items-start gap-2.5\">\n <MessageCircleQuestion className=\"mt-0.5 size-4 shrink-0 text-info\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n {questions.map((q, index) => {\n const selection = selections[index] ?? EMPTY_SELECTION\n return (\n <div key={index} className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-2\">\n {q.header ? <Badge variant=\"info\">{q.header}</Badge> : null}\n <span className=\"text-body-sm font-medium text-fg-1\">{q.question}</span>\n </div>\n <div className=\"flex flex-col gap-1\">\n {q.options.map((option) => {\n const selected = selection.labels.includes(option.label)\n return (\n <button\n key={option.label}\n type=\"button\"\n onClick={() => toggle(index, option.label, q.multiSelect === true)}\n className={cn(\n 'rounded-md border px-2.5 py-1.5 text-left transition-colors',\n selected ? 'border-info bg-bg' : 'border-border bg-bg/50 hover:border-border-strong hover:bg-bg',\n )}\n >\n <span className=\"block text-body-sm font-medium text-fg-1\">{option.label}</span>\n {option.description ? <span className=\"block text-label text-fg-4\">{option.description}</span> : null}\n {selected && option.preview ? (\n <pre className=\"mt-1.5 max-h-40 overflow-auto rounded-md bg-code-bg px-2.5 py-1.5 font-mono text-label whitespace-pre-wrap text-fg-2\">\n {option.preview}\n </pre>\n ) : null}\n </button>\n )\n })}\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => update(index, { otherActive: !selection.otherActive })}\n className={cn(\n 'shrink-0 rounded-md border px-2.5 py-1.5 text-body-sm font-medium transition-colors',\n selection.otherActive\n ? 'border-info bg-bg text-fg-1'\n : 'border-border bg-bg/50 text-fg-3 hover:border-border-strong hover:bg-bg',\n )}\n >\n Other…\n </button>\n {selection.otherActive ? (\n <Input\n autoFocus\n value={selection.other}\n onChange={(e) => update(index, { other: e.target.value })}\n placeholder=\"Type your own answer\"\n className=\"flex-1\"\n />\n ) : null}\n </div>\n </div>\n </div>\n )\n })}\n <div>\n <Button size=\"sm\" onClick={submit} disabled={!complete}>\n Answer\n </Button>\n </div>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Dismiss question\"\n className=\"shrink-0\"\n onClick={() => onDismiss(request.id, 'Question dismissed by user')}\n >\n <X className=\"size-3.5\" />\n </Button>\n </div>\n </div>\n )\n}\n","import { useEffect, useRef, type ReactNode } from 'react'\nimport { cn } from '../../lib/utils.ts'\nimport { Blank, Ink, Row } from './row.tsx'\n\nexport function Rule({ dashed }: { dashed?: boolean }) {\n return <div className={cn('term-rule-row', dashed && 'term-rule-dashed')} aria-hidden />\n}\n\nexport function Hint({ children }: { children: ReactNode }) {\n return <Row tone=\"faint\">{children}</Row>\n}\n\nexport function Box({ children, className }: { children: ReactNode; className?: string }) {\n return <div className={cn('term-box', className)}>{children}</div>\n}\n\nexport function PromptTitle({ title, subject }: { title: string; subject?: string }) {\n return (\n <>\n <Row tone=\"blue\" bold>\n {title}\n </Row>\n {subject ? <Row tone=\"dim\">{subject}</Row> : null}\n </>\n )\n}\n\nexport type Choice = {\n key: string\n label: string\n description?: string\n checked?: boolean\n marker?: 'check' | 'radio'\n selected?: boolean\n danger?: boolean\n detail?: ReactNode\n}\n\nconst MARKERS = {\n check: ['[ ]', '[✓]'],\n radio: ['( )', '(•)'],\n} as const\n\nexport interface ChoicesProps {\n options: Choice[]\n focused: number\n onFocus: (index: number) => void\n onChoose: (index: number) => void\n active?: boolean\n autoFocus?: boolean\n label: string\n}\n\nfunction isTyping(element: Element | null): boolean {\n if (!(element instanceof HTMLElement)) {\n return false\n }\n const editable = element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.isContentEditable\n if (!editable) {\n return false\n }\n const text = element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement ? element.value : (element.textContent ?? '')\n return text.trim().length > 0\n}\n\nexport function Choices({ options, focused, onFocus, onChoose, active = true, autoFocus = true, label }: ChoicesProps) {\n const refs = useRef<Array<HTMLButtonElement | null>>([])\n\n useEffect(() => {\n if (!active) {\n return\n }\n const focusIsInList = refs.current.some((row) => row !== null && row === document.activeElement)\n if (!focusIsInList && (!autoFocus || isTyping(document.activeElement))) {\n return\n }\n refs.current[focused]?.focus()\n }, [active, focused, autoFocus])\n\n const move = (delta: number) => {\n if (options.length > 0) {\n onFocus((focused + delta + options.length) % options.length)\n }\n }\n\n return (\n <div\n role=\"group\"\n aria-label={label}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown') {\n move(1)\n event.preventDefault()\n return\n }\n if (event.key === 'ArrowUp') {\n move(-1)\n event.preventDefault()\n return\n }\n const digit = Number(event.key)\n if (Number.isInteger(digit) && digit >= 1 && digit <= Math.min(options.length, 9)) {\n onFocus(digit - 1)\n onChoose(digit - 1)\n event.preventDefault()\n }\n }}\n >\n {options.map((option, index) => {\n const isFocused = index === focused\n return (\n <div key={option.key}>\n <button\n ref={(element) => {\n refs.current[index] = element\n }}\n type=\"button\"\n tabIndex={isFocused ? 0 : -1}\n aria-pressed={option.checked}\n onFocus={() => onFocus(index)}\n onClick={() => onChoose(index)}\n className=\"term-press\"\n >\n <Row\n columns={5}\n glyph={`${isFocused ? '❯' : ' '} ${index + 1}.`}\n glyphTone={isFocused ? 'fg' : 'faint'}\n tone={option.danger ? 'red' : option.selected ? 'green' : 'fg'}\n data-focused={isFocused ? '' : undefined}\n >\n {option.checked !== undefined ? (\n <Ink tone={option.checked ? 'green' : 'faint'}>{MARKERS[option.marker ?? 'check'][option.checked ? 1 : 0]} </Ink>\n ) : null}\n <Ink bold={isFocused || option.selected}>{option.label}</Ink>\n </Row>\n </button>\n {option.description ? (\n <Row columns={5} tone=\"dim\">\n {option.description}\n </Row>\n ) : null}\n {option.detail ? <div className=\"term-detail\">{option.detail}</div> : null}\n </div>\n )\n })}\n </div>\n )\n}\n\nexport function PromptInput({\n value,\n onChange,\n onSubmit,\n onCancel,\n placeholder,\n}: {\n value: string\n onChange: (value: string) => void\n onSubmit: () => void\n onCancel: () => void\n placeholder?: string\n}) {\n return (\n <Row columns={5} glyph=\" ›\" glyphTone=\"dim\">\n <input\n autoFocus\n value={value}\n placeholder={placeholder}\n onChange={(event) => onChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n onSubmit()\n }\n if (event.key === 'Escape') {\n event.stopPropagation()\n onCancel()\n }\n }}\n className=\"term-input\"\n />\n </Row>\n )\n}\n\nexport function TabStrip({\n tabs,\n active,\n onSelect,\n}: {\n tabs: { key: string; label: string; glyph: string }[]\n active: number\n onSelect: (index: number) => void\n}) {\n return (\n <Row glyph=\"←\" glyphTone=\"faint\">\n {tabs.map((tab, index) => (\n <button\n key={tab.key}\n type=\"button\"\n tabIndex={-1}\n onClick={() => onSelect(index)}\n className={cn('term-tab', index === active && 'term-tab-active')}\n >\n {tab.glyph} {tab.label}\n </button>\n ))}\n <Ink tone=\"faint\"> →</Ink>\n </Row>\n )\n}\n\nexport { Blank }\n","import { useState } from 'react'\nimport type { PermissionRequest } from '@workerdeck/protocol'\nimport { toolInputPreview } from '../../lib/format.ts'\nimport { planFromRequest } from '../../lib/plan-request.ts'\nimport { TerminalDiff, previewPatch } from './diff.tsx'\nimport { TerminalMarkdown } from './markdown.tsx'\nimport { Choices, Hint, PromptInput, PromptTitle, Rule } from './prompt.tsx'\nimport { Blank, Row } from './row.tsx'\n\nconst PLAN_SCROLL = { maxHeight: 'min(24rem, 50vh)', overflowY: 'auto' } as const\n\nexport interface TerminalPermissionPromptProps {\n request: PermissionRequest\n onApprove: (requestId: string) => void\n onDeny: (requestId: string, message?: string, interrupt?: boolean) => void\n className?: string\n}\n\nexport function TerminalPermissionPrompt({ request, onApprove, onDeny, className }: TerminalPermissionPromptProps) {\n const [focused, setFocused] = useState(0)\n const [denying, setDenying] = useState(false)\n const [reason, setReason] = useState('')\n\n const deny = (interrupt: boolean) => {\n const message = reason.trim()\n onDeny(request.id, message || undefined, interrupt || undefined)\n setReason('')\n setDenying(false)\n }\n\n const plan = planFromRequest(request)\n const patch = plan ? undefined : previewPatch(request.input)\n const summary = plan ? '' : toolInputPreview(request.input)\n const heading = plan ? 'Plan ready for review' : (request.displayName ?? request.title ?? 'Permission needed')\n const subject = patch?.path ?? (summary || undefined)\n\n const reasonInput = denying ? (\n <PromptInput\n value={reason}\n onChange={setReason}\n onSubmit={() => deny(false)}\n onCancel={() => setDenying(false)}\n placeholder={\n plan\n ? 'What should change? (optional) — the agent keeps planning and reads this'\n : 'Reason (optional) — the agent reads this and can try something else'\n }\n />\n ) : undefined\n\n const options = plan\n ? [\n { key: 'allow', label: 'Approve plan' },\n { key: 'deny', label: 'Keep planning — tell it what to change', detail: reasonInput },\n { key: 'stop', label: 'No, and stop the turn', danger: true },\n ]\n : [\n { key: 'allow', label: 'Yes' },\n { key: 'deny', label: 'No, and tell the agent what to do differently', detail: reasonInput },\n { key: 'stop', label: 'No, and stop the turn', danger: true },\n ]\n\n return (\n <div\n data-slot=\"permission-prompt\"\n className={className}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n deny(false)\n }\n }}\n >\n <Rule />\n <PromptTitle title={heading} subject={subject} />\n <Blank />\n {plan ? (\n <>\n <div style={PLAN_SCROLL}>\n <TerminalMarkdown>{plan}</TerminalMarkdown>\n </div>\n <Blank />\n <Rule dashed />\n </>\n ) : patch ? (\n <>\n <TerminalDiff patch={patch} />\n <Blank />\n <Rule dashed />\n </>\n ) : request.description ? (\n <>\n <Row tone=\"dim\">{request.description}</Row>\n <Blank />\n </>\n ) : null}\n {request.decisionReason ? <Row tone=\"faint\">{request.decisionReason}</Row> : null}\n <Row>{plan ? 'Ready to implement this plan?' : (request.title ?? `Do you want to proceed?`)}</Row>\n <Choices\n label={heading}\n options={options}\n focused={focused}\n onFocus={setFocused}\n active={!denying}\n onChoose={(index) => {\n if (index === 0) {\n onApprove(request.id)\n } else if (index === 1) {\n setDenying(true)\n } else {\n deny(true)\n }\n }}\n />\n <Blank />\n <Hint>Enter to select · ↑/↓ to navigate · 1–3 to choose · Esc to cancel</Hint>\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { PermissionRequest, UserQuestion } from '@workerdeck/protocol'\nimport { parseUserQuestions } from '../agent/QuestionPrompt.tsx'\nimport { Box, Choices, Hint, PromptInput, Rule, TabStrip, type Choice } from './prompt.tsx'\nimport { Blank, Ink, Row } from './row.tsx'\n\ntype Selection = { labels: string[]; other: string; otherActive: boolean }\n\nconst EMPTY: Selection = { labels: [], other: '', otherActive: false }\n\nfunction answerFor(selection: Selection): string {\n const parts = [...selection.labels]\n if (selection.otherActive && selection.other.trim()) {\n parts.push(selection.other.trim())\n }\n return parts.join(', ')\n}\n\nexport interface TerminalQuestionPromptProps {\n request: PermissionRequest\n onAnswer: (requestId: string, updatedInput: Record<string, unknown>) => void\n onDismiss: (requestId: string, message?: string) => void\n className?: string\n}\n\nexport function TerminalQuestionPrompt({ request, onAnswer, onDismiss, className }: TerminalQuestionPromptProps) {\n const questions = parseUserQuestions(request.input)\n const [selections, setSelections] = useState<Selection[]>(() => questions.map(() => EMPTY))\n const [cursors, setCursors] = useState<number[]>(() => questions.map(() => 0))\n const [tab, setTab] = useState(0)\n const [reviewCursor, setReviewCursor] = useState(0)\n\n const review = tab >= questions.length\n const selection = selections[tab] ?? EMPTY\n const answered = (index: number) => answerFor(selections[index] ?? EMPTY) !== ''\n const complete = questions.every((_, index) => answered(index))\n\n const update = (index: number, patch: Partial<Selection>) =>\n setSelections((prev) => prev.map((s, i) => (i === index ? { ...s, ...patch } : s)))\n\n const toggle = (index: number, label: string, multiSelect: boolean) => {\n setSelections((prev) =>\n prev.map((current, i) => {\n if (i !== index) {\n return current\n }\n if (!multiSelect) {\n return { ...current, labels: [label], otherActive: false }\n }\n return {\n ...current,\n labels: current.labels.includes(label) ? current.labels.filter((l) => l !== label) : [...current.labels, label],\n }\n }),\n )\n }\n\n const submit = () => {\n const answers: Record<string, string> = {}\n questions.forEach((question, index) => {\n answers[question.question] = answerFor(selections[index] ?? EMPTY)\n })\n onAnswer(request.id, { ...request.input, answers })\n }\n\n const dismiss = () => onDismiss(request.id, 'Question dismissed by user')\n\n const move = (delta: number) => setTab((current) => Math.min(questions.length, Math.max(0, current + delta)))\n\n return (\n <div\n data-slot=\"question-prompt\"\n className={className}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n dismiss()\n return\n }\n if (event.key === 'Tab') {\n event.preventDefault()\n move(event.shiftKey ? -1 : 1)\n }\n }}\n >\n <Rule />\n <TabStrip\n tabs={[\n ...questions.map((question, index) => ({\n key: `q${index}`,\n label: question.header || `Question ${index + 1}`,\n glyph: answered(index) ? '▣' : '▢',\n })),\n { key: 'submit', label: 'Submit', glyph: '✓' },\n ]}\n active={tab}\n onSelect={setTab}\n />\n <Blank />\n {review ? (\n <ReviewStep\n questions={questions}\n answers={questions.map((_, index) => answerFor(selections[index] ?? EMPTY))}\n complete={complete}\n cursor={reviewCursor}\n onCursor={setReviewCursor}\n onSubmit={submit}\n onCancel={dismiss}\n />\n ) : (\n <QuestionStep\n // Keyed by question and load-bearing: without it React reuses the step across a Tab and the option list never re-arms its focus.\n key={tab}\n question={questions[tab]!}\n selection={selection}\n cursor={cursors[tab] ?? 0}\n onCursor={(next) => setCursors((prev) => prev.map((c, i) => (i === tab ? next : c)))}\n onToggle={(label) => toggle(tab, label, questions[tab]!.multiSelect === true)}\n onOther={(patch) => update(tab, patch)}\n onAdvance={() => move(1)}\n onDismiss={dismiss}\n />\n )}\n <Blank />\n <Hint>Enter to select · ↑/↓ to navigate · Tab to switch questions · Esc to cancel</Hint>\n </div>\n )\n}\n\nfunction QuestionStep({\n question,\n selection,\n cursor,\n onCursor,\n onToggle,\n onOther,\n onAdvance,\n onDismiss,\n}: {\n question: UserQuestion\n selection: Selection\n cursor: number\n onCursor: (index: number) => void\n onToggle: (label: string) => void\n onOther: (patch: Partial<Selection>) => void\n onAdvance: () => void\n onDismiss: () => void\n}) {\n const multiSelect = question.multiSelect === true\n\n const options: Choice[] = [\n ...question.options.map((option, index): Choice => {\n const selected = selection.labels.includes(option.label)\n return {\n key: option.label,\n label: option.label,\n description: option.description,\n checked: multiSelect ? selected : undefined,\n marker: 'check',\n selected: !multiSelect && selected,\n detail:\n option.preview && cursor === index ? (\n <Box>\n {option.preview.split('\\n').map((line, row) => (\n <Row key={row} columns={0} tone=\"dim\">\n {line || ' '}\n </Row>\n ))}\n </Box>\n ) : undefined,\n }\n }),\n {\n key: '__other',\n label: 'Other…',\n checked: selection.otherActive,\n marker: 'check' as const,\n detail: selection.otherActive ? (\n <PromptInput\n value={selection.other}\n onChange={(value) => onOther({ other: value })}\n onSubmit={onAdvance}\n onCancel={() => onOther({ otherActive: false, other: '' })}\n placeholder=\"Type your own answer\"\n />\n ) : undefined,\n },\n ...(multiSelect ? [{ key: '__next', label: 'Submit' }] : []),\n { key: '__chat', label: 'Chat about this' },\n ]\n\n return (\n <>\n <Row bold tone=\"bright\">\n {question.question}\n </Row>\n <Blank />\n <Choices\n label={question.question}\n options={options}\n focused={cursor}\n active={!selection.otherActive}\n onFocus={onCursor}\n onChoose={(index) => {\n if (index < question.options.length) {\n onToggle(question.options[index]!.label)\n if (!multiSelect) {\n onAdvance()\n }\n return\n }\n if (index === question.options.length) {\n onOther({ otherActive: !selection.otherActive })\n return\n }\n if (multiSelect && index === question.options.length + 1) {\n onAdvance()\n return\n }\n onDismiss()\n }}\n />\n </>\n )\n}\n\nfunction ReviewStep({\n questions,\n answers,\n complete,\n cursor,\n onCursor,\n onSubmit,\n onCancel,\n}: {\n questions: UserQuestion[]\n answers: string[]\n complete: boolean\n cursor: number\n onCursor: (index: number) => void\n onSubmit: () => void\n onCancel: () => void\n}) {\n return (\n <>\n <Row bold tone=\"bright\">\n Review your answers\n </Row>\n <Blank />\n {questions.map((question, index) => (\n <div key={index}>\n <Row glyph=\"●\" glyphTone=\"dim\">\n {question.question}\n </Row>\n <Row indent={1} glyph=\"→\" glyphTone=\"green\">\n <Ink tone={answers[index] ? 'green' : 'faint'}>{answers[index] || 'not answered'}</Ink>\n </Row>\n </div>\n ))}\n <Blank />\n <Row>{complete ? 'Ready to submit your answers?' : 'Some questions are unanswered.'}</Row>\n <Choices\n label=\"Submit answers\"\n options={[\n { key: 'submit', label: complete ? 'Submit answers' : 'Submit anyway' },\n { key: 'cancel', label: 'Cancel', danger: true },\n ]}\n focused={cursor}\n onFocus={onCursor}\n onChoose={(index) => (index === 0 ? onSubmit() : onCancel())}\n />\n </>\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { WorkerDeckClient } from '@workerdeck/client'\nimport type { SessionFileInfo } from '@workerdeck/protocol'\nimport type { TranscriptState } from '@workerdeck/react'\nimport { Download } from 'lucide-react'\nimport { CopyButton } from '../ui/CopyButton.tsx'\nimport { Dialog, DialogBody, DialogContent, DialogHeader, DialogRow } from '../ui/Dialog.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { formatBytes, formatCost, formatRelativeTime } from '../../lib/format.ts'\nimport { permissionModeMeta } from './PermissionModeSelect.tsx'\n\nexport interface SessionInfoDialogProps {\n state: TranscriptState\n client: WorkerDeckClient\n sessionId: string | undefined\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nexport function SessionInfoDialog({ state, client, sessionId, open, onOpenChange }: SessionInfoDialogProps) {\n const session = state.session\n const mode = state.permissionMode ? permissionModeMeta(state.permissionMode) : undefined\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader title=\"Session info\" description={session?.title} />\n <DialogBody>\n <div className=\"flex flex-col divide-y divide-border\">\n <div className=\"pb-2\">\n <DialogRow label=\"Engine\">{state.engine ?? 'claude'}</DialogRow>\n {session?.profile ? <DialogRow label=\"Profile\">{session.profile}</DialogRow> : null}\n {state.model ? (\n <DialogRow label=\"Model\" mono>\n {state.model}\n </DialogRow>\n ) : null}\n {mode ? <DialogRow label=\"Permission mode\">{mode.label}</DialogRow> : null}\n {session?.apiKeySource ? <DialogRow label=\"Credentials\">{session.apiKeySource}</DialogRow> : null}\n </div>\n <div className=\"py-2\">\n {state.cwd ? <CopyRow label=\"Working directory\" value={state.cwd} /> : null}\n {state.sdkSessionId ? <CopyRow label=\"Engine session id\" value={state.sdkSessionId} /> : null}\n {session ? <CopyRow label=\"Gateway session id\" value={session.id} /> : null}\n </div>\n <div className=\"py-2\">\n {session?.createdAt ? <DialogRow label=\"Started\">{formatRelativeTime(session.createdAt)}</DialogRow> : null}\n {session?.numTurns !== undefined ? <DialogRow label=\"Turns\">{session.numTurns}</DialogRow> : null}\n <DialogRow label=\"Cost\" mono>\n {formatCost(state.totalCostUsd)}\n </DialogRow>\n </div>\n {state.capabilities.vfs ? <SessionFiles client={client} sessionId={sessionId} open={open} /> : null}\n </div>\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CopyRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-start justify-between gap-2 py-1.5\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-label text-fg-3\">{label}</div>\n <div className=\"mt-0.5 font-mono text-label break-all text-fg-1\">{value}</div>\n </div>\n <CopyButton value={value} aria-label={`Copy ${label.toLowerCase()}`} />\n </div>\n )\n}\n\nfunction SessionFiles({ client, sessionId, open }: { client: WorkerDeckClient; sessionId: string | undefined; open: boolean }) {\n const [files, setFiles] = useState<SessionFileInfo[] | undefined>()\n const [loading, setLoading] = useState(false)\n\n useEffect(() => {\n if (!open || !sessionId) {\n return\n }\n let cancelled = false\n setLoading(true)\n client\n .listSessionFiles(sessionId)\n .then((list) => {\n if (!cancelled) {\n setFiles(list)\n }\n })\n .catch(() => {\n if (!cancelled) {\n setFiles([])\n }\n })\n .finally(() => {\n if (!cancelled) {\n setLoading(false)\n }\n })\n return () => {\n cancelled = true\n }\n }, [client, sessionId, open])\n\n return (\n <div className=\"pt-3\">\n <h3 className=\"text-label font-medium text-fg-3\">Files</h3>\n {loading ? (\n <div className=\"py-3 text-center\">\n <Spinner className=\"size-4 text-fg-4\" />\n </div>\n ) : !files?.length ? (\n <p className=\"py-2 text-body-sm text-fg-4\">Nothing delivered yet.</p>\n ) : (\n <ul className=\"mt-1 flex flex-col\">\n {files.map((file) => (\n <li key={file.path}>\n <a\n href={sessionId ? client.sessionFileUrl(sessionId, file.path) : undefined}\n className=\"flex items-center gap-2 rounded-md px-1 py-1.5 hover:bg-surface-hover\"\n >\n <Download className=\"size-3.5 shrink-0 text-fg-4\" />\n <span className=\"min-w-0 flex-1 truncate font-mono text-label text-fg-1\">{file.path}</span>\n <span className=\"shrink-0 text-label text-fg-4\">{formatBytes(file.bytes)}</span>\n </a>\n </li>\n ))}\n </ul>\n )}\n </div>\n )\n}\n","import type { SessionStatus } from '@workerdeck/protocol'\nimport type { BadgeProps } from '../ui/Badge.tsx'\n\nexport const STATUS_META: Record<SessionStatus, { label: string; variant: NonNullable<BadgeProps['variant']>; busy: boolean }> = {\n starting: { label: 'Starting', variant: 'info', busy: true },\n running: { label: 'Running', variant: 'info', busy: true },\n awaiting_approval: { label: 'Needs approval', variant: 'warning', busy: true },\n idle: { label: 'Idle', variant: 'success', busy: false },\n parked: { label: 'Parked', variant: 'accent', busy: false },\n failed: { label: 'Failed', variant: 'danger', busy: false },\n closed: { label: 'Closed', variant: 'neutral', busy: false },\n}\n","import { useEffect, useState, type ReactNode } from 'react'\nimport type { ConnectionState, TranscriptState } from '@workerdeck/react'\nimport type { ContextUsage, RateLimitInfo } from '@workerdeck/protocol'\nimport { RefreshCw, WifiOff } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { ProgressRing } from '../ui/ProgressRing.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { Tip } from '../ui/Tooltip.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatCost, formatCountdown, formatTokens } from '../../lib/format.ts'\nimport { meterColorClass } from '../../lib/status.ts'\nimport { cssColor } from '../../lib/css.ts'\nimport { STATUS_META } from './status.ts'\nimport { useTranscriptVariant } from './transcript-variant.tsx'\n\nexport interface StatusBarProps {\n state: TranscriptState\n rateLimits?: Record<string, RateLimitInfo>\n /** @deprecated Pass {@link StatusBarProps.connection}. */\n connected?: boolean\n connection?: ConnectionState\n onOpenStatus?: () => void\n onOpenContext?: () => void\n onOpenUsage?: () => void\n controls?: ReactNode\n actions?: ReactNode\n placement?: 'top' | 'bottom'\n className?: string\n}\n\nfunction useNow(intervalMs = 30_000): number {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), intervalMs)\n return () => clearInterval(timer)\n }, [intervalMs])\n return now\n}\n\nfunction ContextMeter({ usage }: { usage: ContextUsage }) {\n return (\n <Tip\n content={\n <div className=\"flex min-w-44 flex-col gap-1 py-0.5\">\n {usage.categories.map((c) => (\n <div key={c.name} className=\"flex items-center gap-2\">\n <span className=\"size-2 shrink-0 rounded-full bg-fg-4\" style={cssColor(c.color) ? { backgroundColor: c.color } : undefined} />\n <span className=\"flex-1\">{c.name}</span>\n <span className=\"font-mono text-fg-3\">{formatTokens(c.tokens)}</span>\n </div>\n ))}\n <div className=\"mt-0.5 flex items-center justify-between gap-2 border-t border-border pt-1\">\n <span>Total</span>\n <span className=\"font-mono text-fg-3\">\n {formatTokens(usage.totalTokens)} / {formatTokens(usage.maxTokens)} ({usage.percentage.toFixed(0)}%)\n </span>\n </div>\n </div>\n }\n >\n <span className={cn('inline-flex cursor-default items-center gap-1 font-mono text-label', meterColorClass(usage.percentage))}>\n Ctx {formatTokens(usage.totalTokens)}\n </span>\n </Tip>\n )\n}\n\nfunction RateLimitMeter({ label, info, now }: { label: string; info: RateLimitInfo; now: number }) {\n const pct = info.utilization\n const resetsAtMs = info.resetsAt !== undefined ? info.resetsAt * 1000 : undefined\n return (\n <Tip\n content={\n <div className=\"flex min-w-36 flex-col gap-1 py-0.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <span>{label} usage</span>\n <span className=\"font-mono text-fg-3\">{pct !== undefined ? `${pct.toFixed(1)}%` : '—'}</span>\n </div>\n {resetsAtMs !== undefined ? (\n <div className=\"flex items-center justify-between gap-2\">\n <span>Resets in</span>\n <span className=\"font-mono text-fg-3\">{formatCountdown(resetsAtMs, now)}</span>\n </div>\n ) : null}\n {info.isUsingOverage ? <div className=\"text-warning\">Using overage</div> : null}\n {info.status === 'rejected' ? <div className=\"text-danger\">Limit reached</div> : null}\n </div>\n }\n >\n <span\n className={cn(\n 'cursor-default font-mono text-label whitespace-nowrap',\n info.status === 'rejected' ? 'text-danger' : meterColorClass(pct ?? 0),\n )}\n >\n <ProgressRing value={pct ?? 0} className=\"mr-1 inline-block align-middle\" />\n {label}\n {pct !== undefined ? ` ${pct.toFixed(0)}%` : ''}\n {resetsAtMs !== undefined ? <span className=\"text-fg-4\"> · {formatCountdown(resetsAtMs, now)}</span> : null}\n </span>\n </Tip>\n )\n}\n\nfunction Slot({ onClick, hint, children }: { onClick?: () => void; hint: string; children: ReactNode }) {\n if (!onClick) {\n return <>{children}</>\n }\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={hint}\n className=\"rounded-md py-0.5 leading-4 transition-colors outline-none hover:bg-surface-hover focus-visible:bg-surface-hover\"\n >\n {children}\n </button>\n )\n}\n\nexport function StatusBar({\n state,\n rateLimits,\n connected,\n connection,\n onOpenStatus,\n onOpenContext,\n onOpenUsage,\n controls,\n actions,\n placement = 'top',\n className,\n}: StatusBarProps) {\n const meta = STATUS_META[state.status]\n const now = useNow()\n const windows = rateLimits ?? state.rateLimits\n const session = windows?.five_hour\n const weekly = windows?.seven_day\n const link: ConnectionState = connection ?? (connected === false ? 'reconnecting' : 'live')\n const terminal = useTranscriptVariant() === 'terminal'\n return (\n <div\n data-slot=\"status-bar\"\n className={cn(\n 'flex h-[var(--wd-status-bar-height)] items-baseline gap-2 border-border bg-surface p-1.5',\n placement === 'bottom' ? (terminal ? undefined : 'border-t') : 'border-b',\n className,\n )}\n >\n <Slot onClick={onOpenStatus} hint=\"Session info\">\n {link === 'live' ? (\n <Badge variant={meta.variant} dot={!meta.busy} className=\"items-baseline\">\n {meta.busy ? <Spinner className=\"size-3 self-center text-current\" /> : null}\n {meta.label}\n </Badge>\n ) : (\n <Badge variant={link === 'offline' ? 'danger' : 'warning'} dot={false} className=\"items-baseline\">\n {link === 'offline' ? (\n <WifiOff className=\"size-3 self-center text-current\" />\n ) : (\n <RefreshCw className=\"size-3 animate-spin self-center text-current\" />\n )}\n {link === 'offline' ? 'Offline' : 'Reconnecting…'}\n </Badge>\n )}\n </Slot>\n {state.capabilities.contextUsage && state.contextUsage ? (\n <Slot onClick={onOpenContext} hint=\"Context breakdown\">\n <ContextMeter usage={state.contextUsage} />\n </Slot>\n ) : null}\n {session || weekly ? (\n <Slot onClick={onOpenUsage} hint=\"Plan usage\">\n <span className=\"inline-flex items-baseline gap-2\">\n {session ? <RateLimitMeter label=\"Session\" info={session} now={now} /> : null}\n {weekly ? <RateLimitMeter label=\"Weekly\" info={weekly} now={now} /> : null}\n </span>\n </Slot>\n ) : null}\n {controls ? <span className=\"self-center\">{controls}</span> : null}\n <span className=\"flex-1\" />\n <span className=\"font-mono text-label text-fg-3\">{formatCost(state.totalCostUsd)}</span>\n {actions ? <span className=\"self-center\">{actions}</span> : null}\n </div>\n )\n}\n","import type { HTMLAttributes, ReactNode } from 'react'\nimport { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom'\nimport { ArrowDown } from 'lucide-react'\nimport { Button } from '../ui/Button.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface ConversationProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n children: ReactNode\n}\n\nexport function Conversation({ className, children, ...props }: ConversationProps) {\n return (\n <StickToBottom\n data-slot=\"conversation\"\n className={cn('relative flex-1 overflow-y-auto', className)}\n initial=\"instant\"\n resize=\"instant\"\n role=\"log\"\n {...props}\n >\n {children}\n </StickToBottom>\n )\n}\n\nexport function ConversationContent({ className, children, ...props }: HTMLAttributes<HTMLDivElement> & { children: ReactNode }) {\n return (\n <StickToBottom.Content\n data-slot=\"conversation-content\"\n className={cn('mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] flex-col gap-4 px-4 py-4', className)}\n {...props}\n >\n {children}\n </StickToBottom.Content>\n )\n}\n\nexport function ConversationScrollButton({ className }: { className?: string }) {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n if (isAtBottom) {\n return null\n }\n return (\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Scroll to bottom\"\n data-slot=\"conversation-scroll-button\"\n className={cn('absolute bottom-4 left-1/2 -translate-x-1/2 rounded-full shadow-(--shadow-md)', className)}\n onClick={() => void scrollToBottom('instant')}\n >\n <ArrowDown className=\"size-4\" />\n </Button>\n )\n}\n","import { cn } from '../../lib/utils.ts'\n\nexport interface LoaderProps {\n label?: string\n startedAt?: number\n tokens?: number\n className?: string\n}\n\nexport function Loader({ label, className }: LoaderProps) {\n return (\n <div data-slot=\"loader\" className={cn('flex items-center gap-2 py-1 text-body-sm text-fg-4', className)}>\n <span className=\"flex items-center gap-1\">\n {[0, 1, 2].map((i) => (\n <span key={i} className=\"size-1.5 animate-pulse rounded-full bg-fg-4\" style={{ animationDelay: `${i * 160}ms` }} />\n ))}\n </span>\n {label ? <span>{label}</span> : null}\n </div>\n )\n}\n","import { AtSign, MessageSquareText, SlashSquare, Sparkles, Terminal } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface SessionEmptyStateProps {\n cwd?: string\n hasCommands?: boolean\n hasSkills?: boolean\n canBrowseFiles?: boolean\n className?: string\n}\n\nexport function SessionEmptyState({ cwd, hasCommands, hasSkills, canBrowseFiles, className }: SessionEmptyStateProps) {\n const hints = [\n { icon: MessageSquareText, text: 'Tell the agent what to do.' },\n ...(hasCommands ? [{ icon: SlashSquare, text: 'Type / for the CLI’s slash commands.' }] : []),\n ...(hasSkills ? [{ icon: Sparkles, text: 'Type $ to draft a message for one of the agent’s skills.' }] : []),\n ...(canBrowseFiles ? [{ icon: AtSign, text: 'Type @ to search this project’s files.' }] : []),\n ]\n return (\n <div className={cn('flex flex-col items-center gap-4 py-10', className)}>\n <div className=\"flex size-12 items-center justify-center rounded-xl bg-surface text-fg-3\">\n <Terminal className=\"size-5\" />\n </div>\n {cwd ? <p className=\"max-w-full truncate font-mono text-label text-fg-4\">{cwd}</p> : null}\n <ul className=\"w-full max-w-sm divide-y divide-border overflow-hidden rounded-lg bg-surface\">\n {hints.map((hint) => (\n <li key={hint.text} className=\"flex items-center gap-3 px-3.5 py-2.5\">\n <hint.icon className=\"size-4 shrink-0 text-fg-4\" />\n <span className=\"text-body-sm text-fg-3\">{hint.text}</span>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n","import type { FilePatch, PatchHunk } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { COMPACTION_TEXT, formatBytes, formatCost, formatDuration, toolInputPreview } from '../../lib/format.ts'\nimport { taskChildItems, type TerminalBlock, type ToolCallItem } from './blocks.ts'\nimport { IMAGE_BOX_LINES } from './image-box.ts'\nimport { collapsedResult } from './result-preview.ts'\nimport { todoLine, todoPreview } from './todos.ts'\nimport { runSummary, taskSummary } from './tool-run.ts'\n\nexport type CellMetrics = {\n width: number\n ch: number\n line: number\n}\n\nexport type ComputedHeight = {\n px: number\n exact: boolean\n}\n\nexport type HeightEpoch = CellMetrics & {\n cache: WeakMap<TranscriptItem, ComputedHeight>\n}\n\nexport function createHeightEpoch(width: number, ch: number, line: number): HeightEpoch {\n return { width, ch, line, cache: new WeakMap() }\n}\n\nexport function estimateBlockPx(block: TerminalBlock, epoch: HeightEpoch): number {\n if (!('item' in block)) {\n return blockHeight(block, epoch).px\n }\n const hit = epoch.cache.get(block.item)\n if (hit) {\n return hit.px\n }\n const computed = itemHeight(block.item, epoch)\n epoch.cache.set(block.item, computed)\n return computed.px\n}\n\nexport const BRIEF_LINES = 4\n\nexport function briefPx(text: string, m: CellMetrics): number {\n const cols = Math.max(1, Math.floor(m.width / m.ch + EPS))\n return (Math.min(textLines(text, cols).lines, BRIEF_LINES) + 1) * m.line\n}\n\n// Absolutely positioned so the probe adds no layout and cannot re-trigger the ResizeObserver that called it.\nexport function measureCh(surface: HTMLElement): number {\n const probe = document.createElement('span')\n probe.textContent = '0'.repeat(200)\n probe.style.position = 'absolute'\n probe.style.visibility = 'hidden'\n probe.style.whiteSpace = 'pre'\n surface.appendChild(probe)\n const width = probe.getBoundingClientRect().width / 200\n probe.remove()\n return width\n}\n\nconst segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' })\n\nconst WIDE_RANGES: [number, number][] = [\n [0x1100, 0x115f],\n [0x2e80, 0x303e],\n [0x3041, 0x33ff],\n [0x3400, 0x4dbf],\n [0x4e00, 0x9fff],\n [0xa000, 0xa4cf],\n [0xac00, 0xd7a3],\n [0xf900, 0xfaff],\n [0xfe30, 0xfe4f],\n [0xff00, 0xff60],\n [0xffe0, 0xffe6],\n [0x20000, 0x3fffd],\n]\n\nfunction isWide(cp: number): boolean {\n return WIDE_RANGES.some(([lo, hi]) => cp >= lo && cp <= hi)\n}\n\nconst PICTOGRAPHIC = /\\p{Extended_Pictographic}/u\n\nfunction clusterCells(cluster: string): { w: number; exact: boolean } {\n if (PICTOGRAPHIC.test(cluster) || cluster.includes('') || cluster.includes('️')) {\n return { w: 2, exact: false }\n }\n const cp = cluster.codePointAt(0) ?? 0\n if (isWide(cp)) {\n return { w: 2, exact: false }\n }\n if (cp < 0x20) {\n return { w: 0, exact: true }\n }\n return { w: 1, exact: true }\n}\n\ntype Token = { kind: 'word' | 'space'; w: number; exact: boolean }\n\n// Must match `tab-size: 2` on the surface.\nconst TAB_SIZE = 2\n\n// Break after these unless a digit follows; `?` is here because Chrome breaks long URLs after it (verified against real break rects).\nconst BREAK_AFTER = new Set(['-', '–', '—', '?'])\n\nconst PLAIN_ASCII = /^[\\x20-\\x7e]*$/\n\n// Must stay semantically identical to `tokenize`; the height audit runs content that takes each path.\nfunction tokenizeAscii(line: string): Token[] {\n const tokens: Token[] = []\n let wordW = 0\n const flushWord = () => {\n if (wordW > 0) {\n tokens.push({ kind: 'word', w: wordW, exact: true })\n }\n wordW = 0\n }\n for (let i = 0; i < line.length; i++) {\n const code = line.charCodeAt(i)\n if (code === 0x20) {\n flushWord()\n const last = tokens[tokens.length - 1]\n if (last?.kind === 'space') {\n last.w += 1\n } else {\n tokens.push({ kind: 'space', w: 1, exact: true })\n }\n continue\n }\n wordW += 1\n if (code === 0x2d || code === 0x3f) {\n const next = line.charCodeAt(i + 1)\n if (!(next >= 0x30 && next <= 0x39)) {\n flushWord()\n }\n }\n }\n flushWord()\n return tokens\n}\n\nfunction tokenize(line: string): Token[] {\n if (PLAIN_ASCII.test(line)) {\n return tokenizeAscii(line)\n }\n const tokens: Token[] = []\n let word = { w: 0, exact: true }\n let col = 0\n const flushWord = () => {\n if (word.w > 0) {\n tokens.push({ kind: 'word', w: word.w, exact: word.exact })\n }\n word = { w: 0, exact: true }\n }\n const segments = [...segmenter.segment(line)].map((s) => s.segment)\n for (const [index, segment] of segments.entries()) {\n if (segment === ' ') {\n flushWord()\n const last = tokens.at(-1)\n if (last?.kind === 'space') {\n last.w += 1\n } else {\n tokens.push({ kind: 'space', w: 1, exact: true })\n }\n col += 1\n continue\n }\n if (segment === '\\t') {\n flushWord()\n const advance = TAB_SIZE - (col % TAB_SIZE) || TAB_SIZE\n const last = tokens.at(-1)\n if (last?.kind === 'space') {\n last.w += advance\n } else {\n tokens.push({ kind: 'space', w: advance, exact: true })\n }\n col += advance\n continue\n }\n const { w, exact } = clusterCells(segment)\n const cp = segment.codePointAt(0) ?? 0\n if (isWide(cp) || PICTOGRAPHIC.test(segment)) {\n // Each wide cluster is its own token — a break may fall between any two.\n flushWord()\n tokens.push({ kind: 'word', w, exact })\n col += w\n continue\n }\n word.w += w\n word.exact = word.exact && exact\n col += w\n if (BREAK_AFTER.has(segment) && !/^\\d/.test(segments[index + 1] ?? '')) {\n flushWord()\n }\n }\n flushWord()\n return tokens\n}\n\nfunction wrapOne(line: string, cols: number): { lines: number; exact: boolean } {\n if (cols <= 0) {\n return { lines: 1, exact: false }\n }\n const tokens = tokenize(line)\n let lines = 1\n let pos = 0\n let exact = true\n for (const token of tokens) {\n exact = exact && token.exact\n if (token.kind === 'space') {\n // Preserved spaces hang at the line end (CSS Text 3): they overflow without forcing a wrap.\n pos += token.w\n continue\n }\n if (pos + token.w <= cols) {\n pos += token.w\n continue\n }\n if (token.w <= cols) {\n lines += 1\n pos = token.w\n continue\n }\n // break-word: the token first moves to its own line, then fills whole lines.\n if (pos > 0) {\n lines += 1\n }\n const full = Math.ceil(token.w / cols)\n lines += full - 1\n pos = token.w - (full - 1) * cols\n }\n return { lines, exact }\n}\n\nexport function textLines(text: string, cols: number): { lines: number; exact: boolean } {\n let lines = 0\n let exact = true\n for (const hard of text.split('\\n')) {\n const r = wrapOne(hard, cols)\n lines += Math.max(1, r.lines)\n exact = exact && r.exact\n }\n return { lines: Math.max(1, lines), exact }\n}\n\n// Layout rounds to 1/64px; the epsilon keeps a body width of exactly N × ch from flooring to N−1.\nconst EPS = 1e-4\n\ntype Acc = { px: number; exact: boolean }\n\nfunction add(a: Acc, b: Acc): Acc {\n return { px: a.px + b.px, exact: a.exact && b.exact }\n}\n\n// `indent` resolves against the row's own `--term-cell`, so `columns={3} indent={1}` loses 3ch to the indent and 3ch to the gutter.\nfunction rowH(text: string, m: CellMetrics, { indentCells = 0, gutterCells = 2, extraPx = 0 } = {}): Acc {\n const bodyPx = m.width - extraPx - (indentCells + gutterCells) * m.ch\n const cols = Math.floor(bodyPx / m.ch + EPS)\n const { lines, exact } = textLines(text, cols)\n return { px: lines * m.line, exact }\n}\n\nfunction stripInline(s: string): string {\n return s\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/``([^`]+)``/g, '$1')\n .replace(/`([^`]+)`/g, '$1')\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/__([^_]+)__/g, '$1')\n .replace(/\\*([^*\\s][^*]*)\\*/g, '$1')\n .replace(/(^|\\W)_([^_]+)_(?=\\W|$)/g, '$1$2')\n .replace(/\\\\([\\\\`*_{}[\\]()#+.!-])/g, '$1')\n}\n\ntype MdBlock =\n | { t: 'p'; lines: string[] }\n | { t: 'h'; text: string }\n | { t: 'fence'; code: string }\n | { t: 'list'; items: { lines: string[]; gutter: number; indent: number }[] }\n | { t: 'quote'; paras: string[][] }\n | { t: 'table'; rows: number }\n | { t: 'hr' }\n\n// CommonMark: a trailing double space or backslash is a hard break; any other newline is soft and joins with a space.\nfunction hardLines(source: string[]): string[] {\n const out: string[] = []\n let current: string[] = []\n for (const raw of source) {\n const hard = /(?:\\s{2}|\\\\)$/.test(raw)\n current.push(stripInline(raw.replace(/(?:\\s+|\\\\)$/, '')))\n if (hard) {\n out.push(current.join(' '))\n current = []\n }\n }\n if (current.length) {\n out.push(current.join(' '))\n }\n return out\n}\n\nfunction parseBlocks(md: string): MdBlock[] {\n const lines = md.split('\\n')\n const blocks: MdBlock[] = []\n let i = 0\n const isBlank = (s: string | undefined) => s !== undefined && s.trim() === ''\n while (i < lines.length) {\n const line = lines[i]!\n if (line.trim() === '') {\n i += 1\n continue\n }\n if (line.startsWith('```')) {\n const code: string[] = []\n i += 1\n while (i < lines.length && !lines[i]!.startsWith('```')) {\n code.push(lines[i]!)\n i += 1\n }\n i += 1\n blocks.push({ t: 'fence', code: code.join('\\n') })\n continue\n }\n const h = /^(#{1,6})\\s+(.*)$/.exec(line)\n if (h) {\n blocks.push({ t: 'h', text: stripInline(h[2]!) })\n i += 1\n continue\n }\n if (/^(-{3,}|\\*{3,}|_{3,})\\s*$/.test(line)) {\n blocks.push({ t: 'hr' })\n i += 1\n continue\n }\n if (/^>\\s?/.test(line)) {\n const raw: string[] = []\n while (i < lines.length && /^>\\s?/.test(lines[i]!)) {\n raw.push(lines[i]!.replace(/^>\\s?/, ''))\n i += 1\n }\n const paras: string[][] = []\n let current: string[] = []\n for (const l of raw) {\n if (l.trim() === '') {\n if (current.length) {\n paras.push(hardLines(current))\n }\n current = []\n } else {\n current.push(l)\n }\n }\n if (current.length) {\n paras.push(hardLines(current))\n }\n blocks.push({ t: 'quote', paras })\n continue\n }\n const listMarker = (s: string) => {\n const m = /^(\\s*)([-*+]|\\d+\\.)\\s+(.*)$/.exec(s)\n if (!m) {\n return undefined\n }\n const depth = Math.floor(m[1]!.length / 2)\n const ordered = /\\d/.test(m[2]!)\n return { depth, ordered, text: m[3]! }\n }\n if (listMarker(line)) {\n const items: { lines: string[]; gutter: number; indent: number }[] = []\n const gutters: number[] = []\n let listOrdered: boolean | undefined\n while (i < lines.length) {\n const m = listMarker(lines[i]!)\n if (!m) {\n if (isBlank(lines[i]) && listMarker(lines[i + 1] ?? '')) {\n i += 1\n continue\n }\n break\n }\n if (m.depth === 0) {\n if (listOrdered !== undefined && m.ordered !== listOrdered) {\n break\n }\n listOrdered = m.ordered\n }\n gutters[m.depth] = m.ordered ? 3 : 2\n const indent = gutters.slice(0, m.depth).reduce((a, b) => a + (b ?? 2), 0)\n const source = [m.text]\n i += 1\n while (i < lines.length && lines[i]!.trim() !== '' && !listMarker(lines[i]!)) {\n // trimStart only: a trailing double space is the hard-break marker `hardLines` needs to see.\n source.push(lines[i]!.trimStart())\n i += 1\n }\n items.push({ lines: hardLines(source), gutter: gutters[m.depth]!, indent })\n }\n blocks.push({ t: 'list', items })\n continue\n }\n if (line.trimStart().startsWith('|')) {\n let rows = 0\n while (i < lines.length && lines[i]!.trimStart().startsWith('|')) {\n const cells = lines[i]!.trim()\n .replace(/^\\||\\|$/g, '')\n .split('|')\n .map((cell) => cell.trim())\n if (!cells.every((cell) => /^:?-+:?$/.test(cell))) {\n rows += 1\n }\n i += 1\n }\n blocks.push({ t: 'table', rows: Math.max(1, rows) })\n continue\n }\n const para: string[] = [line]\n i += 1\n while (\n i < lines.length &&\n lines[i]!.trim() !== '' &&\n !lines[i]!.startsWith('```') &&\n !/^(#{1,6})\\s+/.test(lines[i]!) &&\n !/^>\\s?/.test(lines[i]!) &&\n !listMarker(lines[i]!) &&\n !lines[i]!.trimStart().startsWith('|') &&\n !/^(-{3,}|\\*{3,}|_{3,})\\s*$/.test(lines[i]!)\n ) {\n para.push(lines[i]!)\n i += 1\n }\n blocks.push({ t: 'p', lines: hardLines(para) })\n }\n return blocks\n}\n\nexport function markdownHeight(md: string, m: CellMetrics, extraPx = 0): Acc {\n const bodyPx = m.width - extraPx - 2 * m.ch\n const cols = Math.floor(bodyPx / m.ch + EPS)\n const blocks = parseBlocks(md)\n let acc: Acc = { px: 0, exact: true }\n for (const [index, block] of blocks.entries()) {\n if (index > 0) {\n acc = add(acc, { px: m.line, exact: true })\n }\n switch (block.t) {\n case 'p': {\n for (const line of block.lines) {\n const r = textLines(line, cols)\n acc = add(acc, { px: r.lines * m.line, exact: r.exact })\n }\n break\n }\n case 'h': {\n const r = textLines(block.text, cols)\n acc = add(acc, { px: r.lines * m.line, exact: r.exact })\n break\n }\n case 'fence': {\n let px = 0\n let exact = true\n for (const codeLine of block.code.split('\\n')) {\n const r = wrapOne(codeLine, cols)\n px += Math.max(1, r.lines) * m.line\n exact = exact && r.exact\n }\n acc = add(acc, { px: Math.max(px, m.line), exact })\n break\n }\n case 'list': {\n let px = 0\n let exact = true\n for (const item of block.items) {\n for (const line of item.lines) {\n const r = textLines(line, cols - item.indent - item.gutter)\n px += r.lines * m.line\n exact = exact && r.exact\n }\n }\n acc = add(acc, { px, exact })\n break\n }\n case 'quote': {\n let px = 0\n let exact = true\n for (const [pi, para] of block.paras.entries()) {\n if (pi > 0) {\n px += m.line\n }\n for (const line of para) {\n const r = textLines(line, cols - 2)\n px += r.lines * m.line\n exact = exact && r.exact\n }\n }\n acc = add(acc, { px, exact })\n break\n }\n case 'table': {\n acc = add(acc, { px: block.rows * m.line, exact: true })\n break\n }\n case 'hr': {\n acc = add(acc, { px: m.line, exact: true })\n break\n }\n }\n }\n return { px: Math.max(acc.px, m.line), exact: acc.exact }\n}\n\nfunction diffHeight(patch: FilePatch, m: CellMetrics, extraPx = 0): Acc {\n const walk = (hunk: PatchHunk) => {\n let newLine = hunk.newStart\n let oldLine = hunk.oldStart\n return hunk.lines.map((line) => {\n const kind = line.startsWith('+') ? 'add' : line.startsWith('-') ? 'remove' : 'context'\n const text = line.slice(1)\n const number = kind === 'add' ? newLine++ : kind === 'remove' ? oldLine++ : newLine\n if (kind === 'context') {\n oldLine++\n newLine++\n }\n return { number, text }\n })\n }\n const hunks = patch.hunks.map(walk)\n const numbered = patch.hunks.some((hunk) => hunk.newStart > 0)\n const width = numbered ? String(Math.max(...hunks.flat().map((row) => row.number), 1)).length : 0\n const columns = numbered ? width + 3 : 2\n let acc: Acc = { px: 0, exact: true }\n for (const [index, hunk] of hunks.entries()) {\n if (index > 0) {\n acc = add(acc, { px: m.line, exact: true })\n } // the ⋮ separator row\n for (const row of hunk) {\n acc = add(acc, rowH(row.text || ' ', m, { indentCells: 2, gutterCells: columns, extraPx }))\n }\n }\n if (patch.truncated) {\n acc = add(acc, { px: m.line, exact: true })\n }\n return acc\n}\n\nfunction toolRowHeight(item: ToolCallItem, m: CellMetrics, extraPx: number): Acc {\n const todos = todoPreview(item.name, item.input)\n const preview = todos ? todos.summary : toolInputPreview(item.input)\n const backend = item.backend && item.backend !== 'server' ? ` · ${item.backend}` : ''\n let acc = rowH(`${item.name}(${preview})${backend}`, m, { gutterCells: 2, extraPx })\n\n const images = item.result?.images\n if (images?.length) {\n acc = add(acc, { px: images.length * IMAGE_BOX_LINES * m.line, exact: true })\n }\n\n if (item.patch) {\n return add(acc, diffHeight(item.patch, m, extraPx))\n }\n if (todos) {\n for (const todo of todos.shown) {\n acc = add(acc, rowH(todoLine(todo), m, { indentCells: 3, gutterCells: 3, extraPx }))\n }\n if (todos.more) {\n acc = add(acc, rowH(todos.more, m, { indentCells: 3, gutterCells: 3, extraPx }))\n }\n return acc\n }\n const text = item.result?.text ?? ''\n if (!text) {\n return acc\n }\n const { shown, more } = collapsedResult(text.trimEnd().split('\\n'), item.result?.totalChars)\n for (const line of shown) {\n acc = add(acc, rowH(line || ' ', m, { indentCells: 3, gutterCells: 3, extraPx }))\n }\n if (more) {\n acc = add(acc, rowH(more, m, { indentCells: 3, gutterCells: 3, extraPx }))\n }\n return acc\n}\n\n// Nested rows are stepped in behind a rule: `border-l-2` (2px) + `pl-3` (12px) on the wrapper in `agent/Transcript.tsx`.\nfunction nestedExtraPx(item: TranscriptItem): number {\n return 'parentToolUseId' in item && item.parentToolUseId != null ? 14 : 0\n}\n\nexport function itemHeight(item: TranscriptItem, m: CellMetrics): ComputedHeight {\n const extraPx = nestedExtraPx(item)\n switch (item.kind) {\n case 'user': {\n let acc: Acc = { px: 0, exact: true }\n if (item.attachments?.length) {\n acc = add(acc, rowH(item.attachments.map((a) => a.name).join(', '), m, { extraPx }))\n }\n if (item.text) {\n for (const line of item.text.split('\\n')) {\n acc = add(acc, rowH(line || ' ', m, { extraPx }))\n }\n }\n return acc\n }\n case 'assistant_text': {\n return markdownHeight(item.text, m, extraPx)\n }\n case 'thinking': {\n return rowH(item.text, m, { extraPx })\n }\n case 'tool_call': {\n return toolRowHeight(item, m, extraPx)\n }\n case 'turn_result': {\n let acc = rowH(`${item.isError ? item.subtype : 'done'} · ${formatDuration(item.durationMs)} · ${formatCost(item.totalCostUsd)}`, m, {\n extraPx,\n })\n for (const message of item.errors ?? []) {\n acc = add(acc, rowH(message, m, { extraPx }))\n }\n return acc\n }\n case 'notice': {\n return rowH(item.text, m, { extraPx })\n }\n // Measured against the exported constant, not a copy of the sentence: the two must not drift,\n // and a mismatch here is a scrubber that points a few pixels off for the rest of the session.\n case 'compaction': {\n return rowH(COMPACTION_TEXT, m, { extraPx })\n }\n case 'file_delivered': {\n const text = `${item.path} · ${formatBytes(item.bytes)}` + (item.description ? ` · ${item.description}` : '')\n return rowH(text, m, { extraPx })\n }\n default: {\n return { px: 0, exact: false }\n }\n }\n}\n\nexport function blockHeight(block: TerminalBlock, m: CellMetrics): ComputedHeight {\n if ('task' in block) {\n return rowH(taskSummary(block.task, taskChildItems(block)), m)\n }\n if ('run' in block) {\n const busy = block.run.some((item) => item.status === 'running' || item.status === 'pending')\n return rowH(runSummary(block.run, busy), m)\n }\n return itemHeight(block.item, m)\n}\n","import { useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { useStickToBottomContext } from 'use-stick-to-bottom'\nimport type { PermissionRequest } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { formatCost, formatDuration, toolInputPreview } from '../../lib/format.ts'\nimport { parentOf } from './blocks.ts'\nimport { TerminalSurface } from './surface.tsx'\n\ntype Lane = 'l' | 'r' | 'f'\ntype MarkKind = 'user' | 'subagent' | 'turn' | 'turnFailed' | 'toolFailed' | 'error' | 'approval' | 'recap' | 'bookmark'\n\ntype Mark = {\n kind: MarkKind\n itemIndex: number\n rowIndex: number\n turnIndex?: number\n}\n\ntype Cluster = { lane: Lane; kind: MarkKind; y: number; h: number; marks: { mark: Mark; y: number }[] }\n\nfunction nearestMember(cluster: Cluster, y: number): Mark | undefined {\n let best: { mark: Mark; y: number } | undefined\n for (const member of cluster.marks) {\n if (!best || Math.abs(member.y - y) < Math.abs(best.y - y)) {\n best = member\n }\n }\n return best?.mark\n}\n\nconst LANE: Record<MarkKind, Lane> = {\n user: 'l',\n subagent: 'l',\n turn: 'r',\n turnFailed: 'r',\n toolFailed: 'r',\n error: 'r',\n approval: 'f',\n recap: 'f',\n bookmark: 'f',\n}\n\nconst LOUDNESS: Record<MarkKind, number> = {\n approval: 7,\n error: 6,\n turnFailed: 5,\n toolFailed: 4,\n user: 3,\n turn: 2,\n bookmark: 1,\n subagent: 1,\n recap: 0,\n}\n\nconst KIND_NAME: Record<MarkKind, string> = {\n user: 'you',\n subagent: 'sub-agent',\n turn: 'response · turn end',\n turnFailed: 'turn failed',\n toolFailed: 'tool failed',\n error: 'error',\n approval: 'pending approval',\n recap: 'catch-up boundary',\n bookmark: 'bookmark',\n}\n\nconst MIN_MARK = 2\n\nexport function railScale(railH: number, totalSize: number, viewportH: number): number {\n return totalSize > 0 ? railH / Math.max(totalSize, viewportH) : 0\n}\n\ntype Segment = { response?: number; turn?: number; failed?: boolean }\n\nfunction doneLine(turn: Extract<TranscriptItem, { kind: 'turn_result' }>): string {\n return `${turn.isError ? turn.subtype : 'done'} · ${formatDuration(turn.durationMs)} · ${formatCost(turn.totalCostUsd)}`\n}\n\nfunction excerpt(item: TranscriptItem): string {\n switch (item.kind) {\n case 'user':\n case 'assistant_text':\n case 'thinking':\n case 'notice': {\n return item.text\n }\n case 'tool_call': {\n return `${item.name}(${toolInputPreview(item.input)})`\n }\n case 'turn_result': {\n return doneLine(item)\n }\n case 'file_delivered': {\n return item.path\n }\n default: {\n return ''\n }\n }\n}\n\nexport interface TerminalScrubberProps {\n items: readonly TranscriptItem[]\n pendingApprovals: readonly PermissionRequest[]\n recapRow?: { rowIndex: number; label: string }\n bookmarks: readonly number[]\n frameParentId?: string\n rowIndexFor: (itemIndex: number) => number\n offsetOfRow: (rowIndex: number) => number\n sizeOfRow: (rowIndex: number) => number\n positionInRow?: (itemIndex: number) => { ordinal: number; count: number } | undefined\n totalSize: number\n scrollOffset: number\n viewportH: number\n onJumpToRow: (rowIndex: number) => void\n interactive: boolean\n fontSize?: number\n lineHeight?: number\n}\n\n// Exported for `test/scrubber.test.ts` only, never from the package.\nexport function buildClusters(props: TerminalScrubberProps, railH: number): Cluster[] {\n const {\n items,\n bookmarks,\n frameParentId,\n recapRow,\n pendingApprovals,\n rowIndexFor,\n offsetOfRow,\n sizeOfRow,\n positionInRow,\n totalSize,\n viewportH,\n } = props\n const marks: Mark[] = []\n const subagentParents = new Set<string>()\n for (const item of items) {\n const parent = parentOf(item)\n if (parent !== undefined) {\n subagentParents.add(parent)\n }\n }\n const rowOutcome = new Map<number, number>()\n items.forEach((item, index) => {\n if (item.kind !== 'tool_call' || parentOf(item) !== frameParentId) {\n return\n }\n rowOutcome.set(rowIndexFor(index), index)\n })\n let segment: Segment = {}\n const closeSegment = () => {\n const anchor = segment.response ?? segment.turn\n if (anchor !== undefined) {\n marks.push({\n kind: segment.failed ? 'turnFailed' : 'turn',\n itemIndex: anchor,\n rowIndex: rowIndexFor(anchor),\n turnIndex: segment.turn,\n })\n }\n segment = {}\n }\n items.forEach((item, index) => {\n if (item.kind === 'tool_call' && subagentParents.has(item.id)) {\n marks.push({ kind: 'subagent', itemIndex: index, rowIndex: rowIndexFor(index) })\n }\n if (item.kind === 'user' && parentOf(item) === frameParentId) {\n closeSegment()\n marks.push({ kind: 'user', itemIndex: index, rowIndex: rowIndexFor(index) })\n } else if (item.kind === 'turn_result') {\n segment.turn = index\n segment.failed = item.isError\n closeSegment()\n } else if (item.kind === 'notice' && item.level === 'error') {\n marks.push({ kind: 'error', itemIndex: index, rowIndex: rowIndexFor(index) })\n } else if (\n item.kind === 'tool_call' &&\n (item.status === 'failed' || item.result?.isError === true) &&\n rowOutcome.get(rowIndexFor(index)) === index\n ) {\n marks.push({ kind: 'toolFailed', itemIndex: index, rowIndex: rowIndexFor(index) })\n } else if (item.kind === 'assistant_text' && parentOf(item) === frameParentId) {\n if (frameParentId !== undefined) {\n marks.push({ kind: 'turn', itemIndex: index, rowIndex: rowIndexFor(index) })\n return\n }\n segment.response = index\n }\n })\n closeSegment()\n for (const index of bookmarks) {\n if (index >= 0 && index < items.length) {\n marks.push({ kind: 'bookmark', itemIndex: index, rowIndex: rowIndexFor(index) })\n }\n }\n if (recapRow) {\n marks.push({ kind: 'recap', itemIndex: -1, rowIndex: recapRow.rowIndex })\n }\n\n const scale = railScale(railH, totalSize, viewportH)\n const lanes = new Map<Lane, { mark: Mark; y: number; h: number }[]>()\n for (const mark of marks) {\n const within = mark.itemIndex >= 0 ? positionInRow?.(mark.itemIndex) : undefined\n const rowH = sizeOfRow(mark.rowIndex)\n const h = within ? MIN_MARK : Math.max(MIN_MARK, Math.round(rowH * scale))\n const y = Math.min(\n Math.max(0, railH - h),\n Math.round((offsetOfRow(mark.rowIndex) + (within ? (within.ordinal / within.count) * rowH : 0)) * scale),\n )\n const lane = LANE[mark.kind]\n const list = lanes.get(lane) ?? []\n list.push({ mark, y, h })\n lanes.set(lane, list)\n }\n const clusters: Cluster[] = []\n for (const [lane, list] of lanes) {\n list.sort((a, b) => a.y - b.y)\n let current: Cluster | null = null\n for (const { mark, y, h } of list) {\n if (current && y <= current.y + current.h + 1) {\n current.h = Math.max(current.h, y + h - current.y)\n if (LOUDNESS[mark.kind] > LOUDNESS[current.kind]) {\n current.kind = mark.kind\n }\n current.marks.push({ mark, y })\n } else {\n current = { lane, kind: mark.kind, y, h, marks: [{ mark, y }] }\n clusters.push(current)\n }\n }\n }\n if (pendingApprovals.length > 0) {\n clusters.push({\n lane: LANE.approval,\n kind: 'approval',\n y: Math.max(0, railH - MIN_MARK),\n h: MIN_MARK,\n marks: [],\n })\n }\n return clusters\n}\n\nfunction peekContent(cluster: Cluster, first: Mark | undefined, { items, pendingApprovals, recapRow }: TerminalScrubberProps): ReactNode {\n const more = cluster.marks.length > 1 ? ` · ${cluster.marks.length} marks` : ''\n let body: ReactNode = null\n if (cluster.kind === 'approval') {\n const request = pendingApprovals[0]\n body = request ? (\n <>\n <div data-tone=\"bright\">{request.title ?? 'Permission required'}</div>\n <div className=\"term-scrub-ex\" data-tone=\"fg\">\n {`${request.displayName ?? request.toolName}(${toolInputPreview(request.input)})`}\n </div>\n </>\n ) : null\n } else if (cluster.kind === 'recap' && !first) {\n body = <div data-tone=\"faint\">※ {recapRow?.label}</div>\n } else if (first) {\n const item = items[first.itemIndex]\n if (first.kind === 'recap') {\n body = <div data-tone=\"faint\">※ {recapRow?.label}</div>\n } else if (first.kind === 'turn' || first.kind === 'turnFailed') {\n const turn = first.turnIndex === undefined ? undefined : items[first.turnIndex]\n body = (\n <>\n {item?.kind === 'assistant_text' ? (\n <div className=\"term-scrub-ex\" data-tone=\"fg\">\n <span data-tone=\"dim\">● </span>\n {item.text}\n </div>\n ) : null}\n {turn?.kind === 'turn_result' ? (\n <>\n <div data-tone={turn.isError ? 'red' : 'faint'}>{doneLine(turn)}</div>\n {turn.errors?.map((message, index) => (\n <div key={index} data-tone=\"red\">\n {message}\n </div>\n ))}\n </>\n ) : null}\n </>\n )\n } else if (item) {\n const failure =\n first.kind === 'toolFailed' && item.kind === 'tool_call'\n ? item.result?.text.split('\\n').find((line) => line.trim() !== '')\n : undefined\n body = (\n <>\n <div className=\"term-scrub-ex\" data-tone={first.kind === 'error' || first.kind === 'toolFailed' ? 'red' : 'fg'}>\n {first.kind === 'user' ? <span data-tone=\"dim\">{'❯ '}</span> : null}\n {excerpt(item)}\n </div>\n {failure ? (\n <div className=\"term-scrub-ex\" data-tone=\"red\">\n {failure}\n </div>\n ) : null}\n </>\n )\n }\n }\n return (\n <>\n <div data-tone=\"faint\">\n {KIND_NAME[first?.kind ?? cluster.kind]}\n {more}\n </div>\n {body}\n </>\n )\n}\n\nexport function TerminalScrubber(props: TerminalScrubberProps) {\n const { scrollOffset, viewportH, totalSize, onJumpToRow, interactive, fontSize, lineHeight } = props\n const stick = useStickToBottomContext()\n const bodyRef = useRef<HTMLDivElement | null>(null)\n const peekRef = useRef<HTMLDivElement | null>(null)\n const [railH, setRailH] = useState(0)\n const [peek, setPeek] = useState<{ cluster: Cluster; mark: Mark | undefined; y: number } | null>(null)\n const drag = useRef<{ y: number; moved: boolean; target: EventTarget | null } | null>(null)\n\n useEffect(() => {\n const element = bodyRef.current\n if (!element) {\n return\n }\n const observer = new ResizeObserver(() => setRailH(element.clientHeight))\n observer.observe(element)\n setRailH(element.clientHeight)\n return () => observer.disconnect()\n }, [])\n\n // The band tracks the scroller's own scroll events, not `scrollOffset`: the virtualizer notifies React only when the row range changes.\n const [liveOffset, setLiveOffset] = useState(scrollOffset)\n useEffect(() => {\n const scroller = stick.scrollRef.current\n if (!scroller) {\n return\n }\n const onScroll = () => setLiveOffset(scroller.scrollTop)\n scroller.addEventListener('scroll', onScroll, { passive: true })\n setLiveOffset(scroller.scrollTop)\n return () => scroller.removeEventListener('scroll', onScroll)\n }, [stick.scrollRef])\n\n useEffect(() => {\n setPeek(null)\n }, [props.items])\n\n // Manual listener because it must `preventDefault` — React's root wheel listeners are passive.\n useEffect(() => {\n if (!interactive) {\n return\n }\n const element = bodyRef.current\n if (!element) {\n return\n }\n const onWheel = (event: WheelEvent) => {\n const scroller = stick.scrollRef.current\n if (!scroller) {\n return\n }\n scroller.scrollTop += event.deltaY\n event.preventDefault()\n }\n element.addEventListener('wheel', onWheel, { passive: false })\n return () => element.removeEventListener('wheel', onWheel)\n }, [interactive, stick.scrollRef])\n\n useLayoutEffect(() => {\n const element = peekRef.current\n if (!element || !peek) {\n return\n }\n const height = element.offsetHeight\n const railHeight = bodyRef.current?.clientHeight ?? 0\n element.style.top = `${Math.max(4, Math.min(railHeight - height - 4, peek.y - height / 2))}px`\n }, [peek])\n\n // Deps are content and geometry: `rowIndexFor`/`offsetOfRow` are per-render closures, and `totalSize` stands in for their measurements.\n const clusters = useMemo(\n () => (railH > 0 ? buildClusters(props, railH) : []),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [props.items, props.bookmarks, props.recapRow, props.pendingApprovals, totalSize, railH, viewportH],\n )\n const scale = railScale(railH, totalSize, viewportH)\n const bandH = Math.max(2, Math.min(railH, Math.round(viewportH * scale)))\n const bandTop = Math.max(0, Math.min(railH - bandH, Math.round(liveOffset * scale)))\n\n const scrub = (clientY: number) => {\n const rail = bodyRef.current\n const scroller = stick.scrollRef.current\n if (!rail || !scroller) {\n return\n }\n const rect = rail.getBoundingClientRect()\n const fraction = Math.min(1, Math.max(0, (clientY - rect.top) / rect.height))\n scroller.scrollTop = fraction * scroller.scrollHeight - scroller.clientHeight / 2\n }\n\n const railY = (clientY: number): number => clientY - (bodyRef.current?.getBoundingClientRect().top ?? 0)\n\n const activate = (cluster: Cluster, clientY: number) => {\n if (cluster.kind === 'approval' && cluster.marks.length === 0) {\n void stick.scrollToBottom()\n return\n }\n const mark = nearestMember(cluster, railY(clientY))\n if (mark) {\n onJumpToRow(mark.rowIndex)\n }\n }\n\n const showPeek = (cluster: Cluster, clientY: number) => {\n const y = railY(clientY)\n const mark = nearestMember(cluster, y)\n setPeek((previous) =>\n previous && previous.cluster === cluster && previous.mark === mark\n ? previous\n : { cluster, mark, y: Math.min(Math.max(y, cluster.y), cluster.y + cluster.h) },\n )\n }\n\n const maxOffset = Math.max(1, totalSize - viewportH)\n return (\n <TerminalSurface\n fontSize={fontSize}\n lineHeight={lineHeight}\n className=\"term-scrubber\"\n data-interactive={interactive || undefined}\n {...(interactive\n ? {\n role: 'scrollbar',\n 'aria-orientation': 'vertical' as const,\n 'aria-label': 'Transcript overview',\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': Math.min(100, Math.max(0, Math.round((liveOffset / maxOffset) * 100))),\n }\n : { 'aria-hidden': true })}\n >\n <div\n ref={bodyRef}\n className=\"term-scrubber-body\"\n {...(interactive\n ? {\n onPointerDown: (event) => {\n stick.stopScroll()\n drag.current = { y: event.clientY, moved: false, target: event.target }\n event.currentTarget.setPointerCapture(event.pointerId)\n },\n onPointerMove: (event) => {\n const state = drag.current\n if (!state) {\n return\n }\n if (!state.moved && Math.abs(event.clientY - state.y) < 3) {\n return\n }\n state.moved = true\n setPeek(null)\n scrub(event.clientY)\n },\n onPointerUp: (event) => {\n const state = drag.current\n drag.current = null\n if (!state || state.moved) {\n return\n }\n const mark = (state.target as HTMLElement | null)?.closest?.('[data-ci]')\n const index = mark ? Number((mark as HTMLElement).dataset.ci) : Number.NaN\n if (Number.isInteger(index) && clusters[index]) {\n activate(clusters[index]!, event.clientY)\n } else {\n scrub(event.clientY)\n }\n },\n }\n : null)}\n >\n <div className=\"term-scrub-band\" style={{ top: bandTop, height: bandH }} />\n {clusters.map((cluster, index) => (\n <div\n key={index}\n data-ci={index}\n className=\"term-scrub-mark\"\n data-lane={cluster.lane}\n data-kind={cluster.kind}\n style={{ top: cluster.y, height: cluster.h }}\n {...(interactive\n ? {\n onPointerEnter: (event) => showPeek(cluster, event.clientY),\n onPointerMove: (event) => {\n if (!drag.current) {\n showPeek(cluster, event.clientY)\n }\n },\n onPointerLeave: () => setPeek(null),\n }\n : null)}\n />\n ))}\n {peek ? (\n <div ref={peekRef} className=\"term-scrub-peek\" style={{ top: peek.y }}>\n {peekContent(peek.cluster, peek.mark, props)}\n </div>\n ) : null}\n </div>\n </TerminalSurface>\n )\n}\n","import type { TranscriptItem } from '@workerdeck/react'\nimport { formatCost, formatDuration, toolInputPreview } from '../../lib/format.ts'\nimport { parentOf } from '../terminal/blocks.ts'\n\nexport type Lane = 'l' | 'r' | 'f'\nexport type MarkKind = 'user' | 'subagent' | 'turn' | 'turnFailed' | 'toolFailed' | 'error' | 'approval' | 'recap' | 'bookmark'\n\nexport type Mark = {\n kind: MarkKind\n itemIndex: number\n turnIndex?: number\n}\n\nexport type Cluster = {\n lane: Lane\n kind: MarkKind\n y: number\n h: number\n marks: { mark: Mark; y: number }[]\n}\n\nexport function nearestMember(cluster: Cluster, y: number): Mark | undefined {\n let best: { mark: Mark; y: number } | undefined\n for (const member of cluster.marks) {\n if (!best || Math.abs(member.y - y) < Math.abs(best.y - y)) {\n best = member\n }\n }\n return best?.mark\n}\n\nexport const LANE: Record<MarkKind, Lane> = {\n user: 'l',\n subagent: 'l',\n turn: 'r',\n turnFailed: 'r',\n toolFailed: 'r',\n error: 'r',\n approval: 'f',\n recap: 'f',\n bookmark: 'f',\n}\n\nexport const LOUDNESS: Record<MarkKind, number> = {\n approval: 7,\n error: 6,\n turnFailed: 5,\n toolFailed: 4,\n user: 3,\n turn: 2,\n bookmark: 1,\n subagent: 1,\n recap: 0,\n}\n\nexport const KIND_NAME: Record<MarkKind, string> = {\n user: 'you',\n subagent: 'sub-agent',\n turn: 'response · turn end',\n turnFailed: 'turn failed',\n toolFailed: 'tool failed',\n error: 'error',\n approval: 'pending approval',\n recap: 'catch-up boundary',\n bookmark: 'bookmark',\n}\n\nexport const MIN_MARK = 2\n\nexport function doneLine(turn: Extract<TranscriptItem, { kind: 'turn_result' }>): string {\n return `${turn.isError ? turn.subtype : 'done'} · ${formatDuration(turn.durationMs)} · ${formatCost(turn.totalCostUsd)}`\n}\n\nexport function excerpt(item: TranscriptItem): string {\n switch (item.kind) {\n case 'user':\n case 'assistant_text':\n case 'thinking':\n case 'notice': {\n return item.text\n }\n case 'tool_call': {\n return `${item.name}(${toolInputPreview(item.input)})`\n }\n case 'turn_result': {\n return doneLine(item)\n }\n case 'file_delivered': {\n return item.path\n }\n default: {\n return ''\n }\n }\n}\n\ntype Segment = { response?: number; turn?: number; failed?: boolean }\n\nexport interface BuildMarksOptions {\n frameParentId?: string\n bookmarks?: readonly number[]\n recapItemIndex?: number\n}\n\nexport function buildMarks(\n items: readonly TranscriptItem[],\n { frameParentId, bookmarks = [], recapItemIndex }: BuildMarksOptions = {},\n): Mark[] {\n const marks: Mark[] = []\n const subagentParents = new Set<string>()\n for (const item of items) {\n const parent = parentOf(item)\n if (parent !== undefined) {\n subagentParents.add(parent)\n }\n }\n let segment: Segment = {}\n const closeSegment = () => {\n const anchor = segment.response ?? segment.turn\n if (anchor !== undefined) {\n marks.push({\n kind: segment.failed ? 'turnFailed' : 'turn',\n itemIndex: anchor,\n turnIndex: segment.turn,\n })\n }\n segment = {}\n }\n items.forEach((item, index) => {\n if (item.kind === 'tool_call' && subagentParents.has(item.id)) {\n marks.push({ kind: 'subagent', itemIndex: index })\n }\n if (item.kind === 'user' && parentOf(item) === frameParentId) {\n closeSegment()\n marks.push({ kind: 'user', itemIndex: index })\n } else if (item.kind === 'turn_result') {\n segment.turn = index\n segment.failed = item.isError\n closeSegment()\n } else if (item.kind === 'notice' && item.level === 'error') {\n marks.push({ kind: 'error', itemIndex: index })\n } else if (\n item.kind === 'tool_call' &&\n parentOf(item) === frameParentId &&\n (item.status === 'failed' || item.result?.isError === true)\n ) {\n marks.push({ kind: 'toolFailed', itemIndex: index })\n } else if (item.kind === 'assistant_text' && parentOf(item) === frameParentId) {\n if (frameParentId !== undefined) {\n marks.push({ kind: 'turn', itemIndex: index })\n return\n }\n segment.response = index\n }\n })\n closeSegment()\n for (const index of bookmarks) {\n if (index >= 0 && index < items.length) {\n marks.push({ kind: 'bookmark', itemIndex: index })\n }\n }\n if (recapItemIndex !== undefined) {\n marks.push({ kind: 'recap', itemIndex: recapItemIndex })\n }\n return marks\n}\n\nexport function clusterMarks(marks: readonly Mark[], railH: number, itemCount: number): Cluster[] {\n const count = Math.max(1, itemCount)\n const h = Math.max(MIN_MARK, Math.round(railH / count))\n const lanes = new Map<Lane, { mark: Mark; y: number }[]>()\n for (const mark of marks) {\n const y = Math.min(Math.max(0, railH - h), Math.round((mark.itemIndex / count) * railH))\n const lane = LANE[mark.kind]\n const list = lanes.get(lane) ?? []\n list.push({ mark, y })\n lanes.set(lane, list)\n }\n const clusters: Cluster[] = []\n for (const [lane, list] of lanes) {\n list.sort((a, b) => a.y - b.y)\n let current: Cluster | null = null\n for (const { mark, y } of list) {\n if (current && y <= current.y + current.h + 1) {\n current.h = Math.max(current.h, y + h - current.y)\n if (LOUDNESS[mark.kind] > LOUDNESS[current.kind]) {\n current.kind = mark.kind\n }\n current.marks.push({ mark, y })\n } else {\n current = { lane, kind: mark.kind, y, h, marks: [{ mark, y }] }\n clusters.push(current)\n }\n }\n }\n return clusters\n}\n\nexport function approvalCluster(railH: number): Cluster {\n return {\n lane: LANE.approval,\n kind: 'approval',\n y: Math.max(0, railH - MIN_MARK),\n h: MIN_MARK,\n marks: [],\n }\n}\n","import { useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport type { PermissionRequest } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { toolInputPreview } from '../../lib/format.ts'\nimport { cn } from '../../lib/utils.ts'\nimport {\n approvalCluster,\n buildMarks,\n clusterMarks,\n doneLine,\n excerpt,\n KIND_NAME,\n nearestMember,\n type Cluster,\n type Mark,\n} from './scrubber-marks.ts'\n\nexport interface ScrubberProps {\n items: readonly TranscriptItem[]\n pendingApprovals: readonly PermissionRequest[]\n recapItemIndex?: number\n bookmarks?: readonly number[]\n frameParentId?: string\n interactive?: boolean\n onJumpToItem?: (itemIndex: number) => void\n className?: string\n}\n\nfunction peekContent(\n cluster: Cluster,\n first: Mark | undefined,\n items: readonly TranscriptItem[],\n pendingApprovals: readonly PermissionRequest[],\n): ReactNode {\n const more = cluster.marks.length > 1 ? ` · ${cluster.marks.length} marks` : ''\n let body: ReactNode = null\n if (cluster.kind === 'approval') {\n const request = pendingApprovals[0]\n body = request ? (\n <>\n <div>{request.title ?? 'Permission required'}</div>\n <div className=\"wd-scrub-ex\" data-tone=\"muted\">\n {`${request.displayName ?? request.toolName}(${toolInputPreview(request.input)})`}\n </div>\n </>\n ) : null\n } else if (first && first.kind !== 'recap') {\n const item = items[first.itemIndex]\n if (first.kind === 'turn' || first.kind === 'turnFailed') {\n const turn = first.turnIndex === undefined ? undefined : items[first.turnIndex]\n body = (\n <>\n {item?.kind === 'assistant_text' ? <div className=\"wd-scrub-ex\">{item.text}</div> : null}\n {turn?.kind === 'turn_result' ? (\n <>\n <div data-tone={turn.isError ? 'danger' : 'muted'}>{doneLine(turn)}</div>\n {turn.errors?.map((message, index) => (\n <div key={index} data-tone=\"danger\">\n {message}\n </div>\n ))}\n </>\n ) : null}\n </>\n )\n } else if (item) {\n const failure =\n first.kind === 'toolFailed' && item.kind === 'tool_call'\n ? item.result?.text.split('\\n').find((line) => line.trim() !== '')\n : undefined\n body = (\n <>\n <div className=\"wd-scrub-ex\" data-tone={first.kind === 'error' || first.kind === 'toolFailed' ? 'danger' : undefined}>\n {first.kind === 'user' ? <span data-tone=\"muted\">{'❯ '}</span> : null}\n {excerpt(item)}\n </div>\n {failure ? (\n <div className=\"wd-scrub-ex\" data-tone=\"danger\">\n {failure}\n </div>\n ) : null}\n </>\n )\n }\n }\n return (\n <>\n <div data-tone=\"muted\">\n {KIND_NAME[first?.kind ?? cluster.kind]}\n {more}\n </div>\n {body}\n </>\n )\n}\n\nexport function Scrubber({\n items,\n pendingApprovals,\n recapItemIndex,\n bookmarks,\n frameParentId,\n interactive = false,\n onJumpToItem,\n className,\n}: ScrubberProps) {\n const railRef = useRef<HTMLDivElement | null>(null)\n const peekRef = useRef<HTMLDivElement | null>(null)\n const [railH, setRailH] = useState(0)\n const [peek, setPeek] = useState<{ cluster: Cluster; mark: Mark | undefined; y: number } | null>(null)\n\n useEffect(() => {\n const element = railRef.current\n if (!element) {\n return\n }\n const observer = new ResizeObserver(() => setRailH(element.clientHeight))\n observer.observe(element)\n setRailH(element.clientHeight)\n return () => observer.disconnect()\n }, [])\n\n useEffect(() => {\n setPeek(null)\n }, [items])\n\n useLayoutEffect(() => {\n const element = peekRef.current\n if (!element || !peek) {\n return\n }\n const height = element.offsetHeight\n const railHeight = railRef.current?.clientHeight ?? 0\n element.style.top = `${Math.max(4, Math.min(railHeight - height - 4, peek.y - height / 2))}px`\n }, [peek])\n\n const clusters = useMemo(() => {\n if (railH <= 0) {\n return []\n }\n const built = clusterMarks(buildMarks(items, { frameParentId, bookmarks, recapItemIndex }), railH, items.length)\n if (pendingApprovals.length > 0) {\n built.push(approvalCluster(railH))\n }\n return built\n }, [items, frameParentId, bookmarks, recapItemIndex, pendingApprovals, railH])\n\n const railY = (clientY: number): number => clientY - (railRef.current?.getBoundingClientRect().top ?? 0)\n\n const activate = (cluster: Cluster, clientY: number) => {\n if (cluster.kind === 'approval' && cluster.marks.length === 0) {\n if (items.length > 0) {\n onJumpToItem?.(items.length - 1)\n }\n return\n }\n const mark = nearestMember(cluster, railY(clientY))\n if (mark) {\n onJumpToItem?.(mark.itemIndex)\n }\n }\n\n const showPeek = (cluster: Cluster, clientY: number) => {\n const y = railY(clientY)\n const mark = nearestMember(cluster, y)\n setPeek((previous) =>\n previous && previous.cluster === cluster && previous.mark === mark\n ? previous\n : { cluster, mark, y: Math.min(Math.max(y, cluster.y), cluster.y + cluster.h) },\n )\n }\n\n return (\n <div ref={railRef} className={cn('wd-scrubber', className)} data-interactive={interactive || undefined} aria-hidden>\n {clusters.map((cluster, index) => (\n <div\n key={index}\n className=\"wd-scrub-mark\"\n data-lane={cluster.lane}\n data-kind={cluster.kind}\n style={{ top: cluster.y, height: cluster.h }}\n {...(interactive\n ? {\n onClick: (event) => activate(cluster, event.clientY),\n onPointerEnter: (event) => showPeek(cluster, event.clientY),\n onPointerMove: (event) => showPeek(cluster, event.clientY),\n onPointerLeave: () => setPeek(null),\n }\n : null)}\n />\n ))}\n {peek ? (\n <div ref={peekRef} className=\"wd-scrub-peek\" style={{ top: peek.y }}>\n {peekContent(peek.cluster, peek.mark, items, pendingApprovals)}\n </div>\n ) : null}\n </div>\n )\n}\n","import type { TranscriptItem } from '@workerdeck/react'\nimport { needsBlank, type TerminalBlock } from '../terminal/blocks.ts'\n\nconst absorbedCache = new WeakMap<readonly TranscriptRow[], Map<number, number>>()\nconst positionCache = new WeakMap<readonly TranscriptRow[], Map<number, RowPosition>>()\n\nexport type TranscriptRow = TerminalBlock | { key: 'recap'; line: string } | { key: 'brief'; text: string }\n\nexport function rowItem(row: TranscriptRow | undefined): TranscriptItem | undefined {\n if (!row) {\n return undefined\n }\n if ('item' in row) {\n return row.item\n }\n if ('run' in row) {\n return row.run[0]\n }\n if ('task' in row) {\n return row.task\n }\n return undefined\n}\n\nexport function gapBefore(rows: TranscriptRow[], index: number): boolean {\n const before = rowItem(rows[index - 1])\n const after = rowItem(rows[index])\n if (!before || !after) {\n return true\n }\n return needsBlank(before, after)\n}\n\nfunction absorbedRows(rows: readonly TranscriptRow[]): Map<number, number> {\n const hit = absorbedCache.get(rows)\n if (hit) {\n return hit\n }\n const map = new Map<number, number>()\n rows.forEach((row, rowIndex) => {\n if ('task' in row) {\n for (const itemIndex of row.childIndices) {\n map.set(itemIndex, rowIndex)\n }\n }\n })\n absorbedCache.set(rows, map)\n return map\n}\n\nexport function rowIndexForItem(rows: readonly TranscriptRow[], itemIndex: number): number {\n const absorbed = absorbedRows(rows).get(itemIndex)\n if (absorbed !== undefined) {\n return absorbed\n }\n let lo = 0\n let hi = rows.length - 1\n let best = 0\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const row = rows[mid]!\n let start: number\n if ('index' in row) {\n start = row.index\n } else {\n const next = rows[mid + 1]\n start = next && 'index' in next ? next.index : Number.MAX_SAFE_INTEGER\n }\n if (start <= itemIndex) {\n if ('index' in row) {\n best = mid\n }\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n return best\n}\n\nexport type RowPosition = { ordinal: number; count: number }\n\nfunction rowPositions(rows: readonly TranscriptRow[]): Map<number, RowPosition> {\n const hit = positionCache.get(rows)\n if (hit) {\n return hit\n }\n const map = new Map<number, RowPosition>()\n for (const row of rows) {\n if ('task' in row) {\n const count = row.childIndices.length\n row.childIndices.forEach((itemIndex, ordinal) => map.set(itemIndex, { ordinal, count }))\n } else if ('run' in row && row.run.length > 1) {\n const count = row.run.length\n row.indices.forEach((itemIndex, ordinal) => map.set(itemIndex, { ordinal, count }))\n }\n }\n positionCache.set(rows, map)\n return map\n}\n\nexport function positionInRow(rows: readonly TranscriptRow[], itemIndex: number): RowPosition | undefined {\n return rowPositions(rows).get(itemIndex)\n}\n","import { useEffect, useState, type RefObject } from 'react'\nimport { createHeightEpoch, measureCh, type HeightEpoch } from '../terminal/height.ts'\n\nexport function useHeightEpoch(options: {\n terminal: boolean\n fontSize?: number\n lineHeight?: number\n rowsRef: RefObject<HTMLDivElement | null>\n}): HeightEpoch | null {\n const { terminal, fontSize, lineHeight, rowsRef } = options\n const [epoch, setEpoch] = useState<HeightEpoch | null>(null)\n useEffect(() => {\n if (!terminal) {\n return\n }\n const element = rowsRef.current\n if (!element) {\n return\n }\n let timer: ReturnType<typeof setTimeout> | undefined\n const measure = () => {\n const line = Number.parseFloat(getComputedStyle(element).getPropertyValue('--term-line'))\n const width = element.clientWidth\n const ch = measureCh(element)\n if (!line || !width || !ch) {\n return\n }\n setEpoch((previous) =>\n previous && previous.width === width && previous.ch === ch && previous.line === line\n ? previous\n : createHeightEpoch(width, ch, line),\n )\n }\n const observer = new ResizeObserver(() => {\n clearTimeout(timer)\n timer = setTimeout(measure, 150)\n })\n observer.observe(element)\n measure()\n return () => {\n observer.disconnect()\n clearTimeout(timer)\n }\n }, [terminal, fontSize, lineHeight, rowsRef])\n return epoch\n}\n","import { useEffect, useRef, type RefObject } from 'react'\nimport type { Virtualizer } from '@tanstack/react-virtual'\nimport type { useStickToBottomContext } from 'use-stick-to-bottom'\nimport type { HeightEpoch } from '../terminal/height.ts'\nimport { gapBefore, type TranscriptRow } from './transcript-rows.ts'\n\nconst AIM_PASSES = 4\nconst AIM_SETTLE_MS = 50\n\n/** How long a send's re-pin outlasts the click — long enough to eat a trackpad's momentum tail. */\nexport const REPIN_HOLD_MS = 750\n\ntype RepinTarget = Pick<ReturnType<typeof useStickToBottomContext>, 'scrollToBottom' | 'state'>\n\n/**\n * The send re-pin: a held, escape-proof pin, not one `scrollToBottom('instant')` — a trackpad's\n * trailing momentum tick reads as escape intent and aborts the one-shot before its first frame\n * (GOTCHAS \"The send re-pin is a held pin\"). Every line is load-bearing: clear the stale escape\n * flag, hold through the momentum tail, seed the `ignoreEscapes` record the library only\n * installs one rAF too late, and press the first scroll synchronously. Deliberate detach\n * (`stopScroll`, drag-selection) still wins immediately.\n */\nexport function repinToBottom(stick: RepinTarget): void {\n const { state } = stick\n state.escapedFromLock = false\n const settled = stick.scrollToBottom({ animation: 'instant', ignoreEscapes: true, duration: REPIN_HOLD_MS })\n state.animation = { behavior: 'instant', ignoreEscapes: true, promise: Promise.resolve(settled) }\n state.scrollTop = state.calculatedTargetScrollTop\n}\n\nexport function useTranscriptJumps(options: {\n rows: TranscriptRow[]\n terminal: boolean\n stickyPrompt: boolean\n epoch: HeightEpoch | null\n promptRows: readonly number[]\n scrollElement: HTMLElement | null\n rowsRef: RefObject<HTMLDivElement | null>\n virtualizer: Virtualizer<HTMLElement, HTMLDivElement>\n stick: ReturnType<typeof useStickToBottomContext>\n jumpToRecapRef?: RefObject<(() => void) | null>\n repinRef?: RefObject<(() => void) | null>\n}): (rowIndex: number, align?: 'start' | 'center') => void {\n const { rows, terminal, stickyPrompt, epoch, promptRows, scrollElement, rowsRef, virtualizer, stick, jumpToRecapRef, repinRef } = options\n\n const aimTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n useEffect(() => () => clearTimeout(aimTimer.current), [])\n\n const jumpToRow = (rowIndex: number, align: 'start' | 'center' = 'center') => {\n if (rowIndex < 0 || rowIndex >= rows.length || !scrollElement) {\n return\n }\n stick.stopScroll()\n clearTimeout(aimTimer.current)\n // `'start'` computes the offset itself, never `scrollIntoView`: a prompt row is `position: sticky`, and while stuck its current rect is where it is pinned, so the jump would no-op on exactly the rows the scrubber's left lane points at.\n if (align === 'start') {\n const linePad = (index: number) => (terminal && epoch && index > 0 && gapBefore(rows, index) ? epoch.line : 0)\n const target = () => {\n const start = virtualizer.measurementsCache[rowIndex]?.start ?? 0\n const spacer = rowsRef.current\n ? rowsRef.current.getBoundingClientRect().top - scrollElement.getBoundingClientRect().top + scrollElement.scrollTop\n : 0\n let top = start + spacer + linePad(rowIndex)\n if (terminal && stickyPrompt && epoch && !promptRows.includes(rowIndex)) {\n const pinned = promptRows.some((index) => index < rowIndex)\n if (pinned) {\n top -= epoch.line\n }\n }\n return Math.round(top)\n }\n const aim = (attempt: number) => {\n const top = target()\n scrollElement.scrollTo({ top, behavior: 'instant' })\n if (attempt >= AIM_PASSES) {\n return\n }\n aimTimer.current = setTimeout(() => {\n if (Math.abs(scrollElement.scrollTop - target()) > 1) {\n aim(attempt + 1)\n }\n }, AIM_SETTLE_MS)\n }\n aim(0)\n return\n }\n const aim = (attempt: number) => {\n const row = scrollElement.querySelector(`[data-index=\"${rowIndex}\"]`)\n if (row) {\n row.scrollIntoView({ behavior: 'instant', block: align })\n return\n }\n if (attempt >= AIM_PASSES) {\n return\n }\n virtualizer.scrollToIndex(rowIndex, { align, behavior: 'auto' })\n aimTimer.current = setTimeout(() => aim(attempt + 1), AIM_SETTLE_MS)\n }\n aim(0)\n }\n\n useEffect(() => {\n if (!jumpToRecapRef) {\n return\n }\n jumpToRecapRef.current = () => {\n jumpToRow(\n rows.findIndex((row) => row.key === 'recap'),\n 'start',\n )\n }\n return () => {\n jumpToRecapRef.current = null\n }\n })\n\n useEffect(() => {\n if (!repinRef) {\n return\n }\n repinRef.current = () => {\n // A pending jump's re-aim would land after the re-pin and yank the view back up.\n clearTimeout(aimTimer.current)\n repinToBottom(stick)\n }\n return () => {\n repinRef.current = null\n }\n })\n\n return jumpToRow\n}\n","import { Fragment, useEffect, useMemo, useState } from 'react'\nimport type { TranscriptItem, TranscriptState } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\nimport type { TerminalAffordances } from './affordances.tsx'\nimport { OpenSubagentAction, WithActions } from './affordances.tsx'\nimport { AssistantRow, CompactionRow, FileRow, NoticeRow, ToolRunRow, ThinkingRow, ToolRow, TurnResultRow, UserRow, WorkingRow } from './items.tsx'\nimport { blockNeedsBlank, taskChildItems, terminalBlocks, type TaskBlock } from './blocks.ts'\nimport { usePulse } from '../agent/pulse.tsx'\nimport { Pressable, useRevealOnOpen } from './press.tsx'\nimport { taskBrief, taskBusy, taskFailed, taskSummary } from './tool-run.ts'\nimport { BRIEF_LINES } from './height.ts'\nimport { Blank, Row } from './row.tsx'\nimport { TerminalSurface } from './surface.tsx'\n\nexport interface TerminalTranscriptProps {\n state: TranscriptState\n fileUrl?: (path: string) => string\n fontSize?: number\n lineHeight?: number\n affordances?: TerminalAffordances | boolean\n className?: string\n}\n\nexport function TerminalItemView({ item, fileUrl }: { item: TranscriptItem; fileUrl?: (path: string) => string }) {\n switch (item.kind) {\n case 'user': {\n return <UserRow item={item} />\n }\n case 'assistant_text': {\n return <AssistantRow item={item} />\n }\n case 'thinking': {\n return <ThinkingRow item={item} />\n }\n case 'tool_call': {\n return <ToolRow item={item} />\n }\n case 'turn_result': {\n return <TurnResultRow item={item} />\n }\n case 'notice': {\n return <NoticeRow item={item} />\n }\n case 'compaction': {\n return <CompactionRow />\n }\n case 'file_delivered': {\n return <FileRow item={item} href={fileUrl?.(item.path)} />\n }\n default: {\n return null\n }\n }\n}\n\nexport function BriefRow({ text, terminal }: { text: string; terminal?: boolean }) {\n const [open, setOpen] = useState(false)\n if (!terminal) {\n return (\n <div data-slot=\"brief\" className=\"px-4 py-2 text-body-sm whitespace-pre-wrap text-fg-2\">\n {text}\n </div>\n )\n }\n return (\n <div data-slot=\"brief\">\n <Pressable onPress={() => setOpen((v) => !v)} expanded={open}>\n <Row glyph=\">\" glyphTone=\"blue\" tone=\"dim\">\n <span\n className={cn('whitespace-pre-wrap', !open && 'term-brief-clip')}\n style={open ? undefined : { WebkitLineClamp: BRIEF_LINES }}\n >\n {text}\n </span>\n </Row>\n </Pressable>\n </div>\n )\n}\n\nexport function TaskRow({\n block,\n fileUrl,\n onOpenSubagent,\n}: {\n block: TaskBlock\n fileUrl?: (path: string) => string\n onOpenSubagent?: (toolUseId: string) => void\n}) {\n const [open, setOpen] = useState(false)\n const reveal = useRevealOnOpen(open)\n const children = useMemo(() => taskChildItems(block), [block])\n const brief = children.some((item) => item.kind === 'user') ? undefined : taskBrief(block.task)\n const busy = taskBusy(block.task, children)\n const failed = taskFailed(block.task)\n const pulse = usePulse(busy)\n\n const row = (\n <div ref={reveal} className={open ? 'term-open' : undefined}>\n <Pressable onPress={() => setOpen((v) => !v)} expanded={open}>\n <Row glyph={busy ? pulse : '●'} glyphTone={failed ? 'red' : busy ? 'mark' : 'dim'} tone={failed ? 'red' : 'green'}>\n {taskSummary(block.task, children)}\n </Row>\n </Pressable>\n {open ? (\n <div className=\"term-nested\">\n {brief ? <BriefRow text={brief} terminal /> : null}\n {block.children.map((leaf, index) => (\n <Fragment key={leaf.key}>\n {index > 0 && blockNeedsBlank(block.children[index - 1]!, leaf) ? <Blank /> : null}\n {'run' in leaf ? <ToolRunRow items={leaf.run} /> : <TerminalItemView item={leaf.item} fileUrl={fileUrl} />}\n </Fragment>\n ))}\n </div>\n ) : null}\n </div>\n )\n return onOpenSubagent === undefined ? (\n row\n ) : (\n <WithActions actions={<OpenSubagentAction onOpen={() => onOpenSubagent(block.task.id)} />}>{row}</WithActions>\n )\n}\n\nfunction useRunStart(status: TranscriptState['status']): number | undefined {\n const running = status === 'running' || status === 'starting'\n const [startedAt, setStartedAt] = useState<number | undefined>(undefined)\n useEffect(() => {\n setStartedAt((previous) => (running ? (previous ?? Date.now()) : undefined))\n }, [running])\n return running ? startedAt : undefined\n}\n\nfunction working(state: TranscriptState): boolean {\n if (state.status !== 'running' && state.status !== 'starting') {\n return false\n }\n const last = state.items.at(-1)\n if (!last) {\n return true\n }\n if (last.kind === 'assistant_text' && last.streaming) {\n return false\n }\n if (last.kind === 'thinking' && last.id === 'streaming-thinking') {\n return false\n }\n return true\n}\n\nexport function TerminalTranscript({ state, fileUrl, fontSize, lineHeight, affordances, className }: TerminalTranscriptProps) {\n const runStartedAt = useRunStart(state.status)\n const blocks = useMemo(() => terminalBlocks(state.items), [state.items])\n return (\n <TerminalSurface\n fontSize={fontSize}\n lineHeight={lineHeight}\n affordances={affordances}\n bleed=\"1ch\"\n className={cn('term-transcript', className)}\n >\n {blocks.map((block, index) => (\n <Fragment key={block.key}>\n {index > 0 && blockNeedsBlank(blocks[index - 1]!, block) ? <Blank /> : null}\n {'run' in block ? (\n <ToolRunRow items={block.run} />\n ) : 'item' in block ? (\n <TerminalItemView item={block.item} fileUrl={fileUrl} />\n ) : (\n <TaskRow block={block} fileUrl={fileUrl} />\n )}\n </Fragment>\n ))}\n {working(state) ? (\n <>\n {state.items.length > 0 ? <Blank /> : null}\n <WorkingRow\n label={state.status === 'starting' ? 'Starting…' : 'Working…'}\n startedAt={runStartedAt}\n tokens={state.contextUsage?.totalTokens}\n />\n </>\n ) : null}\n </TerminalSurface>\n )\n}\n","import type { TranscriptItem } from '@workerdeck/react'\nimport { Download, FileText } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { formatBytes } from '../../lib/format.ts'\n\nexport type FileDeliveredItem = Extract<TranscriptItem, { kind: 'file_delivered' }>\n\nexport interface FileCardProps {\n item: FileDeliveredItem\n href?: string\n className?: string\n}\n\nexport function FileCard({ item, href, className }: FileCardProps) {\n const name = item.path.split('/').pop() || item.path\n return (\n <div\n data-slot=\"file-delivered\"\n className={cn('flex w-full items-center gap-3 rounded-lg border border-border bg-surface px-3 py-2.5', className)}\n >\n <FileText className=\"size-4 shrink-0 text-fg-3\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate font-mono text-body-sm font-medium text-fg-1\">{name}</div>\n <div className=\"truncate text-label text-fg-4\">\n {formatBytes(item.bytes)}\n {item.description ? ` · ${item.description}` : ''}\n </div>\n </div>\n {href ? (\n <a\n href={href}\n download={name}\n className={cn(\n 'flex shrink-0 items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5',\n 'text-body-sm text-fg-2 transition-colors hover:bg-surface-hover',\n )}\n >\n <Download className=\"size-3.5\" />\n Download\n </a>\n ) : null}\n </div>\n )\n}\n","import type { HTMLAttributes } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport interface MessageProps extends HTMLAttributes<HTMLDivElement> {\n from: 'user' | 'assistant'\n}\n\nexport function Message({ from, className, children, ...props }: MessageProps) {\n return (\n <div data-slot=\"message\" data-from={from} className={cn('flex w-full flex-col items-start gap-1', className)} {...props}>\n {children}\n </div>\n )\n}\n\nexport function MessageContent({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n data-slot=\"message-content\"\n className={cn(\n 'min-w-0 text-body-sm leading-6 text-fg-1',\n 'in-data-[from=user]:max-w-[85%] in-data-[from=user]:rounded-lg in-data-[from=user]:rounded-bl-sm',\n 'in-data-[from=user]:bg-accent-bg in-data-[from=user]:px-3 in-data-[from=user]:py-2',\n 'in-data-[from=user]:whitespace-pre-wrap',\n 'in-data-[from=assistant]:w-full',\n className,\n )}\n {...props}\n />\n )\n}\n","import { Fragment } from 'react'\nimport { scanPromptTokens } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\n\nexport function PromptTokenText({ text, className }: { text: string; className?: string }) {\n const tokens = scanPromptTokens(text)\n if (tokens.length === 0) {\n return <span className={className}>{text}</span>\n }\n const parts: React.ReactNode[] = []\n let cursor = 0\n for (const [index, token] of tokens.entries()) {\n if (token.start > cursor) {\n parts.push(text.slice(cursor, token.start))\n }\n parts.push(\n <span key={`${token.start}-${index}`} className={cn('font-mono', token.kind === 'file' ? 'text-accent' : 'text-info')}>\n {token.text}\n </span>,\n )\n cursor = token.end\n }\n if (cursor < text.length) {\n parts.push(text.slice(cursor))\n }\n return (\n <span className={className}>\n {parts.map((part, index) => (\n <Fragment key={index}>{part}</Fragment>\n ))}\n </span>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { Brain, ChevronDown } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { Response } from './Response.tsx'\n\nexport interface ReasoningProps {\n children: string\n isStreaming?: boolean\n defaultOpen?: boolean\n className?: string\n}\n\nexport function Reasoning({ children, isStreaming = false, defaultOpen, className }: ReasoningProps) {\n const [open, setOpen] = useState(defaultOpen ?? isStreaming)\n const userToggled = useRef(false)\n\n useEffect(() => {\n if (userToggled.current) {\n return\n }\n if (isStreaming) {\n setOpen(true)\n } else {\n const timer = setTimeout(() => setOpen(false), 600)\n return () => clearTimeout(timer)\n }\n }, [isStreaming])\n\n const hasText = children.trim() !== ''\n if (!hasText && !isStreaming) {\n return null\n }\n\n return (\n <div data-slot=\"reasoning\" data-streaming={isStreaming || undefined} className={cn('w-full', className)}>\n <button\n type=\"button\"\n disabled={!hasText}\n onClick={() => {\n userToggled.current = true\n setOpen((v) => !v)\n }}\n className=\"flex items-center gap-1.5 text-label text-fg-3 transition-colors outline-none disabled:cursor-default hover:text-fg-1 disabled:hover:text-fg-3\"\n >\n <Brain className=\"size-3.5\" />\n <span>{isStreaming ? 'Thinking…' : 'Thought process'}</span>\n {hasText ? <ChevronDown className={cn('size-3.5 transition-transform', open && 'rotate-180')} /> : null}\n </button>\n {open && hasText ? (\n <div className=\"mt-2 border-l-2 border-border pl-3 text-body-sm text-fg-3 [&_*]:text-fg-3\">\n <Response streaming={isStreaming}>{children}</Response>\n </div>\n ) : null}\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { ChevronDown, Clock } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { CodeBlock } from '../ui/CodeBlock.tsx'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { toolInputPreview } from '../../lib/format.ts'\nimport { toolIcon } from '../../lib/tool-icon.ts'\nimport { useToolResultFetcher } from './tool-result-fetch.tsx'\nimport { useToolResultImageSrc } from './tool-result-image.tsx'\nimport { IMAGE_UNAVAILABLE, imagePlaceholder } from '../terminal/image-box.ts'\n\nexport type ToolCallItem = Extract<TranscriptItem, { kind: 'tool_call' }>\n\nconst RESULT_PREVIEW_CHARS = 2000\n\nconst IMAGE_TOOLS = new Set(['CodexImageGeneration', 'CodexImageView'])\n\nfunction imagePathOf(item: ToolCallItem): string | undefined {\n if (!IMAGE_TOOLS.has(item.name)) {\n return undefined\n }\n const input = item.input as { savedPath?: unknown; path?: unknown } | null\n const path = input?.savedPath ?? input?.path\n return typeof path === 'string' ? path : undefined\n}\n\nexport interface ToolCallCardProps {\n item: ToolCallItem\n hostImage?: (path: string) => Promise<string | undefined>\n className?: string\n}\n\nconst STATE_BADGE = {\n running: { label: 'Running', variant: 'info', busy: true },\n pending: { label: 'Executing', variant: 'info', busy: true },\n deferred: { label: 'Deferred', variant: 'accent', busy: false },\n settled: { label: 'Done', variant: 'success', busy: false },\n failed: { label: 'Error', variant: 'danger', busy: false },\n} as const\n\nconst EXTENSION_LANGUAGE: Record<string, string> = {\n ts: 'ts',\n tsx: 'tsx',\n js: 'js',\n jsx: 'jsx',\n mjs: 'js',\n cjs: 'js',\n json: 'json',\n jsonc: 'json',\n md: 'md',\n mdx: 'md',\n css: 'css',\n scss: 'scss',\n html: 'html',\n xml: 'xml',\n yml: 'yaml',\n yaml: 'yaml',\n toml: 'toml',\n py: 'python',\n rb: 'ruby',\n go: 'go',\n rs: 'rust',\n java: 'java',\n kt: 'kotlin',\n swift: 'swift',\n c: 'c',\n h: 'c',\n cpp: 'cpp',\n hpp: 'cpp',\n cs: 'csharp',\n php: 'php',\n sh: 'bash',\n bash: 'bash',\n zsh: 'bash',\n fish: 'fish',\n sql: 'sql',\n graphql: 'graphql',\n dockerfile: 'dockerfile',\n diff: 'diff',\n patch: 'diff',\n}\n\nfunction resultLanguage(item: ToolCallItem): string | undefined {\n if (item.name === 'Bash' || item.name === 'CodexCommand') {\n return 'bash'\n }\n if (item.name === 'CodexFileChange') {\n return 'diff'\n }\n const input = item.input as { file_path?: unknown; path?: unknown } | null\n const path = input?.file_path ?? input?.path\n if (typeof path !== 'string') {\n return undefined\n }\n const extension = path.slice(path.lastIndexOf('.') + 1).toLowerCase()\n return EXTENSION_LANGUAGE[extension]\n}\n\ntype Status = keyof typeof STATE_BADGE\n\nexport function ToolCallCard({ item, hostImage, className }: ToolCallCardProps) {\n const [open, setOpen] = useState(false)\n const [fullResult, setFullResult] = useState(false)\n const [fetching, setFetching] = useState(false)\n const fetchResult = useToolResultFetcher()\n const imagePath = imagePathOf(item)\n const status: Status = item.status ?? (item.result === undefined ? 'running' : 'settled')\n const badge = STATE_BADGE[status]\n const isError = status === 'failed' || item.result?.isError === true\n const Icon = toolIcon(item.name)\n\n const resultText = item.result?.text ?? ''\n const clipped = !fullResult && resultText.length > RESULT_PREVIEW_CHARS\n const shownResult = clipped ? resultText.slice(0, RESULT_PREVIEW_CHARS) : resultText\n const headOnly = item.result?.truncated === true\n const totalChars = item.result?.totalChars ?? resultText.length\n\n const details = open ? (\n <div className=\"flex flex-col gap-2 border-t border-border p-2.5\">\n <PlainPayload code={JSON.stringify(item.input, null, 2)} language=\"json\" label=\"Parameters\" />\n {item.logs?.length ? <PlainPayload code={item.logs.join('\\n')} label=\"Logs\" /> : null}\n {item.result !== undefined ? (\n <div>\n <PlainPayload\n code={shownResult || '(empty result)'}\n language={resultLanguage(item)}\n label={isError ? 'Error' : 'Result'}\n className={cn(isError && 'border-danger/40 [&_pre]:text-danger')}\n />\n {fetching ? (\n <p className=\"mt-1 text-label text-fg-3\">Fetching {totalChars.toLocaleString()} chars…</p>\n ) : clipped || headOnly ? (\n <button\n type=\"button\"\n className=\"mt-1 text-label text-fg-3 underline-offset-2 hover:underline\"\n onClick={() => {\n setFullResult(true)\n if (!headOnly) {\n return\n }\n setFetching(true)\n void fetchResult(item.id).finally(() => setFetching(false))\n }}\n >\n Show all {totalChars.toLocaleString()} chars\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null\n\n const image = imagePath && hostImage ? <HostImage path={imagePath} load={hostImage} /> : null\n\n const resultImages = item.result?.images?.length ? (\n <div className=\"flex flex-col gap-2 border-t border-border p-2.5\">\n {item.result.images.map((ref) => (\n <ResultImage key={ref.partIndex} toolUseId={item.id} image={ref} />\n ))}\n </div>\n ) : null\n\n return (\n <div\n data-slot=\"tool-call\"\n data-state={status}\n className={cn('w-full overflow-hidden rounded-lg border border-border bg-surface', className)}\n >\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n 'flex w-full items-center gap-2 px-3 py-2 text-left transition-colors outline-none',\n 'hover:bg-surface-hover focus-visible:bg-surface-hover',\n )}\n >\n <Icon className=\"size-3.5 shrink-0 text-fg-3\" />\n <span className=\"shrink-0 font-mono text-body-sm font-medium text-fg-1\">{item.name}</span>\n {item.backend && item.backend !== 'server' ? (\n <Badge variant=\"neutral\" className=\"shrink-0\">\n {item.backend}\n </Badge>\n ) : null}\n <span className=\"min-w-0 flex-1 truncate font-mono text-label text-fg-4\">{toolInputPreview(item.input)}</span>\n <Badge variant={badge.variant} dot={!badge.busy} className=\"shrink-0 gap-1\">\n {badge.busy ? <Spinner className=\"size-3 text-current\" /> : null}\n {status === 'deferred' ? <Clock className=\"size-3 text-current\" /> : null}\n {badge.label}\n </Badge>\n <ChevronDown className={cn('size-3.5 shrink-0 text-fg-4 transition-transform', open && 'rotate-180')} />\n </button>\n {image}\n {resultImages}\n {details}\n </div>\n )\n}\n\nfunction PlainPayload({ code, label, className }: { code: string; label: string; language?: string; className?: string }) {\n return <CodeBlock code={code} label={label} variant=\"panel\" className={className} />\n}\n\ntype ToolResultImage = NonNullable<NonNullable<ToolCallItem['result']>['images']>[number]\n\nfunction ResultImage({ toolUseId, image }: { toolUseId: string; image: ToolResultImage }) {\n const { src, failed } = useToolResultImageSrc({ toolUseId, ...image })\n return (\n <div className=\"flex h-60 items-start overflow-hidden rounded-md border border-border bg-surface-hover\">\n {src ? (\n <img src={src} alt={imagePlaceholder(image)} className=\"h-full max-w-full object-contain\" />\n ) : (\n <span className=\"p-2 text-label text-fg-4\">{failed ? IMAGE_UNAVAILABLE : imagePlaceholder(image)}</span>\n )}\n </div>\n )\n}\n\nfunction HostImage({ path, load }: { path: string; load: (path: string) => Promise<string | undefined> }) {\n const [src, setSrc] = useState<string | undefined>()\n useEffect(() => {\n let cancelled = false\n setSrc(undefined)\n load(path)\n .then((url) => {\n if (!cancelled) {\n setSrc(url)\n }\n })\n .catch(() => {})\n return () => {\n cancelled = true\n }\n }, [path, load])\n if (!src) {\n return null\n }\n return (\n <div className=\"border-t border-border p-2.5\">\n <img\n src={src}\n alt={path.split('/').pop() ?? 'Generated image'}\n className=\"max-h-96 w-auto max-w-full rounded-md border border-border\"\n />\n </div>\n )\n}\n","import type { MessageAttachment } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\nimport { COMPACTION_TEXT, formatCost, formatDuration, formatRelativeTime } from '../../lib/format.ts'\nimport { FileCard } from './FileCard.tsx'\nimport { Message, MessageContent } from './Message.tsx'\nimport { PromptTokenText } from './PromptTokenText.tsx'\nimport { Reasoning } from './Reasoning.tsx'\nimport { Response } from './Response.tsx'\nimport { ToolCallCard } from './ToolCallCard.tsx'\nimport { Row } from '../terminal/row.tsx'\nimport { TerminalItemView } from '../terminal/TerminalTranscript.tsx'\n\nfunction TurnResultRow({ item }: { item: Extract<TranscriptItem, { kind: 'turn_result' }> }) {\n return (\n <div data-slot=\"turn-result\" className=\"py-1\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-px flex-1 bg-border\" />\n <span className={cn('font-mono text-label', item.isError ? 'text-danger' : 'text-fg-4')}>\n {item.isError ? item.subtype : 'turn done'} · {formatDuration(item.durationMs)} · {formatCost(item.totalCostUsd)}\n </span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n {item.errors?.length ? (\n <ul className=\"mt-1 flex flex-col gap-0.5 text-center\">\n {item.errors.map((message, index) => (\n <li key={index} className=\"text-label break-words text-danger\">\n {message}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n )\n}\n\nfunction NoticeRow({ item }: { item: Extract<TranscriptItem, { kind: 'notice' }> }) {\n return (\n <div\n data-slot=\"notice\"\n className={cn(\n 'rounded-md border px-3 py-2 text-body-sm',\n item.level === 'error' ? 'border-transparent bg-danger-bg text-danger' : 'border-border bg-surface text-fg-3',\n )}\n >\n {item.text}\n </div>\n )\n}\n\n/** The item-view switch: one transcript item, drawn for the active variant. */\nexport function TranscriptItemView({\n item,\n fileUrl,\n attachmentUrl,\n hostImage,\n terminal,\n}: {\n item: TranscriptItem\n fileUrl?: (path: string) => string\n attachmentUrl?: (attachmentId: string) => string\n hostImage?: (path: string) => Promise<string | undefined>\n terminal?: boolean\n}) {\n if (terminal) {\n return <TerminalItemView item={item} fileUrl={fileUrl} />\n }\n switch (item.kind) {\n case 'user': {\n return (\n <Message from=\"user\">\n {item.attachments?.length ? <SentAttachments attachments={item.attachments} attachmentUrl={attachmentUrl} /> : null}\n {item.text ? (\n <MessageContent>\n <PromptTokenText text={item.text} />\n </MessageContent>\n ) : null}\n </Message>\n )\n }\n case 'assistant_text': {\n return (\n <Message from=\"assistant\">\n <MessageContent>\n <Response streaming={item.streaming}>{item.text}</Response>\n </MessageContent>\n </Message>\n )\n }\n case 'thinking': {\n return <Reasoning isStreaming={item.id === 'streaming-thinking'}>{item.text}</Reasoning>\n }\n case 'tool_call': {\n return <ToolCallCard item={item} hostImage={hostImage} />\n }\n case 'turn_result': {\n return <TurnResultRow item={item} />\n }\n case 'notice': {\n return <NoticeRow item={item} />\n }\n case 'compaction': {\n return <CompactionRow />\n }\n case 'file_delivered': {\n return <FileCard item={item} href={fileUrl?.(item.path)} />\n }\n default: {\n return null\n }\n }\n}\n\n/**\n * The cards spelling of a compaction boundary — a rule with the label through it, the same shape\n * `RecapRow` uses below, because both are boundaries rather than messages. The terminal spelling is\n * `terminal/items.tsx`'s `CompactionRow`, one grid row, and the two share `COMPACTION_TEXT`.\n */\nfunction CompactionRow() {\n return (\n <div data-slot=\"compaction\" className=\"flex items-center gap-2 py-1\">\n <div className=\"h-px flex-1 bg-border\" />\n <span className=\"font-mono text-label text-fg-3\">≡ {COMPACTION_TEXT}</span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n )\n}\n\nexport function RecapRow({ line, since, terminal }: { line: string; since?: number; terminal?: boolean }) {\n const away = since === undefined ? undefined : formatRelativeTime(since)\n const text = away ? `${line} · last here ${away}` : line\n\n if (terminal) {\n return (\n <div data-slot=\"recap\">\n <Row glyph=\"※\" glyphTone=\"faint\" tone=\"faint\">\n recap: {text}\n </Row>\n </div>\n )\n }\n\n return (\n <div data-slot=\"recap\" className=\"flex items-center gap-2 py-1\">\n <div className=\"h-px flex-1 bg-border\" />\n <span className=\"font-mono text-label text-fg-3\">※ recap: {text}</span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n )\n}\n\nfunction SentAttachments({\n attachments,\n attachmentUrl,\n}: {\n attachments: MessageAttachment[]\n attachmentUrl?: (attachmentId: string) => string\n}) {\n return (\n <div className=\"mb-1 flex flex-wrap justify-start gap-1.5\">\n {attachments.map((attachment) => {\n const href = attachmentUrl?.(attachment.id)\n return attachment.mediaType.startsWith('image/') && href ? (\n <img key={attachment.id} src={href} alt={attachment.name} className=\"size-20 rounded-md border border-border object-cover\" />\n ) : (\n <span key={attachment.id} className=\"rounded-full border border-border bg-surface px-2.5 py-1 text-body-xs text-fg-3\">\n {attachment.name}\n </span>\n )\n })}\n </div>\n )\n}\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode, type RefObject } from 'react'\nimport { createPortal } from 'react-dom'\nimport { defaultRangeExtractor, useVirtualizer, type Range } from '@tanstack/react-virtual'\nimport { useStickToBottomContext } from 'use-stick-to-bottom'\nimport type { PermissionRequest } from '@workerdeck/protocol'\nimport type { TranscriptItem } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\nimport { resolveAffordances, type TerminalAffordances } from '../terminal/affordances.tsx'\nimport { ToolRunRow } from '../terminal/items.tsx'\nimport { parentOf } from '../terminal/blocks.ts'\nimport { briefPx, estimateBlockPx } from '../terminal/height.ts'\nimport { TerminalScrubber } from '../terminal/scrubber.tsx'\nimport { Scrubber } from './Scrubber.tsx'\nimport { gapBefore, positionInRow, rowIndexForItem, type TranscriptRow } from './transcript-rows.ts'\nimport { useHeightEpoch } from './use-height-epoch.ts'\nimport { useTranscriptJumps } from './use-transcript-jumps.ts'\nimport { BriefRow, TaskRow } from '../terminal/TerminalTranscript.tsx'\nimport { RecapRow, TranscriptItemView } from './TranscriptItemView.tsx'\n\nfunction read(boundary: number | undefined, index: number): boolean {\n return boundary !== undefined && index < boundary\n}\n\nfunction nestedClass(item: TranscriptItem, frameParentId?: string): string | undefined {\n const parent = 'parentToolUseId' in item ? item.parentToolUseId : undefined\n const nested = parent != null && parent !== frameParentId\n return nested ? 'border-l-2 border-border pl-3' : undefined\n}\n\nfunction promptHeadText(item: Extract<TranscriptItem, { kind: 'user' }>): string {\n return item.text || (item.attachments ?? []).map((attachment) => attachment.name).join(', ')\n}\n\nfunction StickyPromptLane({\n top,\n height,\n gapClass,\n gapPx,\n terminal,\n scrollRoot,\n index,\n measureRef,\n head,\n content,\n}: {\n top: number\n height: number\n gapClass?: string | false\n gapPx: number\n terminal: boolean\n scrollRoot: HTMLElement | null\n index: number\n measureRef: (element: HTMLDivElement | null) => void\n head: ReactNode\n content: ReactNode\n}) {\n const headRef = useRef<HTMLDivElement | null>(null)\n const sentinelRef = useRef<HTMLDivElement | null>(null)\n useEffect(() => {\n const headElement = headRef.current\n const sentinel = sentinelRef.current\n if (!headElement || !sentinel || !scrollRoot) {\n return\n }\n const evaluate = () => {\n const stuck = sentinel.getBoundingClientRect().top < scrollRoot.getBoundingClientRect().top\n headElement.toggleAttribute('data-stuck', stuck)\n }\n evaluate()\n scrollRoot.addEventListener('scroll', evaluate, { passive: true })\n return () => scrollRoot.removeEventListener('scroll', evaluate)\n }, [scrollRoot, top, height, gapClass])\n return (\n <div data-sticky-lane={terminal ? 'terminal' : 'cards'} className=\"absolute inset-x-0\" style={{ top, height }}>\n <div data-sticky-headlane=\"\" aria-hidden>\n <div ref={headRef} data-sticky-head=\"\" className={(terminal && gapClass) || undefined}>\n {head}\n </div>\n </div>\n <div\n ref={sentinelRef}\n aria-hidden\n className=\"absolute left-0 w-px\"\n style={{ top: gapClass ? (terminal ? 'var(--term-line)' : gapPx) : 0, height: 1 }}\n />\n <div ref={measureRef} data-index={index} className={gapClass || undefined}>\n {content}\n </div>\n </div>\n )\n}\n\n/**\n * The virtualized row lane and its scroll-ownership regime. Two things want to write\n * `scrollTop` — the follow spring and the virtualizer's size-change corrections — and they are\n * split by regime here: pinned, corrections are suppressed outright; escaped, the virtualizer\n * corrects so the scrollback holds still (GOTCHAS \"The transcript is virtualized\").\n */\nexport function TranscriptRows({\n rows,\n boundary,\n since,\n terminal,\n replaying,\n stickyPrompt,\n frameParentId,\n onOpenSubagent,\n gap,\n fontSize,\n lineHeight,\n items,\n pendingApprovals,\n scrubber,\n bookmarks,\n affordances,\n fileUrl,\n attachmentUrl,\n hostImage,\n jumpToRecapRef,\n repinRef,\n reveal,\n}: {\n rows: TranscriptRow[]\n boundary: number | undefined\n since: number | undefined\n terminal: boolean\n replaying: boolean\n stickyPrompt: boolean\n gap: { className?: string; px: number }\n fontSize?: number\n lineHeight?: number\n items: readonly TranscriptItem[]\n pendingApprovals: readonly PermissionRequest[]\n scrubber?: boolean\n bookmarks?: readonly string[]\n frameParentId?: string\n onOpenSubagent?: (toolUseId: string) => void\n affordances?: TerminalAffordances | boolean\n fileUrl?: (path: string) => string\n attachmentUrl?: (attachmentId: string) => string\n hostImage?: (path: string) => Promise<string | undefined>\n jumpToRecapRef?: RefObject<(() => void) | null>\n repinRef?: RefObject<(() => void) | null>\n reveal?: { toolUseId: string; nonce: number }\n}) {\n const stick = useStickToBottomContext()\n const [scrollElement, setScrollElement] = useState<HTMLElement | null>(null)\n const promptRows = useMemo(\n () => rows.flatMap((row, index) => ('item' in row && row.item.kind === 'user' && parentOf(row.item) === undefined ? [index] : [])),\n [rows],\n )\n const pinRef = useRef<{ enabled: boolean; promptRows: readonly number[] }>({\n enabled: false,\n promptRows: [],\n })\n pinRef.current = { enabled: stickyPrompt, promptRows }\n useEffect(() => {\n // A passive effect, not a layout one: the scroll element belongs to an ancestor, so at mount its ref is not attached yet and a layout effect reads null.\n setScrollElement(stick.scrollRef.current)\n }, [stick.scrollRef])\n\n useEffect(() => {\n if (!scrollElement) {\n return\n }\n let last = scrollElement.clientHeight\n const observer = new ResizeObserver(() => {\n const height = scrollElement.clientHeight\n if (height === last) {\n return\n }\n last = height\n if (stick.state.isAtBottom) {\n void stick.scrollToBottom('instant')\n }\n })\n observer.observe(scrollElement)\n return () => observer.disconnect()\n }, [scrollElement, stick])\n\n const wasReplaying = useRef(replaying)\n useLayoutEffect(() => {\n const was = wasReplaying.current\n wasReplaying.current = replaying\n if (!was || replaying) {\n return\n }\n if (!stick.state.isAtBottom) {\n return\n }\n stick.state.scrollTop = stick.state.calculatedTargetScrollTop\n }, [replaying, stick])\n\n const rowsRef = useRef<HTMLDivElement | null>(null)\n const epoch = useHeightEpoch({ terminal, fontSize, lineHeight, rowsRef })\n\n const virtualizer = useVirtualizer<HTMLElement, HTMLDivElement>({\n count: rows.length,\n // The return type is annotated because the body reads `virtualizer` back: without it the inference is circular and tsgo gives up on the hook.\n getScrollElement: (): HTMLElement | null => {\n if (scrollElement && virtualizer.scrollElement !== scrollElement) {\n // On adopting a scroll element the virtualizer replays its remembered offset into the DOM, so syncing here keeps a remembered 0 from yanking a pinned transcript to the top.\n virtualizer.scrollOffset = scrollElement.scrollTop\n }\n return scrollElement\n },\n estimateSize: (index) => {\n if (terminal && epoch) {\n const row = rows[index]\n const gapPx = index > 0 && gapBefore(rows, index) ? epoch.line : 0\n if (row && 'text' in row && row.key === 'brief') {\n return briefPx(row.text, epoch) + gapPx\n }\n if (row && !('line' in row)) {\n return estimateBlockPx(row, epoch) + gapPx\n }\n return epoch.line + gapPx\n }\n return (terminal ? 36 : 100) + gap.px\n },\n overscan: 8,\n getItemKey: (index) => rows[index].key,\n rangeExtractor: useCallback((range: Range) => {\n const indexes = new Set(defaultRangeExtractor(range))\n const { enabled, promptRows: prompts } = pinRef.current\n if (enabled) {\n const offset = virtualizer.scrollOffset ?? 0\n let pinned = -1\n for (const index of prompts) {\n if ((virtualizer.measurementsCache[index]?.start ?? Infinity) <= offset) {\n pinned = index\n } else {\n break\n }\n }\n if (pinned >= 0) {\n indexes.add(pinned)\n }\n }\n return [...indexes].sort((a, b) => a - b)\n }, []),\n useFlushSync: true,\n })\n virtualizer.shouldAdjustScrollPositionOnItemSizeChange = (item, _delta, instance) => {\n if (stick.state.isAtBottom) {\n return false\n }\n const fold = (instance.scrollOffset ?? 0) + instance.scrollAdjustments\n return instance.itemSizeCache.has(item.key) ? item.end <= fold && instance.scrollDirection !== 'backward' : item.start < fold\n }\n\n useEffect(() => {\n if (!terminal || !epoch) {\n return\n }\n virtualizer.measure()\n const container = rowsRef.current\n if (!container) {\n return\n }\n virtualizer.getTotalSize()\n for (const element of container.querySelectorAll<HTMLElement>('[data-index]')) {\n const index = Number(element.getAttribute('data-index'))\n if (Number.isInteger(index) && index >= 0) {\n virtualizer.resizeItem(index, element.getBoundingClientRect().height)\n }\n }\n }, [terminal, epoch, virtualizer])\n\n const jumpToRow = useTranscriptJumps({\n rows,\n terminal,\n stickyPrompt,\n epoch,\n promptRows,\n scrollElement,\n rowsRef,\n virtualizer,\n stick,\n jumpToRecapRef,\n repinRef,\n })\n\n const revealNonce = reveal?.nonce\n const revealId = reveal?.toolUseId\n useEffect(() => {\n if (revealId === undefined) {\n return\n }\n const itemIndex = items.findIndex((item) => item.kind === 'tool_call' && item.id === revealId)\n if (itemIndex < 0) {\n return\n }\n jumpToRow(rowIndexForItem(rows, itemIndex), 'start')\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the nonce IS the trigger\n }, [revealNonce])\n\n const scrubInteractive = resolveAffordances(affordances).hover\n // Hosts hand bookmarks over as item ids (stable across replays); the mark model positions by\n // index, so the translation lives here where the items are. Ids not in this transcript (another\n // frame, a truncated replay) simply draw nothing.\n const bookmarkIndexes = useMemo(() => {\n if (!bookmarks?.length) {\n return []\n }\n const indexById = new Map(items.map((item, index) => [item.id, index]))\n return bookmarks.map((id) => indexById.get(id)).filter((index): index is number => index !== undefined)\n }, [bookmarks, items])\n const recapIndex = rows.findIndex((row) => row.key === 'recap')\n const recapRow = recapIndex >= 0 ? { rowIndex: recapIndex, label: (rows[recapIndex] as { line: string }).line } : undefined\n useEffect(() => {\n if (!terminal || !scrubber || !scrubInteractive || !scrollElement) {\n return\n }\n scrollElement.setAttribute('data-term-scrubber-host', '')\n return () => scrollElement.removeAttribute('data-term-scrubber-host')\n }, [terminal, scrubber, scrubInteractive, scrollElement])\n\n const measurements = virtualizer.measurementsCache\n\n return (\n <div ref={rowsRef} data-slot=\"transcript-rows\" className=\"relative w-full\" style={{ height: virtualizer.getTotalSize() }}>\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index]\n const gapClass = virtualRow.index > 0 && (!terminal || gapBefore(rows, virtualRow.index)) ? gap.className : undefined\n const content =\n 'run' in row ? (\n <div className={cn(read(boundary, row.index) && 'opacity-45')}>\n <ToolRunRow items={row.run} />\n </div>\n ) : 'item' in row ? (\n <div className={cn(read(boundary, row.index) && 'opacity-45', nestedClass(row.item, frameParentId))}>\n <TranscriptItemView\n item={row.item}\n fileUrl={fileUrl}\n attachmentUrl={attachmentUrl}\n hostImage={hostImage}\n terminal={terminal}\n />\n </div>\n ) : 'text' in row && row.key === 'brief' ? (\n <BriefRow text={row.text} terminal={terminal} />\n ) : 'line' in row ? (\n <RecapRow line={row.line} since={since} terminal={terminal} />\n ) : (\n <div className={cn(read(boundary, row.index) && 'opacity-45')}>\n <TaskRow block={row} fileUrl={fileUrl} onOpenSubagent={onOpenSubagent} />\n </div>\n )\n if (stickyPrompt && 'item' in row && row.item.kind === 'user' && parentOf(row.item) === undefined) {\n const next = promptRows.find((index) => index > virtualRow.index)\n const laneEnd = next === undefined ? virtualizer.getTotalSize() : (measurements[next]?.start ?? virtualRow.start)\n return (\n <StickyPromptLane\n key={row.key}\n top={virtualRow.start}\n height={Math.max(laneEnd - virtualRow.start, 0)}\n gapClass={gapClass}\n gapPx={gap.px}\n terminal={terminal}\n scrollRoot={scrollElement}\n index={virtualRow.index}\n measureRef={virtualizer.measureElement}\n head={terminal ? content : promptHeadText(row.item)}\n content={content}\n />\n )\n }\n return (\n <div\n key={row.key}\n ref={virtualizer.measureElement}\n data-index={virtualRow.index}\n className={cn('absolute inset-x-0 top-0', gapClass)}\n style={{ transform: `translateY(${virtualRow.start}px)` }}\n >\n {content}\n </div>\n )\n })}\n {scrubber && scrollElement?.parentElement\n ? createPortal(\n terminal ? (\n <TerminalScrubber\n items={items}\n pendingApprovals={pendingApprovals}\n recapRow={recapRow}\n bookmarks={bookmarkIndexes}\n frameParentId={frameParentId}\n rowIndexFor={(itemIndex) => rowIndexForItem(rows, itemIndex)}\n positionInRow={(itemIndex) => positionInRow(rows, itemIndex)}\n offsetOfRow={(rowIndex) => virtualizer.measurementsCache[rowIndex]?.start ?? 0}\n sizeOfRow={(rowIndex) => virtualizer.measurementsCache[rowIndex]?.size ?? 0}\n totalSize={virtualizer.getTotalSize()}\n scrollOffset={virtualizer.scrollOffset ?? 0}\n viewportH={virtualizer.scrollRect?.height ?? 0}\n onJumpToRow={(rowIndex) => jumpToRow(rowIndex, 'start')}\n interactive={scrubInteractive}\n fontSize={fontSize}\n lineHeight={lineHeight}\n />\n ) : (\n <Scrubber\n items={items}\n pendingApprovals={pendingApprovals}\n recapItemIndex={recapIndex >= 0 ? boundary : undefined}\n bookmarks={bookmarkIndexes}\n frameParentId={frameParentId}\n interactive={scrubInteractive}\n onJumpToItem={(itemIndex) => jumpToRow(rowIndexForItem(rows, itemIndex), 'start')}\n />\n ),\n scrollElement.parentElement,\n )\n : null}\n </div>\n )\n}\n","import { useEffect, useMemo, useState, type ReactNode, type RefObject } from 'react'\nimport { recapLine, summarizeSince, type TranscriptState } from '@workerdeck/react'\nimport { cn } from '../../lib/utils.ts'\nimport { Conversation, ConversationContent, ConversationScrollButton } from './Conversation.tsx'\nimport { Loader } from './Loader.tsx'\nimport { SessionEmptyState } from './SessionEmptyState.tsx'\nimport { type TerminalAffordances } from '../terminal/affordances.tsx'\nimport { WorkingRow } from '../terminal/items.tsx'\nimport { subagentItems, terminalBlocks, type ToolCallItem } from '../terminal/blocks.ts'\nimport { taskBrief, taskBusy } from '../terminal/tool-run.ts'\nimport { type TranscriptRow } from './transcript-rows.ts'\nimport { TranscriptRows } from './TranscriptRows.tsx'\nimport { TerminalSurface } from '../terminal/surface.tsx'\nimport { ROW_GAP, TranscriptVariantProvider, type TranscriptDensity, type TranscriptVariant } from './transcript-variant.tsx'\n\nfunction useRunStart(status: TranscriptState['status']): number | undefined {\n const running = status === 'running' || status === 'starting'\n const [startedAt, setStartedAt] = useState<number | undefined>(undefined)\n useEffect(() => {\n setStartedAt((previous) => (running ? (previous ?? Date.now()) : undefined))\n }, [running])\n return running ? startedAt : undefined\n}\n\nfunction showLoader(state: TranscriptState): boolean {\n if (state.status !== 'running' && state.status !== 'starting') {\n return false\n }\n const last = state.items.at(-1)\n if (!last) {\n return true\n }\n if (last.kind === 'assistant_text' && last.streaming) {\n return false\n }\n if (last.kind === 'thinking' && last.id === 'streaming-thinking') {\n return false\n }\n return last.kind !== 'turn_result' || state.status === 'running'\n}\n\nfunction TerminalShell({\n active,\n fontSize,\n lineHeight,\n affordances,\n children,\n}: {\n active: boolean\n fontSize?: number\n lineHeight?: number\n affordances?: TerminalAffordances | boolean\n children: ReactNode\n}) {\n if (!active) {\n return <>{children}</>\n }\n return (\n <TerminalSurface fontSize={fontSize} lineHeight={lineHeight} affordances={affordances} bleed=\"1ch\" className=\"term-transcript\">\n {children}\n </TerminalSurface>\n )\n}\n\nexport { rowIndexForItem, type TranscriptRow } from './transcript-rows.ts'\n\nexport interface TranscriptProps {\n state: TranscriptState\n fileUrl?: (path: string) => string\n attachmentUrl?: (attachmentId: string) => string\n canBrowseFiles?: boolean\n hostImage?: (path: string) => Promise<string | undefined>\n variant?: TranscriptVariant\n density?: TranscriptDensity\n fontSize?: number\n lineHeight?: number\n affordances?: TerminalAffordances | boolean\n stickyPrompt?: boolean\n scrubber?: boolean\n bookmarks?: readonly string[]\n replaying?: boolean\n catchUp?: { from: number; since?: number }\n jumpToRecapRef?: RefObject<(() => void) | null>\n repinRef?: RefObject<(() => void) | null>\n reveal?: { toolUseId: string; nonce: number }\n frame?: { parentToolUseId: string }\n onOpenSubagent?: (toolUseId: string) => void\n emptyState?: ReactNode\n className?: string\n}\n\nexport function Transcript({\n state,\n fileUrl,\n attachmentUrl,\n canBrowseFiles,\n hostImage,\n variant = 'cards',\n density = 'comfortable',\n fontSize,\n lineHeight,\n affordances,\n stickyPrompt = false,\n scrubber,\n bookmarks,\n replaying = false,\n catchUp,\n jumpToRecapRef,\n repinRef,\n reveal,\n frame,\n onOpenSubagent,\n emptyState,\n className,\n}: TranscriptProps) {\n const terminal = variant === 'terminal'\n const items = useMemo(() => (frame ? subagentItems(state.items, frame.parentToolUseId) : state.items), [state.items, frame])\n const frameTask = useMemo(\n () =>\n frame ? state.items.find((item): item is ToolCallItem => item.kind === 'tool_call' && item.id === frame.parentToolUseId) : undefined,\n [state.items, frame],\n )\n const gap = ROW_GAP[variant][density]\n const runStartedAt = useRunStart(state.status)\n const boundary = !frame && catchUp && catchUp.from > 0 && catchUp.from < state.items.length ? catchUp.from : undefined\n const recap = useMemo(() => (boundary === undefined ? undefined : recapLine(summarizeSince(state, boundary))), [state, boundary])\n const brief = useMemo(\n () => (frame && frameTask && !items.some((item) => item.kind === 'user') ? taskBrief(frameTask) : undefined),\n [frame, frameTask, items],\n )\n const rows = useMemo<TranscriptRow[]>(() => {\n const fold = (from: number, to: number) => terminalBlocks(items.slice(from, to), from, terminal)\n const lead: TranscriptRow[] = brief ? [{ key: 'brief' as const, text: brief }] : []\n if (boundary === undefined || !recap) {\n return [...lead, ...fold(0, items.length)]\n }\n return [...fold(0, boundary), { key: 'recap' as const, line: recap }, ...fold(boundary, items.length)]\n }, [items, boundary, recap, terminal, brief])\n return (\n <TranscriptVariantProvider value={variant}>\n <Conversation className={cn(replaying && 'invisible', className)}>\n <ConversationContent className={cn(terminal && 'gap-0 p-0')}>\n <TerminalShell active={terminal} fontSize={fontSize} lineHeight={lineHeight} affordances={affordances}>\n {frame ? (\n frameTask === undefined && !replaying ? (\n <div className={cn(terminal ? 'term-row text-fg-4' : 'p-4 text-body-sm text-fg-4')}>\n This sub-agent's work is not in this transcript.\n </div>\n ) : null\n ) : items.length === 0 && state.status !== 'starting' ? (\n emptyState !== undefined ? (\n emptyState\n ) : (\n <SessionEmptyState\n cwd={state.cwd}\n hasCommands={!!state.commands?.length}\n hasSkills={!!state.skills?.some((s) => s.enabled)}\n canBrowseFiles={canBrowseFiles}\n />\n )\n ) : null}\n {frame && frameTask === undefined && !replaying ? null : (\n <TranscriptRows\n rows={rows}\n boundary={boundary}\n since={catchUp?.since}\n terminal={terminal}\n replaying={replaying}\n stickyPrompt={!frame && stickyPrompt}\n gap={gap}\n fontSize={fontSize}\n lineHeight={lineHeight}\n items={items}\n pendingApprovals={state.pendingApprovals}\n scrubber={scrubber}\n bookmarks={frame ? undefined : bookmarks}\n affordances={affordances}\n fileUrl={fileUrl}\n attachmentUrl={attachmentUrl}\n hostImage={hostImage}\n jumpToRecapRef={jumpToRecapRef}\n repinRef={repinRef}\n reveal={frame ? undefined : reveal}\n frameParentId={frame?.parentToolUseId}\n onOpenSubagent={frame ? undefined : onOpenSubagent}\n />\n )}\n {(frame ? frameTask !== undefined && taskBusy(frameTask, items) : showLoader(state)) ? (\n terminal ? (\n <>\n {state.items.length > 0 ? <div className=\"term-blank\" aria-hidden /> : null}\n <WorkingRow\n label={state.status === 'starting' ? 'Starting…' : 'Working…'}\n startedAt={runStartedAt}\n tokens={state.contextUsage?.totalTokens}\n />\n </>\n ) : (\n <Loader\n label={state.status === 'starting' ? 'Starting session…' : undefined}\n startedAt={runStartedAt}\n tokens={state.contextUsage?.totalTokens}\n />\n )\n ) : null}\n </TerminalShell>\n </ConversationContent>\n <ConversationScrollButton />\n {replaying ? (\n <div\n data-slot=\"transcript-hold\"\n aria-hidden\n className=\"wd-hold-appear visible pointer-events-none absolute inset-0 overflow-hidden\"\n >\n <div className={cn('mx-auto w-full max-w-[var(--wd-transcript-max-width)]', !terminal && 'px-4 py-4')}>\n {terminal ? (\n <TerminalSurface fontSize={fontSize} lineHeight={lineHeight} affordances={false} bleed=\"1ch\" className=\"term-transcript\">\n <WorkingRow label=\"Loading…\" />\n </TerminalSurface>\n ) : (\n <Loader label=\"Loading session…\" />\n )}\n </div>\n </div>\n ) : null}\n </Conversation>\n </TranscriptVariantProvider>\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { UsageWindowRow } from '@workerdeck/protocol'\nimport { RotateCcw } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { formatAgoPrecise, formatCountdown, formatRateLimitWindowLong, rateLimitWindowSeconds } from '../../lib/format.ts'\nimport { meterTintClass } from '../../lib/status.ts'\n\nexport function useMinuteClock(active = true): number {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n if (!active) {\n return\n }\n setNow(Date.now())\n const timer = setInterval(() => setNow(Date.now()), 60_000)\n return () => clearInterval(timer)\n }, [active])\n return now\n}\n\nexport function UsageMeters({ windows, now, className }: { windows: UsageWindowRow[]; now?: number; className?: string }) {\n const ownClock = useMinuteClock(now === undefined)\n const clock = now ?? ownClock\n return (\n <div className={cn('flex flex-col gap-5', className)}>\n {windows.map((window) => (\n <UsageMeter key={window.key} window={window} now={clock} />\n ))}\n </div>\n )\n}\n\nfunction UsageMeter({ window, now }: { window: UsageWindowRow; now: number }) {\n const { key: windowKey, info, updatedAt, inferredReset } = window\n const utilization = info.utilization ?? 0\n const resetsAtMs = info.resetsAt !== undefined ? info.resetsAt * 1000 : undefined\n const duration = rateLimitWindowSeconds(windowKey)\n const remaining = resetsAtMs !== undefined ? (resetsAtMs - now) / 1000 : undefined\n const pace =\n duration !== undefined && remaining !== undefined && remaining > 0 && remaining < duration\n ? (duration - remaining) / duration\n : undefined\n return (\n <div>\n <div className=\"flex items-baseline justify-between gap-3\">\n <span className=\"truncate text-body-sm text-fg-1\">{formatRateLimitWindowLong(windowKey)}</span>\n <span className={cn('shrink-0 font-mono text-body-sm font-medium', info.status === 'rejected' ? 'text-danger' : 'text-fg-1')}>\n {utilization.toFixed(0)}% used\n </span>\n </div>\n <div className=\"relative mt-2 h-2 rounded-full bg-border\">\n <div\n className={cn('h-full rounded-full', meterTintClass(utilization))}\n style={{ width: `${Math.min(100, Math.max(2, utilization))}%` }}\n />\n {pace !== undefined ? (\n <span\n aria-hidden\n title=\"Spent evenly, usage would be here by now\"\n className=\"absolute -top-1 h-4 w-0.5 -translate-x-1/2 rounded-full bg-fg-1\"\n style={{ left: `${Math.min(100, Math.max(0, pace * 100))}%` }}\n />\n ) : null}\n </div>\n <div className=\"mt-1.5 flex items-center gap-3 text-label text-fg-4\">\n {resetsAtMs !== undefined ? (\n <span className=\"inline-flex items-center gap-1\">\n <RotateCcw className=\"size-3\" /> Resets in {formatCountdown(resetsAtMs, now)}\n </span>\n ) : null}\n {info.isUsingOverage ? <span className=\"text-warning\">overage</span> : null}\n {info.status === 'rejected' ? <span className=\"text-danger\">limit reached</span> : null}\n {inferredReset ? <span>window reset · nothing reported since</span> : null}\n {updatedAt && !inferredReset ? <span>{formatAgoPrecise(updatedAt, now)}</span> : null}\n </div>\n </div>\n )\n}\n","import type { ProfileEngine, UsageWindowRow } from '@workerdeck/protocol'\nimport { Badge } from '../ui/Badge.tsx'\nimport { Dialog, DialogBody, DialogContent, DialogHeader } from '../ui/Dialog.tsx'\nimport { formatAgoPrecise, formatCost } from '../../lib/format.ts'\nimport { UsageMeters, useMinuteClock } from './UsageMeters.tsx'\n\nexport interface UsageDialogProps {\n rateLimits: UsageWindowRow[]\n subscriptionType?: string\n engine: ProfileEngine\n totalCostUsd: number\n updatedAt?: number\n open: boolean\n onOpenChange: (open: boolean) => void\n className?: string\n}\n\nexport function UsageDialog({\n rateLimits,\n subscriptionType,\n engine,\n totalCostUsd,\n updatedAt,\n open,\n onOpenChange,\n className,\n}: UsageDialogProps) {\n const now = useMinuteClock(open)\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className={className}>\n <DialogHeader\n title=\"Usage\"\n description={engine === 'claude' ? 'Claude Code' : engine}\n actions={\n subscriptionType ? (\n <Badge variant=\"accent\" className=\"mt-0.5 shrink-0 capitalize\">\n {subscriptionType}\n </Badge>\n ) : null\n }\n />\n <DialogBody>\n {rateLimits.length === 0 ? (\n <p className=\"py-6 text-center text-body-sm text-fg-4\">\n {engine === 'claude'\n ? 'This session reports no plan windows — API-key sessions have none, and a subscription session reports them once a turn has run.'\n : `Plan windows are a claude.ai subscription thing; this session runs on the ${engine} engine.`}\n </p>\n ) : (\n <UsageMeters windows={rateLimits} now={now} />\n )}\n <div className=\"mt-5 flex items-baseline justify-between gap-4 border-t border-border pt-3\">\n <span className=\"text-label text-fg-3\">This session has cost</span>\n <span className=\"font-mono text-body-sm text-fg-1\">{formatCost(totalCostUsd)}</span>\n </div>\n {updatedAt ? <p className=\"mt-2 text-label text-fg-4\">Updated {formatAgoPrecise(updatedAt, now)}</p> : null}\n </DialogBody>\n </DialogContent>\n </Dialog>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react'\nimport type { WorkerDeckClient } from '@workerdeck/client'\nimport {\n PROTOCOL_VERSION,\n mergeUsage,\n orderUsageWindows,\n usageInfos,\n type ModelOption,\n type PermissionMode,\n type RateLimitInfo,\n type SkillInfo,\n} from '@workerdeck/protocol'\nimport {\n useAttachments,\n useClaudeSession,\n useDraft,\n useHostFileSearch,\n useProfileUsage,\n useToolCallHost,\n type ClientToolHandler,\n type ConnectionState,\n type ProducedFileRef,\n type TranscriptState,\n type UseToolCallHostOptions,\n} from '@workerdeck/react'\nimport { ChartPie, FolderTree, Gauge, Info, MoreHorizontal, Plug, Sparkles, TriangleAlert, X } from 'lucide-react'\nimport { cn } from '../../lib/utils.ts'\nimport { Button } from '../ui/Button.tsx'\nimport { Menu, MenuContent, MenuItem, MenuTrigger } from '../ui/Menu.tsx'\nimport { Composer, skillPrompt, type ComposerHandle } from './Composer.tsx'\nimport { ContextDialog } from './ContextDialog.tsx'\nimport { HostFilesDialog } from './HostFilesDialog.tsx'\nimport { McpDialog } from './McpDialog.tsx'\nimport { SkillsDialog } from './SkillsDialog.tsx'\nimport { ModelSelect } from './ModelSelect.tsx'\nimport { PermissionModeSelect, permissionModeChoices, type PermissionModeChoice } from './PermissionModeSelect.tsx'\nimport { PermissionPrompt } from './PermissionPrompt.tsx'\nimport { SubagentStrip } from './SubagentStrip.tsx'\nimport { useSubagentFrame } from './use-subagent-frame.ts'\nimport { QuestionPrompt, parseUserQuestions } from './QuestionPrompt.tsx'\nimport { TerminalPermissionPrompt } from '../terminal/PermissionPrompt.tsx'\nimport { TerminalQuestionPrompt } from '../terminal/QuestionPrompt.tsx'\nimport { TerminalSurface } from '../terminal/surface.tsx'\nimport { BookmarkProvider, type BookmarkHandle, type TerminalAffordances } from '../terminal/affordances.tsx'\n\nimport { SessionInfoDialog } from './SessionInfoDialog.tsx'\nimport { StatusBar } from './StatusBar.tsx'\nimport { Transcript } from './Transcript.tsx'\nimport { ToolResultFetchProvider } from './tool-result-fetch.tsx'\nimport { ToolResultImageProvider, useToolResultImages } from './tool-result-image.tsx'\nimport {\n TranscriptDensityProvider,\n TranscriptVariantProvider,\n type TranscriptDensity,\n type TranscriptFont,\n type TranscriptVariant,\n} from './transcript-variant.tsx'\nimport { UsageDialog } from './UsageDialog.tsx'\n\nfunction PromptSurface({\n terminal,\n metrics,\n affordances,\n children,\n}: {\n terminal: boolean\n metrics?: TerminalMetrics\n affordances?: TerminalAffordances | boolean\n children: ReactNode\n}) {\n if (!terminal) {\n return <div className=\"mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] flex-col gap-2\">{children}</div>\n }\n return (\n <TerminalSurface\n fontSize={metrics?.fontSize}\n lineHeight={metrics?.lineHeight}\n affordances={affordances}\n bleed=\"1ch\"\n className=\"term-transcript\"\n >\n {children}\n </TerminalSurface>\n )\n}\n\nexport type TerminalMetrics = { fontSize?: number; lineHeight?: number }\n\nexport interface SessionPanelProps {\n client: WorkerDeckClient\n sessionId: string | undefined\n header?: ReactNode | ((slots: { actions: ReactNode }) => ReactNode)\n panelSurface?: 'internal' | 'external'\n statusSurface?: 'internal' | 'external'\n statusPlacement?: 'top' | 'bottom'\n onOpenPanel?: (panel: SessionSurfacePanel) => void\n onVitals?: (vitals: SessionVitals) => void\n transcriptVariant?: TranscriptVariant\n affordances?: TerminalAffordances | boolean\n terminalMetrics?: TerminalMetrics\n scrubber?: boolean\n /** Bookmarked transcript item ids — the host owns membership and persistence. */\n bookmarks?: readonly string[]\n onToggleBookmark?: (itemId: string) => void\n reveal?: { toolUseId: string; nonce: number }\n openSubagent?: { toolUseId: string; nonce: number }\n onSubagentChange?: (toolUseId: string | undefined) => void\n stickyPrompt?: boolean\n transcriptDensity?: TranscriptDensity\n transcriptFont?: TranscriptFont\n controlsSurface?: 'internal' | 'external' | 'status'\n onControls?: (controls: SessionControls | undefined) => void\n focusComposerOnClick?: boolean\n unseen?: { itemCount: number; since?: number }\n readOnly?: boolean\n toolHost?: UseToolCallHostOptions | false\n cacheTranscript?: boolean\n emptyState?: ReactNode\n onLinkClick?: (href: string) => boolean | void\n clientTools?: Record<string, ClientToolHandler>\n fontSize?: number\n className?: string\n}\n\nexport type SessionControls = {\n setModel: (model?: string) => void\n setPermissionMode: (mode: PermissionMode) => void\n interrupt: () => void\n focusComposer: () => void\n insertComposerText: (text: string) => void\n}\n\nconst INTERACTIVE = [\n 'button',\n 'a',\n 'input',\n 'textarea',\n 'select',\n 'summary',\n 'img',\n '[contenteditable=\"true\"]',\n '[role=\"button\"]',\n '[role=\"menuitem\"]',\n '[role=\"checkbox\"]',\n '[role=\"radio\"]',\n '[role=\"tab\"]',\n].join(',')\n\nexport type SessionSurfacePanel = 'info' | 'context' | 'usage' | 'mcp' | 'files' | 'skills'\ntype Panel = SessionSurfacePanel\n\nexport type SessionVitals = {\n status: TranscriptState['status']\n connection: ConnectionState\n engine: TranscriptState['engine']\n capabilities: TranscriptState['capabilities']\n model: string | undefined\n models: ModelOption[]\n permissionMode: TranscriptState['permissionMode']\n permissionModes: PermissionModeChoice[]\n skills: SkillInfo[] | undefined\n cwd: TranscriptState['cwd']\n contextUsage: TranscriptState['contextUsage']\n rateLimits: TranscriptState['rateLimits']\n /**\n * When the newest window in `rateLimits` was reported, as event time — not receive time. External chrome (the\n * VS Code status bar, iOS) cannot otherwise tell a live reading from one a days-old session just replayed.\n * Absent means unknown, which is not the same as fresh.\n */\n rateLimitsUpdatedAt: number | undefined\n itemCount: number\n totalCostUsd: number\n}\n\nexport function SessionPanel({\n client,\n sessionId,\n header,\n panelSurface = 'internal',\n statusSurface = 'internal',\n statusPlacement = 'top',\n onOpenPanel,\n onVitals,\n transcriptVariant = 'cards',\n transcriptDensity = 'comfortable',\n transcriptFont = 'sans',\n affordances,\n terminalMetrics,\n scrubber = false,\n bookmarks,\n onToggleBookmark,\n reveal,\n openSubagent,\n onSubagentChange,\n stickyPrompt = false,\n controlsSurface = 'internal',\n onControls,\n focusComposerOnClick = false,\n unseen,\n readOnly = false,\n toolHost,\n clientTools,\n cacheTranscript,\n emptyState,\n onLinkClick,\n fontSize,\n className,\n}: SessionPanelProps) {\n const effectiveTermFontSize = terminalMetrics?.fontSize ?? fontSize\n const effectiveTermLineHeight = terminalMetrics?.lineHeight ?? (fontSize !== undefined ? Math.round(fontSize * (18 / 13)) : undefined)\n\n const external = panelSurface === 'external'\n const statusExternal = statusSurface === 'external'\n const controlsInStatus = controlsSurface === 'status' && !statusExternal\n const controlsExternal = controlsSurface === 'external' || controlsInStatus\n const [protocolError, setProtocolError] = useState<string | undefined>(undefined)\n const [panel, setPanel] = useState<Panel | undefined>()\n const {\n state,\n connection,\n replaying,\n protocolMismatch,\n models,\n effectiveModel,\n handle,\n send,\n approve,\n deny,\n interrupt,\n setModel,\n setPermissionMode,\n reconnectNow,\n loadFullResult,\n } = useClaudeSession(client, sessionId, { onProtocolError: setProtocolError, cacheTranscript })\n useEffect(() => setProtocolError(undefined), [sessionId])\n const {\n subagentId,\n enterSubagent,\n leaveSubagent,\n returnReveal,\n frameItems: subagentFrameItems,\n task: subagentTask,\n fallbackLabel: subagentFallbackLabel,\n } = useSubagentFrame({ sessionId, items: state.items, session: state.session, reveal, openSubagent, onSubagentChange })\n\n const [caughtUp, setCaughtUp] = useState(false)\n useEffect(() => {\n setCaughtUp(false)\n }, [sessionId])\n const [catchUpMark] = useState(unseen)\n const catchUp = caughtUp ? undefined : catchUpMark\n const newCount = catchUp ? Math.max(0, state.items.length - catchUp.itemCount) : 0\n\n const openPanel = useCallback(\n (target: SessionSurfacePanel) => {\n if (external) {\n onOpenPanel?.(target)\n } else {\n setPanel(target)\n }\n },\n [external, onOpenPanel],\n )\n useEffect(() => {\n const onVisible = () => {\n if (document.visibilityState === 'visible') {\n reconnectNow()\n }\n }\n document.addEventListener('visibilitychange', onVisible)\n return () => document.removeEventListener('visibilitychange', onVisible)\n }, [reconnectNow])\n useToolCallHost(\n handle,\n toolHost === false\n ? { enabled: false }\n : clientTools\n ? { ...toolHost, clientTools: { ...toolHost?.clientTools, ...clientTools } }\n : toolHost,\n )\n const terminal = transcriptVariant === 'terminal'\n\n const capabilities = state.capabilities\n\n const { usage: profileUsage } = useProfileUsage(client, state.session?.profile, {\n enabled: capabilities.rateLimits,\n })\n const usage = useMemo(\n () => mergeUsage({ rateLimits: state.rateLimits, updatedAt: state.rateLimitsUpdatedAt }, profileUsage),\n [state.rateLimits, state.rateLimitsUpdatedAt, profileUsage],\n )\n const rateLimits: Record<string, RateLimitInfo> | undefined = useMemo(\n () => (Object.keys(usage).length > 0 ? usageInfos(usage) : undefined),\n [usage],\n )\n const usageUpdatedAt = useMemo(() => {\n const stamps = Object.values(usage).map((w) => w.updatedAt)\n return stamps.length > 0 ? Math.max(...stamps) : undefined\n }, [usage])\n\n const onVitalsRef = useRef(onVitals)\n onVitalsRef.current = onVitals\n const vitalsModel = effectiveModel ?? state.model\n const permissionModes = useMemo(\n () => permissionModeChoices(capabilities.permissionModes, state.session?.canBypassPermissions),\n [capabilities.permissionModes, state.session?.canBypassPermissions],\n )\n useEffect(() => {\n onVitalsRef.current?.({\n status: state.status,\n connection,\n engine: state.engine,\n capabilities: state.capabilities,\n model: vitalsModel,\n models,\n permissionMode: state.permissionMode,\n permissionModes,\n skills: state.skills,\n cwd: state.cwd,\n contextUsage: state.contextUsage,\n rateLimits,\n rateLimitsUpdatedAt: usageUpdatedAt,\n itemCount: state.items.length,\n totalCostUsd: state.totalCostUsd,\n })\n }, [\n state.status,\n connection,\n state.engine,\n state.capabilities,\n vitalsModel,\n models,\n state.permissionMode,\n permissionModes,\n state.skills,\n state.cwd,\n state.contextUsage,\n rateLimits,\n usageUpdatedAt,\n state.items.length,\n state.totalCostUsd,\n ])\n\n const onControlsRef = useRef(onControls)\n onControlsRef.current = onControls\n const setters = useRef({ setModel, setPermissionMode, interrupt })\n setters.current = { setModel, setPermissionMode, interrupt }\n const controls = useRef<SessionControls>({\n setModel: (model) => setters.current.setModel(model),\n setPermissionMode: (mode) => setters.current.setPermissionMode(mode),\n interrupt: () => setters.current.interrupt(),\n focusComposer: () => composerRef.current?.focus(),\n insertComposerText: (text) => composerRef.current?.insertText(text),\n })\n useEffect(() => {\n const handler = onControlsRef.current\n handler?.(controls.current)\n return () => handler?.(undefined)\n }, [sessionId])\n const bookmarkSet = useMemo(() => new Set(bookmarks ?? []), [bookmarks])\n const bookmarkHandle = useMemo<BookmarkHandle | undefined>(\n () => (onToggleBookmark ? { has: (id) => bookmarkSet.has(id), toggle: onToggleBookmark } : undefined),\n [bookmarkSet, onToggleBookmark],\n )\n\n const busy = state.status === 'running' || state.status === 'awaiting_approval'\n const ended = state.status === 'failed' || state.status === 'closed'\n const attachments = useAttachments(client, sessionId, {\n capabilities,\n engine: state.engine,\n })\n const hostFiles = useHostFileSearch(client, state.cwd)\n const draft = useDraft(client, sessionId)\n // Stable identity: an inline arrow here would bust the Composer's `triggers`\n // memo on every streaming re-render, and with it every prompt-area callback\n // keyed on the triggers.\n const searchComposerFiles = useCallback(\n (query: string, options: { signal: AbortSignal }) => hostFiles.search(query, { ...options, limit: 8 }),\n [hostFiles.search],\n )\n const windows = useMemo(() => orderUsageWindows(usage), [usage])\n const hostImage = useHostImage(client, sessionId, state.producedFiles)\n const resultImages = useToolResultImages(client, sessionId)\n const composerRef = useRef<ComposerHandle>(null)\n const jumpToRecap = useRef<(() => void) | null>(null)\n const repinTranscript = useRef<(() => void) | null>(null)\n\n const commands = useMemo(() => {\n if (!state.commands) {\n return undefined\n }\n if (state.commands.some((c) => c.name === 'model')) {\n return state.commands\n }\n return [{ name: 'model', description: 'Switch the model for this session', argumentHint: '<model>' }, ...state.commands]\n }, [state.commands])\n\n const handleSend = (text: string, attachmentIds: string[]) => {\n if (attachmentIds.length === 0) {\n const modelCommand = /^\\/model\\s+(\\S+)$/.exec(text)\n if (modelCommand) {\n setModel(modelCommand[1])\n return\n }\n if (capabilities.mcpStatus && text.trim() === '/mcp') {\n openPanel('mcp')\n return\n }\n }\n setCaughtUp(true)\n repinTranscript.current?.()\n send(text, attachmentIds)\n }\n\n const actionsMenu = (\n <Menu>\n <MenuTrigger\n render={\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Session actions\">\n <MoreHorizontal className=\"size-4\" />\n </Button>\n }\n />\n <MenuContent>\n {capabilities.contextUsage ? (\n <MenuItem onClick={() => openPanel('context')}>\n <ChartPie className=\"size-3.5 text-fg-3\" /> Context\n </MenuItem>\n ) : null}\n {capabilities.rateLimits ? (\n <MenuItem onClick={() => openPanel('usage')}>\n <Gauge className=\"size-3.5 text-fg-3\" /> Usage\n </MenuItem>\n ) : null}\n <MenuItem onClick={() => openPanel('info')}>\n <Info className=\"size-3.5 text-fg-3\" /> Session info\n </MenuItem>\n {capabilities.mcpStatus ? (\n <MenuItem onClick={() => openPanel('mcp')}>\n <Plug className=\"size-3.5 text-fg-3\" /> MCP servers\n </MenuItem>\n ) : null}\n {capabilities.skillsList ? (\n <MenuItem onClick={() => openPanel('skills')}>\n <Sparkles className=\"size-3.5 text-fg-3\" /> Skills\n </MenuItem>\n ) : null}\n {hostFiles.available ? (\n <MenuItem onClick={() => openPanel('files')}>\n <FolderTree className=\"size-3.5 text-fg-3\" /> Project files\n </MenuItem>\n ) : null}\n </MenuContent>\n </Menu>\n )\n\n const menu = external ? null : actionsMenu\n const headerTakesActions = typeof header === 'function'\n\n const sessionControls = (\n <>\n {models.length ? (\n <ModelSelect\n models={models}\n model={effectiveModel}\n onModelChange={setModel}\n disabled={ended}\n className={controlsInStatus ? 'h-5' : undefined}\n />\n ) : null}\n {state.permissionMode ? (\n <PermissionModeSelect\n mode={state.permissionMode}\n onModeChange={setPermissionMode}\n modes={capabilities.permissionModes}\n canBypass={state.session?.canBypassPermissions}\n disabled={ended}\n className={controlsInStatus ? 'h-5' : undefined}\n />\n ) : null}\n </>\n )\n\n const statusBar = statusExternal ? null : (\n <StatusBar\n state={state}\n rateLimits={rateLimits}\n connection={connection}\n placement={statusPlacement}\n controls={controlsInStatus && !readOnly ? sessionControls : undefined}\n onOpenStatus={external && !onOpenPanel ? undefined : () => openPanel('info')}\n onOpenContext={external && !onOpenPanel ? undefined : () => openPanel('context')}\n onOpenUsage={external && !onOpenPanel ? undefined : () => openPanel('usage')}\n actions={headerTakesActions ? undefined : menu}\n />\n )\n\n const panelRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!onLinkClick) {\n return\n }\n const el = panelRef.current\n if (!el) {\n return\n }\n const handler = (e: MouseEvent) => {\n const anchor = (e.target as HTMLElement)?.closest?.('a[href]') as HTMLAnchorElement | null\n if (!anchor) {\n return\n }\n const href = anchor.getAttribute('href')\n if (!href) {\n return\n }\n if (onLinkClick(href)) {\n e.preventDefault()\n e.stopPropagation()\n }\n }\n el.addEventListener('click', handler, true)\n return () => el.removeEventListener('click', handler, true)\n }, [onLinkClick])\n\n const handleClick = (event: ReactMouseEvent<HTMLDivElement>) => {\n if (!focusComposerOnClick || readOnly) {\n return\n }\n const target = event.target as HTMLElement | null\n if (target?.closest(INTERACTIVE)) {\n return\n }\n if (window.getSelection()?.isCollapsed === false) {\n return\n }\n composerRef.current?.focus()\n }\n\n return (\n <TranscriptVariantProvider value={transcriptVariant}>\n <TranscriptDensityProvider value={transcriptDensity}>\n <ToolResultFetchProvider value={loadFullResult}>\n <ToolResultImageProvider value={resultImages}>\n <div\n ref={panelRef}\n data-slot=\"session-panel\"\n data-agent-font={transcriptFont}\n onClick={handleClick}\n className={cn('flex h-full min-h-0 flex-col overflow-hidden bg-bg', className)}\n style={fontSize !== undefined ? ({ '--wd-font-size': `${Math.round(fontSize)}px` } as React.CSSProperties) : undefined}\n >\n {headerTakesActions ? header({ actions: menu }) : header}\n {statusPlacement === 'top' ? statusBar : null}\n {protocolMismatch !== undefined ? (\n <Notice level=\"warning\">\n Server speaks protocol v{protocolMismatch}, this build renders v{PROTOCOL_VERSION}. Some events may not render.\n </Notice>\n ) : null}\n {protocolError ? (\n <Notice level=\"error\" onDismiss={() => setProtocolError(undefined)}>\n {protocolError}\n </Notice>\n ) : null}\n {subagentId !== undefined ? (\n <SubagentStrip\n task={subagentTask}\n items={subagentFrameItems}\n label={subagentFallbackLabel}\n onBack={leaveSubagent}\n terminal={terminal}\n fontSize={effectiveTermFontSize}\n lineHeight={effectiveTermLineHeight}\n />\n ) : null}\n <BookmarkProvider value={bookmarkHandle}>\n <Transcript\n key={subagentId ?? 'session'}\n state={state}\n fileUrl={sessionId ? (path) => client.sessionFileUrl(sessionId, path) : undefined}\n attachmentUrl={sessionId ? (id) => client.attachmentUrl(sessionId, id) : undefined}\n canBrowseFiles={hostFiles.available}\n hostImage={hostImage}\n variant={transcriptVariant}\n density={transcriptDensity}\n fontSize={effectiveTermFontSize}\n lineHeight={effectiveTermLineHeight}\n affordances={affordances}\n stickyPrompt={stickyPrompt}\n scrubber={scrubber}\n bookmarks={bookmarks}\n replaying={replaying}\n catchUp={catchUp && newCount > 0 ? { from: catchUp.itemCount, since: catchUp.since } : undefined}\n reveal={returnReveal ?? reveal}\n frame={subagentId === undefined ? undefined : { parentToolUseId: subagentId }}\n onOpenSubagent={enterSubagent}\n emptyState={emptyState}\n jumpToRecapRef={jumpToRecap}\n repinRef={repinTranscript}\n />\n </BookmarkProvider>\n {catchUp && newCount > 0 && !replaying && subagentId === undefined ? (\n <div className=\"px-3 pb-1\">\n <div\n data-slot=\"catch-up\"\n className=\"mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 text-label text-fg-3\"\n >\n <span aria-hidden className={cn('select-none', terminal ? 'text-fg-3' : 'text-accent')}>\n ※\n </span>\n <span className=\"min-w-0 flex-1 truncate\">\n {newCount} new {newCount === 1 ? 'row' : 'rows'}\n {catchUp.since !== undefined ? ` since you were last here` : ''}\n </span>\n <button\n type=\"button\"\n onClick={() => jumpToRecap.current?.()}\n className=\"shrink-0 underline-offset-2 hover:text-fg-1 hover:underline\"\n >\n jump\n </button>\n <button\n type=\"button\"\n onClick={() => setCaughtUp(true)}\n className=\"shrink-0 underline-offset-2 hover:text-fg-1 hover:underline\"\n >\n dismiss\n </button>\n </div>\n </div>\n ) : null}\n {!readOnly && capabilities.interactiveApprovals && state.pendingApprovals.length > 0 ? (\n <div className={cn(terminal ? 'pb-2' : 'px-3 pb-2')}>\n <PromptSurface\n terminal={terminal}\n metrics={{ fontSize: effectiveTermFontSize, lineHeight: effectiveTermLineHeight }}\n affordances={affordances}\n >\n {state.pendingApprovals.map((request) => {\n const isQuestion = request.toolName === 'AskUserQuestion' && parseUserQuestions(request.input).length > 0\n if (terminal) {\n return isQuestion ? (\n <TerminalQuestionPrompt\n key={request.id}\n request={request}\n onAnswer={approve}\n onDismiss={(id) => deny(id, 'Question dismissed by user')}\n />\n ) : (\n <TerminalPermissionPrompt key={request.id} request={request} onApprove={approve} onDeny={deny} />\n )\n }\n return isQuestion ? (\n <QuestionPrompt\n key={request.id}\n request={request}\n onAnswer={approve}\n onDismiss={(id) => deny(id, 'Question dismissed by user')}\n />\n ) : (\n <PermissionPrompt key={request.id} request={request} onApprove={approve} onDeny={deny} />\n )\n })}\n </PromptSurface>\n </div>\n ) : null}\n {readOnly || subagentId !== undefined ? null : (\n <Composer\n ref={composerRef}\n onSend={handleSend}\n onInterrupt={interrupt}\n busy={busy}\n disabled={ended || !sessionId}\n commands={capabilities.slashCommands ? commands : undefined}\n skills={capabilities.skillsList ? state.skills : undefined}\n attachments={attachments}\n draft={draft}\n onSearchFiles={hostFiles.available ? searchComposerFiles : undefined}\n layout={controlsExternal ? 'inline' : 'stacked'}\n toolbar={controlsExternal ? undefined : sessionControls}\n fontSize={effectiveTermFontSize}\n lineHeight={effectiveTermLineHeight}\n affordances={affordances}\n />\n )}\n {statusPlacement === 'bottom' ? statusBar : null}\n\n {!external ? (\n <>\n <SessionInfoDialog\n state={state}\n client={client}\n sessionId={sessionId}\n open={panel === 'info'}\n onOpenChange={(next) => setPanel(next ? 'info' : undefined)}\n />\n <ContextDialog\n usage={state.contextUsage}\n open={panel === 'context'}\n onOpenChange={(next) => setPanel(next ? 'context' : undefined)}\n />\n <UsageDialog\n rateLimits={windows}\n subscriptionType={state.subscriptionType}\n engine={state.engine ?? 'claude'}\n totalCostUsd={state.totalCostUsd}\n updatedAt={usageUpdatedAt}\n open={panel === 'usage'}\n onOpenChange={(next) => setPanel(next ? 'usage' : undefined)}\n />\n <McpDialog\n client={client}\n sessionId={sessionId}\n canManageServers={capabilities.mcpServerActions}\n open={panel === 'mcp'}\n onOpenChange={(next) => setPanel(next ? 'mcp' : undefined)}\n />\n <SkillsDialog\n skills={state.skills}\n open={panel === 'skills'}\n onOpenChange={(next) => setPanel(next ? 'skills' : undefined)}\n onUse={(skill) => composerRef.current?.insertText(skillPrompt(skill))}\n />\n <HostFilesDialog\n client={client}\n cwd={state.cwd}\n open={panel === 'files'}\n onOpenChange={(next) => setPanel(next ? 'files' : undefined)}\n />\n </>\n ) : null}\n </div>\n </ToolResultImageProvider>\n </ToolResultFetchProvider>\n </TranscriptDensityProvider>\n </TranscriptVariantProvider>\n )\n}\n\nfunction useHostImage(\n client: WorkerDeckClient,\n sessionId: string | undefined,\n producedFiles: Record<string, ProducedFileRef> | undefined,\n): (path: string) => Promise<string | undefined> {\n const cache = useRef(new Map<string, Promise<string | undefined>>())\n const objectUrls = useRef<string[]>([])\n useEffect(\n () => () => {\n for (const url of objectUrls.current) {\n URL.revokeObjectURL(url)\n }\n objectUrls.current = []\n },\n [],\n )\n return useCallback(\n (path: string) => {\n const produced = producedFiles?.[path]\n const key = produced ? `produced:${produced.fileId}` : `fs:${path}`\n const hit = cache.current.get(key)\n if (hit) {\n return hit\n }\n const pending =\n produced && sessionId\n ? client\n .readProducedFile(sessionId, produced.fileId)\n .then((blob) => {\n if (blob.size === 0) {\n return undefined\n }\n const url = URL.createObjectURL(blob)\n objectUrls.current.push(url)\n return url\n })\n .catch(() => undefined)\n : client\n .readHostFile(path)\n .then((file) => {\n if (file.encoding !== 'base64') {\n return undefined\n }\n const extension = path.slice(path.lastIndexOf('.') + 1).toLowerCase()\n const mediaType = IMAGE_MEDIA_TYPES[extension]\n return mediaType ? `data:${mediaType};base64,${file.content}` : undefined\n })\n .catch(() => undefined)\n cache.current.set(key, pending)\n return pending\n },\n [client, sessionId, producedFiles],\n )\n}\n\nconst IMAGE_MEDIA_TYPES: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n}\n\nfunction Notice({ level, onDismiss, children }: { level: 'warning' | 'error'; onDismiss?: () => void; children: ReactNode }) {\n return (\n <div className=\"px-3 pt-2\">\n <div\n role=\"alert\"\n className={cn(\n 'mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-start gap-2 rounded-md border px-3 py-2 text-body-sm',\n level === 'error' ? 'border-danger/40 bg-danger-bg text-danger' : 'border-warning/40 bg-warning-bg text-warning',\n )}\n >\n <TriangleAlert className=\"mt-0.5 size-3.5 shrink-0\" />\n <span className=\"min-w-0 flex-1 break-words\">{children}</span>\n {onDismiss ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Dismiss\"\n className=\"shrink-0 opacity-70 transition-opacity hover:opacity-100\"\n >\n <X className=\"size-3.5\" />\n </button>\n ) : null}\n </div>\n </div>\n )\n}\n"],"mappings":"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"}
|