@run0/jiki-ui 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/theme.ts","../src/language-labels.ts","../src/shiki-languages.ts","../src/use-shiki-highlighter.ts","../src/CodeEditor.tsx","../src/Terminal.tsx","../src/BrowserWindow.tsx","../src/FileExplorer.tsx","../src/PanelToggle.tsx","../src/MobileTabBar.tsx","../src/useMediaQuery.ts","../src/chat-theme.ts","../src/AIChatPanel.tsx"],"sourcesContent":["import type { AccentColor, TerminalLine } from \"./types\";\n\nexport interface EditorTheme {\n saveButtonActive: string;\n caret: string;\n selection: string;\n}\n\nexport interface TerminalTheme {\n commandStyle: string;\n promptColor: string;\n spinnerBorder: string;\n inputCaret: string;\n}\n\nconst EDITOR_THEMES: Record<AccentColor, EditorTheme> = {\n emerald: {\n saveButtonActive:\n \"bg-emerald-500/20 text-emerald-400 hover:bg-emerald-500/30 border border-emerald-500/30\",\n caret: \"caret-emerald-400\",\n selection: \"selection:bg-emerald-500/20\",\n },\n violet: {\n saveButtonActive:\n \"bg-violet-500/20 text-violet-400 hover:bg-violet-500/30 border border-violet-500/30\",\n caret: \"caret-violet-400\",\n selection: \"selection:bg-violet-500/20\",\n },\n orange: {\n saveButtonActive:\n \"bg-orange-500/20 text-orange-400 hover:bg-orange-500/30 border border-orange-500/30\",\n caret: \"caret-orange-400\",\n selection: \"selection:bg-orange-500/20\",\n },\n blue: {\n saveButtonActive:\n \"bg-blue-500/20 text-blue-400 hover:bg-blue-500/30 border border-blue-500/30\",\n caret: \"caret-blue-400\",\n selection: \"selection:bg-blue-500/20\",\n },\n pink: {\n saveButtonActive:\n \"bg-pink-500/20 text-pink-400 hover:bg-pink-500/30 border border-pink-500/30\",\n caret: \"caret-pink-400\",\n selection: \"selection:bg-pink-500/20\",\n },\n green: {\n saveButtonActive:\n \"bg-green-500/20 text-green-400 hover:bg-green-500/30 border border-green-500/30\",\n caret: \"caret-green-400\",\n selection: \"selection:bg-green-500/20\",\n },\n amber: {\n saveButtonActive:\n \"bg-amber-500/20 text-amber-400 hover:bg-amber-500/30 border border-amber-500/30\",\n caret: \"caret-amber-400\",\n selection: \"selection:bg-amber-500/20\",\n },\n};\n\nconst TERMINAL_THEMES: Record<AccentColor, TerminalTheme> = {\n emerald: {\n commandStyle: \"text-emerald-400 font-semibold\",\n promptColor: \"text-emerald-500\",\n spinnerBorder: \"border-t-emerald-400\",\n inputCaret: \"caret-emerald-400\",\n },\n violet: {\n commandStyle: \"text-violet-400 font-semibold\",\n promptColor: \"text-violet-500\",\n spinnerBorder: \"border-t-violet-400\",\n inputCaret: \"caret-violet-400\",\n },\n orange: {\n commandStyle: \"text-orange-400 font-semibold\",\n promptColor: \"text-orange-500\",\n spinnerBorder: \"border-t-orange-400\",\n inputCaret: \"caret-orange-400\",\n },\n blue: {\n commandStyle: \"text-blue-400 font-semibold\",\n promptColor: \"text-blue-500\",\n spinnerBorder: \"border-t-blue-400\",\n inputCaret: \"caret-blue-400\",\n },\n pink: {\n commandStyle: \"text-pink-400 font-semibold\",\n promptColor: \"text-pink-500\",\n spinnerBorder: \"border-t-pink-400\",\n inputCaret: \"caret-pink-400\",\n },\n green: {\n commandStyle: \"text-green-400 font-semibold\",\n promptColor: \"text-green-500\",\n spinnerBorder: \"border-t-green-400\",\n inputCaret: \"caret-green-400\",\n },\n amber: {\n commandStyle: \"text-amber-400 font-semibold\",\n promptColor: \"text-amber-500\",\n spinnerBorder: \"border-t-amber-400\",\n inputCaret: \"caret-amber-400\",\n },\n};\n\nexport interface FileExplorerTheme {\n selected: string;\n}\n\nconst FILE_EXPLORER_THEMES: Record<AccentColor, FileExplorerTheme> = {\n emerald: { selected: \"bg-emerald-500/15 text-emerald-300\" },\n violet: { selected: \"bg-violet-500/15 text-violet-300\" },\n orange: { selected: \"bg-orange-500/15 text-orange-300\" },\n blue: { selected: \"bg-blue-500/15 text-blue-300\" },\n pink: { selected: \"bg-pink-500/15 text-pink-300\" },\n green: { selected: \"bg-green-500/15 text-green-300\" },\n amber: { selected: \"bg-amber-500/15 text-amber-300\" },\n};\n\nexport function getFileExplorerTheme(color: AccentColor): FileExplorerTheme {\n return FILE_EXPLORER_THEMES[color];\n}\n\nexport function getEditorTheme(color: AccentColor): EditorTheme {\n return EDITOR_THEMES[color];\n}\n\nexport function getTerminalTheme(color: AccentColor): TerminalTheme {\n return TERMINAL_THEMES[color];\n}\n\nexport function getLineStyles(\n color: AccentColor,\n overrides?: Partial<Record<TerminalLine[\"type\"], string>>,\n): Record<TerminalLine[\"type\"], string> {\n return {\n command: TERMINAL_THEMES[color].commandStyle,\n stdout: \"text-zinc-300\",\n stderr: \"text-red-400\",\n info: \"text-blue-400 italic\",\n success: \"text-emerald-400\",\n ...overrides,\n };\n}\n","const LANGUAGE_MAP: Record<string, string> = {\n js: \"JavaScript\",\n jsx: \"JSX\",\n mjs: \"JavaScript\",\n cjs: \"JavaScript\",\n ts: \"TypeScript\",\n tsx: \"TSX\",\n mts: \"TypeScript\",\n cts: \"TypeScript\",\n json: \"JSON\",\n md: \"Markdown\",\n html: \"HTML\",\n css: \"CSS\",\n vue: \"Vue SFC\",\n svelte: \"Svelte\",\n astro: \"Astro\",\n yaml: \"YAML\",\n yml: \"YAML\",\n toml: \"TOML\",\n sh: \"Shell\",\n};\n\nexport function getLanguageLabel(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n return LANGUAGE_MAP[ext || \"\"] || \"Plain Text\";\n}\n","const SHIKI_LANG_MAP: Record<string, string> = {\n js: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n ts: \"typescript\",\n mts: \"typescript\",\n cts: \"typescript\",\n jsx: \"jsx\",\n tsx: \"tsx\",\n json: \"json\",\n html: \"html\",\n css: \"css\",\n md: \"markdown\",\n vue: \"vue\",\n svelte: \"svelte\",\n astro: \"astro\",\n yaml: \"yaml\",\n yml: \"yaml\",\n toml: \"toml\",\n sh: \"shellscript\",\n};\n\nexport function getShikiLang(filename: string | null): string {\n if (!filename) return \"plaintext\";\n const ext = filename.split(\".\").pop()?.toLowerCase();\n return SHIKI_LANG_MAP[ext || \"\"] || \"plaintext\";\n}\n","import { useEffect, useRef } from \"react\";\nimport type { Highlighter } from \"shiki\";\nimport { getShikiLang } from \"./shiki-languages\";\n\n// Module-level singleton — shared across all CodeEditor instances\nlet highlighterInstance: Highlighter | null = null;\nlet highlighterPromise: Promise<Highlighter> | null = null;\n\nasync function getOrCreateHighlighter(): Promise<Highlighter> {\n if (highlighterInstance) return highlighterInstance;\n if (highlighterPromise) return highlighterPromise;\n\n highlighterPromise = import(\"shiki\")\n .then(({ createHighlighter }) =>\n createHighlighter({ themes: [\"github-dark\"], langs: [] }),\n )\n .then(h => {\n highlighterInstance = h;\n return h;\n });\n\n return highlighterPromise;\n}\n\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nexport function buildFallbackHtml(code: string): string {\n return `<pre style=\"margin:0;background:transparent\"><code style=\"color:#e4e4e7\">${escapeHtml(code)}</code></pre>`;\n}\n\nasync function doHighlight(\n code: string,\n filename: string | null,\n el: HTMLDivElement | null,\n): Promise<void> {\n if (!el || !highlighterInstance) return;\n\n const lang = getShikiLang(filename);\n\n if (\n lang !== \"plaintext\" &&\n !highlighterInstance.getLoadedLanguages().includes(lang)\n ) {\n try {\n await highlighterInstance.loadLanguage(\n lang as Parameters<typeof highlighterInstance.loadLanguage>[0],\n );\n } catch {\n el.innerHTML = buildFallbackHtml(code);\n return;\n }\n }\n\n try {\n el.innerHTML = highlighterInstance.codeToHtml(code, {\n lang,\n theme: \"github-dark\",\n });\n } catch {\n el.innerHTML = buildFallbackHtml(code);\n }\n}\n\n/**\n * Manages Shiki syntax highlighting via direct DOM updates — no React state,\n * no re-renders. Updates the target element's innerHTML directly.\n */\nexport function useShikiHighlighter(\n code: string,\n filename: string | null,\n targetRef: React.RefObject<HTMLDivElement | null>,\n): void {\n const readyRef = useRef(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n // Initialize highlighter singleton on first mount\n useEffect(() => {\n let cancelled = false;\n getOrCreateHighlighter().then(() => {\n if (cancelled) return;\n readyRef.current = true;\n doHighlight(code, filename, targetRef.current);\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Debounced highlight on code/filename change — direct DOM mutation\n useEffect(() => {\n if (!readyRef.current) {\n // Show fallback while Shiki loads\n if (targetRef.current) {\n targetRef.current.innerHTML = buildFallbackHtml(code);\n }\n return;\n }\n\n clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n doHighlight(code, filename, targetRef.current);\n }, 30);\n\n return () => clearTimeout(debounceRef.current);\n }, [code, filename]);\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { AccentColor } from \"./types\";\nimport { getEditorTheme } from \"./theme\";\nimport { getLanguageLabel } from \"./language-labels\";\nimport { useShikiHighlighter } from \"./use-shiki-highlighter\";\n\nexport interface CodeEditorProps {\n filename: string | null;\n content: string;\n onSave: (path: string, content: string) => void;\n accentColor?: AccentColor;\n}\n\nexport function CodeEditor({\n filename,\n content,\n onSave,\n accentColor = \"emerald\",\n}: CodeEditorProps) {\n const [localContent, setLocalContent] = useState(content);\n const [isDirty, setIsDirty] = useState(false);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const lineCountRef = useRef<HTMLDivElement>(null);\n const highlightRef = useRef<HTMLDivElement>(null);\n const theme = getEditorTheme(accentColor);\n useShikiHighlighter(localContent, filename, highlightRef);\n\n useEffect(() => {\n setLocalContent(content);\n setIsDirty(false);\n }, [content, filename]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setLocalContent(e.target.value);\n setIsDirty(e.target.value !== content);\n },\n [content],\n );\n\n const handleSave = useCallback(() => {\n if (filename && isDirty) {\n onSave(filename, localContent);\n setIsDirty(false);\n }\n }, [filename, isDirty, localContent, onSave]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"s\") {\n e.preventDefault();\n handleSave();\n }\n if (e.key === \"Tab\") {\n e.preventDefault();\n const ta = textareaRef.current;\n if (!ta) return;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const val = ta.value;\n const newVal = val.substring(0, start) + \" \" + val.substring(end);\n setLocalContent(newVal);\n setIsDirty(newVal !== content);\n requestAnimationFrame(() => {\n ta.selectionStart = ta.selectionEnd = start + 2;\n });\n }\n },\n [handleSave, content],\n );\n\n const handleScroll = useCallback(() => {\n if (textareaRef.current) {\n if (lineCountRef.current) {\n lineCountRef.current.scrollTop = textareaRef.current.scrollTop;\n }\n if (highlightRef.current) {\n highlightRef.current.scrollTop = textareaRef.current.scrollTop;\n highlightRef.current.scrollLeft = textareaRef.current.scrollLeft;\n }\n }\n }, []);\n\n if (!filename) {\n return (\n <div className=\"h-full flex items-center justify-center text-zinc-600 text-sm\">\n Select a file to edit\n </div>\n );\n }\n\n const lineCount = localContent.split(\"\\n\").length;\n const lineNumbers = useMemo(\n () =>\n Array.from({ length: lineCount }, (_, i) => (\n <div\n key={i}\n className=\"px-3 text-right text-zinc-600 text-[12px] leading-5\"\n style={{ minWidth: \"3rem\" }}>\n {i + 1}\n </div>\n )),\n [lineCount],\n );\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Tab bar */}\n <div className=\"flex items-center justify-between px-3 py-1.5 bg-zinc-900/50 border-b border-zinc-800\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-mono text-zinc-300\">\n {filename}\n </span>\n {isDirty && (\n <span\n className=\"inline-block h-2 w-2 rounded-full bg-amber-400\"\n title=\"Unsaved changes\"\n />\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-[11px] text-zinc-600\">\n {getLanguageLabel(filename)}\n </span>\n <button\n onClick={handleSave}\n disabled={!isDirty}\n className={`\n text-[11px] px-2.5 py-1 rounded font-medium transition-colors\n ${\n isDirty\n ? theme.saveButtonActive\n : \"bg-zinc-800 text-zinc-600 border border-zinc-700 cursor-not-allowed\"\n }\n `}>\n Save\n </button>\n </div>\n </div>\n\n {/* Editor area */}\n <div className=\"flex-1 flex overflow-hidden relative font-mono text-[13px] leading-5\">\n {/* Line numbers */}\n <div\n ref={lineCountRef}\n className=\"flex-shrink-0 overflow-hidden bg-zinc-900/30 select-none\">\n {lineNumbers}\n </div>\n\n {/* Code container — overlay of highlight layer + textarea */}\n <div className=\"flex-1 relative min-w-0\">\n {/* Highlight layer (behind textarea, renders Shiki HTML) */}\n <div\n ref={highlightRef}\n className=\"absolute inset-0 overflow-hidden p-2 pointer-events-none [&_pre]:!bg-transparent [&_pre]:!m-0 [&_pre]:!p-0 [&_pre]:!font-[inherit] [&_pre]:![font-size:inherit] [&_pre]:![line-height:inherit] [&_pre]:![letter-spacing:inherit] [&_pre]:![white-space:pre] [&_pre]:![word-wrap:normal] [&_code]:!font-[inherit] [&_code]:![font-size:inherit] [&_code]:![line-height:inherit] [&_.shiki]:!overflow-visible\"\n style={{ tabSize: 2 }}\n />\n\n {/* Textarea (transparent text, captures all input) */}\n <textarea\n ref={textareaRef}\n value={localContent}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onScroll={handleScroll}\n wrap=\"off\"\n spellCheck={false}\n className={`\n absolute inset-0 w-full h-full resize-none bg-transparent p-2\n text-transparent outline-none overflow-auto whitespace-pre\n ${theme.caret} ${theme.selection}\n `}\n style={{ tabSize: 2, overflowWrap: \"normal\", wordBreak: \"normal\" }}\n />\n </div>\n </div>\n\n {/* Status bar */}\n <div className=\"flex items-center justify-between px-3 py-1 bg-zinc-900/30 border-t border-zinc-800 text-[11px] text-zinc-600\">\n <span>{lineCount} lines</span>\n <span>Ctrl+S / Cmd+S to save</span>\n </div>\n </div>\n );\n}\n","import { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { AccentColor, TerminalLine } from \"./types\";\nimport { getTerminalTheme, getLineStyles } from \"./theme\";\n\nexport interface TerminalProps {\n lines: TerminalLine[];\n onCommand?: (cmd: string) => Promise<void>;\n onClear: () => void;\n accentColor?: AccentColor;\n variant?: \"default\" | \"compact\";\n title?: string;\n lineStyles?: Partial<Record<TerminalLine[\"type\"], string>>;\n}\n\nexport function Terminal({\n lines,\n onCommand,\n onClear,\n accentColor = \"emerald\",\n variant = \"default\",\n title = \"Terminal\",\n lineStyles: lineStyleOverrides,\n}: TerminalProps) {\n const [input, setInput] = useState(\"\");\n const [history, setHistory] = useState<string[]>([]);\n const [historyIdx, setHistoryIdx] = useState(-1);\n const [isRunning, setIsRunning] = useState(false);\n const scrollRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const termTheme = getTerminalTheme(accentColor);\n const styles = getLineStyles(accentColor, lineStyleOverrides);\n\n const isCompact = variant === \"compact\";\n const hasInput = !!onCommand;\n\n useEffect(() => {\n const el = scrollRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, [lines]);\n\n const executeCommand = useCallback(\n async (cmd: string) => {\n if (cmd === \"clear\") {\n onClear();\n return;\n }\n if (!onCommand) return;\n setIsRunning(true);\n await onCommand(cmd);\n setIsRunning(false);\n inputRef.current?.focus();\n },\n [onCommand, onClear],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n const cmd = e.currentTarget.value.trim();\n if (!cmd || isRunning) return;\n setInput(\"\");\n setHistory(prev => [...prev, cmd]);\n setHistoryIdx(-1);\n executeCommand(cmd);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (history.length === 0) return;\n const newIdx =\n historyIdx === -1 ? history.length - 1 : Math.max(0, historyIdx - 1);\n setHistoryIdx(newIdx);\n setInput(history[newIdx]);\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (historyIdx === -1) return;\n const newIdx = historyIdx + 1;\n if (newIdx >= history.length) {\n setHistoryIdx(-1);\n setInput(\"\");\n } else {\n setHistoryIdx(newIdx);\n setInput(history[newIdx]);\n }\n }\n },\n [history, historyIdx, isRunning, executeCommand],\n );\n\n // Size tokens based on variant\n const headerPy = isCompact ? \"py-1\" : \"py-1.5\";\n const dotSize = isCompact ? \"h-2 w-2\" : \"h-2.5 w-2.5\";\n const dotOpacity = isCompact ? \"bg-red-500/60\" : \"bg-red-500/70\";\n const dotYellow = isCompact ? \"bg-yellow-500/60\" : \"bg-yellow-500/70\";\n const dotGreen = isCompact ? \"bg-green-500/60\" : \"bg-green-500/70\";\n const titleSize = isCompact ? \"text-[10px]\" : \"text-[11px]\";\n const titleMl = isCompact ? \"ml-1\" : \"\";\n const clearSize = isCompact ? \"text-[10px]\" : \"text-[11px]\";\n const outputClass = isCompact\n ? \"flex-1 overflow-y-auto px-3 py-1.5 font-mono text-[11px] leading-4\"\n : \"flex-1 overflow-y-auto p-3 font-mono text-[13px] leading-5\";\n const inputPy = isCompact ? \"py-1.5\" : \"py-2\";\n const inputGap = isCompact ? \"gap-1.5\" : \"gap-2\";\n const promptSize = isCompact ? \"text-[11px]\" : \"text-sm\";\n const inputFontSize = isCompact ? \"text-[11px]\" : \"text-[13px]\";\n const spinnerSize = isCompact ? \"h-2.5 w-2.5\" : \"h-3 w-3\";\n\n return (\n <div className=\"h-full flex flex-col bg-zinc-950\">\n {/* Header */}\n <div\n className={`flex items-center justify-between px-3 ${headerPy} bg-zinc-900/50 border-b border-zinc-800`}>\n <div className=\"flex items-center gap-1.5\">\n <div className=\"flex gap-1\">\n <div className={`${dotSize} rounded-full ${dotOpacity}`} />\n <div className={`${dotSize} rounded-full ${dotYellow}`} />\n <div className={`${dotSize} rounded-full ${dotGreen}`} />\n </div>\n <span\n className={`${titleSize} font-semibold uppercase tracking-wider text-zinc-500 ${titleMl}`}>\n {title}\n </span>\n </div>\n <button\n onClick={onClear}\n className={`${clearSize} text-zinc-600 hover:text-zinc-400 transition-colors`}>\n Clear\n </button>\n </div>\n\n {/* Output area */}\n <div\n ref={scrollRef}\n data-testid=\"terminal-output\"\n className={outputClass}>\n {lines.map(line => (\n <div key={line.id} className={styles[line.type]}>\n {line.text.split(\"\\n\").map((segment, i) => (\n <div key={i}>{segment || \"\\u00A0\"}</div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Input (only when onCommand is provided) */}\n {hasInput && (\n <div className=\"flex-shrink-0 border-t border-zinc-800\">\n <div className={`flex items-center px-3 ${inputPy} ${inputGap}`}>\n <span\n className={`${termTheme.promptColor} font-mono ${promptSize} font-bold select-none`}>\n $\n </span>\n <input\n ref={inputRef}\n type=\"text\"\n value={input}\n onChange={e => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n disabled={isRunning}\n placeholder={isRunning ? \"Running...\" : \"Type a command...\"}\n className={`\n flex-1 bg-transparent text-zinc-200 ${inputFontSize} font-mono\n outline-none placeholder:text-zinc-700\n disabled:opacity-50\n ${termTheme.inputCaret}\n `}\n />\n {isRunning && (\n <div\n className={`${spinnerSize} animate-spin rounded-full border border-zinc-600 ${termTheme.spinnerBorder}`}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useRef, useEffect, useCallback, useState } from \"react\";\n\nexport interface InspectedElement {\n tagName: string;\n className: string;\n textContent: string;\n outerHTML: string;\n}\n\nexport interface BrowserWindowProps {\n htmlSrc: string;\n url: string;\n canGoBack: boolean;\n canGoForward: boolean;\n onBack: () => void;\n onForward: () => void;\n onRefresh: () => void;\n onNavigate: (path: string) => void;\n port?: number;\n title?: string;\n previewUrl?: string;\n /** When provided, shows an inspect button. Called with element info on pick. */\n onInspectElement?: (element: InspectedElement) => void;\n}\n\nexport function BrowserWindow({\n htmlSrc,\n url,\n canGoBack,\n canGoForward,\n onBack,\n onForward,\n onRefresh,\n onNavigate,\n port = 3000,\n title = \"App Preview\",\n previewUrl,\n onInspectElement,\n}: BrowserWindowProps) {\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const [docTitle, setDocTitle] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n const [inspecting, setInspecting] = useState(false);\n const inspectCleanupRef = useRef<(() => void) | null>(null);\n\n const displayUrl = previewUrl\n ? `${previewUrl}${url === \"/\" ? \"\" : url}`\n : `http://localhost:${port}${url === \"/\" ? \"\" : url}`;\n\n // Track the last written srcdoc to avoid redundant rewrites that cause flash.\n const lastSrcdocRef = useRef(\"\");\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n if (previewUrl) {\n iframe.src = `${previewUrl}${url === \"/\" ? \"/\" : url}`;\n } else if (htmlSrc !== lastSrcdocRef.current) {\n lastSrcdocRef.current = htmlSrc;\n iframe.srcdoc = htmlSrc;\n }\n }, [htmlSrc, previewUrl]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe || previewUrl) return;\n try {\n iframe.contentWindow?.postMessage({ type: \"navigate\", path: url }, \"*\");\n } catch {\n // cross-origin or iframe not ready\n }\n }, [url, previewUrl]);\n\n // Listen for <title> changes inside the iframe\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n let observer: MutationObserver | undefined;\n\n const observe = () => {\n try {\n const doc = iframe.contentDocument;\n if (!doc) return;\n\n const readTitle = () => {\n const t = doc.title;\n if (t) setDocTitle(t);\n };\n\n readTitle();\n\n const head = doc.head ?? doc.documentElement;\n if (!head) return;\n\n observer = new MutationObserver(readTitle);\n observer.observe(head, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n } catch {\n // cross-origin\n }\n };\n\n iframe.addEventListener(\"load\", observe);\n return () => {\n iframe.removeEventListener(\"load\", observe);\n observer?.disconnect();\n };\n }, [htmlSrc, previewUrl]);\n\n // Clean up inspect mode when htmlSrc changes (page rebuild)\n useEffect(() => {\n if (inspecting) {\n inspectCleanupRef.current?.();\n inspectCleanupRef.current = null;\n // Re-inject after a tick so the iframe has loaded\n const timer = setTimeout(() => {\n if (inspecting) injectInspectMode();\n }, 100);\n return () => clearTimeout(timer);\n }\n }, [htmlSrc]);\n\n // Inject inspect mode handlers into the iframe DOM\n const injectInspectMode = useCallback(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n try {\n const doc = iframe.contentDocument;\n if (!doc) return;\n\n let currentHighlight: HTMLElement | null = null;\n const OUTLINE = \"2px solid #3b82f6\";\n const OUTLINE_OFFSET = \"-2px\";\n\n const onMouseOver = (e: Event) => {\n const target = e.target as HTMLElement;\n if (target === doc.body || target === doc.documentElement) return;\n if (currentHighlight) {\n currentHighlight.style.outline = \"\";\n currentHighlight.style.outlineOffset = \"\";\n }\n target.style.outline = OUTLINE;\n target.style.outlineOffset = OUTLINE_OFFSET;\n currentHighlight = target;\n };\n\n const onMouseOut = (e: Event) => {\n const target = e.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n if (currentHighlight === target) currentHighlight = null;\n };\n\n const onClick = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n const target = e.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n\n const text = (target.textContent || \"\").trim().slice(0, 200);\n const html = target.outerHTML.slice(0, 500);\n\n onInspectElement?.({\n tagName: target.tagName.toLowerCase(),\n className: target.className || \"\",\n textContent: text,\n outerHTML: html,\n });\n\n cleanup();\n setInspecting(false);\n };\n\n doc.addEventListener(\"mouseover\", onMouseOver, true);\n doc.addEventListener(\"mouseout\", onMouseOut, true);\n doc.addEventListener(\"click\", onClick, true);\n\n // Set cursor on body\n doc.body.style.cursor = \"crosshair\";\n\n const cleanup = () => {\n doc.removeEventListener(\"mouseover\", onMouseOver, true);\n doc.removeEventListener(\"mouseout\", onMouseOut, true);\n doc.removeEventListener(\"click\", onClick, true);\n doc.body.style.cursor = \"\";\n if (currentHighlight) {\n currentHighlight.style.outline = \"\";\n currentHighlight.style.outlineOffset = \"\";\n currentHighlight = null;\n }\n };\n\n inspectCleanupRef.current = cleanup;\n } catch {\n // cross-origin\n }\n }, [onInspectElement]);\n\n const toggleInspect = useCallback(() => {\n if (inspecting) {\n inspectCleanupRef.current?.();\n inspectCleanupRef.current = null;\n setInspecting(false);\n } else {\n setInspecting(true);\n // Wait a tick for the iframe to be ready\n requestAnimationFrame(() => injectInspectMode());\n }\n }, [inspecting, injectInspectMode]);\n\n const handleAddressKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n const val = e.currentTarget.value.trim();\n try {\n const parsed = new URL(\n val.startsWith(\"http\") ? val : `http://localhost:${port}${val}`,\n );\n onNavigate(parsed.pathname || \"/\");\n } catch {\n onNavigate(val.startsWith(\"/\") ? val : `/${val}`);\n }\n }\n },\n [onNavigate, port],\n );\n\n const tabLabel = docTitle || title;\n\n return (\n <div className=\"h-full flex flex-col rounded-xl overflow-hidden border border-zinc-800 bg-zinc-950 shadow-[0_0_0_1px_rgba(255,255,255,0.03),0_8px_40px_-12px_rgba(0,0,0,0.6)]\">\n {/* Toolbar */}\n <div className=\"flex-shrink-0 flex items-center gap-2 h-10 px-3 bg-zinc-900/80 border-b border-zinc-800/80 select-none\">\n {/* Traffic lights */}\n <div className=\"flex items-center gap-[6px] mr-1\">\n <span className=\"block h-[10px] w-[10px] rounded-full bg-[#ff5f57] ring-1 ring-black/10\" />\n <span className=\"block h-[10px] w-[10px] rounded-full bg-[#febc2e] ring-1 ring-black/10\" />\n <span className=\"block h-[10px] w-[10px] rounded-full bg-[#28c840] ring-1 ring-black/10\" />\n </div>\n\n {/* Navigation buttons */}\n <div className=\"flex items-center\">\n <button\n onClick={onBack}\n disabled={!canGoBack}\n className=\"p-1 rounded-md text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 disabled:text-zinc-700 disabled:hover:bg-transparent transition-colors\"\n title=\"Back\">\n <svg\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M10.354 3.354a.5.5 0 0 0-.708-.708l-5 5a.5.5 0 0 0 0 .708l5 5a.5.5 0 0 0 .708-.708L5.707 8l4.647-4.646z\" />\n </svg>\n </button>\n <button\n onClick={onForward}\n disabled={!canGoForward}\n className=\"p-1 rounded-md text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 disabled:text-zinc-700 disabled:hover:bg-transparent transition-colors\"\n title=\"Forward\">\n <svg\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M5.646 3.354a.5.5 0 0 1 .708-.708l5 5a.5.5 0 0 1 0 .708l-5 5a.5.5 0 0 1-.708-.708L10.293 8 5.646 3.354z\" />\n </svg>\n </button>\n <button\n onClick={onRefresh}\n className=\"p-1 rounded-md text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 transition-colors\"\n title=\"Refresh\">\n <svg\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\">\n <path d=\"M2.5 8a5.5 5.5 0 0 1 9.22-4.05M13.5 8a5.5 5.5 0 0 1-9.22 4.05\" />\n <path d=\"M13.5 2.5v3h-3M2.5 13.5v-3h3\" />\n </svg>\n </button>\n {/* Inspect element button */}\n {onInspectElement && (\n <button\n onClick={toggleInspect}\n className={`p-1 rounded-md transition-colors ${\n inspecting\n ? \"text-blue-400 bg-blue-500/15\"\n : \"text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800\"\n }`}\n title={inspecting ? \"Cancel inspect\" : \"Inspect element\"}>\n <svg\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\">\n <path d=\"M3 12l3 0\" />\n <path d=\"M12 3l0 3\" />\n <path d=\"M7.8 7.8l-2.2 -2.2\" />\n <path d=\"M16.2 7.8l2.2 -2.2\" />\n <path d=\"M7.8 16.2l-2.2 2.2\" />\n <path d=\"M12 12l9 3l-4 2l-2 4l-3 -9\" />\n </svg>\n </button>\n )}\n </div>\n\n {/* Address bar */}\n <div\n className={`flex-1 flex items-center gap-2 h-[26px] rounded-md px-2.5 transition-colors ${\n isFocused\n ? \"bg-zinc-950 ring-1 ring-zinc-600\"\n : \"bg-zinc-800/60 hover:bg-zinc-800\"\n }`}>\n <svg\n className=\"w-3 h-3 flex-shrink-0 text-zinc-500\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path\n fillRule=\"evenodd\"\n d=\"M8 1a4.5 4.5 0 0 0-4.5 4.5V7H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1h-.5V5.5A4.5 4.5 0 0 0 8 1zm2.5 6V5.5a2.5 2.5 0 0 0-5 0V7h5z\"\n />\n </svg>\n <input\n type=\"text\"\n defaultValue={displayUrl}\n key={displayUrl}\n onKeyDown={handleAddressKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className=\"flex-1 bg-transparent text-[11px] text-zinc-400 outline-none font-mono leading-none placeholder:text-zinc-600\"\n spellCheck={false}\n />\n {tabLabel && (\n <span className=\"hidden sm:block text-[10px] text-zinc-600 truncate max-w-[120px] leading-none\">\n {tabLabel}\n </span>\n )}\n </div>\n </div>\n\n {/* Viewport */}\n <div className=\"flex-1 bg-white relative\">\n <iframe\n ref={iframeRef}\n title={docTitle || title}\n sandbox=\"allow-scripts allow-forms allow-popups allow-same-origin\"\n className=\"absolute inset-0 w-full h-full border-0\"\n />\n {/* Inspect mode overlay indicator */}\n {inspecting && (\n <div className=\"absolute top-2 left-1/2 -translate-x-1/2 z-10 px-3 py-1 rounded-full bg-blue-500/90 text-white text-[10px] font-mono shadow-lg pointer-events-none\">\n Click an element to inspect\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { AccentColor, FileEntry } from \"./types\";\nimport { getFileExplorerTheme } from \"./theme\";\n\nexport interface FileExplorerProps {\n files: FileEntry[];\n selectedFile: string | null;\n onSelect: (path: string) => void;\n accentColor?: AccentColor;\n variant?: \"default\" | \"compact\";\n}\n\nconst FILE_COLOR_MAP: Record<string, string> = {\n js: \"text-yellow-400\",\n mjs: \"text-yellow-400\",\n cjs: \"text-yellow-400\",\n jsx: \"text-cyan-400\",\n ts: \"text-blue-400\",\n tsx: \"text-cyan-400\",\n json: \"text-amber-300\",\n html: \"text-orange-400\",\n css: \"text-pink-400\",\n md: \"text-blue-400\",\n vue: \"text-emerald-400\",\n svelte: \"text-orange-400\",\n astro: \"text-orange-400\",\n yaml: \"text-blue-400\",\n yml: \"text-blue-400\",\n toml: \"text-blue-400\",\n sh: \"text-green-400\",\n svg: \"text-emerald-400\",\n};\n\nfunction FileIcon({\n isDir,\n name,\n compact,\n}: {\n isDir: boolean;\n name: string;\n compact: boolean;\n}) {\n const iconSize = compact ? \"text-[11px] w-3.5\" : \"text-xs w-4\";\n if (isDir) {\n return (\n <span\n className={`text-amber-400 ${iconSize} inline-block text-center mr-1.5`}>\n &#x1F4C1;\n </span>\n );\n }\n const ext = name.split(\".\").pop()?.toLowerCase();\n const color = FILE_COLOR_MAP[ext || \"\"] || \"text-zinc-400\";\n return (\n <span className={`${color} ${iconSize} inline-block text-center mr-1.5`}>\n &#x1F4C4;\n </span>\n );\n}\n\nfunction TreeNode({\n entry,\n depth,\n selectedFile,\n onSelect,\n theme,\n compact,\n}: {\n entry: FileEntry;\n depth: number;\n selectedFile: string | null;\n onSelect: (path: string) => void;\n theme: { selected: string };\n compact: boolean;\n}) {\n const [expanded, setExpanded] = useState(true);\n\n const isSelected = entry.path === selectedFile;\n const py = compact ? \"py-[3px]\" : \"py-0.5\";\n const px = compact ? \"px-1.5\" : \"px-2\";\n const fontSize = compact ? \"text-[12px]\" : \"text-[13px]\";\n const arrowSize = compact ? \"text-[9px] w-2.5\" : \"text-[10px] w-3\";\n const indent = compact ? depth * 10 + 6 : depth * 12 + 8;\n\n return (\n <div>\n <button\n onClick={() =>\n entry.isDir ? setExpanded(!expanded) : onSelect(entry.path)\n }\n className={`\n w-full text-left flex items-center ${py} ${px} rounded ${fontSize} font-mono\n transition-colors duration-75\n ${isSelected ? theme.selected : \"text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200\"}\n `}\n style={{ paddingLeft: `${indent}px` }}>\n {entry.isDir && (\n <span className={`${arrowSize} mr-1 text-zinc-500 inline-block`}>\n {expanded ? \"\\u25BE\" : \"\\u25B8\"}\n </span>\n )}\n {!entry.isDir && <span className={`${arrowSize} inline-block`} />}\n <FileIcon isDir={entry.isDir} name={entry.name} compact={compact} />\n <span className=\"truncate\">{entry.name}</span>\n </button>\n {entry.isDir &&\n expanded &&\n entry.children?.map(child => (\n <TreeNode\n key={child.path}\n entry={child}\n depth={depth + 1}\n selectedFile={selectedFile}\n onSelect={onSelect}\n theme={theme}\n compact={compact}\n />\n ))}\n </div>\n );\n}\n\nexport function FileExplorer({\n files,\n selectedFile,\n onSelect,\n accentColor = \"emerald\",\n variant = \"default\",\n}: FileExplorerProps) {\n const theme = getFileExplorerTheme(accentColor);\n const compact = variant === \"compact\";\n\n if (files.length === 0) {\n return (\n <div\n className={`p-2 ${compact ? \"text-[11px]\" : \"text-xs\"} text-zinc-600 italic`}>\n No files\n </div>\n );\n }\n\n return (\n <div className={compact ? \"py-0.5\" : \"py-1\"}>\n {files.map(entry => (\n <TreeNode\n key={entry.path}\n entry={entry}\n depth={0}\n selectedFile={selectedFile}\n onSelect={onSelect}\n theme={theme}\n compact={compact}\n />\n ))}\n </div>\n );\n}\n","import type { AccentColor } from \"./types\";\n\nexport interface PanelToggleProps {\n collapsed: boolean;\n onClick: () => void;\n label: string;\n side?: \"left\" | \"right\";\n accentColor?: AccentColor;\n}\n\nconst ACCENT_LABELS: Record<AccentColor, string> = {\n emerald: \"text-emerald-500/70\",\n violet: \"text-violet-500/70\",\n orange: \"text-orange-500/70\",\n blue: \"text-blue-500/70\",\n pink: \"text-pink-500/70\",\n green: \"text-green-500/70\",\n amber: \"text-amber-500/70\",\n};\n\nconst ACCENT_CHEVRONS: Record<AccentColor, string> = {\n emerald: \"text-emerald-400\",\n violet: \"text-violet-400\",\n orange: \"text-orange-400\",\n blue: \"text-blue-400\",\n pink: \"text-pink-400\",\n green: \"text-green-400\",\n amber: \"text-amber-400\",\n};\n\nconst ACCENT_HOVER_BG: Record<AccentColor, string> = {\n emerald: \"hover:bg-emerald-500/5\",\n violet: \"hover:bg-violet-500/5\",\n orange: \"hover:bg-orange-500/5\",\n blue: \"hover:bg-blue-500/5\",\n pink: \"hover:bg-pink-500/5\",\n green: \"hover:bg-green-500/5\",\n amber: \"hover:bg-amber-500/5\",\n};\n\nexport function PanelToggle({\n collapsed,\n onClick,\n label,\n side = \"left\",\n accentColor = \"emerald\",\n}: PanelToggleProps) {\n const chevronRight = (\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 6l6 6l-6 6\" />\n </>\n );\n const chevronLeft = (\n <>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"m15 6-6 6 6 6\" />\n </>\n );\n\n if (collapsed) {\n return (\n <button\n onClick={onClick}\n className=\"flex-shrink-0 w-7 flex flex-col items-center gap-2 pt-3 pb-3\n border-r border-zinc-800 bg-zinc-900/40\n hover:bg-zinc-800/60 transition-colors cursor-pointer\"\n title={`Show ${label}`}>\n <svg\n className={`w-3 h-3 ${ACCENT_CHEVRONS[accentColor]}`}\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n fill=\"none\">\n {side === \"left\" ? chevronRight : chevronLeft}\n </svg>\n <span\n className={`text-[10px] font-mono tracking-wider uppercase select-none ${ACCENT_LABELS[accentColor]}`}\n style={{ writingMode: \"vertical-rl\", transform: \"rotate(180deg)\" }}>\n {label}\n </span>\n </button>\n );\n }\n\n return (\n <button\n onClick={onClick}\n className={`flex-shrink-0 w-[9px] flex items-center justify-center\n border-r border-zinc-800 bg-transparent\n ${ACCENT_HOVER_BG[accentColor]} transition-colors cursor-pointer group`}\n title={`Hide ${label}`}>\n <svg\n className={`w-2.5 h-2.5 text-zinc-600 opacity-0 group-hover:opacity-100\n transition-opacity ${ACCENT_CHEVRONS[accentColor]}`}\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n {side === \"left\" ? chevronLeft : chevronRight}\n </svg>\n </button>\n );\n}\n","import { useRef, useEffect, useState } from \"react\";\nimport type { AccentColor } from \"./types\";\n\nexport interface TabItem {\n id: string;\n label: string;\n icon?: React.ReactNode;\n}\n\nexport interface MobileTabBarProps {\n tabs: TabItem[];\n activeTab: string;\n onTabChange: (id: string) => void;\n accentColor?: AccentColor;\n}\n\nconst ACTIVE_BG: Record<AccentColor, string> = {\n emerald: \"bg-emerald-500/15\",\n violet: \"bg-violet-500/15\",\n orange: \"bg-orange-500/15\",\n blue: \"bg-blue-500/15\",\n pink: \"bg-pink-500/15\",\n green: \"bg-green-500/15\",\n amber: \"bg-amber-500/15\",\n};\n\nconst ACTIVE_TEXT: Record<AccentColor, string> = {\n emerald: \"text-emerald-300\",\n violet: \"text-violet-300\",\n orange: \"text-orange-300\",\n blue: \"text-blue-300\",\n pink: \"text-pink-300\",\n green: \"text-green-300\",\n amber: \"text-amber-300\",\n};\n\nexport function MobileTabBar({\n tabs,\n activeTab,\n onTabChange,\n accentColor = \"emerald\",\n}: MobileTabBarProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [indicator, setIndicator] = useState({ left: 0, width: 0 });\n\n useEffect(() => {\n if (!containerRef.current) return;\n const activeIndex = tabs.findIndex(t => t.id === activeTab);\n if (activeIndex < 0) return;\n const buttons = containerRef.current.querySelectorAll<HTMLButtonElement>(\n \"[data-tab-id]\",\n );\n const btn = buttons[activeIndex];\n if (!btn) return;\n setIndicator({\n left: btn.offsetLeft,\n width: btn.offsetWidth,\n });\n }, [activeTab, tabs]);\n\n return (\n <div className=\"flex-shrink-0 px-3 py-1.5 border-b border-zinc-800 bg-zinc-950\">\n <div\n ref={containerRef}\n className=\"relative flex rounded-lg bg-zinc-900 border border-zinc-800 p-0.5\">\n {/* Sliding indicator */}\n <div\n className={`absolute top-0.5 bottom-0.5 rounded-md ${ACTIVE_BG[accentColor]} transition-all duration-200 ease-out`}\n style={{ left: indicator.left, width: indicator.width }}\n />\n {tabs.map(tab => {\n const isActive = tab.id === activeTab;\n return (\n <button\n key={tab.id}\n data-tab-id={tab.id}\n onClick={() => onTabChange(tab.id)}\n className={`relative z-10 flex-1 flex items-center justify-center gap-1.5\n rounded-md py-1.5 px-3 font-mono text-[11px] tracking-wide\n transition-colors duration-150\n ${isActive ? ACTIVE_TEXT[accentColor] : \"text-zinc-500 hover:text-zinc-400\"}`}>\n {tab.icon}\n {tab.label}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\n/* ── Preset icon SVGs ────────────────────────────────────────── */\n\nexport function ChatIcon({ className = \"w-3.5 h-3.5\" }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z\" />\n </svg>\n );\n}\n\nexport function PreviewIcon({ className = \"w-3.5 h-3.5\" }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\" />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\" />\n </svg>\n );\n}\n\nexport function CodeIcon({ className = \"w-3.5 h-3.5\" }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4\" />\n </svg>\n );\n}\n\nexport function TerminalIcon({ className = \"w-3.5 h-3.5\" }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n </svg>\n );\n}\n\nexport function FilesIcon({ className = \"w-3.5 h-3.5\" }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z\" />\n </svg>\n );\n}\n","import { useState, useEffect } from \"react\";\n\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n const mql = window.matchMedia(query);\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches);\n mql.addEventListener(\"change\", handler);\n return () => mql.removeEventListener(\"change\", handler);\n }, [query]);\n\n return matches;\n}\n","import type { AccentColor } from \"./types\";\n\nexport interface ChatTheme {\n userBubble: string;\n assistantBubble: string;\n sendButton: string;\n sendButtonDisabled: string;\n streamingDot: string;\n inputCaret: string;\n modelBadge: string;\n}\n\nconst CHAT_THEMES: Record<AccentColor, ChatTheme> = {\n emerald: {\n userBubble: \"bg-emerald-500/15 border border-emerald-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-emerald-500 hover:bg-emerald-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-emerald-400\",\n inputCaret: \"caret-emerald-400\",\n modelBadge: \"bg-emerald-500/10 text-emerald-400 border-emerald-500/20\",\n },\n violet: {\n userBubble: \"bg-violet-500/15 border border-violet-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-violet-500 hover:bg-violet-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-violet-400\",\n inputCaret: \"caret-violet-400\",\n modelBadge: \"bg-violet-500/10 text-violet-400 border-violet-500/20\",\n },\n orange: {\n userBubble: \"bg-orange-500/15 border border-orange-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-orange-500 hover:bg-orange-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-orange-400\",\n inputCaret: \"caret-orange-400\",\n modelBadge: \"bg-orange-500/10 text-orange-400 border-orange-500/20\",\n },\n blue: {\n userBubble: \"bg-blue-500/15 border border-blue-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-blue-500 hover:bg-blue-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-blue-400\",\n inputCaret: \"caret-blue-400\",\n modelBadge: \"bg-blue-500/10 text-blue-400 border-blue-500/20\",\n },\n pink: {\n userBubble: \"bg-pink-500/15 border border-pink-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-pink-500 hover:bg-pink-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-pink-400\",\n inputCaret: \"caret-pink-400\",\n modelBadge: \"bg-pink-500/10 text-pink-400 border-pink-500/20\",\n },\n green: {\n userBubble: \"bg-green-500/15 border border-green-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-green-500 hover:bg-green-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-green-400\",\n inputCaret: \"caret-green-400\",\n modelBadge: \"bg-green-500/10 text-green-400 border-green-500/20\",\n },\n amber: {\n userBubble: \"bg-amber-500/15 border border-amber-500/20\",\n assistantBubble: \"bg-zinc-800/50 border border-zinc-700/50\",\n sendButton: \"bg-amber-500 hover:bg-amber-600 text-white\",\n sendButtonDisabled: \"bg-zinc-700 text-zinc-500\",\n streamingDot: \"bg-amber-400\",\n inputCaret: \"caret-amber-400\",\n modelBadge: \"bg-amber-500/10 text-amber-400 border-amber-500/20\",\n },\n};\n\nexport function getChatTheme(color: AccentColor): ChatTheme {\n return CHAT_THEMES[color];\n}\n","import { useState, useRef, useEffect, useCallback, useMemo } from \"react\";\nimport type { AccentColor } from \"./types\";\nimport { getChatTheme } from \"./chat-theme\";\nimport type { InspectedElement } from \"./BrowserWindow\";\n\nexport interface ChatMessage {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: number;\n isStreaming?: boolean;\n}\n\nexport interface AIChatPanelProps {\n messages: ChatMessage[];\n onSendMessage: (content: string) => void;\n isStreaming?: boolean;\n accentColor?: AccentColor;\n title?: string;\n modelLabel?: string;\n onLoadMore?: () => void;\n hasMoreMessages?: boolean;\n /** Flat list of file paths for @ mention autocomplete */\n filePaths?: string[];\n /** Inspected element context to attach to next message */\n inspectedElement?: InspectedElement | null;\n /** Clear the inspected element context */\n onClearInspectedElement?: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// Collapsible code block\n// ---------------------------------------------------------------------------\n\nfunction CodeBlock({ lang, content }: { lang?: string; content: string }) {\n const [collapsed, setCollapsed] = useState(false);\n const lineCount = content.split(\"\\n\").length;\n\n return (\n <div className=\"my-2 rounded-lg bg-zinc-900 border border-zinc-700/50 overflow-hidden\">\n <div\n className=\"flex items-center justify-between px-3 py-1.5 bg-zinc-800/50 cursor-pointer select-none\"\n onClick={() => setCollapsed(c => !c)}>\n <div className=\"flex items-center gap-2\">\n {lang && (\n <span className=\"text-[10px] text-zinc-500 font-mono uppercase tracking-wider\">\n {lang}\n </span>\n )}\n <span className=\"text-[10px] text-zinc-600 font-mono\">\n {lineCount} lines\n </span>\n </div>\n <svg\n className={`w-3 h-3 text-zinc-500 transition-transform ${collapsed ? \"\" : \"rotate-180\"}`}\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M4.646 5.646a.5.5 0 0 1 .708 0L8 8.293l2.646-2.647a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 0-.708z\" />\n </svg>\n </div>\n {!collapsed && (\n <pre className=\"p-3 overflow-x-auto\">\n <code className=\"text-[12px] font-mono text-zinc-300 leading-relaxed whitespace-pre\">\n {content}\n </code>\n </pre>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Content renderer (text + code blocks)\n// ---------------------------------------------------------------------------\n\nfunction renderContent(text: string) {\n const parts: Array<{\n type: \"text\" | \"code\";\n content: string;\n lang?: string;\n }> = [];\n const codeBlockRegex = /```(\\w*)\\n([\\s\\S]*?)```/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = codeBlockRegex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n parts.push({ type: \"text\", content: text.slice(lastIndex, match.index) });\n }\n parts.push({\n type: \"code\",\n content: match[2],\n lang: match[1] || undefined,\n });\n lastIndex = match.index + match[0].length;\n }\n\n if (lastIndex < text.length) {\n parts.push({ type: \"text\", content: text.slice(lastIndex) });\n }\n\n if (parts.length === 0) {\n parts.push({ type: \"text\", content: text });\n }\n\n return (\n <>\n {parts.map((part, i) => {\n if (part.type === \"code\") {\n return <CodeBlock key={i} lang={part.lang} content={part.content} />;\n }\n return (\n <span key={i} className=\"whitespace-pre-wrap\">\n {part.content}\n </span>\n );\n })}\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Inline file mention rendering (@/path/to/file)\n// ---------------------------------------------------------------------------\n\nfunction renderUserContent(text: string) {\n const parts = text.split(/(@\\/[^\\s]+)/g);\n return (\n <>\n {parts.map((part, i) =>\n part.startsWith(\"@/\") ? (\n <span\n key={i}\n className=\"inline-flex items-center gap-0.5 px-1 py-0.5 rounded bg-blue-500/20 text-blue-300 font-mono text-[11px]\">\n <svg\n className=\"w-2.5 h-2.5 flex-shrink-0\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M3.75 1.5A2.25 2.25 0 0 0 1.5 3.75v8.5A2.25 2.25 0 0 0 3.75 14.5h8.5a2.25 2.25 0 0 0 2.25-2.25V6.621a2.25 2.25 0 0 0-.659-1.591L10.47 1.659A2.25 2.25 0 0 0 8.879 1.5H3.75z\" />\n </svg>\n {part.slice(1)}\n </span>\n ) : (\n <span key={i}>{part}</span>\n ),\n )}\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Collapsible message wrapper\n// ---------------------------------------------------------------------------\n\nfunction MessageBubble({\n msg,\n theme,\n}: {\n msg: ChatMessage;\n theme: ReturnType<typeof getChatTheme>;\n}) {\n const [collapsed, setCollapsed] = useState(false);\n const hasCode = msg.role === \"assistant\" && /```/.test(msg.content);\n const isLong = msg.content.length > 500;\n const canCollapse = (hasCode || isLong) && !msg.isStreaming;\n\n if (msg.role === \"user\") {\n return (\n <div className=\"flex justify-end\">\n <div\n className={`max-w-[85%] rounded-xl px-3.5 py-2.5 text-[13px] leading-relaxed ${theme.userBubble} text-zinc-200`}>\n {renderUserContent(msg.content)}\n </div>\n </div>\n );\n }\n\n // Assistant message — no bubble wrapper, just inline content\n return (\n <div className=\"text-[13px] leading-relaxed text-zinc-300\">\n {collapsed ? (\n <button\n onClick={() => setCollapsed(false)}\n className=\"flex items-center gap-1.5 text-left\">\n <svg\n className=\"w-2.5 h-2.5 text-zinc-600 flex-shrink-0\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M6.646 3.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L9.293 7 6.646 4.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n <span className=\"text-[11px] text-zinc-600\">\n {msg.content\n .split(\"\\n\")[0]\n .replace(/```\\w*/, \"\")\n .trim()\n .slice(0, 60) || \"Response\"}\n ...\n </span>\n </button>\n ) : (\n <div>\n {renderContent(msg.content)}\n {msg.isStreaming && (\n <span className=\"inline-flex items-center gap-1 ml-1\">\n <span\n className={`inline-block h-1.5 w-1.5 rounded-full ${theme.streamingDot} animate-pulse`}\n />\n </span>\n )}\n {canCollapse && (\n <button\n onClick={() => setCollapsed(true)}\n className=\"mt-1 flex items-center gap-1 text-zinc-600 hover:text-zinc-400 transition-colors\">\n <svg\n className=\"w-2.5 h-2.5\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M4.646 5.646a.5.5 0 0 1 .708 0L8 8.293l2.646-2.647a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 0 1 0-.708z\" />\n </svg>\n <span className=\"text-[10px]\">Collapse</span>\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport function AIChatPanel({\n messages,\n onSendMessage,\n isStreaming = false,\n accentColor = \"blue\",\n title = \"Chat\",\n modelLabel,\n onLoadMore,\n hasMoreMessages = false,\n filePaths = [],\n inspectedElement,\n onClearInspectedElement,\n}: AIChatPanelProps) {\n const [input, setInput] = useState(\"\");\n const scrollRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const isAtBottomRef = useRef(true);\n\n // @ mention state\n const [mentionQuery, setMentionQuery] = useState<string | null>(null);\n const [mentionStart, setMentionStart] = useState(0);\n const [mentionIdx, setMentionIdx] = useState(0);\n\n const theme = getChatTheme(accentColor);\n\n // Filtered file paths for autocomplete\n const mentionFiltered = useMemo(() => {\n if (mentionQuery === null) return [];\n const q = mentionQuery.toLowerCase();\n return filePaths.filter(p => p.toLowerCase().includes(q)).slice(0, 8);\n }, [mentionQuery, filePaths]);\n\n // Reset selection when filtered results change\n useEffect(() => {\n setMentionIdx(0);\n }, [mentionFiltered.length]);\n\n // Auto-scroll to bottom when new messages arrive (if user hasn't scrolled up)\n useEffect(() => {\n const el = scrollRef.current;\n if (el && isAtBottomRef.current) {\n el.scrollTop = el.scrollHeight;\n }\n }, [messages]);\n\n // Track whether user is at bottom\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n\n const handleScroll = () => {\n const threshold = 40;\n isAtBottomRef.current =\n el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n };\n\n el.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", handleScroll);\n }, []);\n\n // IntersectionObserver for lazy loading older messages\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel || !onLoadMore || !hasMoreMessages) return;\n\n const observer = new IntersectionObserver(\n entries => {\n if (entries[0].isIntersecting) {\n onLoadMore();\n }\n },\n { root: scrollRef.current, threshold: 0 },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onLoadMore, hasMoreMessages]);\n\n // Auto-resize textarea\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n ta.style.height = `${Math.min(ta.scrollHeight, 200)}px`;\n }, [input]);\n\n // Track @ mentions as user types\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const val = e.target.value;\n setInput(val);\n\n const cursorPos = e.target.selectionStart;\n const textBefore = val.slice(0, cursorPos);\n\n const atMatch = textBefore.match(/(?:^|\\s)@([^\\s]*)$/);\n if (atMatch) {\n setMentionQuery(atMatch[1]);\n setMentionStart(cursorPos - atMatch[1].length - 1);\n } else {\n setMentionQuery(null);\n }\n },\n [],\n );\n\n const handleMentionSelect = useCallback(\n (path: string) => {\n const before = input.slice(0, mentionStart);\n const after = input.slice(mentionStart + 1 + (mentionQuery?.length ?? 0));\n const newInput = `${before}@${path}${after ? after : \" \"}`;\n setInput(newInput);\n setMentionQuery(null);\n\n requestAnimationFrame(() => {\n const ta = textareaRef.current;\n if (ta) {\n ta.focus();\n const pos = before.length + 1 + path.length + 1;\n ta.selectionStart = pos;\n ta.selectionEnd = pos;\n }\n });\n },\n [input, mentionStart, mentionQuery],\n );\n\n const handleSend = useCallback(() => {\n const trimmed = input.trim();\n if (!trimmed || isStreaming) return;\n\n // If there's an inspected element, prepend context\n let messageContent = trimmed;\n if (inspectedElement) {\n const ctx = `[Inspected element: <${inspectedElement.tagName} class=\"${inspectedElement.className}\"> \"${inspectedElement.textContent.slice(0, 100)}\"]\\n\\n`;\n messageContent = ctx + trimmed;\n onClearInspectedElement?.();\n }\n\n onSendMessage(messageContent);\n setInput(\"\");\n setMentionQuery(null);\n isAtBottomRef.current = true;\n }, [\n input,\n isStreaming,\n onSendMessage,\n inspectedElement,\n onClearInspectedElement,\n ]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n // Handle autocomplete keyboard navigation\n if (mentionQuery !== null && mentionFiltered.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setMentionIdx(i => (i + 1) % mentionFiltered.length);\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setMentionIdx(\n i => (i - 1 + mentionFiltered.length) % mentionFiltered.length,\n );\n return;\n }\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n handleMentionSelect(mentionFiltered[mentionIdx]);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setMentionQuery(null);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [\n handleSend,\n mentionQuery,\n mentionFiltered,\n mentionIdx,\n handleMentionSelect,\n ],\n );\n\n return (\n <div className=\"h-full flex flex-col bg-zinc-950\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-3 py-1.5 bg-zinc-900/50 border-b border-zinc-800\">\n <div className=\"flex items-center gap-1.5\">\n <div className=\"flex gap-1\">\n <div className=\"h-2.5 w-2.5 rounded-full bg-red-500/70\" />\n <div className=\"h-2.5 w-2.5 rounded-full bg-yellow-500/70\" />\n <div className=\"h-2.5 w-2.5 rounded-full bg-green-500/70\" />\n </div>\n <span className=\"text-[11px] font-semibold uppercase tracking-wider text-zinc-500\">\n {title}\n </span>\n </div>\n {modelLabel && (\n <span\n className={`text-[10px] font-mono px-2 py-0.5 rounded-full border ${theme.modelBadge}`}>\n {modelLabel}\n </span>\n )}\n </div>\n\n {/* Messages area */}\n <div\n ref={scrollRef}\n className=\"flex-1 overflow-y-auto px-3 py-3 space-y-3\">\n {hasMoreMessages && (\n <div ref={sentinelRef} className=\"flex justify-center py-2\">\n <div className=\"h-4 w-4 animate-spin rounded-full border border-zinc-600 border-t-zinc-400\" />\n </div>\n )}\n\n {messages.map(msg => (\n <MessageBubble key={msg.id} msg={msg} theme={theme} />\n ))}\n </div>\n\n {/* Input area */}\n <div className=\"flex-shrink-0 border-t border-zinc-800 p-3\">\n {/* Inspected element context badge */}\n {inspectedElement && (\n <div className=\"mb-2 flex items-center gap-2 px-2.5 py-1.5 rounded-lg bg-blue-500/10 border border-blue-500/20\">\n <svg\n className=\"w-3.5 h-3.5 text-blue-400 flex-shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\">\n <path d=\"M3 12l3 0\" />\n <path d=\"M12 3l0 3\" />\n <path d=\"M7.8 7.8l-2.2 -2.2\" />\n <path d=\"M16.2 7.8l2.2 -2.2\" />\n <path d=\"M7.8 16.2l-2.2 2.2\" />\n <path d=\"M12 12l9 3l-4 2l-2 4l-3 -9\" />\n </svg>\n <div className=\"flex-1 min-w-0\">\n <span className=\"text-[11px] font-mono text-blue-300\">\n &lt;{inspectedElement.tagName}&gt;\n </span>\n {inspectedElement.textContent && (\n <span className=\"text-[11px] text-zinc-500 ml-1.5 truncate\">\n \"{inspectedElement.textContent.slice(0, 40)}\n {inspectedElement.textContent.length > 40 ? \"...\" : \"\"}\"\n </span>\n )}\n </div>\n <button\n onClick={onClearInspectedElement}\n className=\"text-zinc-500 hover:text-zinc-300 transition-colors flex-shrink-0\">\n <svg className=\"w-3 h-3\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n </button>\n </div>\n )}\n\n <div className=\"relative flex items-end gap-2\">\n {/* @ mention dropdown */}\n {mentionQuery !== null && mentionFiltered.length > 0 && (\n <div className=\"absolute bottom-full left-0 right-0 mb-1 bg-zinc-900 border border-zinc-700 rounded-lg shadow-xl overflow-hidden z-10\">\n {mentionFiltered.map((path, i) => (\n <button\n key={path}\n onMouseDown={e => {\n e.preventDefault();\n handleMentionSelect(path);\n }}\n onMouseEnter={() => setMentionIdx(i)}\n className={`w-full text-left px-3 py-1.5 text-[12px] font-mono flex items-center gap-2 transition-colors ${\n i === mentionIdx\n ? \"bg-blue-500/15 text-blue-300\"\n : \"text-zinc-400 hover:bg-zinc-800\"\n }`}>\n <svg\n className=\"w-3 h-3 flex-shrink-0 text-zinc-500\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\">\n <path d=\"M3.75 1.5A2.25 2.25 0 0 0 1.5 3.75v8.5A2.25 2.25 0 0 0 3.75 14.5h8.5a2.25 2.25 0 0 0 2.25-2.25V6.621a2.25 2.25 0 0 0-.659-1.591L10.47 1.659A2.25 2.25 0 0 0 8.879 1.5H3.75z\" />\n </svg>\n {path}\n </button>\n ))}\n </div>\n )}\n <textarea\n ref={textareaRef}\n value={input}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n disabled={isStreaming}\n placeholder={\n isStreaming\n ? \"Generating...\"\n : \"Describe a component... (@ to reference files)\"\n }\n rows={1}\n className={`\n flex-1 resize-none overflow-hidden bg-zinc-900 border border-zinc-700/50 rounded-lg px-3 py-2\n text-[13px] text-zinc-200 font-mono outline-none\n placeholder:text-zinc-600 disabled:opacity-50\n focus:border-zinc-600 transition-colors\n min-h-[60px]\n ${theme.inputCaret}\n `}\n />\n <button\n onClick={handleSend}\n disabled={isStreaming || !input.trim()}\n className={`\n flex-shrink-0 h-9 w-9 rounded-lg flex items-center justify-center\n transition-colors disabled:cursor-not-allowed\n ${isStreaming || !input.trim() ? theme.sendButtonDisabled : theme.sendButton}\n `}>\n {isStreaming ? (\n <div className=\"h-4 w-4 animate-spin rounded-full border border-zinc-500 border-t-zinc-300\" />\n ) : (\n <svg className=\"w-4 h-4\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M1.724 1.053a.5.5 0 0 0-.714.545l1.403 4.85a.5.5 0 0 0 .397.354l5.69.953c.268.045.268.545 0 .59l-5.69.953a.5.5 0 0 0-.397.354l-1.403 4.85a.5.5 0 0 0 .714.545l13-6.5a.5.5 0 0 0 0-.894l-13-6.5z\" />\n </svg>\n )}\n </button>\n </div>\n <p className=\"text-[10px] text-zinc-600 mt-1.5 px-1\">\n Enter to send · Shift+Enter for newline · @ to reference files\n </p>\n </div>\n </div>\n );\n}\n"],"names":["useRef","useEffect","useState","useCallback","jsx","useMemo","jsxs","Fragment"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export { CodeEditor } from "./CodeEditor";
2
+ export type { CodeEditorProps } from "./CodeEditor";
3
+ export { Terminal } from "./Terminal";
4
+ export type { TerminalProps } from "./Terminal";
5
+ export { BrowserWindow } from "./BrowserWindow";
6
+ export type { BrowserWindowProps, InspectedElement } from "./BrowserWindow";
7
+ export { FileExplorer } from "./FileExplorer";
8
+ export type { FileExplorerProps } from "./FileExplorer";
9
+ export { PanelToggle } from "./PanelToggle";
10
+ export type { PanelToggleProps } from "./PanelToggle";
11
+ export { MobileTabBar, ChatIcon, PreviewIcon, CodeIcon, TerminalIcon, FilesIcon, } from "./MobileTabBar";
12
+ export type { MobileTabBarProps, TabItem } from "./MobileTabBar";
13
+ export { useMediaQuery } from "./useMediaQuery";
14
+ export type { TerminalLine, AccentColor, FileEntry } from "./types";
15
+ export { AIChatPanel } from "./AIChatPanel";
16
+ export type { AIChatPanelProps, ChatMessage } from "./AIChatPanel";
17
+ export { getLanguageLabel } from "./language-labels";
18
+ export { getEditorTheme, getTerminalTheme, getLineStyles, getFileExplorerTheme, } from "./theme";
19
+ export type { EditorTheme, TerminalTheme, FileExplorerTheme } from "./theme";
20
+ export { getChatTheme } from "./chat-theme";
21
+ export type { ChatTheme } from "./chat-theme";