next-ai-editor 1.0.2 → 1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/shared/path-utils.ts","../src/client/fiber-utils.ts","../src/client/components/TaskHistoryPanel.tsx","../src/client/components/MessageItem.tsx","../src/client/components/MessageList.tsx","../src/client/service-config.ts","../src/client/hooks/useChatStream.ts","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/box.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/file-code.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/pencil.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js","../src/client/components/ChatPanel.tsx","../src/client/components/ControlPill.tsx","../src/client/AIEditorProvider.tsx"],"sourcesContent":["/**\n * Shared path utilities for cleaning and normalizing file paths\n * Used by both client and server for consistent path handling\n */\n\n/**\n * Clean a file path by removing protocol prefixes and URL encoding\n * Works with Turbopack, Webpack, and React Server Components paths\n */\nexport function cleanPath(filePath: string): string {\n if (!filePath) return \"\";\n\n let cleaned = filePath;\n\n // Remove about://React/Server/ prefix first (wraps file:// URLs)\n cleaned = cleaned.replace(/^about:\\/\\/React\\/Server\\//, \"\");\n\n // Remove file:// protocol\n if (cleaned.startsWith(\"file://\")) {\n cleaned = cleaned.replace(/^file:\\/\\//, \"\");\n }\n\n // Decode URL-encoded paths (e.g., %5B becomes [, %5D becomes ])\n try {\n if (cleaned.includes(\"%\")) {\n cleaned = decodeURIComponent(cleaned);\n }\n } catch (e) {\n // If decoding fails, continue with original\n }\n\n // Remove other protocol prefixes\n cleaned = cleaned\n .replace(/^webpack-internal:\\/\\/\\/\\([^)]+\\)\\/\\.\\//, \"\")\n .replace(/^webpack-internal:\\/\\/\\/\\([^)]+\\)\\//, \"\")\n .replace(/^webpack-internal:\\/\\//, \"\")\n .replace(/^webpack:\\/\\/[^/]*\\//, \"\")\n .replace(/^\\([^)]+\\)\\//, \"\")\n .replace(/^\\.\\//, \"\")\n .replace(/\\?.*$/, \"\");\n\n return cleaned;\n}\n\n/**\n * Normalize a source path by cleaning it and making it relative to project root\n * @param source - The source path to normalize\n * @param projectRoot - The project root directory\n * @returns Normalized relative path\n */\nexport function normalizeSourcePath(source: string, projectRoot: string): string {\n let cleaned = cleanPath(source);\n\n // Normalize path separators to forward slashes\n cleaned = cleaned.replace(/\\\\/g, \"/\");\n\n // Remove project root prefix if present\n if (cleaned.startsWith(projectRoot)) {\n cleaned = cleaned.substring(projectRoot.length + 1);\n }\n\n // Remove leading slashes\n return cleaned.replace(/^\\/+/, \"\");\n}\n\n/**\n * Check if a file path should be skipped (e.g., node_modules, framework internals)\n * @param filePath - The file path to check\n * @param additionalSkipPatterns - Additional patterns to skip (optional)\n * @returns true if the path should be skipped\n */\nexport function shouldSkipPath(\n filePath: string,\n additionalSkipPatterns: string[] = []\n): boolean {\n if (!filePath) return true;\n\n const defaultSkipPatterns = [\"node_modules\", \"next/dist\", \"react-dom\"];\n const allPatterns = [...defaultSkipPatterns, ...additionalSkipPatterns];\n\n return allPatterns.some((pattern) => filePath.includes(pattern));\n}\n","// =============================================================================\n// FILE: fiber-utils.ts\n// React Fiber tree utilities for extracting component source locations\n// =============================================================================\n\nimport type { ElementContext, SourceLocation } from \"../shared/types\";\nimport { cleanPath, shouldSkipPath } from \"../shared/path-utils\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface FiberNode {\n tag: number;\n type: any;\n key: string | null;\n return: FiberNode | null;\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n _debugStack?: any;\n _debugOwner?: any;\n memoizedProps?: any;\n pendingProps?: any;\n}\n\n// =============================================================================\n// FIBER UTILITIES\n// =============================================================================\n\nexport function getFiberFromElement(element: Element): FiberNode | null {\n const key = Object.keys(element).find(\n (k) =>\n k.startsWith(\"__reactFiber$\") || k.startsWith(\"__reactInternalInstance$\"),\n );\n return key ? (element as any)[key] : null;\n}\n\nexport function getComponentName(fiber: FiberNode | null): string {\n if (!fiber) return \"Unknown\";\n const type = fiber.type;\n\n // Try _debugSource first (most reliable for Client Components)\n if (fiber._debugSource?.fileName) {\n const fileName = fiber._debugSource.fileName;\n // Extract component name from file path (e.g., \"components/InfoBox.tsx\" -> \"InfoBox\")\n const match = fileName.match(/\\/([^/]+)\\.(tsx?|jsx?)$/);\n if (match) return match[1];\n }\n\n // Try type properties\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\")\n return type.displayName || type.name || \"Anonymous\";\n if (type?.displayName) return type.displayName;\n if (type?.render?.name) return type.render.name;\n\n // For Server Components, extract from _debugStack (no _debugSource on client)\n if (fiber._debugStack) {\n const stack = String(fiber._debugStack.stack || fiber._debugStack);\n // Look for pattern: \"at ComponentName (\"\n const match = stack.match(/at\\s+([A-Z][a-zA-Z0-9]*)\\s*\\(/);\n if (match && match[1] !== \"Object\") {\n return match[1];\n }\n }\n\n return \"Unknown\";\n}\n\nexport function isUserComponent(fiber: FiberNode): boolean {\n if (fiber.tag === 5 || fiber.tag === 6 || fiber.tag === 3) return false;\n const type = fiber.type;\n if (!type || typeof type === \"string\") return false;\n return true;\n}\n\n// =============================================================================\n// ELEMENT CONTEXT CAPTURE\n// =============================================================================\n\nfunction countNthOfType(element: Element, tagName: string): number {\n let boundary: Element | null = element.parentElement;\n\n // Find component boundary\n while (boundary) {\n const fiber = getFiberFromElement(boundary);\n if (fiber && isUserComponent(fiber)) break;\n boundary = boundary.parentElement;\n }\n\n if (!boundary) boundary = element.parentElement;\n if (!boundary) return 1;\n\n // Get all matching elements INCLUDING the boundary itself\n const sameTagElements: Element[] = [];\n\n // Check if boundary itself matches\n if (boundary.tagName.toLowerCase() === tagName.toLowerCase()) {\n sameTagElements.push(boundary);\n }\n\n // Add all descendants that match\n sameTagElements.push(...Array.from(boundary.querySelectorAll(tagName)));\n\n let count = 1;\n for (const el of sameTagElements) {\n if (el === element) break;\n count++;\n }\n\n return count;\n}\n\nfunction extractProps(\n fiber: FiberNode | null,\n): Record<string, any> | undefined {\n if (!fiber) return undefined;\n\n const fiberProps = fiber.memoizedProps || fiber.pendingProps;\n if (!fiberProps || typeof fiberProps !== \"object\") return undefined;\n\n const props: Record<string, any> = {};\n const identifyingKeys = [\n \"id\",\n \"name\",\n \"type\",\n \"href\",\n \"src\",\n \"alt\",\n \"role\",\n \"aria-label\",\n \"data-testid\",\n ];\n\n for (const key of identifyingKeys) {\n if (key in fiberProps && typeof fiberProps[key] === \"string\") {\n props[key] = fiberProps[key];\n }\n }\n\n if (fiberProps.style && typeof fiberProps.style === \"object\") {\n props._styleKeys = Object.keys(fiberProps.style).slice(0, 5);\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\nexport function captureElementContext(\n element: Element,\n fiber: FiberNode | null,\n): ElementContext {\n const tagName = element.tagName.toLowerCase();\n\n // Text content (direct text only, truncated)\n let textContent: string | undefined;\n const directText = Array.from(element.childNodes)\n .filter((n) => n.nodeType === Node.TEXT_NODE)\n .map((n) => n.textContent?.trim())\n .filter(Boolean)\n .join(\" \");\n\n if (directText) {\n textContent = directText.slice(0, 50);\n } else if (element.textContent) {\n textContent = element.textContent.trim().slice(0, 50);\n }\n\n // Class name\n const className =\n typeof element.className === \"string\"\n ? element.className.slice(0, 100)\n : undefined;\n\n // Count nth of type within component\n const nthOfType = countNthOfType(element, tagName);\n\n // React key\n const key = fiber?.key ? String(fiber.key) : undefined;\n\n // Identifying props\n const props = extractProps(fiber);\n\n return { tagName, textContent, className, key, nthOfType, props };\n}\n\n// =============================================================================\n// SOURCE LOCATION FINDER\n// =============================================================================\n\nfunction extractFromDebugStack(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const stack = (fiber as any)._debugStack;\n if (!stack) return null;\n\n const stackStr = stack.stack || String(stack);\n const frames = stackStr.split(\"\\n\");\n\n const skipPatterns = [\n \"node_modules\",\n \"SegmentViewNode\",\n \"LayoutRouter\",\n \"ErrorBoundary\",\n \"fakeJSXCallSite\",\n ];\n\n for (const frame of frames) {\n if (skipPatterns.some((p) => frame.includes(p))) continue;\n\n // Match: at Name (path:line:col)\n const match = frame.match(/at\\s+(\\w+)\\s+\\((.+?):(\\d+):(\\d+)\\)?$/);\n if (match) {\n const fileName = cleanPath(match[2].replace(/\\?[^:]*$/, \"\"));\n if (!shouldSkipPath(fileName, [\"ai-editor-provider\"])) {\n return {\n fileName,\n lineNumber: parseInt(match[3], 10),\n columnNumber: parseInt(match[4], 10),\n };\n }\n }\n }\n return null;\n}\n\nfunction extractFromDebugOwner(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const owner = (fiber as any)._debugOwner;\n if (!owner) return null;\n\n if (owner._debugSource?.fileName) {\n return owner._debugSource;\n }\n\n const stack = owner.stack;\n if (Array.isArray(stack) && stack[0]?.fileName) {\n return stack[0];\n }\n\n return null;\n}\n\nexport function findSourceFromFiber(\n fiber: FiberNode | null,\n): Omit<SourceLocation, \"elementContext\"> | null {\n if (!fiber) return null;\n\n // For Server Components, _debugOwner contains the actual component info\n // Structure: { name: \"ComponentName\", owner: { name: \"ParentName\", debugLocation: Error }, debugStack: Error }\n let actualComponentName: string | null = null;\n if (fiber._debugOwner && typeof fiber._debugOwner === \"object\") {\n const debugOwner = fiber._debugOwner as any;\n if (debugOwner.name && typeof debugOwner.name === \"string\") {\n actualComponentName = debugOwner.name;\n }\n }\n\n let current: FiberNode | null = fiber;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 10) {\n iterations++;\n visited.add(current);\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n // Use the actualComponentName from _debugOwner if available (Server Components)\n // Otherwise walk up to find the nearest user component\n if (actualComponentName) {\n // Server Component - use _debugOwner.name\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName: actualComponentName,\n debugStack: rawDebugStack,\n };\n } else {\n // Client Component - walk up fiber tree\n let componentFiber: FiberNode | null = current;\n while (componentFiber) {\n if (isUserComponent(componentFiber)) {\n const componentName = getComponentName(componentFiber);\n\n // Skip Next.js internal components\n const isNextJSInternal = [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (!isNextJSInternal) {\n // Capture the raw _debugStack for server-side source map resolution\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n };\n }\n }\n componentFiber =\n componentFiber.return || componentFiber._debugOwner || null;\n }\n }\n }\n }\n\n current = current.return || current._debugOwner || null;\n }\n\n return null;\n}\n\n/**\n * Find the parent component using _debugOwner (the component that rendered this one)\n */\nexport function findParentComponentFromFiber(\n childFiber: FiberNode,\n childComponentName: string,\n): {\n filePath: string;\n lineNumber: number;\n columnNumber: number;\n componentName: string;\n debugStack?: string;\n childKey?: string;\n} | null {\n if (!childFiber) return null;\n\n // Find the child component's fiber to extract its key\n let childComponentFiber: FiberNode | null = null;\n\n // Check if _debugOwner points to the component fiber\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n // If it's a FiberNode (has type property), that's the component fiber\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n const ownerComponentName = getComponentName(debugOwner);\n if (ownerComponentName === childComponentName) {\n childComponentFiber = debugOwner;\n }\n }\n }\n\n // Otherwise walk up via .return to find component fiber\n if (!childComponentFiber) {\n let current: FiberNode | null = childFiber;\n let iterations = 0;\n while (current && iterations < 20) {\n iterations++;\n const componentName = getComponentName(current);\n const index = (current as any).index;\n\n if (isUserComponent(current)) {\n if (componentName === childComponentName) {\n childComponentFiber = current;\n break;\n }\n }\n\n // For Server Components, check if _debugOwner.name matches\n // Server Components don't have a fiber with the component name, but their rendered elements do have _debugOwner\n if (current._debugOwner && typeof current._debugOwner === \"object\") {\n const debugOwner = current._debugOwner as any;\n if (debugOwner.name === childComponentName && !debugOwner.type) {\n // This is a Server Component's rendered element\n // But we need to make sure this is the ROOT element of the component, not a child element\n // Check if the parent fiber is also part of the same component\n const parent = current.return;\n const parentDebugOwner = parent?._debugOwner as any;\n const isRootElement =\n !parentDebugOwner || parentDebugOwner.name !== childComponentName;\n\n if (isRootElement) {\n // This is the root element of the component - use this fiber's index\n childComponentFiber = current;\n break;\n }\n }\n }\n\n current = current.return;\n }\n }\n\n // Use key if available, otherwise use index\n let childKey: string | undefined;\n if (childComponentFiber?.key) {\n childKey = String(childComponentFiber.key);\n } else if (\n childComponentFiber &&\n typeof (childComponentFiber as any).index === \"number\"\n ) {\n // Use index as fallback for Server Components\n childKey = String((childComponentFiber as any).index);\n }\n\n // Two patterns to handle:\n // 1. Server Component element: fiber._debugOwner = { name: \"ChildComponent\", owner: { name: \"ParentComponent\", ... } }\n // 2. Client Component element: fiber._debugOwner = ComponentFiberNode, ComponentFiberNode._debugOwner = { name: \"ParentComponent\", ... }\n\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n\n // Pattern 1: Server Component - has owner.name\n if (debugOwner.owner && debugOwner.owner.name) {\n const parentName = debugOwner.owner.name;\n const parentDebugLocation = debugOwner.owner.debugLocation;\n\n if (parentDebugLocation) {\n const stack = String(parentDebugLocation.stack || parentDebugLocation);\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n\n // Pattern 2: Client Component - _debugOwner is a FiberNode, check its _debugOwner\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n // This is a FiberNode (Client Component), check its _debugOwner\n const componentFiberOwner = debugOwner._debugOwner;\n\n if (componentFiberOwner && typeof componentFiberOwner === \"object\") {\n const parentName = componentFiberOwner.name;\n const parentDebugLocation = componentFiberOwner.debugLocation;\n\n if (parentName && typeof parentName === \"string\") {\n if (parentDebugLocation) {\n const stack = String(\n parentDebugLocation.stack || parentDebugLocation,\n );\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n }\n }\n }\n\n // Fallback: traverse fiber tree via .return\n let current: FiberNode | null = childFiber.return;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 20) {\n iterations++;\n visited.add(current);\n\n if (isUserComponent(current)) {\n const componentName = getComponentName(current);\n\n // Skip if it's the same component as the child\n if (componentName === childComponentName) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Skip Next.js internal components and AI Editor wrapper\n const shouldSkipComponent =\n componentName.includes(\"AIEditorProvider\") || // Skip the AI Editor wrapper itself\n componentName.startsWith(\"__next\") || // Skip all Next.js internal components like __next_root_layout_boundary__\n componentName.startsWith(\"_\") || // Skip internal components starting with underscore\n [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n \"RootLayout\", // Skip root layout wrapper\n \"NotFound\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (shouldSkipComponent) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n childKey,\n };\n }\n }\n }\n\n // Continue traversing using _debugOwner\n const nextOwner = current._debugOwner;\n current = nextOwner || null;\n }\n\n // If no parent found with source info, use child's debugStack to find parent on server\n // For Server Components, the child's debugStack contains the component call stack\n const childDebugStack = childFiber._debugStack\n ? String(childFiber._debugStack.stack || childFiber._debugStack)\n : null;\n\n if (childDebugStack) {\n // Use the child's debugStack to resolve the real parent on the server\n return {\n filePath: \"\", // Will be resolved on server from debugStack\n lineNumber: 0,\n columnNumber: 0,\n componentName: \"\", // Will be determined on server\n debugStack: childDebugStack, // Use child's debugStack for server-side resolution\n childKey,\n };\n }\n\n return null;\n}\n\n// =============================================================================\n// GET SOURCE FROM ELEMENT (Main export)\n// =============================================================================\n\nexport function getSourceFromElement(element: Element): SourceLocation | null {\n // Walk up DOM to find element with fiber that has source location info\n // This is important: we want the element that corresponds to the line number,\n // not a deeply nested child element\n let current: Element | null = element;\n let elementWithSource: Element | null = null;\n let fiberWithSource: FiberNode | null = null;\n\n while (current && current !== document.body) {\n const fiber = getFiberFromElement(current);\n if (fiber) {\n // Check if this fiber has source location info\n const hasSourceInfo =\n fiber._debugSource?.fileName ||\n fiber._debugStack ||\n (fiber._debugOwner && typeof fiber._debugOwner === 'object');\n\n if (hasSourceInfo && !fiberWithSource) {\n // First fiber with source info - this is the element we want\n elementWithSource = current;\n fiberWithSource = fiber;\n }\n }\n current = current.parentElement;\n }\n\n if (!fiberWithSource || !elementWithSource) return null;\n\n const source = findSourceFromFiber(fiberWithSource);\n if (!source) return null;\n\n // Capture element context from the element that has source info,\n // not from the originally clicked element\n const elementContext = captureElementContext(elementWithSource, fiberWithSource);\n\n // Find parent component from Fiber tree\n const parentComponent = findParentComponentFromFiber(\n fiberWithSource,\n source.componentName,\n );\n\n return {\n ...source,\n elementContext,\n parentComponent: parentComponent || undefined,\n };\n}\n\n// Debug helper\nif (typeof window !== \"undefined\") {\n (window as any).__getSource = getSourceFromElement;\n}\n","\"use client\";\n\nimport React from \"react\";\nimport type { TaskHistoryItem } from \"../../shared/comment-types\";\nimport \"./TaskHistoryPanel.css\";\n\nexport interface TaskHistoryPanelProps {\n isOpen: boolean;\n onClose: () => void;\n tasks: TaskHistoryItem[];\n onTaskClick?: (taskId: string) => void;\n}\n\nexport function TaskHistoryPanel({\n isOpen,\n onClose,\n tasks,\n onTaskClick,\n}: TaskHistoryPanelProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <div className=\"task-history-panel ai-editor-ui\">\n <div className=\"task-history-overlay\" onClick={onClose} />\n <div className=\"task-history-content\">\n {/* Header */}\n <div className=\"task-history-header\">\n <div className=\"header-title\">\n <span className=\"header-icon\">📝</span>\n <h2>Task History</h2>\n </div>\n <button\n className=\"close-btn\"\n onClick={onClose}\n aria-label=\"Close\"\n title=\"Close (Esc)\"\n >\n ✕\n </button>\n </div>\n\n {/* Task List */}\n <div className=\"task-history-body\">\n {tasks.length === 0 ? (\n <div className=\"empty-state\">\n <div className=\"empty-icon\">🎯</div>\n <h3>No tasks yet</h3>\n <p>Create a comment and send a message to see AI actions here.</p>\n </div>\n ) : (\n <div className=\"task-list\">\n {tasks.map((task) => (\n <TaskItem\n key={task.id}\n task={task}\n onClick={() => onTaskClick?.(task.id)}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ninterface TaskItemProps {\n task: TaskHistoryItem;\n onClick: () => void;\n}\n\nfunction TaskItem({ task, onClick }: TaskItemProps) {\n const getStatusIcon = () => {\n switch (task.status) {\n case \"pending\":\n return \"⏳\";\n case \"done\":\n return \"✅\";\n case \"failed\":\n return \"❌\";\n default:\n return \"⏳\";\n }\n };\n\n const getStatusLabel = () => {\n switch (task.status) {\n case \"pending\":\n return \"In Progress\";\n case \"done\":\n return \"Complete\";\n case \"failed\":\n return \"Failed\";\n default:\n return \"Unknown\";\n }\n };\n\n const formatTime = (timestamp: number) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n\n if (diffMins < 1) return \"Just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n const diffHours = Math.floor(diffMins / 60);\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n return `${diffDays}d ago`;\n };\n\n return (\n <div\n className={`task-item status-${task.status}`}\n onClick={onClick}\n >\n <div className=\"task-header\">\n <div className=\"task-status\">\n <span className=\"status-icon\">{getStatusIcon()}</span>\n <span className=\"status-label\">{getStatusLabel()}</span>\n </div>\n <div className=\"task-time\">{formatTime(task.createdAt)}</div>\n </div>\n\n <div className=\"task-request\">{task.userRequest}</div>\n\n {task.actions.length > 0 && (\n <div className=\"task-actions\">\n {task.actions.map((action, idx) => (\n <div key={idx} className=\"action-item\">\n {action.type === \"tool_use\" && (\n <span className=\"action-text\">\n 🔧 {action.tool}\n </span>\n )}\n {action.type === \"result\" && (\n <span className=\"action-text\">\n ✓ {action.result}\n </span>\n )}\n {action.type === \"error\" && (\n <span className=\"action-text error\">\n ⚠️ {action.error}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n\n {task.affectedFiles.length > 0 && (\n <div className=\"task-files\">\n <span className=\"files-label\">Files:</span>\n {task.affectedFiles.map((file, idx) => (\n <span key={idx} className=\"file-badge\">\n {file.split(\"/\").pop()}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\n\nexport interface MessageItemProps {\n message: ChatMessage | CommentMessage;\n}\n\n/**\n * Renders a single user or final assistant message as a bubble\n */\nexport function MessageItem({ message }: MessageItemProps) {\n // Handle simple CommentMessage format (has 'role' property)\n if (\"role\" in message) {\n const commentMsg = message as CommentMessage;\n if (commentMsg.role === \"user\") {\n return (\n <div className=\"message message-user\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {commentMsg.content}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n if (commentMsg.role === \"assistant\") {\n return (\n <div className=\"message message-assistant\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {commentMsg.content}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n }\n\n // Handle complex ChatMessage format (has 'type' property)\n const chatMsg = message as ChatMessage;\n\n // Don't render system/connected messages in the UI\n if (chatMsg.type === \"connected\" || chatMsg.type === \"system\") {\n return null;\n }\n\n // Render user message\n if (chatMsg.type === \"user\") {\n return (\n <div className=\"message message-user\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {chatMsg.message}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render assistant message\n if (chatMsg.type === \"assistant\") {\n const content =\n typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n if (!content.trim()) return null;\n\n return (\n <div className=\"message message-assistant\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render error message\n if (chatMsg.type === \"error\") {\n return (\n <div className=\"message message-error\">\n <div className=\"message-content\">\n <strong>Error:</strong> {chatMsg.error}\n </div>\n </div>\n );\n }\n\n // Other message types (tool_use, tool_result, result, done)\n // are handled by TaskGroup component\n return null;\n}\n\nexport interface TaskStep {\n type: \"status\" | \"tool\" | \"completion\";\n text?: string; // Optional - not needed when isThinkingPlaceholder is true\n tool?: string;\n target?: string;\n toolId?: string;\n isComplete: boolean;\n isExecuting?: boolean;\n isQueued?: boolean;\n isLast: boolean;\n isThinkingPlaceholder?: boolean; // True when this is a \"Thinking...\" placeholder\n}\n\nexport interface TaskGroupProps {\n steps: TaskStep[];\n isStreaming: boolean;\n}\n\n/**\n * Renders a group of task steps (tool calls and status messages)\n * in a compact, checklist-style format\n */\nexport function TaskGroup({ steps, isStreaming }: TaskGroupProps) {\n if (steps.length === 0) return null;\n\n return (\n <div className=\"task-group\">\n {steps.map((step, index) => {\n const isSubtask = step.type === \"tool\";\n const isCompletion = step.type === \"completion\";\n\n return (\n <div\n key={index}\n className={`task-step ${step.type} ${\n step.isComplete ? \"complete\" : \"pending\"\n } ${step.isLast && isStreaming ? \"current\" : \"\"}`}\n >\n <div className=\"task-step-indicator\">\n {step.isComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {step.text || \"\"}\n {step.target && (\n <span className=\"task-step-target\"> {step.target}</span>\n )}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface TaskBlockProps {\n userMessage?: ChatMessage | CommentMessage;\n steps: TaskStep[];\n isStreaming: boolean;\n}\n\ninterface PhaseGroup {\n statusStep?: TaskStep;\n toolSteps: TaskStep[];\n}\n\n/**\n * Groups steps into phases (status message + its tool calls)\n */\nfunction groupStepsIntoPhases(steps: TaskStep[]): PhaseGroup[] {\n const phases: PhaseGroup[] = [];\n let currentPhase: PhaseGroup | null = null;\n\n for (const step of steps) {\n if (step.type === \"status\" || step.type === \"completion\") {\n // Start new phase with this status\n if (currentPhase) {\n phases.push(currentPhase);\n }\n currentPhase = {\n statusStep: step,\n toolSteps: [],\n };\n } else if (step.type === \"tool\") {\n // Add tool to current phase\n if (!currentPhase) {\n // Tools without a preceding status - create phase without status\n currentPhase = {\n toolSteps: [],\n };\n }\n currentPhase.toolSteps.push(step);\n }\n }\n\n // Push final phase\n if (currentPhase) {\n phases.push(currentPhase);\n }\n\n return phases;\n}\n\n/**\n * Component to render a single phase (status + tool calls)\n */\nfunction PhaseItem({\n phase,\n isStreaming,\n}: {\n phase: PhaseGroup;\n isStreaming: boolean;\n}) {\n const hasTools = phase.toolSteps.length > 0;\n\n // Phase is complete when ALL its tools are complete (or no tools)\n const allToolsComplete = phase.toolSteps.length === 0 || phase.toolSteps.every(t => t.isComplete);\n const phaseIsComplete = allToolsComplete && (!phase.statusStep || phase.statusStep.isComplete);\n\n // Phase is active when streaming and has incomplete work\n const isActive = !phaseIsComplete && isStreaming && (phase.statusStep?.isLast || hasTools);\n\n // Auto-expand when active, or when any tool is not complete\n const hasIncompleteTools = phase.toolSteps.some(step => !step.isComplete);\n const shouldAutoExpand = isActive || (hasIncompleteTools && isStreaming);\n\n const [isToolsExpanded, setIsToolsExpanded] = useState(false); // Start collapsed by default\n const [wasManuallyExpanded, setWasManuallyExpanded] = useState(false); // Track manual expansion\n const [secondsElapsed, setSecondsElapsed] = useState(0);\n\n // Auto-expand active phases, auto-collapse inactive ones (unless manually expanded)\n useEffect(() => {\n if (shouldAutoExpand) {\n setIsToolsExpanded(true);\n } else if (!wasManuallyExpanded) {\n // Auto-collapse when no longer active, but only if not manually expanded\n setIsToolsExpanded(false);\n }\n }, [shouldAutoExpand, wasManuallyExpanded]);\n\n // Track elapsed time for active phases\n useEffect(() => {\n if (!isActive) {\n setSecondsElapsed(0);\n return;\n }\n\n console.log('[PhaseItem] Starting timer for phase:', phase.statusStep?.text);\n const startTime = Date.now();\n const interval = setInterval(() => {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n setSecondsElapsed(elapsed);\n if (elapsed % 5 === 0) {\n console.log('[PhaseItem] Timer update:', phase.statusStep?.text, elapsed + 's');\n }\n }, 1000);\n\n return () => {\n console.log('[PhaseItem] Stopping timer for phase:', phase.statusStep?.text);\n clearInterval(interval);\n };\n }, [isActive, phase.statusStep?.text]);\n\n const showElapsedTime = isActive && secondsElapsed >= 3;\n\n return (\n <div className=\"phase-item\">\n {/* Status message */}\n {phase.statusStep && (\n <div\n className={`task-step ${phase.statusStep.type} ${\n phaseIsComplete ? \"complete\" : \"pending\"\n } ${isActive ? \"current\" : \"\"} ${\n hasTools ? \"has-dropdown\" : \"\"\n }`}\n onClick={hasTools ? () => {\n setIsToolsExpanded(!isToolsExpanded);\n setWasManuallyExpanded(true); // Mark as manually toggled\n } : undefined}\n >\n <div className=\"task-step-indicator\">\n {phaseIsComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {phase.statusStep.isThinkingPlaceholder ? \"Thinking...\" : (phase.statusStep.text || \"\")}\n {phase.statusStep.target && (\n <span className=\"task-step-target\">\n {\" \"}\n {phase.statusStep.target}\n </span>\n )}\n {showElapsedTime && (\n <span className=\"task-step-elapsed\"> ({secondsElapsed}s)</span>\n )}\n </span>\n {hasTools && (\n <span className=\"task-step-dropdown-icon\">\n {isToolsExpanded ? \"▼\" : \"▶\"}\n </span>\n )}\n </div>\n )}\n\n {/* Expanded tool details */}\n {isToolsExpanded && (\n <div className=\"task-step-details\">\n {/* Show \"Thinking...\" when active with no tools yet, but not if the status itself is a thinking placeholder */}\n {hasTools === false && isActive && phase.statusStep && !phase.statusStep.isThinkingPlaceholder && (\n <div className=\"task-step-detail executing\">\n <div className=\"task-step-indicator\">\n <span className=\"task-spinner\"></span>\n </div>\n <span className=\"task-step-text\">Thinking...</span>\n </div>\n )}\n\n {/* Show actual tools */}\n {phase.toolSteps.map((step, index) => (\n <div\n key={index}\n className={`task-step-detail ${\n step.isComplete ? \"complete\" : \"executing\"\n }`}\n >\n <div className=\"task-step-indicator\">\n {step.isComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {step.text || \"\"}\n {step.target && (\n <span className=\"task-step-target\"> {step.target}</span>\n )}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Renders a task block with user message as header and agent steps below\n */\nexport function TaskBlock({ userMessage, steps, isStreaming }: TaskBlockProps) {\n // Extract user message content\n let userContent = \"\";\n if (userMessage) {\n if (\"role\" in userMessage) {\n userContent = userMessage.content;\n } else {\n const chatMsg = userMessage as ChatMessage;\n if (chatMsg.type === \"user\") {\n userContent = chatMsg.message;\n }\n }\n }\n\n // Group steps into phases\n const phases = groupStepsIntoPhases(steps);\n\n return (\n <div className=\"task-block\">\n {userContent && (\n <div className=\"task-block-header\">\n <div className=\"task-block-title\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {userContent}\n </ReactMarkdown>\n </div>\n <button className=\"task-block-undo\" title=\"Undo this task\">\n ↶\n </button>\n </div>\n )}\n <div className=\"task-block-steps\">\n {phases.map((phase, index) => (\n <PhaseItem key={index} phase={phase} isStreaming={isStreaming} />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useMemo } from \"react\";\nimport { MessageItem, TaskGroup, TaskBlock, TaskStep } from \"./MessageItem\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\n\nexport interface Todo {\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n activeForm: string;\n}\n\nexport interface MessageListProps {\n messages: (CommentMessage | ChatMessage)[];\n isStreaming?: boolean;\n startedToolIds?: Set<string>;\n completedToolIds?: Set<string>;\n todos?: Todo[];\n}\n\ninterface GroupMessagesOptions {\n isStreaming?: boolean;\n}\n\ninterface MessageGroup {\n type: \"task-block\" | \"error\" | \"assistant\";\n userMessage?: CommentMessage | ChatMessage;\n messages: (CommentMessage | ChatMessage)[];\n}\n\n/**\n * Check if a message is a final completion message\n */\nfunction isCompletionMessage(content: string): boolean {\n if (!content) return false;\n const trimmed = content.trim().toLowerCase();\n return trimmed.startsWith('done.') ||\n trimmed.startsWith('complete.') ||\n trimmed.startsWith('finished.');\n}\n\n/**\n * Check if an assistant message looks like a status update vs a real response\n * Status updates are typically short, action-oriented phrases\n */\nfunction isStatusMessage(content: string): boolean {\n if (!content) return false;\n const trimmed = content.trim();\n\n // Completion messages go in task group\n if (isCompletionMessage(trimmed)) {\n return true;\n }\n\n // Short messages starting with action words are status updates\n // e.g., \"Searching for files\", \"Reading StatsCard.tsx\", \"Updating page content\"\n if (trimmed.length < 100) {\n const actionStarters = [\n 'searching', 'reading', 'writing', 'editing', 'looking', 'finding',\n 'checking', 'analyzing', 'processing', 'updating', 'creating',\n 'modifying', 'changing', 'applying', 'converting', 'transforming'\n ];\n const lowerContent = trimmed.toLowerCase();\n if (actionStarters.some(starter => lowerContent.startsWith(starter))) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Groups messages into task blocks (user message + agent steps)\n */\nfunction groupMessages(messages: (CommentMessage | ChatMessage)[], options?: GroupMessagesOptions): MessageGroup[] {\n const groups: MessageGroup[] = [];\n let currentTaskBlock: {\n userMessage?: CommentMessage | ChatMessage;\n steps: (CommentMessage | ChatMessage)[];\n } = { steps: [] };\n const { isStreaming = false } = options || {};\n\n const flushTaskBlock = () => {\n if (currentTaskBlock.userMessage || currentTaskBlock.steps.length > 0) {\n groups.push({\n type: \"task-block\",\n userMessage: currentTaskBlock.userMessage,\n messages: currentTaskBlock.steps\n });\n currentTaskBlock = { steps: [] };\n }\n };\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const isLastMessage = i === messages.length - 1;\n\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"user\") {\n flushTaskBlock();\n currentTaskBlock.userMessage = msg;\n } else if (msg.role === \"assistant\") {\n if (isStatusMessage(msg.content)) {\n currentTaskBlock.steps.push(msg);\n } else {\n // Real assistant response - standalone\n flushTaskBlock();\n groups.push({ type: \"assistant\", messages: [msg] });\n }\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as ChatMessage;\n\n if (chatMsg.type === \"user\") {\n flushTaskBlock();\n currentTaskBlock.userMessage = msg;\n } else if (chatMsg.type === \"error\") {\n flushTaskBlock();\n groups.push({ type: \"error\", messages: [msg] });\n } else if (chatMsg.type === \"assistant\") {\n const content = typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n // Check if message has tool_use blocks\n const contentBlocks = chatMsg.message?.content || [];\n const hasToolUse = contentBlocks.some((block: any) => block.type === \"tool_use\");\n\n // If streaming and this is the last message, always put in task block\n // (it might get tool_use blocks added in subsequent chunks)\n const shouldBeInTaskBlock = isStatusMessage(content) || hasToolUse || (isStreaming && isLastMessage);\n\n if (shouldBeInTaskBlock) {\n // Status messages or messages with tool calls go in task block\n currentTaskBlock.steps.push(msg);\n } else if (content.trim()) {\n // Real assistant response - standalone\n flushTaskBlock();\n groups.push({ type: \"assistant\", messages: [msg] });\n }\n } else if (\n chatMsg.type === \"tool_use\" ||\n chatMsg.type === \"tool_result\" ||\n chatMsg.type === \"result\" ||\n chatMsg.type === \"done\"\n ) {\n // These all go into the current task block\n currentTaskBlock.steps.push(msg);\n }\n // Ignore connected, system messages\n }\n\n flushTaskBlock();\n return groups;\n}\n\n/**\n * Converts task group messages into task steps for display\n */\nfunction convertToTaskSteps(\n messages: (CommentMessage | ChatMessage)[],\n isStreaming: boolean,\n startedToolIds: Set<string> = new Set(),\n completedToolIds: Set<string> = new Set()\n): TaskStep[] {\n const steps: TaskStep[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"assistant\" && msg.content) {\n const isCompletion = isCompletionMessage(msg.content);\n\n steps.push({\n type: isCompletion ? \"completion\" : \"status\",\n text: msg.content,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as ChatMessage;\n\n if (chatMsg.type === \"assistant\") {\n // Extract content blocks from assistant message\n const contentBlocks = chatMsg.message?.content || [];\n\n for (const block of contentBlocks) {\n // Handle text blocks\n if (block.type === \"text\") {\n const text = block.text || \"\";\n\n if (text && text.trim()) {\n const isCompletion = isCompletionMessage(text);\n\n steps.push({\n type: isCompletion ? \"completion\" : \"status\",\n text: text,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n }\n\n // Handle tool_use blocks embedded in assistant messages\n if (block.type === \"tool_use\") {\n const toolDescriptions: Record<string, string> = {\n Read: \"Reading\",\n Write: \"Writing\",\n Edit: \"Editing\",\n Glob: \"Searching\",\n Grep: \"Searching\",\n Bash: \"Running\",\n Task: \"Running task\",\n };\n const action = toolDescriptions[block.name] || block.name;\n\n // Extract file path or other relevant info from tool input\n let target = \"\";\n const input = block.input || {};\n\n if (block.name === \"Task\") {\n // For Task tool, show the description or first line of prompt\n target = input.description || (input.prompt ? input.prompt.split('\\n')[0].substring(0, 50) : \"\");\n } else if (input.file_path) {\n // Extract just the filename from the path\n const fileName = input.file_path.split('/').pop() || input.file_path;\n target = fileName;\n } else if (input.pattern) {\n target = `\"${input.pattern}\"`;\n } else if (input.command) {\n target = input.command.split(' ')[0]; // Just first word of command\n }\n\n steps.push({\n type: \"tool\",\n text: action,\n tool: block.name,\n target,\n toolId: block.id,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n }\n } else if (chatMsg.type === \"tool_use\") {\n // Map tool names to friendly descriptions\n const toolDescriptions: Record<string, string> = {\n read_file: \"Reading file\",\n write_file: \"Writing file\",\n edit_file: \"Editing file\",\n search_files: \"Searching files\",\n list_files: \"Listing files\",\n run_command: \"Running command\",\n };\n const description = toolDescriptions[chatMsg.tool] || `Running ${chatMsg.tool}`;\n\n steps.push({\n type: \"tool\",\n text: description,\n tool: chatMsg.tool,\n isComplete: false, // Will be set later\n isLast: false,\n });\n } else if (chatMsg.type === \"result\") {\n // Result messages indicate completion\n if (chatMsg.result && chatMsg.result.trim()) {\n steps.push({\n type: \"status\",\n text: chatMsg.result,\n isComplete: true,\n isLast: false,\n });\n }\n }\n // Skip done, tool_result messages\n }\n\n // Now determine which step is actually last and mark completion status\n if (steps.length > 0) {\n const lastStepIndex = steps.length - 1;\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n const isLastStep = i === lastStepIndex;\n\n step.isLast = isLastStep;\n\n // Determine completion based on type\n if (step.type === \"tool\") {\n const toolId = step.toolId;\n\n if (toolId) {\n const hasCompleted = completedToolIds.has(toolId);\n const hasStarted = startedToolIds.has(toolId);\n\n // Debug: Log mismatches\n if (!hasCompleted && !isStreaming) {\n console.warn(`[MessageList] Tool ${toolId} (${step.text}) not in completedToolIds after streaming ended`, {\n completedToolIds: Array.from(completedToolIds),\n startedToolIds: Array.from(startedToolIds),\n });\n }\n\n // If not streaming, all tools are complete\n step.isComplete = !isStreaming || hasCompleted;\n step.isExecuting = isStreaming && hasStarted && !hasCompleted;\n step.isQueued = isStreaming && !hasStarted && !hasCompleted;\n } else {\n // No tool ID - assume complete\n step.isComplete = true;\n step.isExecuting = false;\n step.isQueued = false;\n }\n } else if (step.type === \"status\") {\n // Status steps complete when not streaming or not the last step\n step.isComplete = !isStreaming || !isLastStep;\n } else if (step.type === \"completion\") {\n // Completion messages are always complete\n step.isComplete = true;\n }\n }\n }\n\n return steps;\n}\n\nexport function MessageList({\n messages,\n isStreaming,\n startedToolIds = new Set(),\n completedToolIds = new Set(),\n todos = []\n}: MessageListProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n // Group messages\n const groups = useMemo(() => groupMessages(messages, { isStreaming }), [messages, isStreaming]);\n\n /**\n * Auto-scroll to bottom when new messages arrive\n */\n useEffect(() => {\n if (messagesEndRef.current) {\n messagesEndRef.current.scrollIntoView({ behavior: \"smooth\" });\n }\n }, [messages]);\n\n if (messages.length === 0) {\n return <div className=\"message-list-empty\"></div>;\n }\n\n return (\n <div className=\"message-list\">\n {/* Display todos if present */}\n {todos.length > 0 && (\n <div className=\"todo-list\">\n <div className=\"todo-list-header\">Tasks</div>\n {todos.map((todo, idx) => (\n <div key={idx} className={`todo-item todo-${todo.status}`}>\n <div className=\"todo-indicator\">\n {todo.status === \"completed\" ? (\n <span className=\"todo-checkmark\">✓</span>\n ) : todo.status === \"in_progress\" ? (\n <span className=\"todo-spinner\"></span>\n ) : (\n <span className=\"todo-pending\">○</span>\n )}\n </div>\n <span className=\"todo-text\">\n {todo.status === \"in_progress\" ? todo.activeForm : todo.content}\n </span>\n </div>\n ))}\n </div>\n )}\n {groups.map((group, groupIndex) => {\n const isLastGroup = groupIndex === groups.length - 1;\n\n if (group.type === \"assistant\" || group.type === \"error\") {\n return (\n <MessageItem key={groupIndex} message={group.messages[0]} />\n );\n }\n\n if (group.type === \"task-block\") {\n const steps = convertToTaskSteps(\n group.messages,\n !!(isStreaming && isLastGroup),\n startedToolIds,\n completedToolIds\n );\n\n // Show thinking only if we're streaming, last group, and all steps are complete (or no steps yet)\n const allStepsComplete = steps.length === 0 || steps.every(step => step.isComplete);\n const shouldShowThinking = isStreaming && isLastGroup && allStepsComplete;\n\n const displaySteps = shouldShowThinking\n ? [\n ...steps,\n {\n type: \"status\" as const,\n isComplete: false,\n isLast: true,\n isThinkingPlaceholder: true,\n }\n ]\n : steps;\n\n return (\n <TaskBlock\n key={groupIndex}\n userMessage={group.userMessage}\n steps={displaySteps}\n isStreaming={!!(isStreaming && isLastGroup)}\n />\n );\n }\n\n return null;\n })}\n <div ref={messagesEndRef} />\n </div>\n );\n}\n","/**\n * Configuration for the AI Editor Service\n *\n * The service runs as a separate process (typically in Docker) and handles\n * all file operations, AI processing, and code analysis.\n */\n\n/**\n * Get the AI Editor service URL\n *\n * Priority order:\n * 1. NEXT_PUBLIC_AI_EDITOR_SERVICE_URL environment variable (for custom setups)\n * 2. Auto-detect based on window.location.hostname\n * - localhost -> http://localhost:3456\n * - deployed -> https://${hostname}:3456\n */\nexport function getServiceUrl(): string {\n // Check for environment variable override (can be set in .env.local)\n // if (typeof window !== \"undefined\" && (window as any).env?.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL) {\n // return (window as any).env.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL;\n // }\n\n // if (typeof process !== \"undefined\" && process.env?.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL) {\n // return process.env.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL;\n // }\n\n // Auto-detect based on hostname\n if (typeof window !== \"undefined\") {\n const hostname = window.location.hostname;\n\n // Local development\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return \"http://localhost:3456\";\n }\n\n // Deployed (use same hostname with HTTPS on port 3456)\n return `https://${hostname}:3456`;\n }\n\n // SSR fallback (shouldn't be reached in practice)\n return \"http://localhost:3456\";\n}\n\n/**\n * Build full endpoint URL for a given path\n */\nexport function buildServiceUrl(path: string): string {\n const baseUrl = getServiceUrl();\n // Remove leading slash if present\n const normalizedPath = path.startsWith(\"/\") ? path.slice(1) : path;\n return `${baseUrl}/${normalizedPath}`;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport type { ComponentContext } from \"../../shared/types\";\nimport { buildServiceUrl } from \"../service-config\";\n\n/**\n * Message types from the Agent SDK stream\n */\nexport type ChatMessage =\n | { type: \"connected\"; sessionId: string }\n | { type: \"system\"; subtype: string; [key: string]: any }\n | { type: \"user\"; message: string }\n | { type: \"assistant\"; message: any; [key: string]: any }\n | { type: \"tool_use\"; tool: string; input: any; [key: string]: any }\n | { type: \"tool_result\"; tool: string; output: any; [key: string]: any }\n | { type: \"tool_start\"; toolId: string; toolName: string }\n | { type: \"tool_complete\"; toolId: string; toolName: string }\n | { type: \"result\"; subtype: string; result: string; [key: string]: any }\n | { type: \"error\"; error: string }\n | { type: \"done\" };\n\nexport interface ChatStreamState {\n messages: ChatMessage[];\n isConnected: boolean;\n isStreaming: boolean;\n error: string | null;\n sessionId: string | null;\n}\n\nexport interface UseChatStreamOptions {\n threadId: string;\n sessionId?: string;\n onMessage?: (message: ChatMessage) => void;\n onError?: (error: string) => void;\n onDone?: () => void;\n}\n\n/**\n * React hook for managing SSE chat stream connection\n */\nexport function useChatStream(options: UseChatStreamOptions) {\n const { threadId, sessionId: initialSessionId, onMessage, onError, onDone } = options;\n\n const [state, setState] = useState<ChatStreamState>({\n messages: [],\n isConnected: false,\n isStreaming: false,\n error: null,\n sessionId: initialSessionId || null,\n });\n\n const wsRef = useRef<WebSocket | null>(null);\n const [startedToolIds, setStartedToolIds] = useState<Set<string>>(new Set());\n const [completedToolIds, setCompletedToolIds] = useState<Set<string>>(new Set());\n const [todos, setTodos] = useState<Array<{\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n activeForm: string;\n }>>([]);\n\n /**\n * Parse SSE data line\n */\n const parseEventData = useCallback((data: string): ChatMessage | null => {\n try {\n return JSON.parse(data);\n } catch (error) {\n console.error(\"Failed to parse SSE data:\", data, error);\n return null;\n }\n }, []);\n\n /**\n * Send a message and start streaming response via WebSocket\n */\n const sendMessage = useCallback(\n async (message: string, componentContext?: ComponentContext) => {\n // Close existing connection\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n\n // Add user message to chat\n const userMessage: ChatMessage = { type: \"user\", message };\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, userMessage],\n isStreaming: true,\n error: null,\n }));\n\n try {\n // Create WebSocket connection\n const wsUrl = buildServiceUrl(\"ws/chat\").replace(/^http/, \"ws\");\n const ws = new WebSocket(wsUrl);\n wsRef.current = ws;\n\n // Track accumulated assistant content\n let currentAssistantMessage: ChatMessage | null = null;\n\n ws.onopen = () => {\n console.log(\"[WebSocket] Connected\");\n\n // Helper to send client logs to server\n const logToServer = (level: string, ...args: any[]) => {\n const timestamp = new Date().toISOString();\n const logMessage = args.map(arg =>\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\n ).join(' ');\n ws.send(JSON.stringify({\n type: \"client_log\",\n level,\n timestamp,\n message: logMessage\n }));\n (console[level as keyof typeof console] as (...args: any[]) => void)(`[${timestamp}]`, ...args);\n };\n\n // Store reference for use in event handlers\n (ws as any).logToServer = logToServer;\n\n // Send chat message\n ws.send(\n JSON.stringify({\n type: \"chat\",\n threadId,\n sessionId: state.sessionId,\n message,\n componentContext,\n })\n );\n };\n\n ws.onmessage = (event) => {\n const data = parseEventData(event.data);\n if (!data) return;\n\n // Debug logging with timestamp (send to server too)\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[useChatStream] Received event: ${data.type}`);\n }\n\n // Handle assistant messages - accumulate into single message\n if (data.type === \"assistant\") {\n // Check for TodoWrite tool calls\n const content = data.message?.content || [];\n for (const block of content) {\n if (block.type === \"tool_use\" && block.name === \"TodoWrite\") {\n const todosData = block.input?.todos || [];\n setTodos(todosData);\n }\n }\n\n if (currentAssistantMessage) {\n // Update existing assistant message\n setState((prev) => {\n const messages = [...prev.messages];\n const lastIndex = messages.length - 1;\n if (messages[lastIndex]?.type === \"assistant\") {\n // Merge content\n const existingContent = messages[lastIndex].message?.content || [];\n const newContent = data.message?.content || [];\n messages[lastIndex] = {\n ...messages[lastIndex],\n message: {\n ...messages[lastIndex].message,\n content: [...existingContent, ...newContent],\n },\n };\n }\n return { ...prev, messages };\n });\n } else {\n // First assistant message chunk\n currentAssistantMessage = data;\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n }\n onMessage?.(data);\n return;\n }\n\n // Reset assistant accumulation for any non-assistant event\n currentAssistantMessage = null;\n\n // Track tool start via tool_start events from hooks\n if (data.type === \"tool_start\") {\n const toolId = data.toolId;\n if (toolId) {\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[CLIENT] Tool STARTED: ${data.toolName} (${toolId})`);\n }\n // Create new Set to trigger React re-render\n setStartedToolIds((prev) => new Set(prev).add(toolId));\n }\n return; // Don't show in UI\n }\n\n // Track tool completion via tool_complete events from hooks\n if (data.type === \"tool_complete\") {\n const toolId = data.toolId;\n if (toolId) {\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[CLIENT] Tool COMPLETED: ${data.toolName} (${toolId})`);\n }\n // Create new Set to trigger React re-render with immediate sync\n flushSync(() => {\n setCompletedToolIds((prev) => new Set(prev).add(toolId));\n });\n }\n return; // Don't show in UI\n }\n\n // Filter out user echoes\n if (data.type === \"user\") {\n return;\n }\n\n // Add tool_use messages to show AI actions\n if (data.type === \"tool_use\") {\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n onMessage?.(data);\n return;\n }\n\n // Handle result messages - check for duplication\n if (data.type === \"result\") {\n setState((prev) => {\n const lastMsg = prev.messages[prev.messages.length - 1];\n if (lastMsg?.type === \"assistant\") {\n const lastText = lastMsg.message?.content?.[0]?.text || \"\";\n const resultText = data.result || \"\";\n if (lastText.includes(resultText) || resultText.includes(lastText)) {\n return prev;\n }\n }\n return {\n ...prev,\n messages: [...prev.messages, data],\n };\n });\n onMessage?.(data);\n return;\n }\n\n // Handle connected event\n if (data.type === \"connected\") {\n setState((prev) => ({\n ...prev,\n sessionId: data.sessionId,\n isConnected: true,\n }));\n return;\n }\n\n // Handle done event\n if (data.type === \"done\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n messages: [...prev.messages, data],\n }));\n onDone?.();\n return;\n }\n\n // Handle error event\n if (data.type === \"error\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: data.error,\n messages: [...prev.messages, data],\n }));\n onError?.(data.error);\n return;\n }\n\n // All other events - add to messages\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n onMessage?.(data);\n };\n\n ws.onerror = (error) => {\n console.error(\"[WebSocket] Error:\", error);\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: \"WebSocket connection error\",\n }));\n onError?.(\"WebSocket connection error\");\n };\n\n ws.onclose = () => {\n console.log(\"[WebSocket] Disconnected\");\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n }));\n };\n } catch (error: any) {\n const errorMessage = error.message || \"Failed to send message\";\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: errorMessage,\n }));\n onError?.(errorMessage);\n }\n },\n [threadId, state.sessionId, parseEventData, onMessage, onError, onDone]\n );\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n if (wsRef.current) {\n wsRef.current.close();\n }\n };\n }, []);\n\n return {\n ...state,\n sendMessage,\n startedToolIds,\n completedToolIds,\n todos,\n };\n}\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\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};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\",\n key: \"hh9hay\"\n }\n ],\n [\"path\", { d: \"m3.3 7 8.7 5 8.7-5\", key: \"g66t2b\" }],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }]\n];\nconst Box = createLucideIcon(\"box\", __iconNode);\n\nexport { __iconNode, Box as default };\n//# sourceMappingURL=box.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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 key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 12.5 8 15l2 2.5\", key: \"1tg20x\" }],\n [\"path\", { d: \"m14 12.5 2 2.5-2 2.5\", key: \"yinavb\" }]\n];\nconst FileCode = createLucideIcon(\"file-code\", __iconNode);\n\nexport { __iconNode, FileCode as default };\n//# sourceMappingURL=file-code.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n key: \"1a8usu\"\n }\n ],\n [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","\"use client\";\n\nimport React, { useState, useCallback, useRef, useEffect, useMemo } from \"react\";\nimport { MessageList } from \"./MessageList\";\nimport { useChatStream } from \"../hooks/useChatStream\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { ComponentContext } from \"../../shared/types\";\nimport { Box, Type, FileCode, X } from \"lucide-react\";\nimport \"./ChatPanel.css\";\n\nexport type ToolType = \"component\" | \"area\" | \"text\" | null;\n\nexport interface AttachedContext {\n type: \"component\" | \"area\" | \"text\";\n data: any;\n displayText: string;\n}\n\nexport interface ChatPanelProps {\n isExpanded: boolean;\n onToggle: () => void;\n activeTool: ToolType;\n onToolChange: (tool: ToolType) => void;\n attachedContext: AttachedContext | null;\n onClearContext: () => void;\n theme?: \"light\" | \"dark\";\n}\n\nexport function ChatPanel({\n isExpanded,\n onToggle,\n activeTool,\n onToolChange,\n attachedContext,\n onClearContext,\n theme = \"dark\",\n}: ChatPanelProps) {\n const [message, setMessage] = useState(\"\");\n const [threadId] = useState(() => `thread-${Date.now()}`);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [contextRanges, setContextRanges] = useState<Array<{start: number, end: number, context: AttachedContext}>>([]);\n const [isMessagesCollapsed, setMessagesCollapsed] = useState(false);\n\n const { messages, isStreaming, sendMessage, startedToolIds, completedToolIds, todos } = useChatStream({\n threadId,\n });\n\n // Add context as a pill (don't insert into textarea)\n useEffect(() => {\n if (attachedContext) {\n // Just add to context ranges without modifying the message text\n setContextRanges(prev => [...prev, {\n start: 0,\n end: 0,\n context: attachedContext\n }]);\n\n // Focus textarea\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n\n // Clear the attached context\n onClearContext();\n }\n }, [attachedContext, onClearContext]);\n\n // Auto-resize textarea\n const handleInput = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const target = e.target;\n setMessage(target.value);\n\n // Reset height to auto to get correct scrollHeight\n target.style.height = \"auto\";\n // Set height to scrollHeight (up to max 200px)\n target.style.height = Math.min(target.scrollHeight, 200) + \"px\";\n }, []);\n\n // Handle send message\n const handleSend = useCallback(async () => {\n if (!message.trim() || isStreaming) return;\n\n const messageText = message;\n\n // Extract component context from the message if it contains @references\n // For now, use the first context range\n const componentContext: ComponentContext | undefined =\n contextRanges.length > 0 && contextRanges[0].context.type === \"component\"\n ? contextRanges[0].context.data\n : undefined;\n\n // Clear input\n setMessage(\"\");\n setContextRanges([]);\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n\n await sendMessage(messageText, componentContext);\n }, [message, isStreaming, contextRanges, sendMessage]);\n\n // Handle keyboard shortcuts\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if ((e.ctrlKey || e.metaKey) && e.key === \"Enter\") {\n e.preventDefault();\n handleSend();\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onToggle();\n }\n }, [handleSend, onToggle]);\n\n // Pass raw messages to MessageList - it handles grouping and filtering\n const commentMessages = messages;\n\n // Count visible task blocks (user message + steps grouped together)\n const visibleCount = useMemo(() => {\n let count = 0;\n let hasUserMessage = false;\n\n for (const msg of commentMessages) {\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"user\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n }\n hasUserMessage = true;\n } else if (msg.role === \"assistant\" && !hasUserMessage) {\n // Standalone assistant message\n if (msg.content?.trim()) count++;\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as any;\n if (chatMsg.type === \"user\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n }\n hasUserMessage = true;\n } else if (chatMsg.type === \"error\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n hasUserMessage = false;\n }\n count++; // Error message\n } else if (chatMsg.type === \"assistant\") {\n const content = typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n // Check if standalone assistant message\n const isStatus = content && content.trim().length < 80 &&\n (content.endsWith('.') || content.endsWith('...'));\n\n if (!isStatus && content.trim() && !hasUserMessage) {\n count++; // Standalone assistant message\n }\n }\n }\n\n // Count final task block if exists\n if (hasUserMessage) {\n count++;\n }\n\n return count;\n }, [commentMessages]);\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n <div className={`chat-panel ai-editor-ui ${theme} ${commentMessages.length === 0 ? 'empty' : ''}`}>\n {/* Messages - only show if there are messages */}\n {commentMessages.length > 0 && (\n <div className={`chat-panel-messages-container ${isMessagesCollapsed ? 'collapsed' : 'expanded'}`}>\n <div className=\"chat-panel-messages-header\">\n <div\n className=\"chat-panel-messages-header-left\"\n onClick={() => setMessagesCollapsed(!isMessagesCollapsed)}\n >\n <span className=\"chat-panel-messages-title\">\n {visibleCount} task{visibleCount !== 1 ? 's' : ''}\n </span>\n <span className=\"chat-panel-messages-toggle\">▼</span>\n </div>\n </div>\n <div className=\"chat-panel-messages\">\n <MessageList\n messages={commentMessages}\n isStreaming={isStreaming}\n startedToolIds={startedToolIds}\n completedToolIds={completedToolIds}\n todos={todos}\n />\n </div>\n </div>\n )}\n\n {/* Show empty state when no messages */}\n {commentMessages.length === 0 && (\n <div className=\"chat-panel-empty-content\">\n <MessageList\n messages={[]}\n isStreaming={false}\n startedToolIds={new Set()}\n completedToolIds={new Set()}\n todos={[]}\n />\n </div>\n )}\n\n {/* Input area */}\n <div className=\"chat-panel-input\">\n {/* Context pills above input */}\n {contextRanges.length > 0 && (\n <div className=\"context-pills-container\">\n {contextRanges.map((range, idx) => (\n <div key={idx} className=\"context-pill-inline\">\n <span>{range.context.displayText}</span>\n <button\n className=\"context-pill-remove\"\n onClick={() => {\n // Remove this context range\n setContextRanges(prev => prev.filter((_, i) => i !== idx));\n }}\n title=\"Remove context\"\n >\n ×\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"input-row\">\n <textarea\n ref={textareaRef}\n className=\"message-input\"\n placeholder=\"Ask Claude to edit your code...\"\n value={message}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n disabled={isStreaming}\n rows={1}\n />\n <button\n className=\"send-button\"\n onClick={handleSend}\n disabled={!message.trim() || isStreaming}\n >\n ↑\n </button>\n </div>\n\n {/* Tools below input */}\n <div className=\"chat-panel-toolbar\">\n <div className=\"chat-panel-tools\">\n <button\n className={`tool-button ${activeTool === \"component\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"component\" ? null : \"component\")}\n title=\"Select Component\"\n >\n <FileCode size={16} />\n </button>\n <button\n className={`tool-button ${activeTool === \"area\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"area\" ? null : \"area\")}\n title=\"Select Area\"\n >\n <Box size={16} />\n </button>\n <button\n className={`tool-button ${activeTool === \"text\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"text\" ? null : \"text\")}\n title=\"Select Text\"\n >\n <Type size={16} />\n </button>\n </div>\n <button\n className=\"close-button\"\n onClick={onToggle}\n title=\"Close (Esc)\"\n >\n <X size={16} />\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { Pencil } from \"lucide-react\";\nimport \"./ControlPill.css\";\n\nexport interface ControlPillProps {\n isExpanded: boolean;\n onToggle: () => void;\n activeTool?: \"component\" | \"area\" | \"text\" | null;\n}\n\nexport function ControlPill({\n isExpanded,\n onToggle,\n activeTool,\n}: ControlPillProps) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Ignore if typing in input/textarea\n if (\n e.target instanceof HTMLInputElement ||\n e.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n // Toggle with Space or /\n if (e.key === \" \" || e.key === \"/\") {\n e.preventDefault();\n onToggle();\n }\n\n // Close with Escape\n if (e.key === \"Escape\" && isExpanded) {\n e.preventDefault();\n onToggle();\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [onToggle, isExpanded]);\n\n // Hide pill when expanded - the container becomes the chat window\n if (isExpanded) {\n return null;\n }\n\n return (\n <div className=\"control-pill ai-editor-ui\" onClick={onToggle}>\n <div className=\"control-pill-inner\">\n <Pencil size={16} className=\"pill-icon\" />\n <span className=\"pill-label\">Edit</span>\n {activeTool && (\n <span className=\"active-tool-indicator\" title={`${activeTool} tool active`}>\n {activeTool === \"component\" && \"🎯\"}\n {activeTool === \"area\" && \"⬛\"}\n {activeTool === \"text\" && \"📝\"}\n </span>\n )}\n </div>\n <div className=\"control-pill-hint\">\n Press <kbd>Space</kbd> or <kbd>/</kbd> to toggle\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useRef,\n ReactNode,\n} from \"react\";\nimport type { SourceLocation } from \"../shared/types\";\nimport { getSourceFromElement } from \"./fiber-utils\";\nimport { TaskHistoryPanel } from \"./components/TaskHistoryPanel\";\nimport { ChatPanel } from \"./components/ChatPanel\";\nimport { ControlPill } from \"./components/ControlPill\";\nimport type { AttachedContext, ToolType } from \"./components/ChatPanel\";\nimport { buildServiceUrl } from \"./service-config\";\nimport \"./components/EditorContainer.css\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface ResolvedSourceInfo {\n filePath: string;\n lineNumber: number;\n columnNumber: number;\n}\n\nconst sourceResolutionCache = new Map<string, ResolvedSourceInfo>();\nconst inflightSourceResolutions = new Map<\n string,\n Promise<ResolvedSourceInfo | null>\n>();\n\nfunction inferComponentNameFromPath(filePath: string): string {\n const fileName = filePath.split(\"/\").pop() || \"\";\n const nameWithoutExt = fileName.replace(/\\.(tsx?|jsx?)$/, \"\");\n return nameWithoutExt.charAt(0).toUpperCase() + nameWithoutExt.slice(1);\n}\n\nasync function resolveSourceLocation(\n source: SourceLocation,\n): Promise<SourceLocation | null> {\n if (typeof window === \"undefined\" || process.env.NODE_ENV !== \"development\") {\n return null;\n }\n\n if (!source.debugStack) {\n console.warn(\"No debugStack available for resolution:\", source);\n return null;\n }\n\n const cacheKey = source.debugStack;\n const cached = sourceResolutionCache.get(cacheKey);\n if (cached) {\n const resolved = { ...source, ...cached };\n if (resolved.componentName === \"Unknown\" && resolved.filePath) {\n resolved.componentName = inferComponentNameFromPath(resolved.filePath);\n }\n return resolved;\n }\n\n let inflight = inflightSourceResolutions.get(cacheKey);\n if (!inflight) {\n inflight = fetch(buildServiceUrl(\"api/resolve\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ debugStack: cacheKey }),\n })\n .then(async (res) => {\n if (!res.ok) {\n console.error(`Resolve API error ${res.status}`);\n return null;\n }\n const data = await res.json();\n if (data?.success && data.filePath && data.lineNumber) {\n const resolved: ResolvedSourceInfo = {\n filePath: data.filePath,\n lineNumber: data.lineNumber,\n columnNumber:\n typeof data.columnNumber === \"number\"\n ? data.columnNumber\n : source.columnNumber,\n };\n sourceResolutionCache.set(cacheKey, resolved);\n return resolved;\n }\n return null;\n })\n .catch((err) => {\n console.error(\"Error calling resolve API:\", err);\n return null;\n })\n .finally(() => {\n inflightSourceResolutions.delete(cacheKey);\n });\n\n inflightSourceResolutions.set(cacheKey, inflight);\n }\n\n const resolvedInfo = await inflight;\n if (!resolvedInfo) return null;\n\n const resolved = {\n ...source,\n filePath: resolvedInfo.filePath,\n lineNumber: resolvedInfo.lineNumber,\n columnNumber: resolvedInfo.columnNumber,\n };\n\n if (resolved.componentName === \"Unknown\" && resolved.filePath) {\n resolved.componentName = inferComponentNameFromPath(resolved.filePath);\n }\n\n return resolved;\n}\n\ninterface EditorContextType {\n isEnabled: boolean;\n setEnabled: (enabled: boolean) => void;\n}\n\n// =============================================================================\n// CONTEXT\n// =============================================================================\n\nconst EditorContext = createContext<EditorContextType | null>(null);\n\nexport function useAIEditor() {\n const ctx = useContext(EditorContext);\n if (!ctx) throw new Error(\"useAIEditor must be used within AIEditorProvider\");\n return ctx;\n}\n\n// =============================================================================\n// PROVIDER\n// =============================================================================\n\nexport function AIEditorProvider({\n children,\n theme = \"dark\",\n enabled,\n}: {\n children: ReactNode;\n theme?: \"light\" | \"dark\";\n /**\n * Override the default visibility check. If not provided, the editor\n * visibility is determined by server-side env vars:\n * - NEXT_PUBLIC_AI_EDITOR_ENABLED=true (Next.js)\n * - VITE_AI_EDITOR_ENABLED=true (Vite)\n * - REACT_APP_AI_EDITOR_ENABLED=true (Create React App)\n */\n enabled?: boolean;\n}) {\n // Fetch editor enabled status from server (env vars are checked server-side)\n const [serverEnabled, setServerEnabled] = useState<boolean | null>(null);\n\n useEffect(() => {\n // Skip fetch if enabled prop is explicitly set\n if (enabled !== undefined) return;\n\n fetch(buildServiceUrl(\"api/config\"))\n .then((res) => res.json())\n .then((data) => {\n setServerEnabled(data.enabled === true);\n })\n .catch(() => {\n // If config fetch fails, default to disabled\n setServerEnabled(false);\n });\n }, [enabled]);\n\n // Determine if editor should be shown:\n // 1. If `enabled` prop is explicitly set, use that\n // 2. Otherwise, use server-side config (fetched from buildServiceUrl(\"api/config\"))\n const isEditorEnabled = enabled ?? serverEnabled;\n\n const [isEnabled, setEnabled] = useState(false);\n const [isHistoryOpen, setHistoryOpen] = useState(false);\n\n // Chat panel state\n const [isChatExpanded, setChatExpanded] = useState(false);\n const [activeTool, setActiveTool] = useState<ToolType>(null);\n const [attachedContext, setAttachedContext] =\n useState<AttachedContext | null>(null);\n\n // Chat panel toggle\n const handleChatToggle = useCallback(() => {\n setChatExpanded((prev) => !prev);\n }, []);\n\n // Tool change handler\n const handleToolChange = useCallback((tool: ToolType) => {\n setActiveTool(tool);\n // Clear any existing context when changing tools\n if (tool === null) {\n setAttachedContext(null);\n }\n }, []);\n\n // Clear attached context\n const handleClearContext = useCallback(() => {\n setAttachedContext(null);\n setActiveTool(null);\n }, []);\n\n // Keyboard shortcuts\n useEffect(() => {\n const handleKey = (e: KeyboardEvent) => {\n // Cmd/Ctrl+Shift+E - Toggle editor\n if (\n (e.ctrlKey || e.metaKey) &&\n e.shiftKey &&\n e.key.toLowerCase() === \"e\"\n ) {\n e.preventDefault();\n setEnabled((p) => !p);\n }\n\n // Cmd/Ctrl+Shift+H - Toggle history panel\n if (\n (e.ctrlKey || e.metaKey) &&\n e.shiftKey &&\n e.key.toLowerCase() === \"h\"\n ) {\n e.preventDefault();\n setHistoryOpen((p) => !p);\n }\n\n // Escape - Close history panel\n if (e.key === \"Escape\" && isHistoryOpen) {\n e.preventDefault();\n setHistoryOpen(false);\n }\n };\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }, [isHistoryOpen]);\n\n if (!isEditorEnabled) {\n return <>{children}</>;\n }\n\n return (\n <EditorContext.Provider\n value={{\n isEnabled,\n setEnabled,\n }}\n >\n {children}\n\n {/* Component selection overlay when component tool is active */}\n {activeTool === \"component\" && (\n <EditorOverlay\n theme={theme}\n onComponentSelect={(source, position) => {\n // Attach component context\n const contextData = {\n type: \"component\" as const,\n data: source,\n displayText: `${source.componentName} (${source.filePath}:${source.lineNumber})`,\n };\n setAttachedContext(contextData);\n // Deactivate tool after selection\n setActiveTool(null);\n // Open chat panel if not already open\n if (!isChatExpanded) {\n setChatExpanded(true);\n }\n }}\n />\n )}\n\n {/* Editor Container - unified container for chat and pill */}\n <div\n className={`editor-container ai-editor-ui ${\n isChatExpanded ? \"expanded\" : \"collapsed\"\n } ${theme}`}\n >\n {/* Chat Panel */}\n <ChatPanel\n isExpanded={isChatExpanded}\n onToggle={handleChatToggle}\n activeTool={activeTool}\n onToolChange={handleToolChange}\n attachedContext={attachedContext}\n onClearContext={handleClearContext}\n theme={theme}\n />\n\n {/* Control Pill */}\n <ControlPill\n isExpanded={isChatExpanded}\n onToggle={handleChatToggle}\n activeTool={activeTool}\n />\n </div>\n\n {/* Task History Panel */}\n <TaskHistoryPanel\n isOpen={isHistoryOpen}\n onClose={() => setHistoryOpen(false)}\n tasks={[]}\n />\n </EditorContext.Provider>\n );\n}\n\n// =============================================================================\n// EDITOR OVERLAY - Component Selection\n// =============================================================================\n\ninterface EditorOverlayProps {\n theme: \"light\" | \"dark\";\n onComponentSelect: (\n source: SourceLocation,\n position: { x: number; y: number },\n ) => void;\n}\n\nfunction EditorOverlay({ theme, onComponentSelect }: EditorOverlayProps) {\n const [hoveredSource, setHoveredSource] = useState<SourceLocation | null>(\n null,\n );\n const [hoveredElement, setHoveredElement] = useState<Element | null>(null);\n const [hoveredRect, setHoveredRect] = useState<DOMRect | null>(null);\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 });\n const [isResolvingSource, setIsResolvingSource] = useState(false);\n\n const lastHoverStateRef = useRef<{\n source: SourceLocation;\n element: Element;\n } | null>(null);\n\n useEffect(() => {\n if (hoveredSource && hoveredElement) {\n lastHoverStateRef.current = {\n source: hoveredSource,\n element: hoveredElement,\n };\n }\n }, [hoveredSource, hoveredElement]);\n\n const isDark = theme === \"dark\";\n const c = {\n text: isDark ? \"#e4e4e7\" : \"#18181b\",\n muted: isDark ? \"#71717a\" : \"#a1a1aa\",\n accent: \"#818cf8\",\n bg: isDark ? \"#0d0d14\" : \"#fff\",\n border: isDark ? \"#27273f\" : \"#e4e4e7\",\n success: \"#34d399\",\n };\n\n useEffect(() => {\n let lastEl: Element | null = null;\n let raf: number;\n\n const onMove = (e: MouseEvent) => {\n setMousePos({ x: e.clientX, y: e.clientY });\n\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const el = document.elementFromPoint(e.clientX, e.clientY);\n if (!el || el.closest(\".ai-editor-ui\") || el === lastEl) return;\n lastEl = el;\n\n const source = getSourceFromElement(el);\n if (source) {\n setHoveredElement(el);\n setHoveredRect(el.getBoundingClientRect());\n\n const isCompiledPath =\n source.filePath.includes(\".next/\") ||\n source.filePath.includes(\"/chunks/\") ||\n source.filePath.startsWith(\"file://\") ||\n (source.filePath.endsWith(\".js\") &&\n (source.filePath.includes(\"/server/\") ||\n source.filePath.includes(\"/static/\")));\n\n if (isCompiledPath && source.debugStack) {\n setIsResolvingSource(true);\n resolveSourceLocation(source)\n .then((resolved) => {\n setIsResolvingSource(false);\n setHoveredSource(resolved || source);\n })\n .catch((err) => {\n console.error(\"Error resolving source location:\", err);\n setIsResolvingSource(false);\n setHoveredSource(source);\n });\n } else {\n setIsResolvingSource(false);\n setHoveredSource(source);\n }\n } else {\n setHoveredSource(null);\n setHoveredElement(null);\n setHoveredRect(null);\n setIsResolvingSource(false);\n }\n });\n };\n\n const onClick = async (e: MouseEvent) => {\n if ((e.target as Element).closest(\".ai-editor-ui\")) {\n return;\n }\n\n // Get fresh source from the clicked element\n const el = e.target as Element;\n const source = getSourceFromElement(el);\n\n if (source) {\n e.preventDefault();\n e.stopPropagation();\n\n // If it's a compiled path, resolve it first\n const isCompiledPath =\n source.filePath.includes(\".next/\") ||\n source.filePath.includes(\"/chunks/\") ||\n source.filePath.startsWith(\"file://\") ||\n (source.filePath.endsWith(\".js\") &&\n (source.filePath.includes(\"/server/\") ||\n source.filePath.includes(\"/static/\")));\n\n if (isCompiledPath && source.debugStack) {\n const resolved = await resolveSourceLocation(source);\n onComponentSelect(resolved || source, { x: e.clientX, y: e.clientY });\n } else {\n onComponentSelect(source, { x: e.clientX, y: e.clientY });\n }\n }\n };\n\n document.addEventListener(\"mousemove\", onMove, { passive: true });\n document.addEventListener(\"click\", onClick, true);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"click\", onClick, true);\n cancelAnimationFrame(raf);\n };\n }, [onComponentSelect]);\n\n return (\n <div\n className=\"ai-editor-ui\"\n style={{ fontFamily: \"system-ui, sans-serif\" }}\n >\n {/* Highlight */}\n {hoveredRect && (\n <div\n style={{\n position: \"fixed\",\n left: hoveredRect.left - 2,\n top: hoveredRect.top - 2,\n width: hoveredRect.width + 4,\n height: hoveredRect.height + 4,\n border: `2px solid ${c.accent}`,\n borderRadius: 6,\n background: `${c.accent}15`,\n pointerEvents: \"none\",\n zIndex: 99998,\n }}\n />\n )}\n\n {/* Tooltip */}\n {hoveredSource && !isResolvingSource && (\n <div\n style={{\n position: \"fixed\",\n left: Math.min(mousePos.x + 14, window.innerWidth - 340),\n top: mousePos.y + 14,\n background: c.bg,\n color: c.text,\n border: `1px solid ${c.border}`,\n borderRadius: 10,\n padding: \"12px 16px\",\n fontSize: 12,\n fontFamily: \"ui-monospace, monospace\",\n zIndex: 99999,\n boxShadow: `0 8px 30px rgba(0,0,0,${isDark ? 0.5 : 0.15})`,\n maxWidth: 320,\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n fontWeight: 700,\n color: c.accent,\n marginBottom: 4,\n fontSize: 14,\n }}\n >\n &lt;{hoveredSource.componentName} /&gt;\n </div>\n <div style={{ color: c.muted, fontSize: 11 }}>\n {hoveredSource.filePath}:{hoveredSource.lineNumber}\n </div>\n {hoveredSource.elementContext?.textContent && (\n <div\n style={{\n color: c.muted,\n fontSize: 10,\n marginTop: 4,\n fontStyle: \"italic\",\n }}\n >\n \"{hoveredSource.elementContext.textContent}\"\n </div>\n )}\n </div>\n )}\n\n {/* Badge */}\n <div\n style={{\n position: \"fixed\",\n bottom: 20,\n right: 20,\n background: c.bg,\n color: c.success,\n padding: \"10px 16px\",\n borderRadius: 20,\n fontSize: 13,\n fontWeight: 600,\n zIndex: 99997,\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n border: `1px solid ${c.border}`,\n boxShadow: `0 4px 20px rgba(0,0,0,${isDark ? 0.4 : 0.1})`,\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: c.success,\n }}\n />\n Select Component\n </div>\n </div>\n );\n}\n"],"names":["current","iterations","jsxs","jsx","useState","useEffect","_a","useRef","useMemo","useCallback","_b","flushSync","forwardRef","createElement","__iconNode","resolved","createContext"],"mappings":"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","x_google_ignoreList":[7,8,9,10,11,12,13,14,15]}
1
+ {"version":3,"file":"index.cjs","sources":["../src/shared/path-utils.ts","../src/client/fiber-utils.ts","../src/client/components/TaskHistoryPanel.tsx","../src/client/components/MessageItem.tsx","../src/client/components/MessageList.tsx","../src/client/service-config.ts","../src/client/hooks/useChatStream.ts","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/box.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/check.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/file-code.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/file-text.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/git-branch.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/git-pull-request.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/pencil.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/sparkles.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@0.562.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js","../src/client/hooks/usePRStatus.ts","../src/client/hooks/useCreatePR.ts","../src/client/components/PRBlock.tsx","../src/client/components/ChatPanel.tsx","../src/client/components/ControlPill.tsx","../src/client/AIEditorProvider.tsx","../src/client/components/PRView.tsx"],"sourcesContent":["/**\n * Shared path utilities for cleaning and normalizing file paths\n * Used by both client and server for consistent path handling\n */\n\n/**\n * Clean a file path by removing protocol prefixes and URL encoding\n * Works with Turbopack, Webpack, and React Server Components paths\n */\nexport function cleanPath(filePath: string): string {\n if (!filePath) return \"\";\n\n let cleaned = filePath;\n\n // Remove about://React/Server/ prefix first (wraps file:// URLs)\n cleaned = cleaned.replace(/^about:\\/\\/React\\/Server\\//, \"\");\n\n // Remove file:// protocol\n if (cleaned.startsWith(\"file://\")) {\n cleaned = cleaned.replace(/^file:\\/\\//, \"\");\n }\n\n // Decode URL-encoded paths (e.g., %5B becomes [, %5D becomes ])\n try {\n if (cleaned.includes(\"%\")) {\n cleaned = decodeURIComponent(cleaned);\n }\n } catch (e) {\n // If decoding fails, continue with original\n }\n\n // Remove other protocol prefixes\n cleaned = cleaned\n .replace(/^webpack-internal:\\/\\/\\/\\([^)]+\\)\\/\\.\\//, \"\")\n .replace(/^webpack-internal:\\/\\/\\/\\([^)]+\\)\\//, \"\")\n .replace(/^webpack-internal:\\/\\//, \"\")\n .replace(/^webpack:\\/\\/[^/]*\\//, \"\")\n .replace(/^\\([^)]+\\)\\//, \"\")\n .replace(/^\\.\\//, \"\")\n .replace(/\\?.*$/, \"\");\n\n return cleaned;\n}\n\n/**\n * Normalize a source path by cleaning it and making it relative to project root\n * @param source - The source path to normalize\n * @param projectRoot - The project root directory\n * @returns Normalized relative path\n */\nexport function normalizeSourcePath(source: string, projectRoot: string): string {\n let cleaned = cleanPath(source);\n\n // Normalize path separators to forward slashes\n cleaned = cleaned.replace(/\\\\/g, \"/\");\n\n // Remove project root prefix if present\n if (cleaned.startsWith(projectRoot)) {\n cleaned = cleaned.substring(projectRoot.length + 1);\n }\n\n // Remove leading slashes\n return cleaned.replace(/^\\/+/, \"\");\n}\n\n/**\n * Check if a file path should be skipped (e.g., node_modules, framework internals)\n * @param filePath - The file path to check\n * @param additionalSkipPatterns - Additional patterns to skip (optional)\n * @returns true if the path should be skipped\n */\nexport function shouldSkipPath(\n filePath: string,\n additionalSkipPatterns: string[] = []\n): boolean {\n if (!filePath) return true;\n\n const defaultSkipPatterns = [\"node_modules\", \"next/dist\", \"react-dom\"];\n const allPatterns = [...defaultSkipPatterns, ...additionalSkipPatterns];\n\n return allPatterns.some((pattern) => filePath.includes(pattern));\n}\n","// =============================================================================\n// FILE: fiber-utils.ts\n// React Fiber tree utilities for extracting component source locations\n// =============================================================================\n\nimport type { ElementContext, SourceLocation } from \"../shared/types\";\nimport { cleanPath, shouldSkipPath } from \"../shared/path-utils\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface FiberNode {\n tag: number;\n type: any;\n key: string | null;\n return: FiberNode | null;\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n _debugStack?: any;\n _debugOwner?: any;\n memoizedProps?: any;\n pendingProps?: any;\n}\n\n// =============================================================================\n// FIBER UTILITIES\n// =============================================================================\n\nexport function getFiberFromElement(element: Element): FiberNode | null {\n const key = Object.keys(element).find(\n (k) =>\n k.startsWith(\"__reactFiber$\") || k.startsWith(\"__reactInternalInstance$\"),\n );\n return key ? (element as any)[key] : null;\n}\n\nexport function getComponentName(fiber: FiberNode | null): string {\n if (!fiber) return \"Unknown\";\n const type = fiber.type;\n\n // Try _debugSource first (most reliable for Client Components)\n if (fiber._debugSource?.fileName) {\n const fileName = fiber._debugSource.fileName;\n // Extract component name from file path (e.g., \"components/InfoBox.tsx\" -> \"InfoBox\")\n const match = fileName.match(/\\/([^/]+)\\.(tsx?|jsx?)$/);\n if (match) return match[1];\n }\n\n // Try type properties\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\")\n return type.displayName || type.name || \"Anonymous\";\n if (type?.displayName) return type.displayName;\n if (type?.render?.name) return type.render.name;\n\n // For Server Components, extract from _debugStack (no _debugSource on client)\n if (fiber._debugStack) {\n const stack = String(fiber._debugStack.stack || fiber._debugStack);\n // Look for pattern: \"at ComponentName (\"\n const match = stack.match(/at\\s+([A-Z][a-zA-Z0-9]*)\\s*\\(/);\n if (match && match[1] !== \"Object\") {\n return match[1];\n }\n }\n\n return \"Unknown\";\n}\n\nexport function isUserComponent(fiber: FiberNode): boolean {\n if (fiber.tag === 5 || fiber.tag === 6 || fiber.tag === 3) return false;\n const type = fiber.type;\n if (!type || typeof type === \"string\") return false;\n return true;\n}\n\n// =============================================================================\n// ELEMENT CONTEXT CAPTURE\n// =============================================================================\n\nfunction countNthOfType(element: Element, tagName: string): number {\n let boundary: Element | null = element.parentElement;\n\n // Find component boundary\n while (boundary) {\n const fiber = getFiberFromElement(boundary);\n if (fiber && isUserComponent(fiber)) break;\n boundary = boundary.parentElement;\n }\n\n if (!boundary) boundary = element.parentElement;\n if (!boundary) return 1;\n\n // Get all matching elements INCLUDING the boundary itself\n const sameTagElements: Element[] = [];\n\n // Check if boundary itself matches\n if (boundary.tagName.toLowerCase() === tagName.toLowerCase()) {\n sameTagElements.push(boundary);\n }\n\n // Add all descendants that match\n sameTagElements.push(...Array.from(boundary.querySelectorAll(tagName)));\n\n let count = 1;\n for (const el of sameTagElements) {\n if (el === element) break;\n count++;\n }\n\n return count;\n}\n\nfunction extractProps(\n fiber: FiberNode | null,\n): Record<string, any> | undefined {\n if (!fiber) return undefined;\n\n const fiberProps = fiber.memoizedProps || fiber.pendingProps;\n if (!fiberProps || typeof fiberProps !== \"object\") return undefined;\n\n const props: Record<string, any> = {};\n const identifyingKeys = [\n \"id\",\n \"name\",\n \"type\",\n \"href\",\n \"src\",\n \"alt\",\n \"role\",\n \"aria-label\",\n \"data-testid\",\n ];\n\n for (const key of identifyingKeys) {\n if (key in fiberProps && typeof fiberProps[key] === \"string\") {\n props[key] = fiberProps[key];\n }\n }\n\n if (fiberProps.style && typeof fiberProps.style === \"object\") {\n props._styleKeys = Object.keys(fiberProps.style).slice(0, 5);\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\nexport function captureElementContext(\n element: Element,\n fiber: FiberNode | null,\n): ElementContext {\n const tagName = element.tagName.toLowerCase();\n\n // Text content (direct text only, truncated)\n let textContent: string | undefined;\n const directText = Array.from(element.childNodes)\n .filter((n) => n.nodeType === Node.TEXT_NODE)\n .map((n) => n.textContent?.trim())\n .filter(Boolean)\n .join(\" \");\n\n if (directText) {\n textContent = directText.slice(0, 50);\n } else if (element.textContent) {\n textContent = element.textContent.trim().slice(0, 50);\n }\n\n // Class name\n const className =\n typeof element.className === \"string\"\n ? element.className.slice(0, 100)\n : undefined;\n\n // Count nth of type within component\n const nthOfType = countNthOfType(element, tagName);\n\n // React key\n const key = fiber?.key ? String(fiber.key) : undefined;\n\n // Identifying props\n const props = extractProps(fiber);\n\n return { tagName, textContent, className, key, nthOfType, props };\n}\n\n// =============================================================================\n// SOURCE LOCATION FINDER\n// =============================================================================\n\nfunction extractFromDebugStack(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const stack = (fiber as any)._debugStack;\n if (!stack) return null;\n\n const stackStr = stack.stack || String(stack);\n const frames = stackStr.split(\"\\n\");\n\n const skipPatterns = [\n \"node_modules\",\n \"SegmentViewNode\",\n \"LayoutRouter\",\n \"ErrorBoundary\",\n \"fakeJSXCallSite\",\n ];\n\n for (const frame of frames) {\n if (skipPatterns.some((p) => frame.includes(p))) continue;\n\n // Match: at Name (path:line:col)\n const match = frame.match(/at\\s+(\\w+)\\s+\\((.+?):(\\d+):(\\d+)\\)?$/);\n if (match) {\n const fileName = cleanPath(match[2].replace(/\\?[^:]*$/, \"\"));\n if (!shouldSkipPath(fileName, [\"ai-editor-provider\"])) {\n return {\n fileName,\n lineNumber: parseInt(match[3], 10),\n columnNumber: parseInt(match[4], 10),\n };\n }\n }\n }\n return null;\n}\n\nfunction extractFromDebugOwner(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const owner = (fiber as any)._debugOwner;\n if (!owner) return null;\n\n if (owner._debugSource?.fileName) {\n return owner._debugSource;\n }\n\n const stack = owner.stack;\n if (Array.isArray(stack) && stack[0]?.fileName) {\n return stack[0];\n }\n\n return null;\n}\n\nexport function findSourceFromFiber(\n fiber: FiberNode | null,\n): Omit<SourceLocation, \"elementContext\"> | null {\n if (!fiber) return null;\n\n // For Server Components, _debugOwner contains the actual component info\n // Structure: { name: \"ComponentName\", owner: { name: \"ParentName\", debugLocation: Error }, debugStack: Error }\n let actualComponentName: string | null = null;\n if (fiber._debugOwner && typeof fiber._debugOwner === \"object\") {\n const debugOwner = fiber._debugOwner as any;\n if (debugOwner.name && typeof debugOwner.name === \"string\") {\n actualComponentName = debugOwner.name;\n }\n }\n\n let current: FiberNode | null = fiber;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 10) {\n iterations++;\n visited.add(current);\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n // Use the actualComponentName from _debugOwner if available (Server Components)\n // Otherwise walk up to find the nearest user component\n if (actualComponentName) {\n // Server Component - use _debugOwner.name\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName: actualComponentName,\n debugStack: rawDebugStack,\n };\n } else {\n // Client Component - walk up fiber tree\n let componentFiber: FiberNode | null = current;\n while (componentFiber) {\n if (isUserComponent(componentFiber)) {\n const componentName = getComponentName(componentFiber);\n\n // Skip Next.js internal components\n const isNextJSInternal = [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (!isNextJSInternal) {\n // Capture the raw _debugStack for server-side source map resolution\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n };\n }\n }\n componentFiber =\n componentFiber.return || componentFiber._debugOwner || null;\n }\n }\n }\n }\n\n current = current.return || current._debugOwner || null;\n }\n\n return null;\n}\n\n/**\n * Find the parent component using _debugOwner (the component that rendered this one)\n */\nexport function findParentComponentFromFiber(\n childFiber: FiberNode,\n childComponentName: string,\n): {\n filePath: string;\n lineNumber: number;\n columnNumber: number;\n componentName: string;\n debugStack?: string;\n childKey?: string;\n} | null {\n if (!childFiber) return null;\n\n // Find the child component's fiber to extract its key\n let childComponentFiber: FiberNode | null = null;\n\n // Check if _debugOwner points to the component fiber\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n // If it's a FiberNode (has type property), that's the component fiber\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n const ownerComponentName = getComponentName(debugOwner);\n if (ownerComponentName === childComponentName) {\n childComponentFiber = debugOwner;\n }\n }\n }\n\n // Otherwise walk up via .return to find component fiber\n if (!childComponentFiber) {\n let current: FiberNode | null = childFiber;\n let iterations = 0;\n while (current && iterations < 20) {\n iterations++;\n const componentName = getComponentName(current);\n const index = (current as any).index;\n\n if (isUserComponent(current)) {\n if (componentName === childComponentName) {\n childComponentFiber = current;\n break;\n }\n }\n\n // For Server Components, check if _debugOwner.name matches\n // Server Components don't have a fiber with the component name, but their rendered elements do have _debugOwner\n if (current._debugOwner && typeof current._debugOwner === \"object\") {\n const debugOwner = current._debugOwner as any;\n if (debugOwner.name === childComponentName && !debugOwner.type) {\n // This is a Server Component's rendered element\n // But we need to make sure this is the ROOT element of the component, not a child element\n // Check if the parent fiber is also part of the same component\n const parent = current.return;\n const parentDebugOwner = parent?._debugOwner as any;\n const isRootElement =\n !parentDebugOwner || parentDebugOwner.name !== childComponentName;\n\n if (isRootElement) {\n // This is the root element of the component - use this fiber's index\n childComponentFiber = current;\n break;\n }\n }\n }\n\n current = current.return;\n }\n }\n\n // Use key if available, otherwise use index\n let childKey: string | undefined;\n if (childComponentFiber?.key) {\n childKey = String(childComponentFiber.key);\n } else if (\n childComponentFiber &&\n typeof (childComponentFiber as any).index === \"number\"\n ) {\n // Use index as fallback for Server Components\n childKey = String((childComponentFiber as any).index);\n }\n\n // Two patterns to handle:\n // 1. Server Component element: fiber._debugOwner = { name: \"ChildComponent\", owner: { name: \"ParentComponent\", ... } }\n // 2. Client Component element: fiber._debugOwner = ComponentFiberNode, ComponentFiberNode._debugOwner = { name: \"ParentComponent\", ... }\n\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n\n // Pattern 1: Server Component - has owner.name\n if (debugOwner.owner && debugOwner.owner.name) {\n const parentName = debugOwner.owner.name;\n const parentDebugLocation = debugOwner.owner.debugLocation;\n\n if (parentDebugLocation) {\n const stack = String(parentDebugLocation.stack || parentDebugLocation);\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n\n // Pattern 2: Client Component - _debugOwner is a FiberNode, check its _debugOwner\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n // This is a FiberNode (Client Component), check its _debugOwner\n const componentFiberOwner = debugOwner._debugOwner;\n\n if (componentFiberOwner && typeof componentFiberOwner === \"object\") {\n const parentName = componentFiberOwner.name;\n const parentDebugLocation = componentFiberOwner.debugLocation;\n\n if (parentName && typeof parentName === \"string\") {\n if (parentDebugLocation) {\n const stack = String(\n parentDebugLocation.stack || parentDebugLocation,\n );\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n }\n }\n }\n\n // Fallback: traverse fiber tree via .return\n let current: FiberNode | null = childFiber.return;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 20) {\n iterations++;\n visited.add(current);\n\n if (isUserComponent(current)) {\n const componentName = getComponentName(current);\n\n // Skip if it's the same component as the child\n if (componentName === childComponentName) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Skip Next.js internal components and AI Editor wrapper\n const shouldSkipComponent =\n componentName.includes(\"AIEditorProvider\") || // Skip the AI Editor wrapper itself\n componentName.startsWith(\"__next\") || // Skip all Next.js internal components like __next_root_layout_boundary__\n componentName.startsWith(\"_\") || // Skip internal components starting with underscore\n [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n \"RootLayout\", // Skip root layout wrapper\n \"NotFound\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (shouldSkipComponent) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n childKey,\n };\n }\n }\n }\n\n // Continue traversing using _debugOwner\n const nextOwner = current._debugOwner;\n current = nextOwner || null;\n }\n\n // If no parent found with source info, use child's debugStack to find parent on server\n // For Server Components, the child's debugStack contains the component call stack\n const childDebugStack = childFiber._debugStack\n ? String(childFiber._debugStack.stack || childFiber._debugStack)\n : null;\n\n if (childDebugStack) {\n // Use the child's debugStack to resolve the real parent on the server\n return {\n filePath: \"\", // Will be resolved on server from debugStack\n lineNumber: 0,\n columnNumber: 0,\n componentName: \"\", // Will be determined on server\n debugStack: childDebugStack, // Use child's debugStack for server-side resolution\n childKey,\n };\n }\n\n return null;\n}\n\n// =============================================================================\n// GET SOURCE FROM ELEMENT (Main export)\n// =============================================================================\n\nexport function getSourceFromElement(element: Element): SourceLocation | null {\n // Walk up DOM to find element with fiber that has source location info\n // This is important: we want the element that corresponds to the line number,\n // not a deeply nested child element\n let current: Element | null = element;\n let elementWithSource: Element | null = null;\n let fiberWithSource: FiberNode | null = null;\n\n while (current && current !== document.body) {\n const fiber = getFiberFromElement(current);\n if (fiber) {\n // Check if this fiber has source location info\n const hasSourceInfo =\n fiber._debugSource?.fileName ||\n fiber._debugStack ||\n (fiber._debugOwner && typeof fiber._debugOwner === 'object');\n\n if (hasSourceInfo && !fiberWithSource) {\n // First fiber with source info - this is the element we want\n elementWithSource = current;\n fiberWithSource = fiber;\n }\n }\n current = current.parentElement;\n }\n\n if (!fiberWithSource || !elementWithSource) return null;\n\n const source = findSourceFromFiber(fiberWithSource);\n if (!source) return null;\n\n // Capture element context from the element that has source info,\n // not from the originally clicked element\n const elementContext = captureElementContext(elementWithSource, fiberWithSource);\n\n // Find parent component from Fiber tree\n const parentComponent = findParentComponentFromFiber(\n fiberWithSource,\n source.componentName,\n );\n\n return {\n ...source,\n elementContext,\n parentComponent: parentComponent || undefined,\n };\n}\n\n// Debug helper\nif (typeof window !== \"undefined\") {\n (window as any).__getSource = getSourceFromElement;\n}\n","\"use client\";\n\nimport React from \"react\";\nimport type { TaskHistoryItem } from \"../../shared/comment-types\";\nimport \"./TaskHistoryPanel.css\";\n\nexport interface TaskHistoryPanelProps {\n isOpen: boolean;\n onClose: () => void;\n tasks: TaskHistoryItem[];\n onTaskClick?: (taskId: string) => void;\n}\n\nexport function TaskHistoryPanel({\n isOpen,\n onClose,\n tasks,\n onTaskClick,\n}: TaskHistoryPanelProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <div className=\"task-history-panel ai-editor-ui\">\n <div className=\"task-history-overlay\" onClick={onClose} />\n <div className=\"task-history-content\">\n {/* Header */}\n <div className=\"task-history-header\">\n <div className=\"header-title\">\n <span className=\"header-icon\">📝</span>\n <h2>Task History</h2>\n </div>\n <button\n className=\"close-btn\"\n onClick={onClose}\n aria-label=\"Close\"\n title=\"Close (Esc)\"\n >\n ✕\n </button>\n </div>\n\n {/* Task List */}\n <div className=\"task-history-body\">\n {tasks.length === 0 ? (\n <div className=\"empty-state\">\n <div className=\"empty-icon\">🎯</div>\n <h3>No tasks yet</h3>\n <p>Create a comment and send a message to see AI actions here.</p>\n </div>\n ) : (\n <div className=\"task-list\">\n {tasks.map((task) => (\n <TaskItem\n key={task.id}\n task={task}\n onClick={() => onTaskClick?.(task.id)}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ninterface TaskItemProps {\n task: TaskHistoryItem;\n onClick: () => void;\n}\n\nfunction TaskItem({ task, onClick }: TaskItemProps) {\n const getStatusIcon = () => {\n switch (task.status) {\n case \"pending\":\n return \"⏳\";\n case \"done\":\n return \"✅\";\n case \"failed\":\n return \"❌\";\n default:\n return \"⏳\";\n }\n };\n\n const getStatusLabel = () => {\n switch (task.status) {\n case \"pending\":\n return \"In Progress\";\n case \"done\":\n return \"Complete\";\n case \"failed\":\n return \"Failed\";\n default:\n return \"Unknown\";\n }\n };\n\n const formatTime = (timestamp: number) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n\n if (diffMins < 1) return \"Just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n const diffHours = Math.floor(diffMins / 60);\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n return `${diffDays}d ago`;\n };\n\n return (\n <div\n className={`task-item status-${task.status}`}\n onClick={onClick}\n >\n <div className=\"task-header\">\n <div className=\"task-status\">\n <span className=\"status-icon\">{getStatusIcon()}</span>\n <span className=\"status-label\">{getStatusLabel()}</span>\n </div>\n <div className=\"task-time\">{formatTime(task.createdAt)}</div>\n </div>\n\n <div className=\"task-request\">{task.userRequest}</div>\n\n {task.actions.length > 0 && (\n <div className=\"task-actions\">\n {task.actions.map((action, idx) => (\n <div key={idx} className=\"action-item\">\n {action.type === \"tool_use\" && (\n <span className=\"action-text\">\n 🔧 {action.tool}\n </span>\n )}\n {action.type === \"result\" && (\n <span className=\"action-text\">\n ✓ {action.result}\n </span>\n )}\n {action.type === \"error\" && (\n <span className=\"action-text error\">\n ⚠️ {action.error}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n\n {task.affectedFiles.length > 0 && (\n <div className=\"task-files\">\n <span className=\"files-label\">Files:</span>\n {task.affectedFiles.map((file, idx) => (\n <span key={idx} className=\"file-badge\">\n {file.split(\"/\").pop()}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\n\nexport interface MessageItemProps {\n message: ChatMessage | CommentMessage;\n}\n\n/**\n * Renders a single user or final assistant message as a bubble\n */\nexport function MessageItem({ message }: MessageItemProps) {\n // Handle simple CommentMessage format (has 'role' property)\n if (\"role\" in message) {\n const commentMsg = message as CommentMessage;\n if (commentMsg.role === \"user\") {\n return (\n <div className=\"message message-user\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {commentMsg.content}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n if (commentMsg.role === \"assistant\") {\n return (\n <div className=\"message message-assistant\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {commentMsg.content}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n }\n\n // Handle complex ChatMessage format (has 'type' property)\n const chatMsg = message as ChatMessage;\n\n // Don't render system/connected messages in the UI\n if (chatMsg.type === \"connected\" || chatMsg.type === \"system\") {\n return null;\n }\n\n // Render user message\n if (chatMsg.type === \"user\") {\n return (\n <div className=\"message message-user\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {chatMsg.message}\n </ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render assistant message\n if (chatMsg.type === \"assistant\") {\n const content =\n typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n if (!content.trim()) return null;\n\n return (\n <div className=\"message message-assistant\">\n <div className=\"message-content\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render error message\n if (chatMsg.type === \"error\") {\n return (\n <div className=\"message message-error\">\n <div className=\"message-content\">\n <strong>Error:</strong> {chatMsg.error}\n </div>\n </div>\n );\n }\n\n // Other message types (tool_use, tool_result, result, done)\n // are handled by TaskGroup component\n return null;\n}\n\nexport interface TaskStep {\n type: \"status\" | \"tool\" | \"completion\";\n text?: string; // Optional - not needed when isThinkingPlaceholder is true\n tool?: string;\n target?: string;\n toolId?: string;\n isComplete: boolean;\n isExecuting?: boolean;\n isQueued?: boolean;\n isLast: boolean;\n isThinkingPlaceholder?: boolean; // True when this is a \"Thinking...\" placeholder\n}\n\nexport interface TaskGroupProps {\n steps: TaskStep[];\n isStreaming: boolean;\n}\n\n/**\n * Renders a group of task steps (tool calls and status messages)\n * in a compact, checklist-style format\n */\nexport function TaskGroup({ steps, isStreaming }: TaskGroupProps) {\n if (steps.length === 0) return null;\n\n return (\n <div className=\"task-group\">\n {steps.map((step, index) => {\n const isSubtask = step.type === \"tool\";\n const isCompletion = step.type === \"completion\";\n\n return (\n <div\n key={index}\n className={`task-step ${step.type} ${\n step.isComplete ? \"complete\" : \"pending\"\n } ${step.isLast && isStreaming ? \"current\" : \"\"}`}\n >\n <div className=\"task-step-indicator\">\n {step.isComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {step.text || \"\"}\n {step.target && (\n <span className=\"task-step-target\"> {step.target}</span>\n )}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface TaskBlockProps {\n userMessage?: ChatMessage | CommentMessage;\n steps: TaskStep[];\n isStreaming: boolean;\n}\n\ninterface PhaseGroup {\n statusStep?: TaskStep;\n toolSteps: TaskStep[];\n}\n\n/**\n * Groups steps into phases (status message + its tool calls)\n */\nfunction groupStepsIntoPhases(steps: TaskStep[]): PhaseGroup[] {\n const phases: PhaseGroup[] = [];\n let currentPhase: PhaseGroup | null = null;\n\n for (const step of steps) {\n if (step.type === \"status\" || step.type === \"completion\") {\n // Start new phase with this status\n if (currentPhase) {\n phases.push(currentPhase);\n }\n currentPhase = {\n statusStep: step,\n toolSteps: [],\n };\n } else if (step.type === \"tool\") {\n // Add tool to current phase\n if (!currentPhase) {\n // Tools without a preceding status - create phase without status\n currentPhase = {\n toolSteps: [],\n };\n }\n currentPhase.toolSteps.push(step);\n }\n }\n\n // Push final phase\n if (currentPhase) {\n phases.push(currentPhase);\n }\n\n return phases;\n}\n\n/**\n * Component to render a single phase (status + tool calls)\n */\nfunction PhaseItem({\n phase,\n isStreaming,\n}: {\n phase: PhaseGroup;\n isStreaming: boolean;\n}) {\n const hasTools = phase.toolSteps.length > 0;\n\n // Phase is complete when ALL its tools are complete (or no tools)\n const allToolsComplete = phase.toolSteps.length === 0 || phase.toolSteps.every(t => t.isComplete);\n const phaseIsComplete = allToolsComplete && (!phase.statusStep || phase.statusStep.isComplete);\n\n // Phase is active when streaming and has incomplete work\n const isActive = !phaseIsComplete && isStreaming && (phase.statusStep?.isLast || hasTools);\n\n // Auto-expand when active, or when any tool is not complete\n const hasIncompleteTools = phase.toolSteps.some(step => !step.isComplete);\n const shouldAutoExpand = isActive || (hasIncompleteTools && isStreaming);\n\n const [isToolsExpanded, setIsToolsExpanded] = useState(false); // Start collapsed by default\n const [wasManuallyExpanded, setWasManuallyExpanded] = useState(false); // Track manual expansion\n const [secondsElapsed, setSecondsElapsed] = useState(0);\n\n // Auto-expand active phases, auto-collapse inactive ones (unless manually expanded)\n useEffect(() => {\n if (shouldAutoExpand) {\n setIsToolsExpanded(true);\n } else if (!wasManuallyExpanded) {\n // Auto-collapse when no longer active, but only if not manually expanded\n setIsToolsExpanded(false);\n }\n }, [shouldAutoExpand, wasManuallyExpanded]);\n\n // Track elapsed time for active phases\n useEffect(() => {\n if (!isActive) {\n setSecondsElapsed(0);\n return;\n }\n\n console.log('[PhaseItem] Starting timer for phase:', phase.statusStep?.text);\n const startTime = Date.now();\n const interval = setInterval(() => {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n setSecondsElapsed(elapsed);\n if (elapsed % 5 === 0) {\n console.log('[PhaseItem] Timer update:', phase.statusStep?.text, elapsed + 's');\n }\n }, 1000);\n\n return () => {\n console.log('[PhaseItem] Stopping timer for phase:', phase.statusStep?.text);\n clearInterval(interval);\n };\n }, [isActive, phase.statusStep?.text]);\n\n const showElapsedTime = isActive && secondsElapsed >= 3;\n\n return (\n <div className=\"phase-item\">\n {/* Status message */}\n {phase.statusStep && (\n <div\n className={`task-step ${phase.statusStep.type} ${\n phaseIsComplete ? \"complete\" : \"pending\"\n } ${isActive ? \"current\" : \"\"} ${\n hasTools ? \"has-dropdown\" : \"\"\n }`}\n onClick={hasTools ? () => {\n setIsToolsExpanded(!isToolsExpanded);\n setWasManuallyExpanded(true); // Mark as manually toggled\n } : undefined}\n >\n <div className=\"task-step-indicator\">\n {phaseIsComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {phase.statusStep.isThinkingPlaceholder ? \"Thinking...\" : (phase.statusStep.text || \"\")}\n {phase.statusStep.target && (\n <span className=\"task-step-target\">\n {\" \"}\n {phase.statusStep.target}\n </span>\n )}\n {showElapsedTime && (\n <span className=\"task-step-elapsed\"> ({secondsElapsed}s)</span>\n )}\n </span>\n {hasTools && (\n <span className=\"task-step-dropdown-icon\">\n {isToolsExpanded ? \"▼\" : \"▶\"}\n </span>\n )}\n </div>\n )}\n\n {/* Expanded tool details */}\n {isToolsExpanded && (\n <div className=\"task-step-details\">\n {/* Show \"Thinking...\" when active with no tools yet, but not if the status itself is a thinking placeholder */}\n {hasTools === false && isActive && phase.statusStep && !phase.statusStep.isThinkingPlaceholder && (\n <div className=\"task-step-detail executing\">\n <div className=\"task-step-indicator\">\n <span className=\"task-spinner\"></span>\n </div>\n <span className=\"task-step-text\">Thinking...</span>\n </div>\n )}\n\n {/* Show actual tools */}\n {phase.toolSteps.map((step, index) => (\n <div\n key={index}\n className={`task-step-detail ${\n step.isComplete ? \"complete\" : \"executing\"\n }`}\n >\n <div className=\"task-step-indicator\">\n {step.isComplete ? (\n <span className=\"task-checkmark\">✓</span>\n ) : (\n <span className=\"task-spinner\"></span>\n )}\n </div>\n <span className=\"task-step-text\">\n {step.text || \"\"}\n {step.target && (\n <span className=\"task-step-target\"> {step.target}</span>\n )}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Renders a task block with user message as header and agent steps below\n */\nexport function TaskBlock({ userMessage, steps, isStreaming }: TaskBlockProps) {\n // Extract user message content\n let userContent = \"\";\n if (userMessage) {\n if (\"role\" in userMessage) {\n userContent = userMessage.content;\n } else {\n const chatMsg = userMessage as ChatMessage;\n if (chatMsg.type === \"user\") {\n userContent = chatMsg.message;\n }\n }\n }\n\n // Group steps into phases\n const phases = groupStepsIntoPhases(steps);\n\n return (\n <div className=\"task-block\">\n {userContent && (\n <div className=\"task-block-header\">\n <div className=\"task-block-title\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {userContent}\n </ReactMarkdown>\n </div>\n <button className=\"task-block-undo\" title=\"Undo this task\">\n ↶\n </button>\n </div>\n )}\n <div className=\"task-block-steps\">\n {phases.map((phase, index) => (\n <PhaseItem key={index} phase={phase} isStreaming={isStreaming} />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useMemo } from \"react\";\nimport { MessageItem, TaskGroup, TaskBlock, TaskStep } from \"./MessageItem\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\n\nexport interface Todo {\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n activeForm: string;\n}\n\nexport interface MessageListProps {\n messages: (CommentMessage | ChatMessage)[];\n isStreaming?: boolean;\n startedToolIds?: Set<string>;\n completedToolIds?: Set<string>;\n todos?: Todo[];\n}\n\ninterface GroupMessagesOptions {\n isStreaming?: boolean;\n}\n\ninterface MessageGroup {\n type: \"task-block\" | \"error\" | \"assistant\";\n userMessage?: CommentMessage | ChatMessage;\n messages: (CommentMessage | ChatMessage)[];\n}\n\n/**\n * Check if a message is a final completion message\n */\nfunction isCompletionMessage(content: string): boolean {\n if (!content) return false;\n const trimmed = content.trim().toLowerCase();\n return trimmed.startsWith('done.') ||\n trimmed.startsWith('complete.') ||\n trimmed.startsWith('finished.');\n}\n\n/**\n * Check if an assistant message looks like a status update vs a real response\n * Status updates are typically short, action-oriented phrases\n */\nfunction isStatusMessage(content: string): boolean {\n if (!content) return false;\n const trimmed = content.trim();\n\n // Completion messages go in task group\n if (isCompletionMessage(trimmed)) {\n return true;\n }\n\n // Short messages starting with action words are status updates\n // e.g., \"Searching for files\", \"Reading StatsCard.tsx\", \"Updating page content\"\n if (trimmed.length < 100) {\n const actionStarters = [\n 'searching', 'reading', 'writing', 'editing', 'looking', 'finding',\n 'checking', 'analyzing', 'processing', 'updating', 'creating',\n 'modifying', 'changing', 'applying', 'converting', 'transforming'\n ];\n const lowerContent = trimmed.toLowerCase();\n if (actionStarters.some(starter => lowerContent.startsWith(starter))) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Groups messages into task blocks (user message + agent steps)\n */\nfunction groupMessages(messages: (CommentMessage | ChatMessage)[], options?: GroupMessagesOptions): MessageGroup[] {\n const groups: MessageGroup[] = [];\n let currentTaskBlock: {\n userMessage?: CommentMessage | ChatMessage;\n steps: (CommentMessage | ChatMessage)[];\n } = { steps: [] };\n const { isStreaming = false } = options || {};\n\n const flushTaskBlock = () => {\n if (currentTaskBlock.userMessage || currentTaskBlock.steps.length > 0) {\n groups.push({\n type: \"task-block\",\n userMessage: currentTaskBlock.userMessage,\n messages: currentTaskBlock.steps\n });\n currentTaskBlock = { steps: [] };\n }\n };\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const isLastMessage = i === messages.length - 1;\n\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"user\") {\n flushTaskBlock();\n currentTaskBlock.userMessage = msg;\n } else if (msg.role === \"assistant\") {\n if (isStatusMessage(msg.content)) {\n currentTaskBlock.steps.push(msg);\n } else {\n // Real assistant response - standalone\n flushTaskBlock();\n groups.push({ type: \"assistant\", messages: [msg] });\n }\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as ChatMessage;\n\n if (chatMsg.type === \"user\") {\n flushTaskBlock();\n currentTaskBlock.userMessage = msg;\n } else if (chatMsg.type === \"error\") {\n flushTaskBlock();\n groups.push({ type: \"error\", messages: [msg] });\n } else if (chatMsg.type === \"assistant\") {\n const content = typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n // Check if message has tool_use blocks\n const contentBlocks = chatMsg.message?.content || [];\n const hasToolUse = contentBlocks.some((block: any) => block.type === \"tool_use\");\n\n // If streaming and this is the last message, always put in task block\n // (it might get tool_use blocks added in subsequent chunks)\n const shouldBeInTaskBlock = isStatusMessage(content) || hasToolUse || (isStreaming && isLastMessage);\n\n if (shouldBeInTaskBlock) {\n // Status messages or messages with tool calls go in task block\n currentTaskBlock.steps.push(msg);\n } else if (content.trim()) {\n // Real assistant response - standalone\n flushTaskBlock();\n groups.push({ type: \"assistant\", messages: [msg] });\n }\n } else if (\n chatMsg.type === \"tool_use\" ||\n chatMsg.type === \"tool_result\" ||\n chatMsg.type === \"result\" ||\n chatMsg.type === \"done\"\n ) {\n // These all go into the current task block\n currentTaskBlock.steps.push(msg);\n }\n // Ignore connected, system messages\n }\n\n flushTaskBlock();\n return groups;\n}\n\n/**\n * Converts task group messages into task steps for display\n */\nfunction convertToTaskSteps(\n messages: (CommentMessage | ChatMessage)[],\n isStreaming: boolean,\n startedToolIds: Set<string> = new Set(),\n completedToolIds: Set<string> = new Set()\n): TaskStep[] {\n const steps: TaskStep[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"assistant\" && msg.content) {\n const isCompletion = isCompletionMessage(msg.content);\n\n steps.push({\n type: isCompletion ? \"completion\" : \"status\",\n text: msg.content,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as ChatMessage;\n\n if (chatMsg.type === \"assistant\") {\n // Extract content blocks from assistant message\n const contentBlocks = chatMsg.message?.content || [];\n\n for (const block of contentBlocks) {\n // Handle text blocks\n if (block.type === \"text\") {\n const text = block.text || \"\";\n\n if (text && text.trim()) {\n const isCompletion = isCompletionMessage(text);\n\n steps.push({\n type: isCompletion ? \"completion\" : \"status\",\n text: text,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n }\n\n // Handle tool_use blocks embedded in assistant messages\n if (block.type === \"tool_use\") {\n const toolDescriptions: Record<string, string> = {\n Read: \"Reading\",\n Write: \"Writing\",\n Edit: \"Editing\",\n Glob: \"Searching\",\n Grep: \"Searching\",\n Bash: \"Running\",\n Task: \"Running task\",\n };\n const action = toolDescriptions[block.name] || block.name;\n\n // Extract file path or other relevant info from tool input\n let target = \"\";\n const input = block.input || {};\n\n if (block.name === \"Task\") {\n // For Task tool, show the description or first line of prompt\n target = input.description || (input.prompt ? input.prompt.split('\\n')[0].substring(0, 50) : \"\");\n } else if (input.file_path) {\n // Extract just the filename from the path\n const fileName = input.file_path.split('/').pop() || input.file_path;\n target = fileName;\n } else if (input.pattern) {\n target = `\"${input.pattern}\"`;\n } else if (input.command) {\n target = input.command.split(' ')[0]; // Just first word of command\n }\n\n steps.push({\n type: \"tool\",\n text: action,\n tool: block.name,\n target,\n toolId: block.id,\n isComplete: false, // Will be set later\n isLast: false,\n });\n }\n }\n } else if (chatMsg.type === \"tool_use\") {\n // Map tool names to friendly descriptions\n const toolDescriptions: Record<string, string> = {\n read_file: \"Reading file\",\n write_file: \"Writing file\",\n edit_file: \"Editing file\",\n search_files: \"Searching files\",\n list_files: \"Listing files\",\n run_command: \"Running command\",\n };\n const description = toolDescriptions[chatMsg.tool] || `Running ${chatMsg.tool}`;\n\n steps.push({\n type: \"tool\",\n text: description,\n tool: chatMsg.tool,\n isComplete: false, // Will be set later\n isLast: false,\n });\n } else if (chatMsg.type === \"result\") {\n // Result messages indicate completion\n if (chatMsg.result && chatMsg.result.trim()) {\n steps.push({\n type: \"status\",\n text: chatMsg.result,\n isComplete: true,\n isLast: false,\n });\n }\n }\n // Skip done, tool_result messages\n }\n\n // Now determine which step is actually last and mark completion status\n if (steps.length > 0) {\n const lastStepIndex = steps.length - 1;\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n const isLastStep = i === lastStepIndex;\n\n step.isLast = isLastStep;\n\n // Determine completion based on type\n if (step.type === \"tool\") {\n const toolId = step.toolId;\n\n if (toolId) {\n const hasCompleted = completedToolIds.has(toolId);\n const hasStarted = startedToolIds.has(toolId);\n\n // Debug: Log mismatches\n if (!hasCompleted && !isStreaming) {\n console.warn(`[MessageList] Tool ${toolId} (${step.text}) not in completedToolIds after streaming ended`, {\n completedToolIds: Array.from(completedToolIds),\n startedToolIds: Array.from(startedToolIds),\n });\n }\n\n // If not streaming, all tools are complete\n step.isComplete = !isStreaming || hasCompleted;\n step.isExecuting = isStreaming && hasStarted && !hasCompleted;\n step.isQueued = isStreaming && !hasStarted && !hasCompleted;\n } else {\n // No tool ID - assume complete\n step.isComplete = true;\n step.isExecuting = false;\n step.isQueued = false;\n }\n } else if (step.type === \"status\") {\n // Status steps complete when not streaming or not the last step\n step.isComplete = !isStreaming || !isLastStep;\n } else if (step.type === \"completion\") {\n // Completion messages are always complete\n step.isComplete = true;\n }\n }\n }\n\n return steps;\n}\n\nexport function MessageList({\n messages,\n isStreaming,\n startedToolIds = new Set(),\n completedToolIds = new Set(),\n todos = []\n}: MessageListProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n // Group messages\n const groups = useMemo(() => groupMessages(messages, { isStreaming }), [messages, isStreaming]);\n\n /**\n * Auto-scroll to bottom when new messages arrive\n */\n useEffect(() => {\n if (messagesEndRef.current) {\n messagesEndRef.current.scrollIntoView({ behavior: \"smooth\" });\n }\n }, [messages]);\n\n if (messages.length === 0) {\n return <div className=\"message-list-empty\"></div>;\n }\n\n return (\n <div className=\"message-list\">\n {/* Display todos if present */}\n {todos.length > 0 && (\n <div className=\"todo-list\">\n <div className=\"todo-list-header\">Tasks</div>\n {todos.map((todo, idx) => (\n <div key={idx} className={`todo-item todo-${todo.status}`}>\n <div className=\"todo-indicator\">\n {todo.status === \"completed\" ? (\n <span className=\"todo-checkmark\">✓</span>\n ) : todo.status === \"in_progress\" ? (\n <span className=\"todo-spinner\"></span>\n ) : (\n <span className=\"todo-pending\">○</span>\n )}\n </div>\n <span className=\"todo-text\">\n {todo.status === \"in_progress\" ? todo.activeForm : todo.content}\n </span>\n </div>\n ))}\n </div>\n )}\n {groups.map((group, groupIndex) => {\n const isLastGroup = groupIndex === groups.length - 1;\n\n if (group.type === \"assistant\" || group.type === \"error\") {\n return (\n <MessageItem key={groupIndex} message={group.messages[0]} />\n );\n }\n\n if (group.type === \"task-block\") {\n const steps = convertToTaskSteps(\n group.messages,\n !!(isStreaming && isLastGroup),\n startedToolIds,\n completedToolIds\n );\n\n // Show thinking only if we're streaming, last group, and all steps are complete (or no steps yet)\n const allStepsComplete = steps.length === 0 || steps.every(step => step.isComplete);\n const shouldShowThinking = isStreaming && isLastGroup && allStepsComplete;\n\n const displaySteps = shouldShowThinking\n ? [\n ...steps,\n {\n type: \"status\" as const,\n isComplete: false,\n isLast: true,\n isThinkingPlaceholder: true,\n }\n ]\n : steps;\n\n return (\n <TaskBlock\n key={groupIndex}\n userMessage={group.userMessage}\n steps={displaySteps}\n isStreaming={!!(isStreaming && isLastGroup)}\n />\n );\n }\n\n return null;\n })}\n <div ref={messagesEndRef} />\n </div>\n );\n}\n","/**\n * Configuration for the AI Editor Service\n *\n * The service runs as a separate process (typically in Docker) and handles\n * all file operations, AI processing, and code analysis.\n */\n\n/**\n * Get the AI Editor service URL\n *\n * Priority order:\n * 1. NEXT_PUBLIC_AI_EDITOR_SERVICE_URL environment variable (for custom setups)\n * 2. Auto-detect based on window.location.hostname\n * - localhost -> http://localhost:3456\n * - deployed -> https://${hostname}:3456\n */\nexport function getServiceUrl(): string {\n // Check for environment variable override (can be set in .env.local)\n // if (typeof window !== \"undefined\" && (window as any).env?.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL) {\n // return (window as any).env.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL;\n // }\n\n // if (typeof process !== \"undefined\" && process.env?.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL) {\n // return process.env.NEXT_PUBLIC_AI_EDITOR_SERVICE_URL;\n // }\n\n // Auto-detect based on hostname\n if (typeof window !== \"undefined\") {\n const hostname = window.location.hostname;\n\n // Local development\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return \"http://localhost:3456\";\n }\n\n // Deployed (use same hostname with HTTPS on port 3456)\n return `https://${hostname}:3456`;\n }\n\n // SSR fallback (shouldn't be reached in practice)\n return \"http://localhost:3456\";\n}\n\n/**\n * Build full endpoint URL for a given path\n */\nexport function buildServiceUrl(path: string): string {\n const baseUrl = getServiceUrl();\n // Remove leading slash if present\n const normalizedPath = path.startsWith(\"/\") ? path.slice(1) : path;\n return `${baseUrl}/${normalizedPath}`;\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport type { ComponentContext } from \"../../shared/types\";\nimport { buildServiceUrl } from \"../service-config\";\n\n/**\n * Message types from the Agent SDK stream\n */\nexport type ChatMessage =\n | { type: \"connected\"; sessionId: string }\n | { type: \"system\"; subtype: string; [key: string]: any }\n | { type: \"user\"; message: string }\n | { type: \"assistant\"; message: any; [key: string]: any }\n | { type: \"tool_use\"; tool: string; input: any; [key: string]: any }\n | { type: \"tool_result\"; tool: string; output: any; [key: string]: any }\n | { type: \"tool_start\"; toolId: string; toolName: string }\n | { type: \"tool_complete\"; toolId: string; toolName: string }\n | { type: \"result\"; subtype: string; result: string; [key: string]: any }\n | { type: \"error\"; error: string }\n | { type: \"done\" };\n\nexport interface ChatStreamState {\n messages: ChatMessage[];\n isConnected: boolean;\n isStreaming: boolean;\n error: string | null;\n sessionId: string | null;\n}\n\nexport interface UseChatStreamOptions {\n threadId: string;\n sessionId?: string;\n onMessage?: (message: ChatMessage) => void;\n onError?: (error: string) => void;\n onDone?: () => void;\n}\n\n/**\n * React hook for managing SSE chat stream connection\n */\nexport function useChatStream(options: UseChatStreamOptions) {\n const { threadId, sessionId: initialSessionId, onMessage, onError, onDone } = options;\n\n const [state, setState] = useState<ChatStreamState>({\n messages: [],\n isConnected: false,\n isStreaming: false,\n error: null,\n sessionId: initialSessionId || null,\n });\n\n const wsRef = useRef<WebSocket | null>(null);\n const [startedToolIds, setStartedToolIds] = useState<Set<string>>(new Set());\n const [completedToolIds, setCompletedToolIds] = useState<Set<string>>(new Set());\n const [todos, setTodos] = useState<Array<{\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n activeForm: string;\n }>>([]);\n\n /**\n * Parse SSE data line\n */\n const parseEventData = useCallback((data: string): ChatMessage | null => {\n try {\n return JSON.parse(data);\n } catch (error) {\n console.error(\"Failed to parse SSE data:\", data, error);\n return null;\n }\n }, []);\n\n /**\n * Send a message and start streaming response via WebSocket\n */\n const sendMessage = useCallback(\n async (message: string, componentContext?: ComponentContext) => {\n // Close existing connection\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n\n // Add user message to chat\n const userMessage: ChatMessage = { type: \"user\", message };\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, userMessage],\n isStreaming: true,\n error: null,\n }));\n\n try {\n // Create WebSocket connection\n const wsUrl = buildServiceUrl(\"ws/chat\").replace(/^http/, \"ws\");\n const ws = new WebSocket(wsUrl);\n wsRef.current = ws;\n\n // Track accumulated assistant content\n let currentAssistantMessage: ChatMessage | null = null;\n\n ws.onopen = () => {\n console.log(\"[WebSocket] Connected\");\n\n // Helper to send client logs to server\n const logToServer = (level: string, ...args: any[]) => {\n const timestamp = new Date().toISOString();\n const logMessage = args.map(arg =>\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\n ).join(' ');\n ws.send(JSON.stringify({\n type: \"client_log\",\n level,\n timestamp,\n message: logMessage\n }));\n (console[level as keyof typeof console] as (...args: any[]) => void)(`[${timestamp}]`, ...args);\n };\n\n // Store reference for use in event handlers\n (ws as any).logToServer = logToServer;\n\n // Send chat message\n ws.send(\n JSON.stringify({\n type: \"chat\",\n threadId,\n sessionId: state.sessionId,\n message,\n componentContext,\n })\n );\n };\n\n ws.onmessage = (event) => {\n const data = parseEventData(event.data);\n if (!data) return;\n\n // Debug logging with timestamp (send to server too)\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[useChatStream] Received event: ${data.type}`);\n }\n\n // Handle assistant messages - accumulate into single message\n if (data.type === \"assistant\") {\n // Check for TodoWrite tool calls\n const content = data.message?.content || [];\n for (const block of content) {\n if (block.type === \"tool_use\" && block.name === \"TodoWrite\") {\n const todosData = block.input?.todos || [];\n setTodos(todosData);\n }\n }\n\n if (currentAssistantMessage) {\n // Update existing assistant message\n setState((prev) => {\n const messages = [...prev.messages];\n const lastIndex = messages.length - 1;\n if (messages[lastIndex]?.type === \"assistant\") {\n // Merge content\n const existingContent = messages[lastIndex].message?.content || [];\n const newContent = data.message?.content || [];\n messages[lastIndex] = {\n ...messages[lastIndex],\n message: {\n ...messages[lastIndex].message,\n content: [...existingContent, ...newContent],\n },\n };\n }\n return { ...prev, messages };\n });\n } else {\n // First assistant message chunk\n currentAssistantMessage = data;\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n }\n onMessage?.(data);\n return;\n }\n\n // Reset assistant accumulation for any non-assistant event\n currentAssistantMessage = null;\n\n // Track tool start via tool_start events from hooks\n if (data.type === \"tool_start\") {\n const toolId = data.toolId;\n if (toolId) {\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[CLIENT] Tool STARTED: ${data.toolName} (${toolId})`);\n }\n // Create new Set to trigger React re-render\n setStartedToolIds((prev) => new Set(prev).add(toolId));\n }\n return; // Don't show in UI\n }\n\n // Track tool completion via tool_complete events from hooks\n if (data.type === \"tool_complete\") {\n const toolId = data.toolId;\n if (toolId) {\n if ((ws as any).logToServer) {\n (ws as any).logToServer('log', `[CLIENT] Tool COMPLETED: ${data.toolName} (${toolId})`);\n }\n // Create new Set to trigger React re-render with immediate sync\n flushSync(() => {\n setCompletedToolIds((prev) => new Set(prev).add(toolId));\n });\n }\n return; // Don't show in UI\n }\n\n // Filter out user echoes\n if (data.type === \"user\") {\n return;\n }\n\n // Add tool_use messages to show AI actions\n if (data.type === \"tool_use\") {\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n onMessage?.(data);\n return;\n }\n\n // Handle result messages - check for duplication\n if (data.type === \"result\") {\n setState((prev) => {\n const lastMsg = prev.messages[prev.messages.length - 1];\n if (lastMsg?.type === \"assistant\") {\n const lastText = lastMsg.message?.content?.[0]?.text || \"\";\n const resultText = data.result || \"\";\n if (lastText.includes(resultText) || resultText.includes(lastText)) {\n return prev;\n }\n }\n return {\n ...prev,\n messages: [...prev.messages, data],\n };\n });\n onMessage?.(data);\n return;\n }\n\n // Handle connected event\n if (data.type === \"connected\") {\n setState((prev) => ({\n ...prev,\n sessionId: data.sessionId,\n isConnected: true,\n }));\n return;\n }\n\n // Handle done event\n if (data.type === \"done\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n messages: [...prev.messages, data],\n }));\n onDone?.();\n return;\n }\n\n // Handle error event\n if (data.type === \"error\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: data.error,\n messages: [...prev.messages, data],\n }));\n onError?.(data.error);\n return;\n }\n\n // All other events - add to messages\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, data],\n }));\n onMessage?.(data);\n };\n\n ws.onerror = (error) => {\n console.error(\"[WebSocket] Error:\", error);\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: \"WebSocket connection error\",\n }));\n onError?.(\"WebSocket connection error\");\n };\n\n ws.onclose = () => {\n console.log(\"[WebSocket] Disconnected\");\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n }));\n };\n } catch (error: any) {\n const errorMessage = error.message || \"Failed to send message\";\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: errorMessage,\n }));\n onError?.(errorMessage);\n }\n },\n [threadId, state.sessionId, parseEventData, onMessage, onError, onDone]\n );\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n if (wsRef.current) {\n wsRef.current.close();\n }\n };\n }, []);\n\n return {\n ...state,\n sendMessage,\n startedToolIds,\n completedToolIds,\n todos,\n };\n}\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\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};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\",\n key: \"hh9hay\"\n }\n ],\n [\"path\", { d: \"m3.3 7 8.7 5 8.7-5\", key: \"g66t2b\" }],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }]\n];\nconst Box = createLucideIcon(\"box\", __iconNode);\n\nexport { __iconNode, Box as default };\n//# sourceMappingURL=box.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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 key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 12.5 8 15l2 2.5\", key: \"1tg20x\" }],\n [\"path\", { d: \"m14 12.5 2 2.5-2 2.5\", key: \"yinavb\" }]\n];\nconst FileCode = createLucideIcon(\"file-code\", __iconNode);\n\nexport { __iconNode, FileCode as default };\n//# sourceMappingURL=file-code.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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 key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n];\nconst FileText = createLucideIcon(\"file-text\", __iconNode);\n\nexport { __iconNode, FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"6\", x2: \"6\", y1: \"3\", y2: \"15\", key: \"17qcm7\" }],\n [\"circle\", { cx: \"18\", cy: \"6\", r: \"3\", key: \"1h7g24\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M18 9a9 9 0 0 1-9 9\", key: \"n2h4wq\" }]\n];\nconst GitBranch = createLucideIcon(\"git-branch\", __iconNode);\n\nexport { __iconNode, GitBranch as default };\n//# sourceMappingURL=git-branch.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }],\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M13 6h3a2 2 0 0 1 2 2v7\", key: \"1yeb86\" }],\n [\"line\", { x1: \"6\", x2: \"6\", y1: \"9\", y2: \"21\", key: \"rroup\" }]\n];\nconst GitPullRequest = createLucideIcon(\"git-pull-request\", __iconNode);\n\nexport { __iconNode, GitPullRequest as default };\n//# sourceMappingURL=git-pull-request.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]];\nconst LoaderCircle = createLucideIcon(\"loader-circle\", __iconNode);\n\nexport { __iconNode, LoaderCircle as default };\n//# sourceMappingURL=loader-circle.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n key: \"1a8usu\"\n }\n ],\n [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\",\n key: \"1s2grr\"\n }\n ],\n [\"path\", { d: \"M20 2v4\", key: \"1rf3ol\" }],\n [\"path\", { d: \"M22 4h-4\", key: \"gwowj6\" }],\n [\"circle\", { cx: \"4\", cy: \"20\", r: \"2\", key: \"6kqj1y\" }]\n];\nconst Sparkles = createLucideIcon(\"sparkles\", __iconNode);\n\nexport { __iconNode, Sparkles as default };\n//# sourceMappingURL=sparkles.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","import { useState, useEffect, useCallback } from \"react\";\nimport { buildServiceUrl } from \"../service-config\";\n\nexport interface PRStatus {\n hasChanges: boolean;\n changedFiles: string[];\n baseBranch: string;\n}\n\nexport interface UsePRStatusResult {\n status: PRStatus | null;\n isLoading: boolean;\n error: string | null;\n refresh: () => Promise<void>;\n}\n\nexport function usePRStatus(): UsePRStatusResult {\n const [status, setStatus] = useState<PRStatus | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetchStatus = useCallback(async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n const response = await fetch(buildServiceUrl(\"api/pr/status\"));\n\n if (!response.ok) {\n throw new Error(\"Failed to fetch PR status\");\n }\n\n const data = await response.json();\n setStatus(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Unknown error\");\n setStatus(null);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchStatus();\n }, [fetchStatus]);\n\n return {\n status,\n isLoading,\n error,\n refresh: fetchStatus,\n };\n}\n","import { useState, useCallback } from \"react\";\nimport { buildServiceUrl } from \"../service-config\";\n\nexport interface CreatePRInput {\n title: string;\n description: string;\n}\n\nexport interface CreatePRResult {\n success: boolean;\n prUrl?: string;\n prNumber?: number;\n branchName?: string;\n error?: string;\n partialSuccess?: boolean;\n}\n\nexport interface GeneratedPRContent {\n title: string;\n description: string;\n}\n\nexport interface UseCreatePRResult {\n createPR: (input: CreatePRInput) => Promise<CreatePRResult>;\n generateContent: () => Promise<GeneratedPRContent>;\n isCreating: boolean;\n isGenerating: boolean;\n}\n\nexport function useCreatePR(): UseCreatePRResult {\n const [isCreating, setIsCreating] = useState(false);\n const [isGenerating, setIsGenerating] = useState(false);\n\n const generateContent = useCallback(async (): Promise<GeneratedPRContent> => {\n setIsGenerating(true);\n try {\n const response = await fetch(buildServiceUrl(\"api/pr/generate-description\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to generate PR content\");\n }\n\n const data = await response.json();\n return {\n title: data.title || \"\",\n description: data.description || \"\",\n };\n } catch (err) {\n console.error(\"Error generating PR content:\", err);\n return { title: \"\", description: \"\" };\n } finally {\n setIsGenerating(false);\n }\n }, []);\n\n const createPR = useCallback(async (input: CreatePRInput): Promise<CreatePRResult> => {\n setIsCreating(true);\n try {\n const response = await fetch(buildServiceUrl(\"api/pr/create\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || \"Failed to create PR\",\n branchName: data.branchName,\n partialSuccess: data.partialSuccess,\n };\n }\n\n return {\n success: true,\n prUrl: data.prUrl,\n prNumber: data.prNumber,\n branchName: data.branchName,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : \"Failed to create PR\",\n };\n } finally {\n setIsCreating(false);\n }\n }, []);\n\n return {\n createPR,\n generateContent,\n isCreating,\n isGenerating,\n };\n}\n","\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { Sparkles, GitPullRequest, Check, Loader2, FileText, GitBranch, X } from \"lucide-react\";\nimport { usePRStatus } from \"../hooks/usePRStatus\";\nimport { useCreatePR, CreatePRResult } from \"../hooks/useCreatePR\";\nimport \"./PRBlock.css\";\n\nexport interface PRBlockProps {\n onCancel: () => void;\n onSuccess?: (result: CreatePRResult) => void;\n}\n\ntype BlockState = \"generating\" | \"form\" | \"creating\" | \"success\";\n\nexport function PRBlock({ onCancel, onSuccess }: PRBlockProps) {\n const [title, setTitle] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<CreatePRResult | null>(null);\n const [blockState, setBlockState] = useState<BlockState>(\"generating\");\n const hasGenerated = useRef(false);\n\n const { status } = usePRStatus();\n const { createPR, generateContent, isGenerating } = useCreatePR();\n\n // Auto-generate on mount\n useEffect(() => {\n if (!hasGenerated.current) {\n hasGenerated.current = true;\n generateContent().then((content) => {\n setTitle(content.title);\n setDescription(content.description);\n setBlockState(\"form\");\n });\n }\n }, [generateContent]);\n\n const handleRegenerate = useCallback(async () => {\n setError(null);\n const content = await generateContent();\n setTitle(content.title);\n setDescription(content.description);\n }, [generateContent]);\n\n const handleSubmit = useCallback(async () => {\n if (!title.trim()) {\n setError(\"Title is required\");\n return;\n }\n\n setError(null);\n setBlockState(\"creating\");\n const prResult = await createPR({ title: title.trim(), description });\n\n if (prResult.success) {\n setResult(prResult);\n setBlockState(\"success\");\n onSuccess?.(prResult);\n } else {\n setError(prResult.error || \"Failed to create PR\");\n setBlockState(\"form\");\n }\n }, [title, description, createPR, onSuccess]);\n\n // Success state\n if (blockState === \"success\" && result) {\n return (\n <div className=\"pr-block pr-block-success\">\n <div className=\"pr-block-success-content\">\n <div className=\"pr-block-success-icon\">\n <Check size={16} />\n </div>\n <div className=\"pr-block-success-text\">\n <span className=\"pr-block-success-title\">PR Created</span>\n <a\n href={result.prUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"pr-block-success-link\"\n >\n #{result.prNumber}\n </a>\n <span className=\"pr-block-success-branch\">\n on <code>{result.branchName}</code>\n </span>\n </div>\n </div>\n </div>\n );\n }\n\n // Generating state\n if (blockState === \"generating\") {\n return (\n <div className=\"pr-block pr-block-generating\">\n <div className=\"pr-block-loading\">\n <Loader2 size={16} className=\"pr-block-spinner\" />\n <span>Generating PR details...</span>\n </div>\n </div>\n );\n }\n\n // Form state (and creating state with disabled form)\n const isDisabled = blockState === \"creating\" || isGenerating;\n\n return (\n <div className=\"pr-block\">\n <div className=\"pr-block-header\">\n <span className=\"pr-block-title\">Create Pull Request</span>\n <button\n className=\"pr-block-cancel\"\n onClick={onCancel}\n disabled={blockState === \"creating\"}\n title=\"Cancel\"\n >\n <X size={14} />\n </button>\n </div>\n\n <div className=\"pr-block-content\">\n {error && <div className=\"pr-block-error\">{error}</div>}\n\n <div className=\"pr-block-field\">\n <label htmlFor=\"pr-block-title\">Title</label>\n <input\n id=\"pr-block-title\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"PR title...\"\n disabled={isDisabled}\n />\n </div>\n\n <div className=\"pr-block-field\">\n <div className=\"pr-block-field-header\">\n <label htmlFor=\"pr-block-description\">Description</label>\n <button\n className=\"pr-block-regenerate\"\n onClick={handleRegenerate}\n disabled={isDisabled}\n >\n {isGenerating ? (\n <Loader2 size={12} className=\"pr-block-spinner\" />\n ) : (\n <Sparkles size={12} />\n )}\n Regen\n </button>\n </div>\n <textarea\n id=\"pr-block-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe your changes...\"\n disabled={isDisabled}\n rows={3}\n />\n </div>\n\n {status && (\n <div className=\"pr-block-info\">\n <span>\n <FileText size={12} />\n {status.changedFiles.length} files\n </span>\n <span>\n <GitBranch size={12} />\n {status.baseBranch}\n </span>\n </div>\n )}\n </div>\n\n <div className=\"pr-block-footer\">\n <button\n className=\"pr-block-submit\"\n onClick={handleSubmit}\n disabled={isDisabled || !title.trim()}\n >\n {blockState === \"creating\" ? (\n <>\n <Loader2 size={14} className=\"pr-block-spinner\" />\n Creating...\n </>\n ) : (\n <>\n <GitPullRequest size={14} />\n Create PR\n </>\n )}\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useState, useCallback, useRef, useEffect, useMemo } from \"react\";\nimport { MessageList } from \"./MessageList\";\nimport { useChatStream } from \"../hooks/useChatStream\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { ComponentContext } from \"../../shared/types\";\nimport { Box, Type, FileCode, X, GitPullRequest } from \"lucide-react\";\nimport { PRBlock } from \"./PRBlock\";\nimport { usePRStatus } from \"../hooks/usePRStatus\";\nimport \"./ChatPanel.css\";\n\nexport type ToolType = \"component\" | \"area\" | \"text\" | null;\n\nexport interface AttachedContext {\n type: \"component\" | \"area\" | \"text\";\n data: any;\n displayText: string;\n}\n\nexport interface ChatPanelProps {\n isExpanded: boolean;\n onToggle: () => void;\n activeTool: ToolType;\n onToolChange: (tool: ToolType) => void;\n attachedContext: AttachedContext | null;\n onClearContext: () => void;\n theme?: \"light\" | \"dark\";\n}\n\nexport function ChatPanel({\n isExpanded,\n onToggle,\n activeTool,\n onToolChange,\n attachedContext,\n onClearContext,\n theme = \"dark\",\n}: ChatPanelProps) {\n const [message, setMessage] = useState(\"\");\n const [threadId] = useState(() => `thread-${Date.now()}`);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [contextRanges, setContextRanges] = useState<Array<{start: number, end: number, context: AttachedContext}>>([]);\n const [isMessagesCollapsed, setMessagesCollapsed] = useState(false);\n const [showPRBlock, setShowPRBlock] = useState(false);\n\n const { messages, isStreaming, sendMessage, startedToolIds, completedToolIds, todos } = useChatStream({\n threadId,\n });\n\n const { status: prStatus, isLoading: prLoading, refresh: refreshPRStatus } = usePRStatus();\n const hasChanges = prStatus?.hasChanges ?? false;\n\n // Refresh PR status when streaming completes (AI finished making changes)\n const prevIsStreaming = useRef(isStreaming);\n useEffect(() => {\n if (prevIsStreaming.current && !isStreaming) {\n refreshPRStatus();\n }\n prevIsStreaming.current = isStreaming;\n }, [isStreaming, refreshPRStatus]);\n\n // Add context as a pill (don't insert into textarea)\n useEffect(() => {\n if (attachedContext) {\n // Just add to context ranges without modifying the message text\n setContextRanges(prev => [...prev, {\n start: 0,\n end: 0,\n context: attachedContext\n }]);\n\n // Focus textarea\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n\n // Clear the attached context\n onClearContext();\n }\n }, [attachedContext, onClearContext]);\n\n // Auto-resize textarea\n const handleInput = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const target = e.target;\n setMessage(target.value);\n\n // Reset height to auto to get correct scrollHeight\n target.style.height = \"auto\";\n // Set height to scrollHeight (up to max 200px)\n target.style.height = Math.min(target.scrollHeight, 200) + \"px\";\n }, []);\n\n // Handle send message\n const handleSend = useCallback(async () => {\n if (!message.trim() || isStreaming) return;\n\n const messageText = message;\n\n // Extract component context from the message if it contains @references\n // For now, use the first context range\n const componentContext: ComponentContext | undefined =\n contextRanges.length > 0 && contextRanges[0].context.type === \"component\"\n ? contextRanges[0].context.data\n : undefined;\n\n // Clear input\n setMessage(\"\");\n setContextRanges([]);\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n\n await sendMessage(messageText, componentContext);\n }, [message, isStreaming, contextRanges, sendMessage]);\n\n // Handle keyboard shortcuts\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if ((e.ctrlKey || e.metaKey) && e.key === \"Enter\") {\n e.preventDefault();\n handleSend();\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onToggle();\n }\n }, [handleSend, onToggle]);\n\n // Pass raw messages to MessageList - it handles grouping and filtering\n const commentMessages = messages;\n\n // Count visible task blocks (user message + steps grouped together)\n const visibleCount = useMemo(() => {\n let count = 0;\n let hasUserMessage = false;\n\n for (const msg of commentMessages) {\n // Handle CommentMessage format\n if (\"role\" in msg) {\n if (msg.role === \"user\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n }\n hasUserMessage = true;\n } else if (msg.role === \"assistant\" && !hasUserMessage) {\n // Standalone assistant message\n if (msg.content?.trim()) count++;\n }\n continue;\n }\n\n // Handle ChatMessage format\n const chatMsg = msg as any;\n if (chatMsg.type === \"user\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n }\n hasUserMessage = true;\n } else if (chatMsg.type === \"error\") {\n if (hasUserMessage) {\n count++; // Previous task block complete\n hasUserMessage = false;\n }\n count++; // Error message\n } else if (chatMsg.type === \"assistant\") {\n const content = typeof chatMsg.message === \"string\"\n ? chatMsg.message\n : chatMsg.message?.content?.[0]?.text || \"\";\n\n // Check if standalone assistant message\n const isStatus = content && content.trim().length < 80 &&\n (content.endsWith('.') || content.endsWith('...'));\n\n if (!isStatus && content.trim() && !hasUserMessage) {\n count++; // Standalone assistant message\n }\n }\n }\n\n // Count final task block if exists\n if (hasUserMessage) {\n count++;\n }\n\n return count;\n }, [commentMessages]);\n\n const handlePRCancel = useCallback(() => {\n setShowPRBlock(false);\n }, []);\n\n const prButtonTitle = prLoading\n ? \"Checking for changes...\"\n : hasChanges\n ? `Create PR (${prStatus?.changedFiles.length} files)`\n : \"No changes to commit\";\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n <div className={`chat-panel ai-editor-ui ${theme} ${commentMessages.length === 0 && !showPRBlock ? 'empty' : ''}`}>\n {/* Messages - only show if there are messages or PR block is shown */}\n {(commentMessages.length > 0 || showPRBlock) && (\n <div className={`chat-panel-messages-container ${isMessagesCollapsed ? 'collapsed' : 'expanded'}`}>\n <div className=\"chat-panel-messages-header\">\n <div\n className=\"chat-panel-messages-header-left\"\n onClick={() => setMessagesCollapsed(!isMessagesCollapsed)}\n >\n <span className=\"chat-panel-messages-title\">\n {visibleCount} task{visibleCount !== 1 ? 's' : ''}\n </span>\n <span className=\"chat-panel-messages-toggle\">▼</span>\n </div>\n </div>\n <div className=\"chat-panel-messages\">\n <MessageList\n messages={commentMessages}\n isStreaming={isStreaming}\n startedToolIds={startedToolIds}\n completedToolIds={completedToolIds}\n todos={todos}\n />\n {showPRBlock && (\n <PRBlock onCancel={handlePRCancel} />\n )}\n </div>\n </div>\n )}\n\n {/* Show empty state when no messages and no PR block */}\n {commentMessages.length === 0 && !showPRBlock && (\n <div className=\"chat-panel-empty-content\">\n <MessageList\n messages={[]}\n isStreaming={false}\n startedToolIds={new Set()}\n completedToolIds={new Set()}\n todos={[]}\n />\n </div>\n )}\n\n {/* Input area */}\n <div className=\"chat-panel-input\">\n {/* Context pills above input */}\n {contextRanges.length > 0 && (\n <div className=\"context-pills-container\">\n {contextRanges.map((range, idx) => (\n <div key={idx} className=\"context-pill-inline\">\n <span>{range.context.displayText}</span>\n <button\n className=\"context-pill-remove\"\n onClick={() => {\n // Remove this context range\n setContextRanges(prev => prev.filter((_, i) => i !== idx));\n }}\n title=\"Remove context\"\n >\n ×\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"input-row\">\n <textarea\n ref={textareaRef}\n className=\"message-input\"\n placeholder=\"Ask Claude to edit your code...\"\n value={message}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n disabled={isStreaming}\n rows={1}\n />\n <button\n className=\"send-button\"\n onClick={handleSend}\n disabled={!message.trim() || isStreaming}\n >\n ↑\n </button>\n </div>\n\n {/* Tools below input */}\n <div className=\"chat-panel-toolbar\">\n <div className=\"chat-panel-tools\">\n <button\n className={`tool-button ${activeTool === \"component\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"component\" ? null : \"component\")}\n title=\"Select Component\"\n >\n <FileCode size={16} />\n </button>\n <button\n className={`tool-button ${activeTool === \"area\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"area\" ? null : \"area\")}\n title=\"Select Area\"\n >\n <Box size={16} />\n </button>\n <button\n className={`tool-button ${activeTool === \"text\" ? \"active\" : \"\"}`}\n onClick={() => onToolChange(activeTool === \"text\" ? null : \"text\")}\n title=\"Select Text\"\n >\n <Type size={16} />\n </button>\n <button\n className={`tool-button ${showPRBlock ? \"active\" : \"\"}`}\n onClick={() => setShowPRBlock(!showPRBlock)}\n disabled={!hasChanges || prLoading}\n title={prButtonTitle}\n >\n <GitPullRequest size={16} />\n </button>\n </div>\n <button\n className=\"close-button\"\n onClick={onToggle}\n title=\"Close (Esc)\"\n >\n <X size={16} />\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { Pencil } from \"lucide-react\";\nimport \"./ControlPill.css\";\n\nexport interface ControlPillProps {\n isExpanded: boolean;\n onToggle: () => void;\n activeTool?: \"component\" | \"area\" | \"text\" | null;\n}\n\nexport function ControlPill({\n isExpanded,\n onToggle,\n activeTool,\n}: ControlPillProps) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Ignore if typing in input/textarea\n if (\n e.target instanceof HTMLInputElement ||\n e.target instanceof HTMLTextAreaElement\n ) {\n return;\n }\n\n // Toggle with Space or /\n if (e.key === \" \" || e.key === \"/\") {\n e.preventDefault();\n onToggle();\n }\n\n // Close with Escape\n if (e.key === \"Escape\" && isExpanded) {\n e.preventDefault();\n onToggle();\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [onToggle, isExpanded]);\n\n // Hide pill when expanded - the container becomes the chat window\n if (isExpanded) {\n return null;\n }\n\n return (\n <div className=\"control-pill ai-editor-ui\" onClick={onToggle}>\n <div className=\"control-pill-inner\">\n <Pencil size={16} className=\"pill-icon\" />\n <span className=\"pill-label\">Edit</span>\n {activeTool && (\n <span className=\"active-tool-indicator\" title={`${activeTool} tool active`}>\n {activeTool === \"component\" && \"🎯\"}\n {activeTool === \"area\" && \"⬛\"}\n {activeTool === \"text\" && \"📝\"}\n </span>\n )}\n </div>\n <div className=\"control-pill-hint\">\n Press <kbd>Space</kbd> or <kbd>/</kbd> to toggle\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useRef,\n ReactNode,\n} from \"react\";\nimport type { SourceLocation } from \"../shared/types\";\nimport { getSourceFromElement } from \"./fiber-utils\";\nimport { TaskHistoryPanel } from \"./components/TaskHistoryPanel\";\nimport { ChatPanel } from \"./components/ChatPanel\";\nimport { ControlPill } from \"./components/ControlPill\";\nimport type { AttachedContext, ToolType } from \"./components/ChatPanel\";\nimport { buildServiceUrl } from \"./service-config\";\nimport \"./components/EditorContainer.css\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface ResolvedSourceInfo {\n filePath: string;\n lineNumber: number;\n columnNumber: number;\n}\n\nconst sourceResolutionCache = new Map<string, ResolvedSourceInfo>();\nconst inflightSourceResolutions = new Map<\n string,\n Promise<ResolvedSourceInfo | null>\n>();\n\nfunction inferComponentNameFromPath(filePath: string): string {\n const fileName = filePath.split(\"/\").pop() || \"\";\n const nameWithoutExt = fileName.replace(/\\.(tsx?|jsx?)$/, \"\");\n return nameWithoutExt.charAt(0).toUpperCase() + nameWithoutExt.slice(1);\n}\n\nasync function resolveSourceLocation(\n source: SourceLocation,\n): Promise<SourceLocation | null> {\n if (typeof window === \"undefined\" || process.env.NODE_ENV !== \"development\") {\n return null;\n }\n\n if (!source.debugStack) {\n console.warn(\"No debugStack available for resolution:\", source);\n return null;\n }\n\n const cacheKey = source.debugStack;\n const cached = sourceResolutionCache.get(cacheKey);\n if (cached) {\n const resolved = { ...source, ...cached };\n if (resolved.componentName === \"Unknown\" && resolved.filePath) {\n resolved.componentName = inferComponentNameFromPath(resolved.filePath);\n }\n return resolved;\n }\n\n let inflight = inflightSourceResolutions.get(cacheKey);\n if (!inflight) {\n inflight = fetch(buildServiceUrl(\"api/resolve\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ debugStack: cacheKey }),\n })\n .then(async (res) => {\n if (!res.ok) {\n console.error(`Resolve API error ${res.status}`);\n return null;\n }\n const data = await res.json();\n if (data?.success && data.filePath && data.lineNumber) {\n const resolved: ResolvedSourceInfo = {\n filePath: data.filePath,\n lineNumber: data.lineNumber,\n columnNumber:\n typeof data.columnNumber === \"number\"\n ? data.columnNumber\n : source.columnNumber,\n };\n sourceResolutionCache.set(cacheKey, resolved);\n return resolved;\n }\n return null;\n })\n .catch((err) => {\n console.error(\"Error calling resolve API:\", err);\n return null;\n })\n .finally(() => {\n inflightSourceResolutions.delete(cacheKey);\n });\n\n inflightSourceResolutions.set(cacheKey, inflight);\n }\n\n const resolvedInfo = await inflight;\n if (!resolvedInfo) return null;\n\n const resolved = {\n ...source,\n filePath: resolvedInfo.filePath,\n lineNumber: resolvedInfo.lineNumber,\n columnNumber: resolvedInfo.columnNumber,\n };\n\n if (resolved.componentName === \"Unknown\" && resolved.filePath) {\n resolved.componentName = inferComponentNameFromPath(resolved.filePath);\n }\n\n return resolved;\n}\n\ninterface EditorContextType {\n isEnabled: boolean;\n setEnabled: (enabled: boolean) => void;\n}\n\n// =============================================================================\n// CONTEXT\n// =============================================================================\n\nconst EditorContext = createContext<EditorContextType | null>(null);\n\nexport function useAIEditor() {\n const ctx = useContext(EditorContext);\n if (!ctx) throw new Error(\"useAIEditor must be used within AIEditorProvider\");\n return ctx;\n}\n\n// =============================================================================\n// PROVIDER\n// =============================================================================\n\nexport function AIEditorProvider({\n children,\n theme = \"dark\",\n enabled,\n}: {\n children: ReactNode;\n theme?: \"light\" | \"dark\";\n /**\n * Override the default visibility check. If not provided, the editor\n * visibility is determined by server-side env vars:\n * - NEXT_PUBLIC_AI_EDITOR_ENABLED=true (Next.js)\n * - VITE_AI_EDITOR_ENABLED=true (Vite)\n * - REACT_APP_AI_EDITOR_ENABLED=true (Create React App)\n */\n enabled?: boolean;\n}) {\n // Fetch editor enabled status from server (env vars are checked server-side)\n const [serverEnabled, setServerEnabled] = useState<boolean | null>(null);\n\n useEffect(() => {\n // Skip fetch if enabled prop is explicitly set\n if (enabled !== undefined) return;\n\n fetch(buildServiceUrl(\"api/config\"))\n .then((res) => res.json())\n .then((data) => {\n setServerEnabled(data.enabled === true);\n })\n .catch(() => {\n // If config fetch fails, default to disabled\n setServerEnabled(false);\n });\n }, [enabled]);\n\n // Determine if editor should be shown:\n // 1. If `enabled` prop is explicitly set, use that\n // 2. Otherwise, use server-side config (fetched from buildServiceUrl(\"api/config\"))\n const isEditorEnabled = enabled ?? serverEnabled;\n\n const [isEnabled, setEnabled] = useState(false);\n const [isHistoryOpen, setHistoryOpen] = useState(false);\n\n // Chat panel state\n const [isChatExpanded, setChatExpanded] = useState(false);\n const [activeTool, setActiveTool] = useState<ToolType>(null);\n const [attachedContext, setAttachedContext] =\n useState<AttachedContext | null>(null);\n\n // Chat panel toggle\n const handleChatToggle = useCallback(() => {\n setChatExpanded((prev) => !prev);\n }, []);\n\n // Tool change handler\n const handleToolChange = useCallback((tool: ToolType) => {\n setActiveTool(tool);\n // Clear any existing context when changing tools\n if (tool === null) {\n setAttachedContext(null);\n }\n }, []);\n\n // Clear attached context\n const handleClearContext = useCallback(() => {\n setAttachedContext(null);\n setActiveTool(null);\n }, []);\n\n // Keyboard shortcuts\n useEffect(() => {\n const handleKey = (e: KeyboardEvent) => {\n // Cmd/Ctrl+Shift+E - Toggle editor\n if (\n (e.ctrlKey || e.metaKey) &&\n e.shiftKey &&\n e.key.toLowerCase() === \"e\"\n ) {\n e.preventDefault();\n setEnabled((p) => !p);\n }\n\n // Cmd/Ctrl+Shift+H - Toggle history panel\n if (\n (e.ctrlKey || e.metaKey) &&\n e.shiftKey &&\n e.key.toLowerCase() === \"h\"\n ) {\n e.preventDefault();\n setHistoryOpen((p) => !p);\n }\n\n // Escape - Close history panel\n if (e.key === \"Escape\" && isHistoryOpen) {\n e.preventDefault();\n setHistoryOpen(false);\n }\n };\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }, [isHistoryOpen]);\n\n if (!isEditorEnabled) {\n return <>{children}</>;\n }\n\n return (\n <EditorContext.Provider\n value={{\n isEnabled,\n setEnabled,\n }}\n >\n {children}\n\n {/* Component selection overlay when component tool is active */}\n {activeTool === \"component\" && (\n <EditorOverlay\n theme={theme}\n onComponentSelect={(source, position) => {\n // Attach component context\n const contextData = {\n type: \"component\" as const,\n data: source,\n displayText: `${source.componentName} (${source.filePath}:${source.lineNumber})`,\n };\n setAttachedContext(contextData);\n // Deactivate tool after selection\n setActiveTool(null);\n // Open chat panel if not already open\n if (!isChatExpanded) {\n setChatExpanded(true);\n }\n }}\n />\n )}\n\n {/* Editor Container - unified container for chat and pill */}\n <div\n className={`editor-container ai-editor-ui ${\n isChatExpanded ? \"expanded\" : \"collapsed\"\n } ${theme}`}\n >\n {/* Chat Panel */}\n <ChatPanel\n isExpanded={isChatExpanded}\n onToggle={handleChatToggle}\n activeTool={activeTool}\n onToolChange={handleToolChange}\n attachedContext={attachedContext}\n onClearContext={handleClearContext}\n theme={theme}\n />\n\n {/* Control Pill */}\n <ControlPill\n isExpanded={isChatExpanded}\n onToggle={handleChatToggle}\n activeTool={activeTool}\n />\n </div>\n\n {/* Task History Panel */}\n <TaskHistoryPanel\n isOpen={isHistoryOpen}\n onClose={() => setHistoryOpen(false)}\n tasks={[]}\n />\n </EditorContext.Provider>\n );\n}\n\n// =============================================================================\n// EDITOR OVERLAY - Component Selection\n// =============================================================================\n\ninterface EditorOverlayProps {\n theme: \"light\" | \"dark\";\n onComponentSelect: (\n source: SourceLocation,\n position: { x: number; y: number },\n ) => void;\n}\n\nfunction EditorOverlay({ theme, onComponentSelect }: EditorOverlayProps) {\n const [hoveredSource, setHoveredSource] = useState<SourceLocation | null>(\n null,\n );\n const [hoveredElement, setHoveredElement] = useState<Element | null>(null);\n const [hoveredRect, setHoveredRect] = useState<DOMRect | null>(null);\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 });\n const [isResolvingSource, setIsResolvingSource] = useState(false);\n\n const lastHoverStateRef = useRef<{\n source: SourceLocation;\n element: Element;\n } | null>(null);\n\n useEffect(() => {\n if (hoveredSource && hoveredElement) {\n lastHoverStateRef.current = {\n source: hoveredSource,\n element: hoveredElement,\n };\n }\n }, [hoveredSource, hoveredElement]);\n\n const isDark = theme === \"dark\";\n const c = {\n text: isDark ? \"#e4e4e7\" : \"#18181b\",\n muted: isDark ? \"#71717a\" : \"#a1a1aa\",\n accent: \"#818cf8\",\n bg: isDark ? \"#0d0d14\" : \"#fff\",\n border: isDark ? \"#27273f\" : \"#e4e4e7\",\n success: \"#34d399\",\n };\n\n useEffect(() => {\n let lastEl: Element | null = null;\n let raf: number;\n\n const onMove = (e: MouseEvent) => {\n setMousePos({ x: e.clientX, y: e.clientY });\n\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const el = document.elementFromPoint(e.clientX, e.clientY);\n if (!el || el.closest(\".ai-editor-ui\") || el === lastEl) return;\n lastEl = el;\n\n const source = getSourceFromElement(el);\n if (source) {\n setHoveredElement(el);\n setHoveredRect(el.getBoundingClientRect());\n\n const isCompiledPath =\n source.filePath.includes(\".next/\") ||\n source.filePath.includes(\"/chunks/\") ||\n source.filePath.startsWith(\"file://\") ||\n (source.filePath.endsWith(\".js\") &&\n (source.filePath.includes(\"/server/\") ||\n source.filePath.includes(\"/static/\")));\n\n if (isCompiledPath && source.debugStack) {\n setIsResolvingSource(true);\n resolveSourceLocation(source)\n .then((resolved) => {\n setIsResolvingSource(false);\n setHoveredSource(resolved || source);\n })\n .catch((err) => {\n console.error(\"Error resolving source location:\", err);\n setIsResolvingSource(false);\n setHoveredSource(source);\n });\n } else {\n setIsResolvingSource(false);\n setHoveredSource(source);\n }\n } else {\n setHoveredSource(null);\n setHoveredElement(null);\n setHoveredRect(null);\n setIsResolvingSource(false);\n }\n });\n };\n\n const onClick = async (e: MouseEvent) => {\n if ((e.target as Element).closest(\".ai-editor-ui\")) {\n return;\n }\n\n // Get fresh source from the clicked element\n const el = e.target as Element;\n const source = getSourceFromElement(el);\n\n if (source) {\n e.preventDefault();\n e.stopPropagation();\n\n // If it's a compiled path, resolve it first\n const isCompiledPath =\n source.filePath.includes(\".next/\") ||\n source.filePath.includes(\"/chunks/\") ||\n source.filePath.startsWith(\"file://\") ||\n (source.filePath.endsWith(\".js\") &&\n (source.filePath.includes(\"/server/\") ||\n source.filePath.includes(\"/static/\")));\n\n if (isCompiledPath && source.debugStack) {\n const resolved = await resolveSourceLocation(source);\n onComponentSelect(resolved || source, { x: e.clientX, y: e.clientY });\n } else {\n onComponentSelect(source, { x: e.clientX, y: e.clientY });\n }\n }\n };\n\n document.addEventListener(\"mousemove\", onMove, { passive: true });\n document.addEventListener(\"click\", onClick, true);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"click\", onClick, true);\n cancelAnimationFrame(raf);\n };\n }, [onComponentSelect]);\n\n return (\n <div\n className=\"ai-editor-ui\"\n style={{ fontFamily: \"system-ui, sans-serif\" }}\n >\n {/* Highlight */}\n {hoveredRect && (\n <div\n style={{\n position: \"fixed\",\n left: hoveredRect.left - 2,\n top: hoveredRect.top - 2,\n width: hoveredRect.width + 4,\n height: hoveredRect.height + 4,\n border: `2px solid ${c.accent}`,\n borderRadius: 6,\n background: `${c.accent}15`,\n pointerEvents: \"none\",\n zIndex: 99998,\n }}\n />\n )}\n\n {/* Tooltip */}\n {hoveredSource && !isResolvingSource && (\n <div\n style={{\n position: \"fixed\",\n left: Math.min(mousePos.x + 14, window.innerWidth - 340),\n top: mousePos.y + 14,\n background: c.bg,\n color: c.text,\n border: `1px solid ${c.border}`,\n borderRadius: 10,\n padding: \"12px 16px\",\n fontSize: 12,\n fontFamily: \"ui-monospace, monospace\",\n zIndex: 99999,\n boxShadow: `0 8px 30px rgba(0,0,0,${isDark ? 0.5 : 0.15})`,\n maxWidth: 320,\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n fontWeight: 700,\n color: c.accent,\n marginBottom: 4,\n fontSize: 14,\n }}\n >\n &lt;{hoveredSource.componentName} /&gt;\n </div>\n <div style={{ color: c.muted, fontSize: 11 }}>\n {hoveredSource.filePath}:{hoveredSource.lineNumber}\n </div>\n {hoveredSource.elementContext?.textContent && (\n <div\n style={{\n color: c.muted,\n fontSize: 10,\n marginTop: 4,\n fontStyle: \"italic\",\n }}\n >\n \"{hoveredSource.elementContext.textContent}\"\n </div>\n )}\n </div>\n )}\n\n {/* Badge */}\n <div\n style={{\n position: \"fixed\",\n bottom: 20,\n right: 20,\n background: c.bg,\n color: c.success,\n padding: \"10px 16px\",\n borderRadius: 20,\n fontSize: 13,\n fontWeight: 600,\n zIndex: 99997,\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n border: `1px solid ${c.border}`,\n boxShadow: `0 4px 20px rgba(0,0,0,${isDark ? 0.4 : 0.1})`,\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: c.success,\n }}\n />\n Select Component\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { Sparkles, GitPullRequest, Check, Loader2, FileText, GitBranch } from \"lucide-react\";\nimport { usePRStatus } from \"../hooks/usePRStatus\";\nimport { useCreatePR, CreatePRResult } from \"../hooks/useCreatePR\";\nimport \"./PRView.css\";\n\nexport interface PRViewProps {\n onClose: () => void;\n onSuccess?: (result: CreatePRResult) => void;\n}\n\nexport function PRView({ onClose, onSuccess }: PRViewProps) {\n const [title, setTitle] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<CreatePRResult | null>(null);\n const hasGenerated = useRef(false);\n\n const { status } = usePRStatus();\n const { createPR, generateContent, isCreating, isGenerating } = useCreatePR();\n\n // Auto-generate on mount\n useEffect(() => {\n if (!hasGenerated.current && !isGenerating) {\n hasGenerated.current = true;\n generateContent().then((content) => {\n setTitle(content.title);\n setDescription(content.description);\n });\n }\n }, [isGenerating, generateContent]);\n\n // Auto-return to chat after success\n useEffect(() => {\n if (result?.success) {\n const timer = setTimeout(() => {\n onClose();\n }, 2000);\n return () => clearTimeout(timer);\n }\n }, [result?.success, onClose]);\n\n const handleRegenerate = useCallback(async () => {\n setError(null);\n const content = await generateContent();\n setTitle(content.title);\n setDescription(content.description);\n }, [generateContent]);\n\n const handleSubmit = useCallback(async () => {\n if (!title.trim()) {\n setError(\"Title is required\");\n return;\n }\n\n setError(null);\n const prResult = await createPR({ title: title.trim(), description });\n\n if (prResult.success) {\n setResult(prResult);\n onSuccess?.(prResult);\n } else {\n setError(prResult.error || \"Failed to create PR\");\n }\n }, [title, description, createPR, onSuccess]);\n\n // Success state\n if (result?.success) {\n return (\n <div className=\"pr-view\">\n <div className=\"pr-view-success\">\n <div className=\"pr-view-success-icon\">\n <Check size={32} />\n </div>\n <h3>PR Created!</h3>\n <p>\n <a href={result.prUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n #{result.prNumber}\n </a>\n {\" \"}on <code>{result.branchName}</code>\n </p>\n </div>\n </div>\n );\n }\n\n // Loading state\n if (isGenerating && !title) {\n return (\n <div className=\"pr-view\">\n <div className=\"pr-view-loading\">\n <Loader2 size={24} className=\"pr-view-spinner\" />\n <p>Generating PR details...</p>\n </div>\n </div>\n );\n }\n\n // Form state\n return (\n <div className=\"pr-view\">\n <div className=\"pr-view-content\">\n {error && <div className=\"pr-view-error\">{error}</div>}\n\n <div className=\"pr-view-field\">\n <label htmlFor=\"pr-title\">Title</label>\n <input\n id=\"pr-title\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"PR title...\"\n disabled={isCreating || isGenerating}\n />\n </div>\n\n <div className=\"pr-view-field\">\n <div className=\"pr-view-field-header\">\n <label htmlFor=\"pr-description\">Description</label>\n <button\n className=\"pr-view-regenerate\"\n onClick={handleRegenerate}\n disabled={isGenerating || isCreating}\n >\n {isGenerating ? (\n <Loader2 size={12} className=\"pr-view-spinner\" />\n ) : (\n <Sparkles size={12} />\n )}\n Regenerate\n </button>\n </div>\n <textarea\n id=\"pr-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe your changes...\"\n disabled={isCreating || isGenerating}\n />\n </div>\n\n {status && (\n <div className=\"pr-view-info\">\n <span>\n <FileText size={12} />\n {status.changedFiles.length} files\n </span>\n <span>\n <GitBranch size={12} />\n {status.baseBranch}\n </span>\n </div>\n )}\n </div>\n\n <div className=\"pr-view-footer\">\n <button\n className=\"pr-view-btn pr-view-btn-secondary\"\n onClick={onClose}\n disabled={isCreating}\n >\n Cancel\n </button>\n <button\n className=\"pr-view-btn pr-view-btn-primary\"\n onClick={handleSubmit}\n disabled={isCreating || !title.trim()}\n >\n {isCreating ? (\n <>\n <Loader2 size={14} className=\"pr-view-spinner\" />\n Creating...\n </>\n ) : (\n <>\n <GitPullRequest size={14} />\n Create PR\n </>\n )}\n </button>\n </div>\n </div>\n );\n}\n"],"names":["current","iterations","jsxs","jsx","useState","useEffect","_a","useRef","useMemo","useCallback","_b","flushSync","forwardRef","createElement","__iconNode","Loader2","Fragment","resolved","createContext"],"mappings":"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","x_google_ignoreList":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]}