next-ai-editor 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AIEditorProvider-IjMydA1Y.cjs → AIEditorProvider-CLgf1Vwa.cjs} +185 -153
- package/dist/{AIEditorProvider-IjMydA1Y.cjs.map → AIEditorProvider-CLgf1Vwa.cjs.map} +1 -1
- package/dist/{AIEditorProvider-633ZBZul.js → AIEditorProvider-DWId5Qmv.js} +185 -153
- package/dist/{AIEditorProvider-633ZBZul.js.map → AIEditorProvider-DWId5Qmv.js.map} +1 -1
- package/dist/client/AIEditorProvider.d.ts +9 -1
- package/dist/client/AIEditorProvider.d.ts.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.js +1 -1
- package/dist/{comments-Daur80r4.cjs → comments-2HX-AAwu.cjs} +545 -1051
- package/dist/comments-2HX-AAwu.cjs.map +1 -0
- package/dist/{comments-D3m0RsOO.js → comments-BYFEhf6K.js} +563 -1069
- package/dist/comments-BYFEhf6K.js.map +1 -0
- package/dist/index.cjs +2 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +20 -22
- package/dist/next-ai-editor.css +1 -2
- package/dist/server/handlers/config.d.ts +7 -0
- package/dist/server/handlers/config.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +0 -2
- package/dist/server/handlers/index.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server.cjs +1 -3
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +19 -21
- package/package.json +2 -5
- package/dist/comments-D3m0RsOO.js.map +0 -1
- package/dist/comments-Daur80r4.cjs.map +0 -1
- package/dist/server/handlers/edit.d.ts +0 -3
- package/dist/server/handlers/edit.d.ts.map +0 -1
- package/dist/server/handlers/suggestions.d.ts +0 -3
- package/dist/server/handlers/suggestions.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AIEditorProvider-IjMydA1Y.cjs","sources":["../src/client/fiber-utils.ts","../src/client/components/TaskHistoryPanel.tsx","../src/client/components/MessageItem.tsx","../src/client/components/MessageList.tsx","../src/client/hooks/useChatStream.ts","../src/client/components/ChatPanel.tsx","../src/client/components/ControlPill.tsx","../src/client/AIEditorProvider.tsx"],"sourcesContent":["// =============================================================================\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 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\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]}>{commentMsg.content}</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]}>{commentMsg.content}</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]}>{chatMsg.message}</ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render assistant message\n if (chatMsg.type === \"assistant\") {\n const content = chatMsg.message?.content?.[0]?.text || \"\";\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 tool use message - show as compact action indicator\n if (chatMsg.type === \"tool_use\") {\n // Map tool names to icons and descriptions\n const toolInfo: Record<string, { icon: string; description: string }> = {\n read_file: { icon: \"📖\", description: \"Reading code\" },\n write_file: { icon: \"✏️\", description: \"Writing changes\" },\n edit_file: { icon: \"✨\", description: \"Editing code\" },\n search_files: { icon: \"🔍\", description: \"Searching files\" },\n list_files: { icon: \"📁\", description: \"Listing files\" },\n run_command: { icon: \"⚙️\", description: \"Running command\" },\n };\n\n const info = toolInfo[chatMsg.tool] || { icon: \"🔧\", description: \"Working\" };\n\n return (\n <div className=\"message message-tool\">\n <span className=\"tool-icon\">{info.icon}</span>\n <span className=\"tool-name\">{info.description}</span>\n <span className=\"tool-description\">• {chatMsg.tool}</span>\n </div>\n );\n }\n\n // Render tool result message\n if (chatMsg.type === \"tool_result\") {\n return (\n <div className=\"message message-tool-result\">\n <div className=\"message-avatar\">✓</div>\n <div className=\"message-content\">\n <div className=\"tool-result\">\n <strong>Tool result:</strong> {chatMsg.tool}\n <details className=\"tool-details\">\n <summary>View output</summary>\n <pre>{typeof chatMsg.output === \"string\" ? chatMsg.output : JSON.stringify(chatMsg.output, null, 2)}</pre>\n </details>\n </div>\n </div>\n </div>\n );\n }\n\n // Render result/success message\n if (chatMsg.type === \"result\") {\n return (\n <div className=\"message message-result\">\n <div className=\"message-content\">\n <div className=\"result-header\">\n <span className=\"result-icon\">✓</span>\n <span className=\"result-label\">Changes Applied</span>\n </div>\n {chatMsg.result && (\n <div className=\"result-description\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{chatMsg.result}</ReactMarkdown>\n </div>\n )}\n {chatMsg.total_cost_usd && (\n <div className=\"result-cost\">\n Cost: ${chatMsg.total_cost_usd.toFixed(4)}\n </div>\n )}\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-avatar\">❌</div>\n <div className=\"message-content\">\n <strong>Error:</strong> {chatMsg.error}\n </div>\n </div>\n );\n }\n\n // Render done message (subtle indicator)\n if (chatMsg.type === \"done\") {\n return (\n <div className=\"message message-done\">\n <div className=\"message-separator\"></div>\n </div>\n );\n }\n\n // Unknown message type - render as JSON for debugging\n const unknownMessage = message as any;\n return (\n <div className=\"message message-unknown\">\n <div className=\"message-avatar\">?</div>\n <div className=\"message-content\">\n <details className=\"tool-details\">\n <summary>Unknown message type: {unknownMessage.type || \"unknown\"}</summary>\n <pre>{JSON.stringify(message, null, 2)}</pre>\n </details>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef } from \"react\";\nimport { MessageItem } from \"./MessageItem\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\n\nexport interface MessageListProps {\n messages: CommentMessage[];\n isStreaming?: boolean;\n}\n\nexport function MessageList({ messages, isStreaming }: MessageListProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\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 (\n <div className=\"message-list-empty\">\n <div className=\"empty-state\">\n <div className=\"empty-icon\">💬</div>\n <h3>Start a conversation</h3>\n <p>\n Ask Claude to help you edit components, add features, or refactor code.\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className=\"message-list\">\n {messages.map((message, index) => (\n <MessageItem key={index} message={message} />\n ))}\n {isStreaming && (\n <div className=\"message message-streaming\">\n <div className=\"message-avatar\">⋯</div>\n <div className=\"message-content\">\n <div className=\"streaming-indicator\">\n <span className=\"dot\"></span>\n <span className=\"dot\"></span>\n <span className=\"dot\"></span>\n </div>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport type { ComponentContext } from \"../../server/agent/sdk-client\";\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: \"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 eventSourceRef = useRef<EventSource | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\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\n */\n const sendMessage = useCallback(\n async (message: string, componentContext?: ComponentContext) => {\n // Close existing connection\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n\n // Abort existing request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n abortControllerRef.current = new AbortController();\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 // Use fetch with ReadableStream for SSE\n const response = await fetch(\"/api/ai-editor/chat\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n threadId,\n sessionId: state.sessionId,\n message,\n componentContext,\n }),\n signal: abortControllerRef.current.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n\n if (!reader) {\n throw new Error(\"No response body\");\n }\n\n // Track accumulated assistant content\n let currentAssistantMessage: ChatMessage | null = null;\n\n // Process the stream\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6); // Remove \"data: \" prefix\n const event = parseEventData(data);\n\n if (event) {\n // Handle assistant messages - accumulate into single message\n if (event.type === \"assistant\") {\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 = event.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 = event;\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n }\n onMessage?.(event);\n continue;\n }\n\n // Reset assistant accumulation for any non-assistant event\n currentAssistantMessage = null;\n\n // Filter out tool_result and user echoes from server\n // (user messages are already shown client-side before sending)\n // But keep tool_use to show what actions AI is taking\n if (event.type === \"tool_result\" || event.type === \"user\") {\n // Silently skip - tool results and user echoes are not needed in UI\n continue;\n }\n\n // Add tool_use messages to show AI actions\n if (event.type === \"tool_use\") {\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n onMessage?.(event);\n continue;\n }\n\n // Handle result messages - check for duplication\n if (event.type === \"result\") {\n setState((prev) => {\n // Check if last assistant message has same content\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 = event.result || \"\";\n\n // If result is similar to last assistant text, skip it\n if (lastText.includes(resultText) || resultText.includes(lastText)) {\n return prev;\n }\n }\n return {\n ...prev,\n messages: [...prev.messages, event],\n };\n });\n onMessage?.(event);\n continue;\n }\n\n // Handle connected event\n if (event.type === \"connected\") {\n setState((prev) => ({\n ...prev,\n sessionId: event.sessionId,\n isConnected: true,\n }));\n continue;\n }\n\n // Handle done event\n if (event.type === \"done\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n messages: [...prev.messages, event],\n }));\n onDone?.();\n continue;\n }\n\n // Handle error event\n if (event.type === \"error\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: event.error,\n messages: [...prev.messages, event],\n }));\n onError?.(event.error);\n continue;\n }\n\n // All other events - add to messages\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n onMessage?.(event);\n }\n }\n }\n }\n } catch (error: any) {\n if (error.name === \"AbortError\") {\n // Request was aborted, ignore\n return;\n }\n\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 * Clear messages\n */\n const clearMessages = useCallback(() => {\n setState((prev) => ({\n ...prev,\n messages: [],\n }));\n }, []);\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n }\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return {\n ...state,\n sendMessage,\n clearMessages,\n };\n}\n","\"use client\";\n\nimport React, { useState, useCallback, useRef, useEffect } from \"react\";\nimport { MessageList } from \"./MessageList\";\nimport { useChatStream } from \"../hooks/useChatStream\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { ComponentContext } from \"../../server/agent/sdk-client\";\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 } = 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 // Convert ChatMessage[] to CommentMessage[] format for MessageList\n const commentMessages = messages\n .filter((msg): msg is ChatMessage =>\n msg.type === \"user\" ||\n msg.type === \"assistant\" ||\n msg.type === \"tool_use\" ||\n msg.type === \"tool_result\"\n )\n .map((msg) => {\n if (msg.type === \"user\") {\n return { role: \"user\" as const, content: msg.message };\n }\n if (msg.type === \"assistant\") {\n const content = typeof msg.message === \"string\"\n ? msg.message\n : msg.message?.content?.[0]?.text || \"\";\n return { role: \"assistant\" as const, content };\n }\n // Pass through tool messages as-is for MessageItem to handle\n return msg as any;\n });\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n <div className={`chat-panel ai-editor-ui ${theme}`}>\n {/* Messages - only show if there are messages */}\n {commentMessages.length > 0 && (\n <div className={`chat-panel-messages-container ${isMessagesCollapsed ? 'collapsed' : 'expanded'}`}>\n <div\n className=\"chat-panel-messages-header\"\n onClick={() => setMessagesCollapsed(!isMessagesCollapsed)}\n >\n <span className=\"chat-panel-messages-title\">\n {commentMessages.length} message{commentMessages.length !== 1 ? 's' : ''}\n </span>\n <span className=\"chat-panel-messages-toggle\">▼</span>\n </div>\n <div className=\"chat-panel-messages\">\n <MessageList messages={commentMessages} isStreaming={isStreaming} />\n </div>\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 type { TaskHistoryItem } from \"../shared/comment-types\";\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(\"/api/ai-editor/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: 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}: {\n children: ReactNode;\n theme?: \"light\" | \"dark\";\n}) {\n const [isEnabled, setEnabled] = useState(false);\n const [isHistoryOpen, setHistoryOpen] = useState(false);\n const [taskHistory, setTaskHistory] = useState<TaskHistoryItem[]>([]);\n\n // Chat panel state\n const [isChatExpanded, setChatExpanded] = useState(false);\n const [activeTool, setActiveTool] = useState<ToolType>(null);\n const [attachedContext, setAttachedContext] = useState<AttachedContext | null>(null);\n\n // Task update handler\n const handleTaskUpdate = useCallback((taskUpdate: Partial<TaskHistoryItem> & { id: string }) => {\n setTaskHistory((prev) => {\n const existing = prev.find((t) => t.id === taskUpdate.id);\n if (existing) {\n // Update existing task\n return prev.map((t) =>\n t.id === taskUpdate.id ? { ...t, ...taskUpdate } : t\n );\n } else {\n // Add new task\n return [...prev, taskUpdate as TaskHistoryItem];\n }\n });\n }, []);\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\n if (process.env.NODE_ENV !== \"development\") {\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 className={`editor-container ai-editor-ui ${isChatExpanded ? 'expanded' : 'collapsed'} ${theme}`}>\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={taskHistory}\n />\n </EditorContext.Provider>\n );\n}\n\n// =============================================================================\n// EDITOR OVERLAY - Component Selection\n// =============================================================================\n\ninterface EditorOverlayProps {\n theme: \"light\" | \"dark\";\n onComponentSelect: (source: SourceLocation, position: { x: number; y: number }) => void;\n}\n\nfunction EditorOverlay({ theme, onComponentSelect }: EditorOverlayProps) {\n const [hoveredSource, setHoveredSource] = useState<SourceLocation | null>(null);\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<{ source: SourceLocation; element: Element } | null>(null);\n\n useEffect(() => {\n if (hoveredSource && hoveredElement) {\n lastHoverStateRef.current = { source: hoveredSource, element: hoveredElement };\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 className=\"ai-editor-ui\" style={{ fontFamily: \"system-ui, sans-serif\" }}>\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 <{hoveredSource.componentName} />\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":["cleanPath","shouldSkipPath","current","iterations","jsxs","jsx","useRef","useEffect","useState","useCallback","_a","FileCode","Box","Type","X","Pencil","resolved","createContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AIEditorProvider-CLgf1Vwa.cjs","sources":["../src/client/fiber-utils.ts","../src/client/components/TaskHistoryPanel.tsx","../src/client/components/MessageItem.tsx","../src/client/components/MessageList.tsx","../src/client/hooks/useChatStream.ts","../src/client/components/ChatPanel.tsx","../src/client/components/ControlPill.tsx","../src/client/AIEditorProvider.tsx"],"sourcesContent":["// =============================================================================\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 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\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]}>{commentMsg.content}</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]}>{commentMsg.content}</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]}>{chatMsg.message}</ReactMarkdown>\n </div>\n </div>\n );\n }\n\n // Render assistant message\n if (chatMsg.type === \"assistant\") {\n const content = chatMsg.message?.content?.[0]?.text || \"\";\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 tool use message - show as compact action indicator\n if (chatMsg.type === \"tool_use\") {\n // Map tool names to icons and descriptions\n const toolInfo: Record<string, { icon: string; description: string }> = {\n read_file: { icon: \"📖\", description: \"Reading code\" },\n write_file: { icon: \"✏️\", description: \"Writing changes\" },\n edit_file: { icon: \"✨\", description: \"Editing code\" },\n search_files: { icon: \"🔍\", description: \"Searching files\" },\n list_files: { icon: \"📁\", description: \"Listing files\" },\n run_command: { icon: \"⚙️\", description: \"Running command\" },\n };\n\n const info = toolInfo[chatMsg.tool] || { icon: \"🔧\", description: \"Working\" };\n\n return (\n <div className=\"message message-tool\">\n <span className=\"tool-icon\">{info.icon}</span>\n <span className=\"tool-name\">{info.description}</span>\n <span className=\"tool-description\">• {chatMsg.tool}</span>\n </div>\n );\n }\n\n // Render tool result message\n if (chatMsg.type === \"tool_result\") {\n return (\n <div className=\"message message-tool-result\">\n <div className=\"message-avatar\">✓</div>\n <div className=\"message-content\">\n <div className=\"tool-result\">\n <strong>Tool result:</strong> {chatMsg.tool}\n <details className=\"tool-details\">\n <summary>View output</summary>\n <pre>{typeof chatMsg.output === \"string\" ? chatMsg.output : JSON.stringify(chatMsg.output, null, 2)}</pre>\n </details>\n </div>\n </div>\n </div>\n );\n }\n\n // Render result/success message\n if (chatMsg.type === \"result\") {\n return (\n <div className=\"message message-result\">\n <div className=\"message-content\">\n <div className=\"result-header\">\n <span className=\"result-icon\">✓</span>\n <span className=\"result-label\">Changes Applied</span>\n </div>\n {chatMsg.result && (\n <div className=\"result-description\">\n <ReactMarkdown remarkPlugins={[remarkGfm]}>{chatMsg.result}</ReactMarkdown>\n </div>\n )}\n {chatMsg.total_cost_usd && (\n <div className=\"result-cost\">\n Cost: ${chatMsg.total_cost_usd.toFixed(4)}\n </div>\n )}\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-avatar\">❌</div>\n <div className=\"message-content\">\n <strong>Error:</strong> {chatMsg.error}\n </div>\n </div>\n );\n }\n\n // Render done message (subtle indicator)\n if (chatMsg.type === \"done\") {\n return (\n <div className=\"message message-done\">\n <div className=\"message-separator\"></div>\n </div>\n );\n }\n\n // Unknown message type - render as JSON for debugging\n const unknownMessage = message as any;\n return (\n <div className=\"message message-unknown\">\n <div className=\"message-avatar\">?</div>\n <div className=\"message-content\">\n <details className=\"tool-details\">\n <summary>Unknown message type: {unknownMessage.type || \"unknown\"}</summary>\n <pre>{JSON.stringify(message, null, 2)}</pre>\n </details>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef } from \"react\";\nimport { MessageItem } from \"./MessageItem\";\nimport type { CommentMessage } from \"../../shared/comment-types\";\n\nexport interface MessageListProps {\n messages: CommentMessage[];\n isStreaming?: boolean;\n}\n\nexport function MessageList({ messages, isStreaming }: MessageListProps) {\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\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 (\n <div className=\"message-list-empty\">\n <div className=\"empty-state\">\n <div className=\"empty-icon\">💬</div>\n <h3>Start a conversation</h3>\n <p>\n Ask Claude to help you edit components, add features, or refactor code.\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className=\"message-list\">\n {messages.map((message, index) => (\n <MessageItem key={index} message={message} />\n ))}\n {isStreaming && (\n <div className=\"message message-streaming\">\n <div className=\"message-avatar\">⋯</div>\n <div className=\"message-content\">\n <div className=\"streaming-indicator\">\n <span className=\"dot\"></span>\n <span className=\"dot\"></span>\n <span className=\"dot\"></span>\n </div>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\nimport type { ComponentContext } from \"../../server/agent/sdk-client\";\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: \"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 eventSourceRef = useRef<EventSource | null>(null);\n const abortControllerRef = useRef<AbortController | null>(null);\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\n */\n const sendMessage = useCallback(\n async (message: string, componentContext?: ComponentContext) => {\n // Close existing connection\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n\n // Abort existing request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n abortControllerRef.current = new AbortController();\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 // Use fetch with ReadableStream for SSE\n const response = await fetch(\"/api/ai-editor/chat\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n threadId,\n sessionId: state.sessionId,\n message,\n componentContext,\n }),\n signal: abortControllerRef.current.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n\n if (!reader) {\n throw new Error(\"No response body\");\n }\n\n // Track accumulated assistant content\n let currentAssistantMessage: ChatMessage | null = null;\n\n // Process the stream\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6); // Remove \"data: \" prefix\n const event = parseEventData(data);\n\n if (event) {\n // Handle assistant messages - accumulate into single message\n if (event.type === \"assistant\") {\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 = event.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 = event;\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n }\n onMessage?.(event);\n continue;\n }\n\n // Reset assistant accumulation for any non-assistant event\n currentAssistantMessage = null;\n\n // Filter out tool_result and user echoes from server\n // (user messages are already shown client-side before sending)\n // But keep tool_use to show what actions AI is taking\n if (event.type === \"tool_result\" || event.type === \"user\") {\n // Silently skip - tool results and user echoes are not needed in UI\n continue;\n }\n\n // Add tool_use messages to show AI actions\n if (event.type === \"tool_use\") {\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n onMessage?.(event);\n continue;\n }\n\n // Handle result messages - check for duplication\n if (event.type === \"result\") {\n setState((prev) => {\n // Check if last assistant message has same content\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 = event.result || \"\";\n\n // If result is similar to last assistant text, skip it\n if (lastText.includes(resultText) || resultText.includes(lastText)) {\n return prev;\n }\n }\n return {\n ...prev,\n messages: [...prev.messages, event],\n };\n });\n onMessage?.(event);\n continue;\n }\n\n // Handle connected event\n if (event.type === \"connected\") {\n setState((prev) => ({\n ...prev,\n sessionId: event.sessionId,\n isConnected: true,\n }));\n continue;\n }\n\n // Handle done event\n if (event.type === \"done\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n messages: [...prev.messages, event],\n }));\n onDone?.();\n continue;\n }\n\n // Handle error event\n if (event.type === \"error\") {\n setState((prev) => ({\n ...prev,\n isStreaming: false,\n error: event.error,\n messages: [...prev.messages, event],\n }));\n onError?.(event.error);\n continue;\n }\n\n // All other events - add to messages\n setState((prev) => ({\n ...prev,\n messages: [...prev.messages, event],\n }));\n onMessage?.(event);\n }\n }\n }\n }\n } catch (error: any) {\n if (error.name === \"AbortError\") {\n // Request was aborted, ignore\n return;\n }\n\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 * Clear messages\n */\n const clearMessages = useCallback(() => {\n setState((prev) => ({\n ...prev,\n messages: [],\n }));\n }, []);\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n }\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n return {\n ...state,\n sendMessage,\n clearMessages,\n };\n}\n","\"use client\";\n\nimport React, { useState, useCallback, useRef, useEffect } from \"react\";\nimport { MessageList } from \"./MessageList\";\nimport { useChatStream } from \"../hooks/useChatStream\";\nimport type { ChatMessage } from \"../hooks/useChatStream\";\nimport type { ComponentContext } from \"../../server/agent/sdk-client\";\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 } = 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 // Convert ChatMessage[] to CommentMessage[] format for MessageList\n const commentMessages = messages\n .filter((msg): msg is ChatMessage =>\n msg.type === \"user\" ||\n msg.type === \"assistant\" ||\n msg.type === \"tool_use\" ||\n msg.type === \"tool_result\"\n )\n .map((msg) => {\n if (msg.type === \"user\") {\n return { role: \"user\" as const, content: msg.message };\n }\n if (msg.type === \"assistant\") {\n const content = typeof msg.message === \"string\"\n ? msg.message\n : msg.message?.content?.[0]?.text || \"\";\n return { role: \"assistant\" as const, content };\n }\n // Pass through tool messages as-is for MessageItem to handle\n return msg as any;\n });\n\n if (!isExpanded) {\n return null;\n }\n\n return (\n <div className={`chat-panel ai-editor-ui ${theme}`}>\n {/* Messages - only show if there are messages */}\n {commentMessages.length > 0 && (\n <div className={`chat-panel-messages-container ${isMessagesCollapsed ? 'collapsed' : 'expanded'}`}>\n <div\n className=\"chat-panel-messages-header\"\n onClick={() => setMessagesCollapsed(!isMessagesCollapsed)}\n >\n <span className=\"chat-panel-messages-title\">\n {commentMessages.length} message{commentMessages.length !== 1 ? 's' : ''}\n </span>\n <span className=\"chat-panel-messages-toggle\">▼</span>\n </div>\n <div className=\"chat-panel-messages\">\n <MessageList messages={commentMessages} isStreaming={isStreaming} />\n </div>\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 type { TaskHistoryItem } from \"../shared/comment-types\";\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(\"/api/ai-editor/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(\"/api/ai-editor/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 /api/ai-editor/config)\n const isEditorEnabled = enabled ?? serverEnabled;\n\n const [isEnabled, setEnabled] = useState(false);\n const [isHistoryOpen, setHistoryOpen] = useState(false);\n const [taskHistory, setTaskHistory] = useState<TaskHistoryItem[]>([]);\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 // Task update handler\n const handleTaskUpdate = useCallback(\n (taskUpdate: Partial<TaskHistoryItem> & { id: string }) => {\n setTaskHistory((prev) => {\n const existing = prev.find((t) => t.id === taskUpdate.id);\n if (existing) {\n // Update existing task\n return prev.map((t) =>\n t.id === taskUpdate.id ? { ...t, ...taskUpdate } : t,\n );\n } else {\n // Add new task\n return [...prev, taskUpdate as TaskHistoryItem];\n }\n });\n },\n [],\n );\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={taskHistory}\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 <{hoveredSource.componentName} />\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":["cleanPath","shouldSkipPath","current","iterations","jsxs","jsx","useRef","useEffect","useState","useCallback","_a","FileCode","Box","Type","X","Pencil","resolved","createContext"],"mappings":"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"}
|