next-ai-editor 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AIEditorProvider-CKA2K_g2.js +1428 -0
- package/dist/AIEditorProvider-CKA2K_g2.js.map +1 -0
- package/dist/AIEditorProvider-C_zRSAuV.cjs +1427 -0
- package/dist/AIEditorProvider-C_zRSAuV.cjs.map +1 -0
- package/dist/client/AIEditorProvider.d.ts +1 -33
- package/dist/client/AIEditorProvider.d.ts.map +1 -1
- package/dist/client/components/ChatPanel.d.ts +18 -0
- package/dist/client/components/ChatPanel.d.ts.map +1 -0
- package/dist/client/components/ControlPill.d.ts +8 -0
- package/dist/client/components/ControlPill.d.ts.map +1 -0
- package/dist/client/components/MessageItem.d.ts +7 -0
- package/dist/client/components/MessageItem.d.ts.map +1 -0
- package/dist/client/components/MessageList.d.ts +7 -0
- package/dist/client/components/MessageList.d.ts.map +1 -0
- package/dist/client/components/TaskHistoryPanel.d.ts +10 -0
- package/dist/client/components/TaskHistoryPanel.d.ts.map +1 -0
- package/dist/client/components/index.d.ts +11 -0
- package/dist/client/components/index.d.ts.map +1 -0
- package/dist/client/hooks/index.d.ts +3 -0
- package/dist/client/hooks/index.d.ts.map +1 -0
- package/dist/client/hooks/useChatStream.d.ts +66 -0
- package/dist/client/hooks/useChatStream.d.ts.map +1 -0
- package/dist/client/hooks/useHotReload.d.ts +10 -0
- package/dist/client/hooks/useHotReload.d.ts.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client.cjs +7 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +8 -2
- package/dist/client.js.map +1 -1
- package/dist/{index-3OMXRwpD.js → comments-D3m0RsOO.js} +505 -26
- package/dist/comments-D3m0RsOO.js.map +1 -0
- package/dist/{index-9QODCOgD.cjs → comments-Daur80r4.cjs} +492 -13
- package/dist/comments-Daur80r4.cjs.map +1 -0
- package/dist/index.cjs +34 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -14
- package/dist/index.js.map +1 -1
- package/dist/next-ai-editor.css +880 -0
- package/dist/server/agent/sdk-client.d.ts +54 -0
- package/dist/server/agent/sdk-client.d.ts.map +1 -0
- package/dist/server/agent/session-store.d.ts +101 -0
- package/dist/server/agent/session-store.d.ts.map +1 -0
- package/dist/server/handlers/chat.d.ts +6 -0
- package/dist/server/handlers/chat.d.ts.map +1 -0
- package/dist/server/handlers/comments.d.ts +10 -0
- package/dist/server/handlers/comments.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +2 -1
- package/dist/server/handlers/index.d.ts.map +1 -1
- package/dist/server/handlers/read.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/utils/ast.d.ts.map +1 -1
- package/dist/server/utils/source-map.d.ts +5 -0
- package/dist/server/utils/source-map.d.ts.map +1 -1
- package/dist/server.cjs +27 -25
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +14 -12
- package/dist/shared/comment-types.d.ts +140 -0
- package/dist/shared/comment-types.d.ts.map +1 -0
- package/package.json +13 -4
- package/dist/AIEditorProvider-CFFnEtEB.js +0 -2170
- package/dist/AIEditorProvider-CFFnEtEB.js.map +0 -1
- package/dist/AIEditorProvider-CmiACRfw.cjs +0 -2169
- package/dist/AIEditorProvider-CmiACRfw.cjs.map +0 -1
- package/dist/index-3OMXRwpD.js.map +0 -1
- package/dist/index-9QODCOgD.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AIEditorProvider-CmiACRfw.cjs","sources":["../src/shared/storage.ts","../src/client/query-params.ts","../src/client/fiber-utils.ts","../src/client/AIEditorProvider.tsx"],"sourcesContent":["// =============================================================================\n// FILE: lib/ai-editor-storage.ts\n// Session storage management for AI editor using localStorage\n// =============================================================================\n\nimport type { ElementContext, PersistedSession } from \"./types\";\n\n// Re-export types for convenience\nexport type { ElementContext, PersistedSession };\n\n// =============================================================================\n// STORAGE UTILITY CLASS\n// =============================================================================\n\nexport class AIEditorStorage {\n private static readonly STORAGE_PREFIX = \"ai-editor:session:\";\n private static readonly VERSION = \"1.0.0\";\n private static readonly MAX_STORAGE_SIZE = 5 * 1024 * 1024; // 5MB\n\n /**\n * Generate storage key from file path and component name\n * Format: \"ai-editor:session:components/Header.tsx#Header\"\n */\n static getSessionKey(filePath: string, componentName: string): string {\n // Normalize path separators\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n return `${this.STORAGE_PREFIX}${normalizedPath}#${componentName}`;\n }\n\n /**\n * Save session to localStorage\n */\n static saveSession(session: PersistedSession): boolean {\n try {\n const key = this.getSessionKey(\n session.sourceLocation.filePath,\n session.sourceLocation.componentName\n );\n\n // Check storage size before saving\n if (this.getStorageSize() > this.MAX_STORAGE_SIZE) {\n console.warn(\"Storage size exceeded, pruning old sessions...\");\n this.pruneOldSessions(7 * 24 * 60 * 60 * 1000); // 7 days\n }\n\n const serialized = JSON.stringify(session);\n localStorage.setItem(key, serialized);\n return true;\n } catch (e) {\n if (e instanceof Error && e.name === \"QuotaExceededError\") {\n console.error(\"localStorage quota exceeded\");\n // Try pruning and retry\n this.pruneOldSessions(7 * 24 * 60 * 60 * 1000);\n try {\n const key = this.getSessionKey(\n session.sourceLocation.filePath,\n session.sourceLocation.componentName\n );\n const serialized = JSON.stringify(session);\n localStorage.setItem(key, serialized);\n return true;\n } catch {\n return false;\n }\n }\n console.error(\"Failed to save session:\", e);\n return false;\n }\n }\n\n /**\n * Load session by filePath + componentName\n */\n static loadSession(\n filePath: string,\n componentName: string\n ): PersistedSession | null {\n try {\n const key = this.getSessionKey(filePath, componentName);\n const stored = localStorage.getItem(key);\n\n if (!stored) return null;\n\n const session = JSON.parse(stored) as PersistedSession;\n\n // Validate schema\n if (!session.version || !session.sourceLocation || !session.editHistory) {\n console.warn(\"Invalid session schema, removing corrupted data\");\n localStorage.removeItem(key);\n return null;\n }\n\n return session;\n } catch (e) {\n console.error(\"Failed to load session:\", e);\n // Remove corrupted data\n const key = this.getSessionKey(filePath, componentName);\n localStorage.removeItem(key);\n return null;\n }\n }\n\n /**\n * Delete specific session\n */\n static deleteSession(filePath: string, componentName: string): void {\n try {\n const key = this.getSessionKey(filePath, componentName);\n localStorage.removeItem(key);\n } catch (e) {\n console.error(\"Failed to delete session:\", e);\n }\n }\n\n /**\n * Get all session keys\n */\n static getAllSessionKeys(): string[] {\n const keys: string[] = [];\n try {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith(this.STORAGE_PREFIX)) {\n keys.push(key);\n }\n }\n } catch (e) {\n console.error(\"Failed to get session keys:\", e);\n }\n return keys;\n }\n\n /**\n * Clear all sessions\n */\n static clearAllSessions(): void {\n try {\n const keys = this.getAllSessionKeys();\n keys.forEach((key) => localStorage.removeItem(key));\n console.log(`Cleared ${keys.length} session(s)`);\n } catch (e) {\n console.error(\"Failed to clear sessions:\", e);\n }\n }\n\n /**\n * Get total storage usage in bytes\n */\n static getStorageSize(): number {\n let total = 0;\n try {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith(this.STORAGE_PREFIX)) {\n const value = localStorage.getItem(key);\n if (value) {\n // Approximate size: 2 bytes per character in UTF-16\n total += (key.length + value.length) * 2;\n }\n }\n }\n } catch (e) {\n console.error(\"Failed to calculate storage size:\", e);\n }\n return total;\n }\n\n /**\n * Remove sessions older than maxAge milliseconds\n */\n static pruneOldSessions(maxAge: number): void {\n try {\n const now = Date.now();\n const keys = this.getAllSessionKeys();\n\n keys.forEach((key) => {\n const value = localStorage.getItem(key);\n if (!value) return;\n\n try {\n const session = JSON.parse(value) as PersistedSession;\n const age = now - session.lastModified;\n\n if (age > maxAge) {\n console.log(`Pruning old session: ${key} (age: ${Math.round(age / (24 * 60 * 60 * 1000))} days)`);\n localStorage.removeItem(key);\n }\n } catch (e) {\n // Corrupted data, remove it\n console.warn(`Removing corrupted session: ${key}`);\n localStorage.removeItem(key);\n }\n });\n } catch (e) {\n console.error(\"Failed to prune sessions:\", e);\n }\n }\n\n /**\n * Compute SHA-256 hash of file content using Web Crypto API\n */\n static async hashFileContent(content: string): Promise<string> {\n try {\n // Use Web Crypto API (available in browsers)\n const encoder = new TextEncoder();\n const data = encoder.encode(content);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n\n // Convert buffer to hex string\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n return hashHex;\n } catch (e) {\n console.error(\"Failed to hash content:\", e);\n // Fallback: use simple hash for consistency\n return this.simpleHash(content);\n }\n }\n\n /**\n * Simple hash fallback (for environments without Web Crypto API)\n */\n private static simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(16);\n }\n\n /**\n * Get most recently modified session\n */\n static getLastActiveSession(): PersistedSession | null {\n try {\n const keys = this.getAllSessionKeys();\n if (keys.length === 0) return null;\n\n let latestSession: PersistedSession | null = null;\n let latestTime = 0;\n\n keys.forEach((key) => {\n const value = localStorage.getItem(key);\n if (!value) return;\n\n try {\n const session = JSON.parse(value) as PersistedSession;\n\n // Validate schema\n if (!session.version || !session.sourceLocation || !session.editHistory) {\n console.warn(`Skipping invalid session: ${key}`);\n return;\n }\n\n if (session.lastModified > latestTime) {\n latestTime = session.lastModified;\n latestSession = session;\n }\n } catch (e) {\n console.warn(`Skipping corrupted session: ${key}`);\n }\n });\n\n return latestSession;\n } catch (e) {\n console.error(\"Failed to get last active session:\", e);\n return null;\n }\n }\n}\n","/**\n * Utility functions for building API query parameters\n */\n\nimport type { SourceLocation } from \"../shared/types\";\n\n/**\n * Build query parameters for the /api/ai-editor/read endpoint\n */\nexport function buildReadQueryParams(\n selectedSource: SourceLocation,\n includeParent: boolean = true\n): Record<string, string> {\n const params: Record<string, string> = {\n path: selectedSource.filePath,\n line: String(selectedSource.lineNumber),\n tagName: selectedSource.elementContext?.tagName || \"\",\n nthOfType: String(selectedSource.elementContext?.nthOfType || 0),\n textContent: selectedSource.elementContext?.textContent || \"\",\n className: selectedSource.elementContext?.className || \"\",\n };\n\n // Include debugStack if available for server-side source map resolution\n if (selectedSource.debugStack) {\n params.debugStack = selectedSource.debugStack;\n }\n\n // Include parent component info if available and requested\n if (includeParent && selectedSource.parentComponent) {\n params.parentFilePath = selectedSource.parentComponent.filePath;\n params.parentLine = String(selectedSource.parentComponent.lineNumber);\n params.parentComponentName = selectedSource.parentComponent.componentName;\n if (selectedSource.parentComponent.debugStack) {\n params.parentDebugStack = selectedSource.parentComponent.debugStack;\n }\n if (selectedSource.parentComponent.childKey) {\n params.childKey = selectedSource.parentComponent.childKey;\n }\n }\n\n return params;\n}\n","// =============================================================================\n// FILE: fiber-utils.ts\n// React Fiber tree utilities for extracting component source locations\n// =============================================================================\n\nimport type { ElementContext, SourceLocation } from \"../shared/types\";\nimport { cleanPath, shouldSkipPath } from \"../shared/path-utils\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface FiberNode {\n tag: number;\n type: any;\n key: string | null;\n return: FiberNode | null;\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n _debugStack?: any;\n _debugOwner?: any;\n memoizedProps?: any;\n pendingProps?: any;\n}\n\n// =============================================================================\n// FIBER UTILITIES\n// =============================================================================\n\nexport function getFiberFromElement(element: Element): FiberNode | null {\n const key = Object.keys(element).find(\n (k) =>\n k.startsWith(\"__reactFiber$\") || k.startsWith(\"__reactInternalInstance$\"),\n );\n return key ? (element as any)[key] : null;\n}\n\nexport function getComponentName(fiber: FiberNode | null): string {\n if (!fiber) return \"Unknown\";\n const type = fiber.type;\n\n // Try _debugSource first (most reliable for Client Components)\n if (fiber._debugSource?.fileName) {\n const fileName = fiber._debugSource.fileName;\n // Extract component name from file path (e.g., \"components/InfoBox.tsx\" -> \"InfoBox\")\n const match = fileName.match(/\\/([^/]+)\\.(tsx?|jsx?)$/);\n if (match) return match[1];\n }\n\n // Try type properties\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\")\n return type.displayName || type.name || \"Anonymous\";\n if (type?.displayName) return type.displayName;\n if (type?.render?.name) return type.render.name;\n\n // For Server Components, extract from _debugStack (no _debugSource on client)\n if (fiber._debugStack) {\n const stack = String(fiber._debugStack.stack || fiber._debugStack);\n // Look for pattern: \"at ComponentName (\"\n const match = stack.match(/at\\s+([A-Z][a-zA-Z0-9]*)\\s*\\(/);\n if (match && match[1] !== \"Object\") {\n return match[1];\n }\n }\n\n return \"Unknown\";\n}\n\nexport function isUserComponent(fiber: FiberNode): boolean {\n if (fiber.tag === 5 || fiber.tag === 6 || fiber.tag === 3) return false;\n const type = fiber.type;\n if (!type || typeof type === \"string\") return false;\n return true;\n}\n\n// =============================================================================\n// ELEMENT CONTEXT CAPTURE\n// =============================================================================\n\nfunction countNthOfType(element: Element, tagName: string): number {\n let boundary: Element | null = element.parentElement;\n\n // Find component boundary\n while (boundary) {\n const fiber = getFiberFromElement(boundary);\n if (fiber && isUserComponent(fiber)) break;\n boundary = boundary.parentElement;\n }\n\n if (!boundary) boundary = element.parentElement;\n if (!boundary) return 1;\n\n // Get all matching elements INCLUDING the boundary itself\n const sameTagElements: Element[] = [];\n\n // Check if boundary itself matches\n if (boundary.tagName.toLowerCase() === tagName.toLowerCase()) {\n sameTagElements.push(boundary);\n }\n\n // Add all descendants that match\n sameTagElements.push(...Array.from(boundary.querySelectorAll(tagName)));\n\n let count = 1;\n for (const el of sameTagElements) {\n if (el === element) break;\n count++;\n }\n\n return count;\n}\n\nfunction extractProps(\n fiber: FiberNode | null,\n): Record<string, any> | undefined {\n if (!fiber) return undefined;\n\n const fiberProps = fiber.memoizedProps || fiber.pendingProps;\n if (!fiberProps || typeof fiberProps !== \"object\") return undefined;\n\n const props: Record<string, any> = {};\n const identifyingKeys = [\n \"id\",\n \"name\",\n \"type\",\n \"href\",\n \"src\",\n \"alt\",\n \"role\",\n \"aria-label\",\n \"data-testid\",\n ];\n\n for (const key of identifyingKeys) {\n if (key in fiberProps && typeof fiberProps[key] === \"string\") {\n props[key] = fiberProps[key];\n }\n }\n\n if (fiberProps.style && typeof fiberProps.style === \"object\") {\n props._styleKeys = Object.keys(fiberProps.style).slice(0, 5);\n }\n\n return Object.keys(props).length > 0 ? props : undefined;\n}\n\nexport function captureElementContext(\n element: Element,\n fiber: FiberNode | null,\n): ElementContext {\n const tagName = element.tagName.toLowerCase();\n\n // Text content (direct text only, truncated)\n let textContent: string | undefined;\n const directText = Array.from(element.childNodes)\n .filter((n) => n.nodeType === Node.TEXT_NODE)\n .map((n) => n.textContent?.trim())\n .filter(Boolean)\n .join(\" \");\n\n if (directText) {\n textContent = directText.slice(0, 50);\n } else if (element.textContent) {\n textContent = element.textContent.trim().slice(0, 50);\n }\n\n // Class name\n const className =\n typeof element.className === \"string\"\n ? element.className.slice(0, 100)\n : undefined;\n\n // Count nth of type within component\n const nthOfType = countNthOfType(element, tagName);\n\n // React key\n const key = fiber?.key ? String(fiber.key) : undefined;\n\n // Identifying props\n const props = extractProps(fiber);\n\n return { tagName, textContent, className, key, nthOfType, props };\n}\n\n// =============================================================================\n// SOURCE LOCATION FINDER\n// =============================================================================\n\nfunction extractFromDebugStack(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const stack = (fiber as any)._debugStack;\n if (!stack) return null;\n\n const stackStr = stack.stack || String(stack);\n const frames = stackStr.split(\"\\n\");\n\n const skipPatterns = [\n \"node_modules\",\n \"SegmentViewNode\",\n \"LayoutRouter\",\n \"ErrorBoundary\",\n \"fakeJSXCallSite\",\n ];\n\n for (const frame of frames) {\n if (skipPatterns.some((p) => frame.includes(p))) continue;\n\n // Match: at Name (path:line:col)\n const match = frame.match(/at\\s+(\\w+)\\s+\\((.+?):(\\d+):(\\d+)\\)?$/);\n if (match) {\n const fileName = cleanPath(match[2].replace(/\\?[^:]*$/, \"\"));\n if (!shouldSkipPath(fileName, [\"ai-editor-provider\"])) {\n return {\n fileName,\n lineNumber: parseInt(match[3], 10),\n columnNumber: parseInt(match[4], 10),\n };\n }\n }\n }\n return null;\n}\n\nfunction extractFromDebugOwner(\n fiber: FiberNode,\n): { fileName: string; lineNumber: number; columnNumber?: number } | null {\n const owner = (fiber as any)._debugOwner;\n if (!owner) return null;\n\n if (owner._debugSource?.fileName) {\n return owner._debugSource;\n }\n\n const stack = owner.stack;\n if (Array.isArray(stack) && stack[0]?.fileName) {\n return stack[0];\n }\n\n return null;\n}\n\nexport function findSourceFromFiber(\n fiber: FiberNode | null,\n): Omit<SourceLocation, \"elementContext\"> | null {\n if (!fiber) return null;\n\n // For Server Components, _debugOwner contains the actual component info\n // Structure: { name: \"ComponentName\", owner: { name: \"ParentName\", debugLocation: Error }, debugStack: Error }\n let actualComponentName: string | null = null;\n if (fiber._debugOwner && typeof fiber._debugOwner === \"object\") {\n const debugOwner = fiber._debugOwner as any;\n if (debugOwner.name && typeof debugOwner.name === \"string\") {\n actualComponentName = debugOwner.name;\n }\n }\n\n let current: FiberNode | null = fiber;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 10) {\n iterations++;\n visited.add(current);\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n // Use the actualComponentName from _debugOwner if available (Server Components)\n // Otherwise walk up to find the nearest user component\n if (actualComponentName) {\n // Server Component - use _debugOwner.name\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName: actualComponentName,\n debugStack: rawDebugStack,\n };\n } else {\n // Client Component - walk up fiber tree\n let componentFiber: FiberNode | null = current;\n while (componentFiber) {\n if (isUserComponent(componentFiber)) {\n const componentName = getComponentName(componentFiber);\n\n // Skip Next.js internal components\n const isNextJSInternal = [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (!isNextJSInternal) {\n // Capture the raw _debugStack for server-side source map resolution\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n };\n }\n }\n componentFiber =\n componentFiber.return || componentFiber._debugOwner || null;\n }\n }\n }\n }\n\n current = current.return || current._debugOwner || null;\n }\n\n return null;\n}\n\n/**\n * Find the parent component using _debugOwner (the component that rendered this one)\n */\nexport function findParentComponentFromFiber(\n childFiber: FiberNode,\n childComponentName: string,\n): {\n filePath: string;\n lineNumber: number;\n columnNumber: number;\n componentName: string;\n debugStack?: string;\n childKey?: string;\n} | null {\n if (!childFiber) return null;\n\n // Find the child component's fiber to extract its key\n let childComponentFiber: FiberNode | null = null;\n\n // Check if _debugOwner points to the component fiber\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n // If it's a FiberNode (has type property), that's the component fiber\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n const ownerComponentName = getComponentName(debugOwner);\n if (ownerComponentName === childComponentName) {\n childComponentFiber = debugOwner;\n }\n }\n }\n\n // Otherwise walk up via .return to find component fiber\n if (!childComponentFiber) {\n let current: FiberNode | null = childFiber;\n let iterations = 0;\n while (current && iterations < 20) {\n iterations++;\n const componentName = getComponentName(current);\n const index = (current as any).index;\n\n if (isUserComponent(current)) {\n if (componentName === childComponentName) {\n childComponentFiber = current;\n break;\n }\n }\n\n // For Server Components, check if _debugOwner.name matches\n // Server Components don't have a fiber with the component name, but their rendered elements do have _debugOwner\n if (current._debugOwner && typeof current._debugOwner === \"object\") {\n const debugOwner = current._debugOwner as any;\n if (debugOwner.name === childComponentName && !debugOwner.type) {\n // This is a Server Component's rendered element\n // But we need to make sure this is the ROOT element of the component, not a child element\n // Check if the parent fiber is also part of the same component\n const parent = current.return;\n const parentDebugOwner = parent?._debugOwner as any;\n const isRootElement =\n !parentDebugOwner || parentDebugOwner.name !== childComponentName;\n\n if (isRootElement) {\n // This is the root element of the component - use this fiber's index\n childComponentFiber = current;\n break;\n }\n }\n }\n\n current = current.return;\n }\n }\n\n // Use key if available, otherwise use index\n let childKey: string | undefined;\n if (childComponentFiber?.key) {\n childKey = String(childComponentFiber.key);\n } else if (\n childComponentFiber &&\n typeof (childComponentFiber as any).index === \"number\"\n ) {\n // Use index as fallback for Server Components\n childKey = String((childComponentFiber as any).index);\n }\n\n // Two patterns to handle:\n // 1. Server Component element: fiber._debugOwner = { name: \"ChildComponent\", owner: { name: \"ParentComponent\", ... } }\n // 2. Client Component element: fiber._debugOwner = ComponentFiberNode, ComponentFiberNode._debugOwner = { name: \"ParentComponent\", ... }\n\n if (childFiber._debugOwner && typeof childFiber._debugOwner === \"object\") {\n const debugOwner = childFiber._debugOwner as any;\n\n // Pattern 1: Server Component - has owner.name\n if (debugOwner.owner && debugOwner.owner.name) {\n const parentName = debugOwner.owner.name;\n const parentDebugLocation = debugOwner.owner.debugLocation;\n\n if (parentDebugLocation) {\n const stack = String(parentDebugLocation.stack || parentDebugLocation);\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n\n // Pattern 2: Client Component - _debugOwner is a FiberNode, check its _debugOwner\n if (debugOwner.type && typeof debugOwner.type === \"function\") {\n // This is a FiberNode (Client Component), check its _debugOwner\n const componentFiberOwner = debugOwner._debugOwner;\n\n if (componentFiberOwner && typeof componentFiberOwner === \"object\") {\n const parentName = componentFiberOwner.name;\n const parentDebugLocation = componentFiberOwner.debugLocation;\n\n if (parentName && typeof parentName === \"string\") {\n if (parentDebugLocation) {\n const stack = String(\n parentDebugLocation.stack || parentDebugLocation,\n );\n\n return {\n filePath: \"\", // Will be resolved on server\n lineNumber: 0,\n columnNumber: 0,\n componentName: parentName,\n debugStack: stack,\n childKey,\n };\n }\n }\n }\n }\n }\n\n // Fallback: traverse fiber tree via .return\n let current: FiberNode | null = childFiber.return;\n const visited = new Set<FiberNode>();\n let iterations = 0;\n\n while (current && !visited.has(current) && iterations < 20) {\n iterations++;\n visited.add(current);\n\n if (isUserComponent(current)) {\n const componentName = getComponentName(current);\n\n // Skip if it's the same component as the child\n if (componentName === childComponentName) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Skip Next.js internal components and AI Editor wrapper\n const shouldSkipComponent =\n componentName.includes(\"AIEditorProvider\") || // Skip the AI Editor wrapper itself\n componentName.startsWith(\"__next\") || // Skip all Next.js internal components like __next_root_layout_boundary__\n componentName.startsWith(\"_\") || // Skip internal components starting with underscore\n [\n \"Segment\",\n \"Boundary\",\n \"Router\",\n \"Handler\",\n \"Context\",\n \"Layout\",\n \"Template\",\n \"Scroll\",\n \"Focus\",\n \"Loading\",\n \"Error\",\n \"RootLayout\", // Skip root layout wrapper\n \"NotFound\",\n ].some((pattern) => componentName.includes(pattern));\n\n if (shouldSkipComponent) {\n current = current._debugOwner || null;\n continue;\n }\n\n // Try to get source from various debug properties\n const sourceData =\n current._debugSource ||\n extractFromDebugStack(current) ||\n extractFromDebugOwner(current);\n\n if (sourceData?.fileName) {\n const filePath = cleanPath(sourceData.fileName);\n\n if (!shouldSkipPath(filePath, [\"ai-editor-provider\"])) {\n const rawDebugStack = current._debugStack\n ? String(current._debugStack.stack || current._debugStack)\n : undefined;\n\n return {\n filePath,\n lineNumber: sourceData.lineNumber || 1,\n columnNumber: sourceData.columnNumber || 0,\n componentName,\n debugStack: rawDebugStack,\n childKey,\n };\n }\n }\n }\n\n // Continue traversing using _debugOwner\n const nextOwner = current._debugOwner;\n current = nextOwner || null;\n }\n\n // If no parent found with source info, use child's debugStack to find parent on server\n // For Server Components, the child's debugStack contains the component call stack\n const childDebugStack = childFiber._debugStack\n ? String(childFiber._debugStack.stack || childFiber._debugStack)\n : null;\n\n if (childDebugStack) {\n // Use the child's debugStack to resolve the real parent on the server\n return {\n filePath: \"\", // Will be resolved on server from debugStack\n lineNumber: 0,\n columnNumber: 0,\n componentName: \"\", // Will be determined on server\n debugStack: childDebugStack, // Use child's debugStack for server-side resolution\n childKey,\n };\n }\n\n return null;\n}\n\n// =============================================================================\n// GET SOURCE FROM ELEMENT (Main export)\n// =============================================================================\n\nexport function getSourceFromElement(element: Element): SourceLocation | null {\n // Walk up DOM to find element with fiber that has source location info\n // This is important: we want the element that corresponds to the line number,\n // not a deeply nested child element\n let current: Element | null = element;\n let elementWithSource: Element | null = null;\n let fiberWithSource: FiberNode | null = null;\n\n while (current && current !== document.body) {\n const fiber = getFiberFromElement(current);\n if (fiber) {\n // Check if this fiber has source location info\n const hasSourceInfo =\n fiber._debugSource?.fileName ||\n fiber._debugStack ||\n (fiber._debugOwner && typeof fiber._debugOwner === 'object');\n\n if (hasSourceInfo && !fiberWithSource) {\n // First fiber with source info - this is the element we want\n elementWithSource = current;\n fiberWithSource = fiber;\n }\n }\n current = current.parentElement;\n }\n\n if (!fiberWithSource || !elementWithSource) return null;\n\n const source = findSourceFromFiber(fiberWithSource);\n if (!source) return null;\n\n // Capture element context from the element that has source info,\n // not from the originally clicked element\n const elementContext = captureElementContext(elementWithSource, fiberWithSource);\n\n // Find parent component from Fiber tree\n const parentComponent = findParentComponentFromFiber(\n fiberWithSource,\n source.componentName,\n );\n\n return {\n ...source,\n elementContext,\n parentComponent: parentComponent || undefined,\n };\n}\n\n// Debug helper\nif (typeof window !== \"undefined\") {\n (window as any).__getSource = getSourceFromElement;\n}\n","\"use client\";\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n ReactNode,\n} from \"react\";\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\nimport { vscDarkPlus, vs } from \"react-syntax-highlighter/dist/esm/styles/prism\";\nimport { AIEditorStorage, type PersistedSession } from \"../shared/storage\";\nimport type { SourceLocation } from \"../shared/types\";\nimport { buildReadQueryParams } from \"./query-params\";\nimport { getSourceFromElement } from \"./fiber-utils\";\n\n// =============================================================================\n// FEATURE FLAGS\n// =============================================================================\n\nconst ENABLE_SESSION_PERSISTENCE = false; // TODO: Enable when fully tested\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 // Extract component name from file path\n // e.g., \"components/ProductCard.tsx\" -> \"ProductCard\"\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 // Need debugStack to resolve\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 component name is Unknown, infer from resolved file path\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 const errorText = await res.text();\n console.error(\n `Resolve API error ${res.status}:`,\n errorText,\n \"for stack:\",\n cacheKey.substring(0, 200),\n );\n // Fallback: Try to infer file path from component name\n return inferFilePathFromComponentName(source.componentName);\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 console.warn(\"Resolve API returned unsuccessful response:\", data);\n // Fallback: Try to infer file path from component name\n return inferFilePathFromComponentName(source.componentName);\n })\n .catch((err) => {\n console.error(\"Error calling resolve API:\", err);\n // Fallback: Try to infer file path from component name\n return inferFilePathFromComponentName(source.componentName);\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 component name is Unknown, infer from resolved file path\n if (resolved.componentName === \"Unknown\" && resolved.filePath) {\n resolved.componentName = inferComponentNameFromPath(resolved.filePath);\n }\n\n return resolved;\n}\n\nasync function inferFilePathFromComponentName(\n componentName: string,\n): Promise<ResolvedSourceInfo | null> {\n if (!componentName || componentName === \"Unknown\") return null;\n\n // Try common locations for components\n const possiblePaths = [\n `components/${componentName}.tsx`,\n `components/${componentName}.jsx`,\n `app/${componentName}.tsx`,\n `app/${componentName}.jsx`,\n `src/components/${componentName}.tsx`,\n `src/components/${componentName}.jsx`,\n ];\n\n // Check which file exists by trying to read it\n for (const tryPath of possiblePaths) {\n try {\n const response = await fetch(\n `/api/ai-editor/absolute-path?path=${encodeURIComponent(tryPath)}`,\n );\n if (response.ok) {\n const data = await response.json();\n if (data.success) {\n console.log(\n `Inferred file path for ${componentName}: ${tryPath}`,\n );\n return {\n filePath: tryPath,\n lineNumber: 1,\n columnNumber: 0,\n };\n }\n }\n } catch (err) {\n // Continue trying other paths\n }\n }\n\n console.warn(`Could not infer file path for component: ${componentName}`);\n return null;\n}\n\ninterface EditHistoryItem {\n id: string; // Unique identifier for each edit\n suggestion: string;\n success: boolean;\n pending?: boolean; // True while edit is in progress\n error?: string;\n timestamp: number;\n // Undo support\n fileSnapshot?: string; // File content BEFORE this edit\n editedFilePath?: string; // Path of the file that was actually edited (may differ from selectedSource.filePath if parent was edited)\n modifiedLines?: {\n // Lines that were changed\n start: number;\n end: number;\n };\n generatedCode?: string; // AI-generated code\n}\n\ninterface EditorContextType {\n isEnabled: boolean;\n setEnabled: (enabled: boolean) => void;\n selectedSource: SourceLocation | null;\n setSelectedSource: (el: SourceLocation | null) => void;\n selectedDOMElement: Element | null;\n isLoading: boolean;\n setIsLoading: (loading: boolean) => void;\n editHistory: EditHistoryItem[];\n setEditHistory: React.Dispatch<React.SetStateAction<EditHistoryItem[]>>;\n submitEdit: (\n suggestion: string,\n ) => Promise<{ success: boolean; error?: string }>;\n suggestions: string[];\n suggestionsLoading: boolean;\n lastAppliedSuggestion?: string;\n setLastAppliedSuggestion: (value: string | undefined) => void;\n fetchSuggestions: (\n source: SourceLocation,\n history: EditHistoryItem[],\n lastEdit?: string,\n excludedSuggestions?: string[]\n ) => Promise<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// =============================================================================\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 [selectedSource, setSelectedSource] = useState<SourceLocation | null>(\n null,\n );\n const [selectedDOMElement, setSelectedDOMElement] = useState<Element | null>(\n null,\n );\n const [isLoading, setIsLoading] = useState(false);\n const [editHistory, setEditHistory] = useState<EditHistoryItem[]>([]);\n const [showStaleWarning, setShowStaleWarning] = useState(false);\n const [staleSession, setStaleSession] = useState<PersistedSession | null>(null);\n const [hasActiveSession, setHasActiveSession] = useState(false);\n const [parentInstance, setParentInstance] = useState<{\n filePath: string;\n content: string;\n lineStart: number;\n lineEnd: number;\n usageLineStart: number;\n usageLineEnd: number;\n componentName: string;\n } | null>(null);\n\n // Suggestion chips state\n const [suggestions, setSuggestions] = useState<string[]>([]);\n const [suggestionsLoading, setSuggestionsLoading] = useState(false);\n const [lastAppliedSuggestion, setLastAppliedSuggestion] = useState<string | undefined>(undefined);\n const [suggestionsCache, setSuggestionsCache] = useState<\n Map<\n string,\n {\n suggestions: string[];\n timestamp: number;\n }\n >\n >(new Map());\n\n useEffect(() => {\n const handleKey = (e: KeyboardEvent) => {\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 window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }, []);\n\n // Auto-restore last session on mount\n useEffect(() => {\n if (!ENABLE_SESSION_PERSISTENCE) return;\n if (typeof window === \"undefined\") return;\n\n const lastSession = AIEditorStorage.getLastActiveSession();\n if (!lastSession) return;\n\n setHasActiveSession(true);\n\n // Validate session\n fetch(\"/api/ai-editor/validate-session\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filePath: lastSession.sourceLocation.filePath,\n lastKnownHash: lastSession.fileValidation.lastKnownHash,\n lastKnownSize: lastSession.fileValidation.lastKnownSize,\n }),\n })\n .then((r) => r.json())\n .then((result) => {\n if (!result.isValid) {\n setStaleSession(lastSession);\n setShowStaleWarning(true);\n } else {\n restoreSession(lastSession);\n }\n })\n .catch((err) => {\n console.error(\"Session validation failed:\", err);\n // On error, show warning (safer than auto-restore)\n setStaleSession(lastSession);\n setShowStaleWarning(true);\n });\n }, []);\n\n const restoreSession = useCallback(async (session: PersistedSession) => {\n const sourceLocation = session.sourceLocation;\n\n setSelectedSource(sourceLocation);\n setEditHistory(session.editHistory);\n\n // Trigger async source resolution if needed\n if (sourceLocation.debugStack) {\n const resolved = await resolveSourceLocation(sourceLocation);\n if (resolved) {\n setSelectedSource(resolved);\n }\n }\n }, []);\n\n const handleClearSession = useCallback(() => {\n if (selectedSource) {\n AIEditorStorage.deleteSession(\n selectedSource.filePath,\n selectedSource.componentName\n );\n setHasActiveSession(false);\n setSelectedSource(null);\n setEditHistory([]);\n }\n }, [selectedSource]);\n\n const submitEdit = useCallback(\n async (suggestion: string) => {\n if (!selectedSource)\n return { success: false, error: \"No element selected\" };\n\n // Generate unique ID for this edit\n const editId =\n Date.now().toString(36) + Math.random().toString(36).substring(2);\n\n // Immediately add pending edit to history\n const pendingEdit: EditHistoryItem = {\n id: editId,\n suggestion,\n success: false,\n pending: true,\n timestamp: Date.now(),\n };\n setEditHistory((prev) => [...prev, pendingEdit]);\n\n setIsLoading(true);\n try {\n const res = await fetch(\"/api/ai-editor/edit\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filePath: selectedSource.filePath,\n lineNumber: selectedSource.lineNumber,\n componentName: selectedSource.componentName,\n suggestion,\n // NEW: Pass element context for precise matching\n elementContext: selectedSource.elementContext,\n // Pass debugStack for server-side source map resolution\n debugStack: selectedSource.debugStack,\n // Pass edit history for context\n editHistory: editHistory.map((item) => ({\n suggestion: item.suggestion,\n success: item.success,\n })),\n // Pass parent instance if available\n parentInstance,\n }),\n });\n const result = await res.json();\n\n // Update the pending edit with the result\n const completedEdit: EditHistoryItem = {\n id: editId,\n suggestion,\n success: result.success,\n pending: false,\n error: result.error,\n timestamp: Date.now(),\n fileSnapshot: result.fileSnapshot,\n editedFilePath: result.editedFile, // Track which file was actually edited\n generatedCode: result.generatedCode,\n modifiedLines: result.modifiedLines,\n };\n\n // Replace pending edit with completed result\n setEditHistory((prev) =>\n prev.map((item) => (item.id === editId ? completedEdit : item))\n );\n\n // Save session to localStorage\n if (ENABLE_SESSION_PERSISTENCE && selectedSource && result.fileSnapshot) {\n try {\n const hash = await AIEditorStorage.hashFileContent(result.fileSnapshot);\n const session: PersistedSession = {\n sessionId: `${selectedSource.filePath}#${selectedSource.componentName}`,\n version: \"1.0.0\",\n lastModified: Date.now(),\n sourceLocation: selectedSource,\n editHistory: [...editHistory, completedEdit],\n fileValidation: {\n lastKnownHash: hash,\n lastKnownSize: result.fileSnapshot.length,\n lastEditTimestamp: Date.now(),\n },\n uiState: {\n currentSuggestion: \"\", // Clear after successful edit\n modalWasOpen: true,\n },\n };\n AIEditorStorage.saveSession(session);\n setHasActiveSession(true);\n } catch (e) {\n console.error(\"Failed to save session:\", e);\n }\n }\n\n return result;\n } catch (err) {\n const error = String(err);\n\n // Update pending edit with error\n setEditHistory((prev) =>\n prev.map((item) =>\n item.id === editId\n ? { ...item, success: false, pending: false, error }\n : item\n )\n );\n\n return { success: false, error };\n } finally {\n setIsLoading(false);\n }\n },\n [selectedSource, editHistory, parentInstance],\n );\n\n const fetchSuggestions = useCallback(\n async (\n source: SourceLocation,\n history: EditHistoryItem[],\n lastEdit?: string,\n excludedSuggestions?: string[]\n ) => {\n const CACHE_TTL = 30000; // 30 seconds\n\n // Generate cache key\n const cacheKey = `${source.componentName}:${source.elementContext?.tagName || \"div\"}:${lastEdit || \"initial\"}`;\n console.log('[AI Editor] fetchSuggestions called. cacheKey:', cacheKey, 'lastEdit:', lastEdit, 'excludedSuggestions:', excludedSuggestions);\n\n // Check cache (skip if we're excluding suggestions)\n const cached = !excludedSuggestions?.length ? suggestionsCache.get(cacheKey) : null;\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n console.log('[AI Editor] Using cached suggestions');\n setSuggestions(cached.suggestions);\n return;\n }\n\n console.log('[AI Editor] Fetching new suggestions from API');\n setSuggestionsLoading(true);\n\n try {\n const params = new URLSearchParams({\n componentName: source.componentName,\n });\n\n if (source.elementContext?.tagName) {\n params.append(\"elementTag\", source.elementContext.tagName);\n }\n if (source.elementContext?.className) {\n params.append(\"className\", source.elementContext.className);\n }\n if (source.elementContext?.textContent) {\n params.append(\"textContent\", source.elementContext.textContent);\n }\n if (lastEdit) {\n params.append(\"lastSuggestion\", lastEdit);\n }\n if (history.length > 0) {\n params.append(\n \"editHistory\",\n JSON.stringify(\n history\n .slice(-3)\n .map((h) => ({ suggestion: h.suggestion, success: h.success }))\n )\n );\n }\n if (excludedSuggestions && excludedSuggestions.length > 0) {\n params.append(\"excludedSuggestions\", JSON.stringify(excludedSuggestions));\n }\n\n const response = await fetch(`/api/ai-editor/suggestions?${params}`);\n const data = await response.json();\n\n if (data.success) {\n setSuggestions(data.suggestions);\n // Update cache\n setSuggestionsCache((prev) => {\n const newCache = new Map(prev);\n newCache.set(cacheKey, {\n suggestions: data.suggestions,\n timestamp: Date.now(),\n });\n return newCache;\n });\n } else {\n setSuggestions([]);\n }\n } catch (error) {\n setSuggestions([]);\n } finally {\n setSuggestionsLoading(false);\n }\n },\n [suggestionsCache, setSuggestions, setSuggestionsLoading, setSuggestionsCache]\n );\n\n const handleSelect = useCallback(\n (element: Element, source: SourceLocation) => {\n setSelectedDOMElement(element);\n setSelectedSource(source);\n // Clear edit history and parent instance when selecting a new component\n setEditHistory([]);\n setParentInstance(null);\n\n resolveSourceLocation(source).then((resolved) => {\n if (resolved) {\n setSelectedSource((prev) => (prev === source ? resolved : prev));\n }\n });\n },\n [setSelectedDOMElement, setSelectedSource, setParentInstance],\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 selectedSource,\n setSelectedSource,\n selectedDOMElement,\n isLoading,\n setIsLoading,\n editHistory,\n setEditHistory,\n submitEdit,\n suggestions,\n suggestionsLoading,\n lastAppliedSuggestion,\n setLastAppliedSuggestion,\n fetchSuggestions,\n }}\n >\n {children}\n {isEnabled && (\n <EditorOverlay\n theme={theme}\n onSelect={handleSelect}\n showStaleWarning={showStaleWarning}\n staleSession={staleSession}\n hasActiveSession={hasActiveSession}\n setShowStaleWarning={setShowStaleWarning}\n setStaleSession={setStaleSession}\n setHasActiveSession={setHasActiveSession}\n restoreSession={restoreSession}\n handleClearSession={handleClearSession}\n parentInstance={parentInstance}\n setParentInstance={setParentInstance}\n />\n )}\n </EditorContext.Provider>\n );\n}\n\n// =============================================================================\n// OVERLAY\n// =============================================================================\n\nfunction EditorOverlay({\n theme,\n onSelect,\n showStaleWarning,\n staleSession,\n hasActiveSession,\n setShowStaleWarning,\n setStaleSession,\n setHasActiveSession,\n restoreSession,\n handleClearSession,\n parentInstance,\n setParentInstance,\n}: {\n theme: \"light\" | \"dark\";\n onSelect: (el: Element, source: SourceLocation) => void;\n showStaleWarning: boolean;\n staleSession: PersistedSession | null;\n hasActiveSession: boolean;\n setShowStaleWarning: (value: boolean) => void;\n setStaleSession: (value: PersistedSession | null) => void;\n setHasActiveSession: (value: boolean) => void;\n restoreSession: (session: PersistedSession) => void;\n handleClearSession: () => void;\n parentInstance: {\n filePath: string;\n content: string;\n lineStart: number;\n lineEnd: number;\n usageLineStart: number;\n usageLineEnd: number;\n componentName: string;\n } | null;\n setParentInstance: (value: {\n filePath: string;\n content: string;\n lineStart: number;\n lineEnd: number;\n usageLineStart: number;\n usageLineEnd: number;\n componentName: string;\n } | null) => void;\n}) {\n const {\n selectedSource,\n setSelectedSource,\n submitEdit,\n isLoading,\n setIsLoading,\n setEnabled,\n selectedDOMElement,\n editHistory,\n setEditHistory,\n suggestions,\n suggestionsLoading,\n lastAppliedSuggestion,\n setLastAppliedSuggestion,\n fetchSuggestions,\n } = useAIEditor();\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 const [suggestion, setSuggestion] = useState(\"\");\n const [result, setResult] = useState<{\n success: boolean;\n error?: string;\n } | null>(null);\n const [code, setCode] = useState(\"\");\n const [codeLineStart, setCodeLineStart] = useState(1);\n const [targetStartLine, setTargetStartLine] = useState<number | null>(null);\n const [targetEndLine, setTargetEndLine] = useState<number | null>(null);\n const [absolutePath, setAbsolutePath] = useState<string | null>(null);\n const [parsedComponentName, setParsedComponentName] = useState<string | null>(\n null,\n );\n\n // Collapsible sections state\n const [isSourcePreviewExpanded, setIsSourcePreviewExpanded] = useState(false);\n const [isParentPreviewExpanded, setIsParentPreviewExpanded] = useState(false);\n const [isEditHistoryExpanded, setIsEditHistoryExpanded] = useState(true);\n\n const isDark = theme === \"dark\";\n\n /**\n * Helper function to refresh code preview after edits\n */\n const refreshCodePreview = useCallback(async (\n source: SourceLocation,\n options: { includeParent?: boolean } = {}\n ) => {\n const params = buildReadQueryParams(source, options.includeParent ?? true);\n\n try {\n const response = await fetch(`/api/ai-editor/read?` + new URLSearchParams(params));\n const data = await response.json();\n\n if (data.success) {\n setCode(data.content);\n setCodeLineStart(data.lineStart || 1);\n setTargetStartLine(data.targetStartLine || null);\n setTargetEndLine(data.targetEndLine || null);\n // Always update parentInstance, even if null (to clear old values)\n setParentInstance(data.parentInstance || null);\n if (data.componentName) {\n setParsedComponentName(data.componentName);\n }\n }\n } catch (error) {\n console.error(\"Error refreshing code preview:\", error);\n }\n }, []);\n\n // Fetch code preview and absolute path\n useEffect(() => {\n if (selectedSource) {\n refreshCodePreview(selectedSource);\n fetchSuggestions(selectedSource, []);\n\n // Fetch absolute path\n fetch(\n `/api/ai-editor/absolute-path?` +\n new URLSearchParams({ path: selectedSource.filePath }),\n )\n .then((r) => r.json())\n .then((d) => d.success && setAbsolutePath(d.absolutePath))\n .catch(() => setAbsolutePath(null));\n } else {\n setAbsolutePath(null);\n setParsedComponentName(null);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedSource, refreshCodePreview]);\n\n // Mouse tracking\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 if (selectedSource) return;\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 // Check if this looks like a compiled path that needs resolution\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 // Wait for resolution before showing the tooltip\n setIsResolvingSource(true);\n resolveSourceLocation(source)\n .then((resolved) => {\n setIsResolvingSource(false);\n if (resolved) {\n console.log(\"Resolved source location:\", resolved);\n setHoveredSource(resolved);\n } else {\n console.warn(\n \"Failed to resolve source location for:\",\n source,\n );\n // If resolution fails, still show the source (might be a client component)\n setHoveredSource(source);\n }\n })\n .catch((err) => {\n console.error(\"Error resolving source location:\", err);\n setIsResolvingSource(false);\n setHoveredSource(source);\n });\n } else if (isCompiledPath && !source.debugStack) {\n // Compiled path but no debugStack - can't resolve, show as-is\n console.warn(\"Compiled path but no debugStack:\", source);\n setIsResolvingSource(false);\n setHoveredSource(source);\n } else {\n // Not a compiled path, show immediately\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 = (e: MouseEvent) => {\n if ((e.target as Element).closest(\".ai-editor-ui\")) return;\n if (hoveredSource && hoveredElement) {\n e.preventDefault();\n e.stopPropagation();\n onSelect(hoveredElement, hoveredSource);\n setSuggestion(\"\");\n setResult(null);\n }\n };\n\n document.addEventListener(\"mousemove\", onMove, { passive: true });\n document.addEventListener(\"click\", onClick, true);\n return () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"click\", onClick, true);\n cancelAnimationFrame(raf);\n };\n }, [hoveredSource, hoveredElement, selectedSource, onSelect]);\n\n const handleSubmit = async () => {\n if (!suggestion.trim()) return;\n const appliedSuggestion = suggestion; // Save before clearing\n const res = await submitEdit(suggestion);\n setResult(res);\n // Don't auto-reload, let user continue editing or manually finish\n if (res.success) {\n setSuggestion(\"\"); // Clear input for next edit\n setLastAppliedSuggestion(appliedSuggestion); // Save for refresh button\n\n // Refresh code preview to show the updated code\n if (selectedSource) {\n // Small delay to ensure file write completes\n await new Promise(resolve => setTimeout(resolve, 100));\n await refreshCodePreview(selectedSource);\n // Regenerate suggestions based on the edit that was just applied\n console.log('[AI Editor] Fetching suggestions after edit:', appliedSuggestion);\n fetchSuggestions(selectedSource, editHistory, appliedSuggestion);\n }\n\n // Reset result after a delay\n setTimeout(() => setResult(null), 3000);\n }\n };\n\n const handleUndo = async () => {\n if (editHistory.length === 0 || !selectedSource) return;\n\n // Find the last successful edit with a snapshot\n const lastSuccessfulEdit = [...editHistory]\n .reverse()\n .find((edit) => edit.success && edit.fileSnapshot);\n\n if (!lastSuccessfulEdit) {\n console.warn(\"No successful edit with snapshot found to undo\");\n return;\n }\n\n // Use the actual file that was edited (may be parent), not necessarily the selected source\n const fileToRestore = lastSuccessfulEdit.editedFilePath || selectedSource.filePath;\n console.log(`[Undo] Restoring file: ${fileToRestore}`);\n\n setIsLoading(true);\n try {\n // Call undo endpoint to restore file\n const response = await fetch(\"/api/ai-editor/undo\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filePath: fileToRestore,\n content: lastSuccessfulEdit.fileSnapshot,\n }),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || \"Undo failed\");\n }\n\n // Remove the last successful edit from history\n setEditHistory((prev) => {\n const lastIndex = prev.lastIndexOf(lastSuccessfulEdit);\n return prev.filter((_, idx) => idx !== lastIndex);\n });\n\n // Refresh code preview\n await refreshCodePreview(selectedSource);\n\n setResult({ success: true, error: undefined });\n setTimeout(() => setResult(null), 3000);\n } catch (error) {\n console.error(\"Undo error:\", error);\n setResult({ success: false, error: String(error) });\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleRetry = async (editIndex: number) => {\n const editToRetry = editHistory[editIndex];\n if (!editToRetry) return;\n\n // Re-submit the same suggestion\n const res = await submitEdit(editToRetry.suggestion);\n\n // Refresh code preview if successful\n if (res.success && selectedSource) {\n // Small delay to ensure file write completes\n await new Promise(resolve => setTimeout(resolve, 100));\n await refreshCodePreview(selectedSource, { includeParent: false });\n }\n };\n\n const handleUndoAndRetry = async () => {\n if (editHistory.length === 0 || !selectedSource) return;\n\n // Find the last successful edit with a snapshot\n const lastSuccessfulEdit = [...editHistory]\n .reverse()\n .find((edit) => edit.success && edit.fileSnapshot);\n\n if (!lastSuccessfulEdit) {\n console.warn(\"No successful edit with snapshot found to undo and retry\");\n return;\n }\n\n // Use the actual file that was edited (may be parent), not necessarily the selected source\n const fileToRestore = lastSuccessfulEdit.editedFilePath || selectedSource.filePath;\n console.log(`[Undo & Retry] Restoring file: ${fileToRestore}`);\n\n setIsLoading(true);\n try {\n // Step 1: Undo the last edit\n const undoResponse = await fetch(\"/api/ai-editor/undo\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n filePath: fileToRestore,\n content: lastSuccessfulEdit.fileSnapshot,\n }),\n });\n\n const undoResult = await undoResponse.json();\n\n if (!undoResult.success) {\n throw new Error(undoResult.error || \"Undo failed\");\n }\n\n // Remove the last successful edit from history\n setEditHistory((prev) => {\n const lastIndex = prev.lastIndexOf(lastSuccessfulEdit);\n return prev.filter((_, idx) => idx !== lastIndex);\n });\n\n // Refresh code preview\n await refreshCodePreview(selectedSource);\n\n // Step 2: Retry the same suggestion\n setIsLoading(true); // Keep loading state\n const retryResult = await submitEdit(lastSuccessfulEdit.suggestion);\n\n // Refresh code preview after retry\n if (retryResult.success && selectedSource) {\n // Small delay to ensure file write completes\n await new Promise(resolve => setTimeout(resolve, 100));\n await refreshCodePreview(selectedSource);\n }\n\n if (retryResult.success) {\n setResult({ success: true, error: undefined });\n } else {\n setResult({ success: false, error: retryResult.error });\n }\n\n setTimeout(() => setResult(null), 3000);\n } catch (error) {\n console.error(\"Undo and retry error:\", error);\n setResult({ success: false, error: String(error) });\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleDone = () => {\n // Clear session before reload\n if (ENABLE_SESSION_PERSISTENCE && selectedSource) {\n AIEditorStorage.deleteSession(\n selectedSource.filePath,\n selectedSource.componentName\n );\n }\n // Close modal and reload page to see all changes\n window.location.reload();\n };\n\n const c = {\n bg: isDark ? \"#0d0d14\" : \"#fff\",\n bgAlt: isDark ? \"#16162a\" : \"#f5f5f5\",\n text: isDark ? \"#e4e4e7\" : \"#18181b\",\n muted: isDark ? \"#71717a\" : \"#a1a1aa\",\n accent: \"#818cf8\",\n border: isDark ? \"#27273f\" : \"#e4e4e7\",\n success: \"#34d399\",\n error: \"#f87171\",\n };\n\n const elCtx = selectedSource?.elementContext;\n\n return (\n <div\n className=\"ai-editor-ui\"\n style={{ fontFamily: \"system-ui, sans-serif\" }}\n >\n <style>\n {`\n @keyframes ai-editor-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}\n </style>\n {/* Highlight */}\n {hoveredRect && !selectedSource && (\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 && !selectedSource && !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 {/* Stale File Warning Modal */}\n {ENABLE_SESSION_PERSISTENCE && showStaleWarning && staleSession && (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background: \"rgba(0,0,0,0.7)\",\n zIndex: 100001,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n background: c.bg,\n color: c.text,\n borderRadius: 16,\n padding: 32,\n maxWidth: 500,\n border: `1px solid ${c.border}`,\n boxShadow: `0 24px 80px rgba(0,0,0,0.8)`,\n }}\n >\n <div style={{ fontSize: 24, marginBottom: 16 }}>\n ⚠️ File Modified Externally\n </div>\n <p style={{ marginBottom: 12, color: c.muted }}>\n The file has been modified since your last edit session.\n </p>\n <div\n style={{\n background: c.bgAlt,\n padding: 12,\n borderRadius: 8,\n marginBottom: 20,\n fontFamily: \"monospace\",\n fontSize: 12,\n }}\n >\n <div>\n <strong>Component:</strong>{\" \"}\n {staleSession.sourceLocation.componentName}\n </div>\n <div>\n <strong>File:</strong> {staleSession.sourceLocation.filePath}\n </div>\n <div>\n <strong>Last edit:</strong>{\" \"}\n {new Date(staleSession.lastModified).toLocaleString()}\n </div>\n <div>\n <strong>Edits:</strong> {staleSession.editHistory.length}\n </div>\n </div>\n <p style={{ marginBottom: 20, fontSize: 14 }}>\n Continuing may cause conflicts. You can discard this session or\n continue anyway.\n </p>\n <div style={{ display: \"flex\", gap: 12 }}>\n <button\n onClick={() => {\n AIEditorStorage.deleteSession(\n staleSession.sourceLocation.filePath,\n staleSession.sourceLocation.componentName\n );\n setShowStaleWarning(false);\n setStaleSession(null);\n setHasActiveSession(false);\n }}\n style={{\n flex: 1,\n padding: \"12px 20px\",\n borderRadius: 10,\n border: `1px solid ${c.border}`,\n background: \"transparent\",\n color: c.text,\n cursor: \"pointer\",\n }}\n >\n Discard Session\n </button>\n <button\n onClick={() => {\n restoreSession(staleSession);\n setShowStaleWarning(false);\n }}\n style={{\n flex: 1,\n padding: \"12px 20px\",\n borderRadius: 10,\n border: \"none\",\n background: \"#f59e0b\",\n color: \"#fff\",\n fontWeight: 600,\n cursor: \"pointer\",\n }}\n >\n Continue Anyway\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Modal */}\n {selectedSource && (\n <div\n style={{\n position: \"fixed\",\n bottom: 20,\n right: 20,\n background: c.bg,\n color: c.text,\n borderRadius: 16,\n padding: 24,\n width: 560,\n maxWidth: \"calc(100vw - 40px)\",\n maxHeight: \"calc(100vh - 40px)\",\n overflowY: \"auto\",\n overflowX: \"hidden\",\n zIndex: 100000,\n boxShadow: `0 24px 80px rgba(0,0,0,${isDark ? 0.6 : 0.25})`,\n border: `1px solid ${c.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n marginBottom: 20,\n }}\n >\n <div>\n <div\n style={{\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: 1,\n color: c.muted,\n }}\n >\n Editing\n </div>\n <div style={{ fontSize: 20, fontWeight: 700, color: c.accent }}>\n <{parsedComponentName || selectedSource.componentName} />\n </div>\n <div\n style={{\n fontSize: 12,\n color: c.muted,\n fontFamily: \"monospace\",\n marginTop: 4,\n }}\n >\n <a\n href={\n absolutePath\n ? `cursor://file/${absolutePath}:${selectedSource.lineNumber}`\n : `cursor://file/${selectedSource.filePath}:${selectedSource.lineNumber}`\n }\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n const path = absolutePath || selectedSource.filePath;\n const cursorPath = path.startsWith(\"/\") ? path : `/${path}`;\n window.location.href = `cursor://file${cursorPath}:${selectedSource.lineNumber}`;\n }}\n style={{\n color: c.accent,\n textDecoration: \"none\",\n cursor: \"pointer\",\n borderBottom: `1px solid ${c.accent}40`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.borderBottomColor = c.accent;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.borderBottomColor = `${c.accent}40`;\n }}\n >\n {selectedSource.filePath}:{selectedSource.lineNumber}\n </a>\n </div>\n {elCtx?.textContent && (\n <div\n style={{\n fontSize: 11,\n color: c.muted,\n marginTop: 4,\n fontStyle: \"italic\",\n }}\n >\n Element text: \"{elCtx.textContent}\"\n </div>\n )}\n </div>\n <button\n onClick={() => setSelectedSource(null)}\n style={{\n width: 36,\n height: 36,\n borderRadius: 10,\n border: \"none\",\n background: c.bgAlt,\n color: c.muted,\n fontSize: 20,\n cursor: \"pointer\",\n }}\n >\n ×\n </button>\n </div>\n\n {code && (\n <div style={{ marginBottom: 20 }}>\n <button\n onClick={() => setIsSourcePreviewExpanded(!isSourcePreviewExpanded)}\n style={{\n fontSize: 11,\n fontWeight: 600,\n marginBottom: 8,\n color: c.muted,\n textTransform: \"uppercase\",\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}\n >\n <span style={{ fontSize: 10 }}>\n {isSourcePreviewExpanded ? \"▼\" : \"▶\"}\n </span>\n Source Preview\n </button>\n {isSourcePreviewExpanded && (\n <SyntaxHighlighter\n language=\"tsx\"\n style={isDark ? vscDarkPlus : vs}\n showLineNumbers={true}\n startingLineNumber={codeLineStart}\n customStyle={{\n background: c.bgAlt,\n borderRadius: 10,\n fontSize: 14,\n margin: 0,\n maxHeight: 180,\n overflowX: \"auto\",\n border: `1px solid ${c.border}`,\n }}\n lineNumberStyle={{\n minWidth: \"2.5em\",\n paddingRight: \"1em\",\n color: c.muted,\n textAlign: \"right\",\n userSelect: \"none\",\n }}\n wrapLines={true}\n lineProps={(lineNumber) => {\n const isHighlighted =\n targetStartLine !== null &&\n targetEndLine !== null &&\n lineNumber >= targetStartLine &&\n lineNumber <= targetEndLine;\n return {\n style: {\n backgroundColor: isHighlighted\n ? isDark\n ? \"rgba(102, 126, 234, 0.15)\"\n : \"rgba(147, 197, 253, 0.3)\"\n : \"transparent\",\n },\n };\n }}\n >\n {code}\n </SyntaxHighlighter>\n )}\n </div>\n )}\n\n {parentInstance && (\n <div style={{ marginBottom: 20 }}>\n <button\n onClick={() => setIsParentPreviewExpanded(!isParentPreviewExpanded)}\n style={{\n fontSize: 11,\n fontWeight: 600,\n marginBottom: 8,\n color: c.muted,\n textTransform: \"uppercase\",\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}\n >\n <span style={{ fontSize: 10 }}>\n {isParentPreviewExpanded ? \"▼\" : \"▶\"}\n </span>\n Used In: {parentInstance.componentName} ({parentInstance.filePath})\n </button>\n {isParentPreviewExpanded && (\n <SyntaxHighlighter\n language=\"tsx\"\n style={isDark ? vscDarkPlus : vs}\n showLineNumbers={true}\n startingLineNumber={parentInstance.lineStart}\n customStyle={{\n background: c.bgAlt,\n borderRadius: 10,\n fontSize: 14,\n margin: 0,\n maxHeight: 180,\n overflowX: \"auto\",\n border: `1px solid ${c.border}`,\n }}\n lineNumberStyle={{\n minWidth: \"2.5em\",\n paddingRight: \"1em\",\n color: c.muted,\n textAlign: \"right\",\n userSelect: \"none\",\n }}\n wrapLines={true}\n lineProps={(lineNumber) => {\n const isUsageLine =\n lineNumber >= parentInstance.usageLineStart &&\n lineNumber <= parentInstance.usageLineEnd;\n return {\n style: {\n backgroundColor: isUsageLine\n ? isDark\n ? \"rgba(255, 165, 0, 0.15)\"\n : \"rgba(255, 165, 0, 0.2)\"\n : \"transparent\",\n },\n };\n }}\n >\n {parentInstance.content}\n </SyntaxHighlighter>\n )}\n </div>\n )}\n\n {editHistory.length > 0 && (\n <div style={{ marginBottom: 20 }}>\n <button\n onClick={() => setIsEditHistoryExpanded(!isEditHistoryExpanded)}\n style={{\n fontSize: 11,\n fontWeight: 600,\n marginBottom: 8,\n color: c.muted,\n textTransform: \"uppercase\",\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}\n >\n <span style={{ fontSize: 10 }}>\n {isEditHistoryExpanded ? \"▼\" : \"▶\"}\n </span>\n Edit History ({editHistory.length})\n </button>\n {isEditHistoryExpanded && (\n <div\n style={{\n background: c.bgAlt,\n borderRadius: 10,\n border: `1px solid ${c.border}`,\n maxHeight: 200,\n overflow: \"auto\",\n }}\n >\n {editHistory.map((item, idx) => {\n const isLastEdit = idx === editHistory.length - 1;\n const hasSnapshot = item.success && item.fileSnapshot;\n\n return (\n <div\n key={idx}\n style={{\n padding: \"10px 14px\",\n borderBottom:\n idx < editHistory.length - 1\n ? `1px solid ${c.border}`\n : \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n }}\n >\n <div style={{ flex: 1 }}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 4,\n }}\n >\n {item.pending ? (\n <div\n style={{\n width: 16,\n height: 16,\n border: \"2px solid transparent\",\n borderTopColor: c.accent,\n borderRadius: \"50%\",\n animation: \"ai-editor-spin 0.8s linear infinite\",\n }}\n />\n ) : (\n <span\n style={{\n color: item.success ? c.success : c.error,\n fontSize: 16,\n }}\n >\n {item.success ? \"✓\" : \"✗\"}\n </span>\n )}\n <span\n style={{\n fontSize: 11,\n color: c.muted,\n }}\n >\n Edit {idx + 1}\n </span>\n </div>\n <div\n style={{\n fontSize: 13,\n color: c.text,\n marginLeft: 24,\n }}\n >\n {item.suggestion}\n </div>\n {item.error && (\n <div\n style={{\n fontSize: 11,\n color: c.error,\n marginLeft: 24,\n marginTop: 4,\n }}\n >\n {item.error}\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n {isLastEdit && hasSnapshot && !item.pending && (\n <>\n <button\n onClick={handleUndo}\n disabled={isLoading}\n style={{\n padding: \"4px 10px\",\n fontSize: 11,\n borderRadius: 6,\n border: \"none\",\n background: isLoading ? c.muted : \"#f59e0b\",\n color: \"#fff\",\n fontWeight: 600,\n cursor: isLoading ? \"wait\" : \"pointer\",\n whiteSpace: \"nowrap\",\n }}\n title=\"Undo this edit\"\n onMouseEnter={(e) => {\n if (!isLoading)\n e.currentTarget.style.background = \"#d97706\";\n }}\n onMouseLeave={(e) => {\n if (!isLoading)\n e.currentTarget.style.background = \"#f59e0b\";\n }}\n >\n ↶ Undo\n </button>\n <button\n onClick={handleUndoAndRetry}\n disabled={isLoading}\n style={{\n padding: \"4px 10px\",\n fontSize: 11,\n borderRadius: 6,\n border: \"none\",\n background: isLoading ? c.muted : \"#8b5cf6\",\n color: \"#fff\",\n fontWeight: 600,\n cursor: isLoading ? \"wait\" : \"pointer\",\n whiteSpace: \"nowrap\",\n }}\n title=\"Undo and retry with AI\"\n onMouseEnter={(e) => {\n if (!isLoading)\n e.currentTarget.style.background = \"#7c3aed\";\n }}\n onMouseLeave={(e) => {\n if (!isLoading)\n e.currentTarget.style.background = \"#8b5cf6\";\n }}\n >\n ↶↻ Undo & Retry\n </button>\n </>\n )}\n <button\n onClick={() => handleRetry(idx)}\n disabled={isLoading || item.pending}\n style={{\n padding: \"4px 10px\",\n fontSize: 11,\n borderRadius: 6,\n border: \"none\",\n background: isLoading || item.pending ? c.muted : c.accent,\n color: \"#fff\",\n fontWeight: 600,\n cursor: isLoading || item.pending ? \"wait\" : \"pointer\",\n whiteSpace: \"nowrap\",\n }}\n title=\"Retry this edit\"\n onMouseEnter={(e) => {\n if (!isLoading && !item.pending)\n e.currentTarget.style.background = \"#6366f1\";\n }}\n onMouseLeave={(e) => {\n if (!isLoading && !item.pending)\n e.currentTarget.style.background = c.accent;\n }}\n >\n ↻ Retry\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n <div style={{ marginBottom: 20 }}>\n <div\n style={{\n fontSize: 11,\n fontWeight: 600,\n marginBottom: 8,\n color: c.muted,\n textTransform: \"uppercase\",\n }}\n >\n Describe Changes\n </div>\n <textarea\n value={suggestion}\n onChange={(e) => setSuggestion(e.target.value)}\n placeholder={`e.g., Make this ${\n elCtx?.tagName || \"element\"\n } blue with rounded corners...`}\n autoFocus\n style={{\n width: \"100%\",\n height: 100,\n padding: 14,\n borderRadius: 10,\n border: `1px solid ${c.border}`,\n background: c.bgAlt,\n color: c.text,\n fontSize: 14,\n resize: \"vertical\",\n fontFamily: \"inherit\",\n boxSizing: \"border-box\",\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleSubmit();\n }\n }}\n />\n </div>\n\n {/* Suggestion Chips */}\n {(suggestions.length > 0 || suggestionsLoading) && (\n <div style={{ marginBottom: 20 }}>\n <div\n style={{\n fontSize: 11,\n fontWeight: 600,\n marginBottom: 8,\n color: c.muted,\n textTransform: \"uppercase\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n }}\n >\n Quick Suggestions\n {suggestionsLoading ? (\n <div\n style={{\n width: 12,\n height: 12,\n border: \"2px solid transparent\",\n borderTopColor: c.accent,\n borderRadius: \"50%\",\n animation: \"ai-editor-spin 0.8s linear infinite\",\n }}\n />\n ) : (\n suggestions.length > 0 && selectedSource && (\n <button\n onClick={() => {\n console.log('[AI Editor] Refreshing suggestions, excluding:', suggestions);\n fetchSuggestions(selectedSource, editHistory, lastAppliedSuggestion, suggestions);\n }}\n disabled={isLoading}\n style={{\n background: \"transparent\",\n border: \"none\",\n padding: 4,\n cursor: isLoading ? \"wait\" : \"pointer\",\n color: c.muted,\n fontSize: 14,\n display: \"flex\",\n alignItems: \"center\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n if (!isLoading) {\n e.currentTarget.style.color = c.accent;\n e.currentTarget.style.transform = \"rotate(180deg)\";\n }\n }}\n onMouseLeave={(e) => {\n if (!isLoading) {\n e.currentTarget.style.color = c.muted;\n e.currentTarget.style.transform = \"rotate(0deg)\";\n }\n }}\n title=\"Get different suggestions\"\n >\n ↻\n </button>\n )\n )}\n </div>\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n }}\n >\n {suggestionsLoading ? (\n // Loading skeletons\n Array.from({ length: 6 }).map((_, idx) => (\n <div\n key={idx}\n style={{\n padding: \"8px 14px\",\n borderRadius: 8,\n background: c.bgAlt,\n border: `1px solid ${c.border}`,\n fontSize: 13,\n height: 34,\n width: Math.random() * 60 + 80, // Variable width\n opacity: 0.5,\n }}\n />\n ))\n ) : (\n suggestions.map((suggestionText: string, idx: number) => (\n <button\n key={idx}\n onClick={(e) => {\n if (e.metaKey || e.ctrlKey) {\n // Cmd+Click: populate and submit immediately\n setSuggestion(suggestionText);\n setTimeout(() => handleSubmit(), 50);\n } else {\n // Normal click: populate textarea\n setSuggestion(suggestionText);\n }\n }}\n disabled={isLoading}\n style={{\n padding: \"8px 14px\",\n borderRadius: 8,\n border: `1px solid ${c.border}`,\n background: c.bgAlt,\n color: c.text,\n fontSize: 13,\n cursor: isLoading ? \"wait\" : \"pointer\",\n transition: \"all 0.15s ease\",\n whiteSpace: \"nowrap\",\n }}\n onMouseEnter={(e) => {\n if (!isLoading) {\n e.currentTarget.style.background = c.accent + \"20\";\n e.currentTarget.style.borderColor = c.accent;\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }\n }}\n onMouseLeave={(e) => {\n if (!isLoading) {\n e.currentTarget.style.background = c.bgAlt;\n e.currentTarget.style.borderColor = c.border;\n e.currentTarget.style.transform = \"translateY(0)\";\n }\n }}\n title=\"Click to use • Cmd+Click to apply immediately\"\n >\n {suggestionText}\n </button>\n ))\n )}\n </div>\n </div>\n )}\n\n {result && (\n <div\n style={{\n marginBottom: 20,\n padding: 14,\n borderRadius: 10,\n background: result.success ? `${c.success}15` : `${c.error}15`,\n color: result.success ? c.success : c.error,\n fontWeight: 500,\n }}\n >\n {result.success ? \"✓ Applied!\" : `✗ ${result.error}`}\n </div>\n )}\n\n <div style={{ display: \"flex\", gap: 12, flexWrap: \"wrap\" }}>\n <button\n onClick={() => setSelectedSource(null)}\n style={{\n flex: \"1 1 auto\",\n padding: \"12px 20px\",\n borderRadius: 10,\n border: `1px solid ${c.border}`,\n background: \"transparent\",\n color: c.text,\n cursor: \"pointer\",\n }}\n >\n Cancel\n </button>\n\n {/* Clear Session Button */}\n {ENABLE_SESSION_PERSISTENCE && (\n <button\n onClick={handleClearSession}\n style={{\n flex: \"0 0 auto\",\n padding: \"12px 20px\",\n borderRadius: 10,\n border: `1px solid ${c.error}`,\n background: \"transparent\",\n color: c.error,\n cursor: \"pointer\",\n fontSize: 12,\n }}\n title=\"Clear this session and start fresh\"\n >\n Clear Session\n </button>\n )}\n\n {editHistory.length > 0 && (\n <button\n onClick={handleDone}\n style={{\n flex: \"1 1 auto\",\n padding: \"12px 20px\",\n borderRadius: 10,\n border: `1px solid ${c.success}`,\n background: \"transparent\",\n color: c.success,\n fontWeight: 600,\n cursor: \"pointer\",\n }}\n >\n Finish & Reload\n </button>\n )}\n <button\n onClick={handleSubmit}\n disabled={isLoading || !suggestion.trim()}\n style={{\n flex: \"2 1 auto\",\n padding: \"12px 20px\",\n borderRadius: 10,\n border: \"none\",\n background: isLoading ? c.muted : c.accent,\n color: \"#fff\",\n fontWeight: 600,\n cursor: isLoading ? \"wait\" : \"pointer\",\n opacity: !suggestion.trim() ? 0.5 : 1,\n }}\n >\n {isLoading ? \"Applying...\" : \"Apply Changes ⌘↵\"}\n </button>\n </div>\n </div>\n )}\n\n {/* Badge */}\n {!selectedSource && (\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 AI Editor\n <span style={{ color: c.muted, fontSize: 11 }}>⌘⇧E</span>\n\n {ENABLE_SESSION_PERSISTENCE && hasActiveSession && (\n <>\n <span style={{ color: c.muted }}>|</span>\n <span style={{ color: \"#f59e0b\", fontSize: 11 }}>📝 Session</span>\n <button\n onClick={handleClearSession}\n style={{\n background: \"none\",\n border: \"none\",\n color: c.muted,\n cursor: \"pointer\",\n fontSize: 11,\n }}\n title=\"Clear active session\"\n >\n 🗑️\n </button>\n </>\n )}\n\n <button\n onClick={() => setEnabled(false)}\n style={{\n background: \"none\",\n border: \"none\",\n color: c.muted,\n cursor: \"pointer\",\n }}\n >\n ×\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"names":["cleanPath","shouldSkipPath","current","iterations","resolved","createContext","useContext","useState","useEffect","useCallback","jsxs","jsx","result","SyntaxHighlighter","vscDarkPlus","vs","Fragment"],"mappings":"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"}
|