next-ai-editor 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments-CjBQxjDP.js","sources":["../src/server/utils/file-system.ts","../src/server/utils/source-map.ts","../src/server/utils/ast.ts","../src/server/handlers/read.ts","../src/server/handlers/undo.ts","../src/server/handlers/resolve.ts","../src/server/handlers/absolute-path.ts","../src/server/handlers/validate-session.ts","../src/server/agent/sdk-client.ts","../src/server/agent/session-store.ts","../src/server/handlers/chat.ts","../src/server/handlers/config.ts","../src/server/handlers/index.ts","../src/server/handlers/pages-router.ts","../src/server/handlers/comments.ts"],"sourcesContent":["// =============================================================================\n// FILE: lib/ai-editor-utils.ts\n// Shared utilities for AI editor API routes\n// =============================================================================\n\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { NextResponse } from \"next/server\";\n\n/**\n * Validate that we're in development mode\n * Returns error response if not in dev mode, null otherwise\n */\nexport function validateDevMode(): NextResponse | null {\n if (process.env.NODE_ENV !== \"development\") {\n return NextResponse.json(\n { success: false, error: \"Development mode only\" },\n { status: 403 },\n );\n }\n return null;\n}\n\n/**\n * Normalize file path by removing webpack/turbopack prefixes\n */\nexport function normalizePath(filePath: string): string {\n return filePath\n .replace(/^webpack-internal:\\/\\/\\/\\([^)]+\\)\\/\\.?/, \"\")\n .replace(/^webpack:\\/\\/[^/]*\\//, \"\")\n .replace(/^\\.\\//, \"\")\n .replace(/\\?.*$/, \"\");\n}\n\n/**\n * Resolve a file path to an absolute path within the project\n * Returns null if file doesn't exist or is outside project root\n */\nexport async function resolveFilePath(\n projectRoot: string,\n normalizedPath: string,\n): Promise<string | null> {\n const candidates = [\n path.resolve(projectRoot, normalizedPath),\n path.resolve(projectRoot, \"src\", normalizedPath),\n path.resolve(projectRoot, \"app\", normalizedPath),\n ];\n\n for (const candidate of candidates) {\n // Security: ensure path is within project root\n if (!candidate.startsWith(projectRoot)) continue;\n\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n // File doesn't exist, try next candidate\n }\n }\n\n return null;\n}\n\n/**\n * Validate that a file path is within the project root (security check)\n */\nexport function isPathSecure(\n absolutePath: string,\n projectRoot: string,\n): boolean {\n return absolutePath.startsWith(projectRoot);\n}\n\n/**\n * Check if a file exists\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","// =============================================================================\n// FILE: lib/source-map-resolver.ts\n// Source map resolution utility for Next.js dev mode\n// =============================================================================\n\nimport { SourceMapConsumer } from \"@jridgewell/source-map\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { cleanPath, normalizeSourcePath, shouldSkipPath } from \"../../shared/path-utils\";\n\ninterface CompiledPosition {\n filePath: string;\n line: number;\n column: number;\n chunkId?: string;\n}\n\ninterface OriginalPosition {\n source: string;\n line: number;\n column: number;\n}\n\n// (SourceMapConsumer as any).initialize({\n// \"lib/mappings.wasm\": require.resolve(\"source-map/lib/mappings.wasm\"),\n// });\n\n/**\n * Parse _debugStack format to extract compiled position\n * Format: \"at ComponentName (file-path:line:column)\"\n * With turbopack, the file path is the compiled JS file path\n */\nexport function parseDebugStack(stack: string | any): CompiledPosition | null {\n if (!stack) return null;\n\n const stackStr =\n typeof stack === \"string\" ? stack : 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) or at Name (path?id:line:col)\n // Also handle file:// URLs and about://React/Server/ prefixes in the path\n const match = frame.match(/at\\s+(\\w+)\\s+\\((.+?):(\\d+):(\\d+)\\)?$/);\n if (match) {\n let filePath = match[2];\n const line = parseInt(match[3], 10);\n const column = parseInt(match[4], 10);\n\n // Extract chunk ID if present (e.g., \"path?21\" -> chunkId: \"21\")\n // Need to do this before cleaning, as the query param is before the line:col\n let chunkId: string | undefined;\n const chunkMatch = filePath.match(/\\?([^:]+)$/);\n if (chunkMatch) {\n chunkId = chunkMatch[1];\n filePath = filePath.replace(/\\?[^:]*$/, \"\");\n }\n\n // With turbopack, preserve the full file path (don't clean webpack patterns)\n // The path is already the compiled file path we need\n // Handle about://React/Server/file://... format\n filePath = cleanPath(filePath);\n\n if (!shouldSkipPath(filePath)) {\n console.log(\"parseDebugStack extracted:\", { filePath, line, column });\n return { filePath, line, column, chunkId };\n }\n }\n }\n\n console.log(\n \"parseDebugStack: no valid frame found in stack:\",\n stackStr.substring(0, 200),\n );\n return null;\n}\n\n/**\n * Extract component name from debug stack\n * Format: \"at ComponentName (file-path:line:column)\"\n */\nexport function extractComponentNameFromStack(stack: string | any): string | null {\n if (!stack) return null;\n\n const stackStr =\n typeof stack === \"string\" ? stack : 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 \"react_stack_bottom_frame\",\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+\\(/);\n if (match && match[1]) {\n const componentName = match[1];\n // Skip generic names\n if (componentName !== \"Object\" && componentName !== \"anonymous\") {\n return componentName;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Parse debug stack to extract both component instance (parent) and definition\n * Returns up to 2 frames: [componentDefinition, parentInstance]\n */\nexport function parseDebugStackFrames(stack: string | any): CompiledPosition[] {\n if (!stack) return [];\n\n const stackStr =\n typeof stack === \"string\" ? stack : 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 \"react_stack_bottom_frame\",\n ];\n\n const positions: CompiledPosition[] = [];\n\n for (const frame of frames) {\n if (skipPatterns.some((p) => frame.includes(p))) continue;\n\n const match = frame.match(/at\\s+(\\w+)\\s+\\((.+?):(\\d+):(\\d+)\\)?$/);\n if (match) {\n const componentName = match[1];\n let filePath = match[2];\n const line = parseInt(match[3], 10);\n const column = parseInt(match[4], 10);\n\n // Extract chunk ID\n let chunkId: string | undefined;\n const chunkMatch = filePath.match(/\\?([^:]+)$/);\n if (chunkMatch) {\n chunkId = chunkMatch[1];\n filePath = filePath.replace(/\\?[^:]*$/, \"\");\n }\n\n filePath = cleanPath(filePath);\n\n if (!shouldSkipPath(filePath)) {\n positions.push({ filePath, line, column, chunkId });\n\n // Get up to 2 frames: component definition and parent instance\n if (positions.length >= 2) break;\n }\n }\n }\n\n console.log(`parseDebugStackFrames extracted ${positions.length} frames:`, positions);\n return positions;\n}\n\n\n/**\n * Resolve original source position from compiled position\n * With turbopack, source maps are separate .map files with the same path as the compiled file\n */\nexport async function resolveOriginalPosition(\n compiledPos: CompiledPosition,\n projectRoot: string,\n): Promise<OriginalPosition | null> {\n try {\n console.log(\"resolveOriginalPosition called with:\", compiledPos);\n\n // With turbopack, the filePath from React is the compiled JS file path\n // The source map is the same path with .map appended\n let compiledFilePath = compiledPos.filePath;\n\n // Normalize the path (handle file:// URLs, URL encoding, etc.)\n compiledFilePath = cleanPath(compiledFilePath);\n console.log(\"After cleanPath:\", compiledFilePath);\n\n // Check if it's an HTTP URL (from dev server)\n if (compiledFilePath.startsWith(\"http://\") || compiledFilePath.startsWith(\"https://\")) {\n // Convert HTTP URL to filesystem path\n // e.g., http://localhost:3002/_next/static/chunks/... -> <projectRoot>/.next/dev/static/chunks/...\n const url = new URL(compiledFilePath);\n const pathname = url.pathname; // e.g., /_next/static/chunks/...\n\n // Map to filesystem (dev server serves from .next/dev/)\n if (pathname.startsWith(\"/_next/\")) {\n // Replace /_next/ with .next/dev/\n const relativePath = pathname.substring(\"/_next/\".length); // e.g., static/chunks/...\n compiledFilePath = path.join(projectRoot, \".next\", \"dev\", relativePath);\n } else {\n console.warn(\"Unexpected HTTP URL path:\", pathname);\n return null;\n }\n }\n // Resolve the path relative to project root\n else if (!path.isAbsolute(compiledFilePath)) {\n // If it starts with .next, it's relative to project root\n if (compiledFilePath.startsWith(\".next/\")) {\n compiledFilePath = path.resolve(projectRoot, compiledFilePath);\n } else {\n // Try to resolve as-is first\n const resolved = path.resolve(projectRoot, compiledFilePath);\n if (await fileExists(resolved)) {\n compiledFilePath = resolved;\n } else {\n // Try common locations\n const possiblePaths = [\n path.join(projectRoot, \".next\", \"dev\", compiledFilePath),\n path.join(projectRoot, compiledFilePath),\n ];\n for (const tryPath of possiblePaths) {\n if (await fileExists(tryPath)) {\n compiledFilePath = tryPath;\n break;\n }\n }\n }\n }\n }\n // If already absolute, just normalize it\n else {\n compiledFilePath = path.normalize(compiledFilePath);\n }\n\n console.log(\"Normalized compiled file path:\", compiledFilePath);\n\n // Check if the compiled file exists (for debugging)\n const compiledExists = await fileExists(compiledFilePath);\n console.log(\n \"Compiled file exists:\",\n compiledExists,\n \"at:\",\n compiledFilePath,\n );\n if (!compiledExists) {\n console.error(\n `Compiled file not found: ${compiledFilePath} (from parsed: ${compiledPos.filePath})`,\n );\n // Still try to find the source map, in case the file was moved\n }\n\n // Append .map to get the source map file path\n const sourceMapPath = compiledFilePath + \".map\";\n console.log(\"Looking for source map at:\", sourceMapPath);\n\n // Check if source map file exists\n const sourceMapExists = await fileExists(sourceMapPath);\n console.log(\"Source map exists:\", sourceMapExists);\n if (!sourceMapExists) {\n console.error(\n `Source map not found: ${sourceMapPath} (from compiled: ${compiledPos.filePath}, normalized: ${compiledFilePath})`,\n );\n // Try alternative paths\n const altPaths = [\n compiledFilePath.replace(/\\.js$/, \".map\"),\n path.join(\n path.dirname(compiledFilePath),\n path.basename(compiledFilePath) + \".map\",\n ),\n ];\n console.log(\"Trying alternative paths:\", altPaths);\n for (const altPath of altPaths) {\n if (await fileExists(altPath)) {\n console.log(\"Found source map at alternative path:\", altPath);\n return await resolveFromSourceMap(altPath, compiledPos, projectRoot);\n }\n }\n return null;\n }\n\n return await resolveFromSourceMap(sourceMapPath, compiledPos, projectRoot);\n } catch (error) {\n console.error(\"Error resolving source map:\", error);\n return null;\n }\n}\n\nasync function resolveFromSourceMap(\n sourceMapPath: string,\n compiledPos: CompiledPosition,\n projectRoot: string,\n): Promise<OriginalPosition | null> {\n try {\n // Read the source map file\n const sourceMapContent = await fs.readFile(sourceMapPath, \"utf-8\");\n const sourceMap = JSON.parse(sourceMapContent);\n\n // Handle empty source maps (common with server-side bundles)\n if (\n (!sourceMap.sources || sourceMap.sources.length === 0) &&\n (!sourceMap.sections || sourceMap.sections.length === 0)\n ) {\n console.warn(\n \"Empty source map detected, cannot resolve position:\",\n sourceMapPath,\n );\n return null;\n }\n\n // Handle sectioned source maps (turbopack uses these)\n if (sourceMap.sections) {\n // Find the section that contains our line\n // Sections are ordered by offset, find the last section that starts before our position\n // Offset is 0-indexed, compiledPos.line is 1-indexed\n let matchingSection = null;\n for (let i = sourceMap.sections.length - 1; i >= 0; i--) {\n const section = sourceMap.sections[i];\n const offset = section.offset;\n const sectionStartLine1Indexed = offset.line + 1;\n // Check if our position is at or after this section's start\n if (\n compiledPos.line > sectionStartLine1Indexed ||\n (compiledPos.line === sectionStartLine1Indexed &&\n compiledPos.column >= offset.column)\n ) {\n matchingSection = section;\n break;\n }\n }\n\n if (matchingSection && matchingSection.map) {\n const sectionMap = matchingSection.map;\n const offset = matchingSection.offset;\n\n // Use the section's source map\n let consumer: SourceMapConsumer;\n try {\n consumer = await new SourceMapConsumer(sectionMap);\n } catch (error) {\n console.error(\"Error creating SourceMapConsumer:\", error);\n return null;\n }\n try {\n // Adjust line/column relative to section offset\n // Offset is 0-indexed, source-map library uses 1-indexed lines\n // If offset is {line: 14, column: 0}, section starts at line 15 (1-indexed)\n // For compiled line 82 (1-indexed) with offset 14, adjusted line = 82 - 14 = 68 (1-indexed)\n const adjustedLine = compiledPos.line - offset.line;\n const adjustedColumn =\n compiledPos.line === offset.line + 1\n ? compiledPos.column - offset.column\n : compiledPos.column;\n\n const originalPos = consumer.originalPositionFor({\n line: adjustedLine,\n column: adjustedColumn,\n });\n\n if (originalPos.source && originalPos.line !== null) {\n const source = normalizeSourcePath(\n originalPos.source || \"\",\n projectRoot,\n );\n\n return {\n source,\n line: originalPos.line,\n column: originalPos.column ?? 0,\n };\n }\n } finally {\n consumer.destroy();\n }\n }\n return null;\n }\n\n // Handle regular (non-sectioned) source maps\n const consumer = await new SourceMapConsumer(sourceMap);\n try {\n const originalPos = consumer.originalPositionFor({\n line: compiledPos.line,\n column: compiledPos.column,\n });\n\n if (originalPos.source && originalPos.line !== null) {\n const source = normalizeSourcePath(\n originalPos.source || \"\",\n projectRoot,\n );\n\n return {\n source,\n line: originalPos.line,\n column: originalPos.column ?? 0,\n };\n }\n } finally {\n consumer.destroy();\n }\n\n return null;\n } catch (error) {\n console.error(\"Error resolving source map:\", error);\n return null;\n }\n}\n\n/**\n * Check if a file exists\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract ALL source maps from compiled JS content (legacy, for webpack)\n * Returns array of source maps since webpack bundles can have multiple\n */\nfunction extractAllSourceMaps(content: string): any[] {\n const sourceMaps: any[] = [];\n\n // Find all inline source maps (data URLs)\n const inlinePattern =\n /\\/\\/# sourceMappingURL=data:application\\/json;charset=utf-8;base64,([A-Za-z0-9+/=]+)/g;\n let match;\n\n while ((match = inlinePattern.exec(content)) !== null) {\n try {\n const base64Data = match[1];\n const jsonStr = Buffer.from(base64Data, \"base64\").toString(\"utf-8\");\n const sourceMap = JSON.parse(jsonStr);\n sourceMaps.push(sourceMap);\n } catch (err) {\n console.error(\"Error parsing inline source map:\", err);\n }\n }\n\n return sourceMaps;\n}\n\n/**\n * Extract source map from compiled JS content (single map, for backwards compat)\n */\nfunction extractSourceMap(content: string): any | null {\n const maps = extractAllSourceMaps(content);\n return maps.length > 0 ? maps[0] : null;\n}\n\n/**\n * Helper to get original position from _debugStack\n * Combines parsing and resolution into one function\n */\nexport async function getOriginalPositionFromDebugStack(\n debugStack: string | any,\n projectRoot: string,\n): Promise<OriginalPosition | null> {\n const compiledPos = parseDebugStack(debugStack);\n if (!compiledPos) return null;\n\n return await resolveOriginalPosition(compiledPos, projectRoot);\n}\n","// =============================================================================\n// FILE: lib/ai-editor-ast.ts\n// Shared AST parsing and element matching utilities for AI editor\n// =============================================================================\n\nimport * as parser from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport type { NodePath } from \"@babel/traverse\";\nimport * as t from \"@babel/types\";\nimport type { ElementContext } from \"../../shared/types\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface ElementMatch {\n node: t.JSXElement | t.JSXFragment;\n startLine: number;\n endLine: number;\n score: number;\n}\n\nexport interface TargetElementResult {\n startLine: number;\n endLine: number;\n componentStart: number;\n componentEnd: number;\n}\n\n// =============================================================================\n// PARSING\n// =============================================================================\n\n/**\n * Parse a file with Babel (TypeScript + JSX)\n */\nexport function parseFile(content: string): t.File | null {\n try {\n return parser.parse(content, {\n sourceType: \"module\",\n plugins: [\n \"jsx\",\n \"typescript\",\n \"decorators-legacy\",\n \"classProperties\",\n \"optionalChaining\",\n \"nullishCoalescingOperator\",\n ],\n });\n } catch (e) {\n console.error(\"Parse error:\", e);\n return null;\n }\n}\n\n/**\n * Extract the component name from an AST\n * Looks for both default and named exports\n */\nexport function extractComponentName(ast: t.File): string | null {\n let componentName: string | null = null;\n\n traverse(ast, {\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\n if (t.isFunctionDeclaration(path.node.declaration)) {\n componentName = path.node.declaration.id?.name || null;\n } else if (t.isArrowFunctionExpression(path.node.declaration)) {\n // Handle: export default () => <div>...</div>\n componentName = \"default\";\n } else if (t.isIdentifier(path.node.declaration)) {\n // Handle: const Foo = () => {}; export default Foo;\n componentName = path.node.declaration.name;\n }\n },\n ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {\n if (t.isFunctionDeclaration(path.node.declaration)) {\n componentName = path.node.declaration.id?.name || null;\n } else if (t.isVariableDeclaration(path.node.declaration)) {\n // Handle: export const Foo = () => {}\n const declarator = path.node.declaration.declarations[0];\n if (t.isIdentifier(declarator.id)) {\n componentName = declarator.id.name;\n }\n } else if (path.node.specifiers && path.node.specifiers.length > 0) {\n // Handle: function Foo() {}; export { Foo };\n const specifier = path.node.specifiers[0];\n if (t.isExportSpecifier(specifier) && t.isIdentifier(specifier.exported)) {\n componentName = specifier.exported.name;\n }\n }\n },\n });\n\n return componentName;\n}\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\n/**\n * Validate that generated code is syntactically correct\n * Checks if code can be parsed and maintains reasonable structure balance\n */\nexport function validateGeneratedCode(\n newCode: string,\n originalCode: string,\n fileContent?: string,\n): boolean {\n // Try to parse the new code as JSX\n try {\n // Check if it's a full component/function declaration\n const isFullComponent =\n /^(export\\s+)?(default\\s+)?function\\s+\\w+/.test(newCode.trim()) ||\n /^(export\\s+)?(default\\s+)?const\\s+\\w+\\s*=/.test(newCode.trim());\n\n if (isFullComponent) {\n // For full components, include any interface/type definitions from the original file\n let codeToValidate = newCode;\n if (fileContent) {\n const interfaceMatches = fileContent.match(\n /^(interface|type)\\s+\\w+[^}]*\\}/gm,\n );\n if (interfaceMatches) {\n codeToValidate = interfaceMatches.join(\"\\n\\n\") + \"\\n\\n\" + newCode;\n }\n }\n\n // Parse as a full module\n parser.parse(codeToValidate, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n } else {\n // Wrap in a function to make it valid\n const wrapped = `function _() { return (${newCode}); }`;\n parser.parse(wrapped, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n }\n } catch (e) {\n console.error(\"Generated code parse error:\", e);\n return false;\n }\n\n // Check brace/tag balance\n const origBraces = (originalCode.match(/[{}]/g) || []).length;\n const newBraces = (newCode.match(/[{}]/g) || []).length;\n const origTags = (originalCode.match(/[<>]/g) || []).length;\n const newTags = (newCode.match(/[<>]/g) || []).length;\n\n // Allow some variance but flag major differences\n if (\n Math.abs(origBraces - newBraces) > 4 ||\n Math.abs(origTags - newTags) > 4\n ) {\n console.warn(\n `Structure changed significantly: braces ${origBraces}->${newBraces}, tags ${origTags}->${newTags}`,\n );\n }\n\n return true;\n}\n\n// =============================================================================\n// ELEMENT FINDING\n// =============================================================================\n\n/**\n * Find the target element in the AST\n */\nexport function findTargetElement(\n ast: t.File,\n fileContent: string,\n options: {\n componentName: string;\n lineNumber: number;\n elementContext?: ElementContext;\n },\n): TargetElementResult | null {\n const { componentName, lineNumber, elementContext } = options;\n\n // First, find the component function/class\n let componentNode: t.Node | null = null;\n let componentStart = 0;\n let componentEnd = Infinity;\n let fallbackExportDefault: { node: t.Node; start: number; end: number } | null =\n null;\n\n traverse(ast, {\n FunctionDeclaration(path: NodePath<t.FunctionDeclaration>) {\n if (path.node.id?.name === componentName) {\n componentNode = path.node;\n componentStart = path.node.loc?.start.line || 0;\n componentEnd = path.node.loc?.end.line || Infinity;\n }\n },\n VariableDeclarator(path: NodePath<t.VariableDeclarator>) {\n if (\n t.isIdentifier(path.node.id) &&\n path.node.id.name === componentName\n ) {\n componentNode = path.node;\n const parent = path.parentPath.parent;\n componentStart = parent?.loc?.start.line || 0;\n componentEnd = parent?.loc?.end.line || Infinity;\n }\n },\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\n if (t.isFunctionDeclaration(path.node.declaration)) {\n const funcName = path.node.declaration.id?.name;\n if (funcName === componentName || !funcName) {\n componentNode = path.node;\n componentStart = path.node.loc?.start.line || 0;\n componentEnd = path.node.loc?.end.line || Infinity;\n } else if (!componentNode) {\n // Store as fallback if we don't find an exact match\n fallbackExportDefault = {\n node: path.node,\n start: path.node.loc?.start.line || 0,\n end: path.node.loc?.end.line || Infinity,\n };\n }\n }\n },\n });\n\n // If we didn't find the component by name, use the export default as fallback\n if (!componentNode && fallbackExportDefault !== null) {\n const fallback = fallbackExportDefault as { node: t.Node; start: number; end: number };\n console.log(\n `⚠️ Component \"${componentName}\" not found, using export default function as fallback`,\n );\n componentNode = fallback.node;\n componentStart = fallback.start;\n componentEnd = fallback.end;\n }\n\n // Find JSX elements within the component\n const allElementsByTag: Map<string, ElementMatch[]> = new Map();\n const elementsAtLine: ElementMatch[] = [];\n\n traverse(ast, {\n JSXElement(path: NodePath<t.JSXElement>) {\n const loc = path.node.loc;\n if (!loc) return;\n\n const startLine = loc.start.line;\n const endLine = loc.end.line;\n\n // Must be within component bounds\n if (startLine < componentStart || endLine > componentEnd) return;\n\n // Track ALL elements by tag name for nthOfType matching\n const opening = path.node.openingElement;\n if (t.isJSXIdentifier(opening.name)) {\n const tagName = opening.name.name;\n if (!allElementsByTag.has(tagName)) {\n allElementsByTag.set(tagName, []);\n }\n allElementsByTag\n .get(tagName)!\n .push({ node: path.node, startLine, endLine, score: 0 });\n }\n\n // Collect elements that start at the target line number\n if (startLine === lineNumber) {\n elementsAtLine.push({ node: path.node, startLine, endLine, score: 0 });\n }\n },\n });\n\n // Strategy 1: If we have elements at the exact line, use those (TRUST THE LINE NUMBER)\n if (elementsAtLine.length > 0) {\n // If only one element at this line, use it\n if (elementsAtLine.length === 1) {\n const target = elementsAtLine[0];\n return {\n startLine: target.startLine,\n endLine: target.endLine,\n componentStart,\n componentEnd,\n };\n }\n\n // Multiple elements at this line - use element context to disambiguate\n if (elementContext) {\n for (const elem of elementsAtLine) {\n if (t.isJSXElement(elem.node)) {\n const score = scoreElementMatch(elem.node, elementContext, fileContent);\n elem.score = score;\n }\n }\n elementsAtLine.sort((a, b) => b.score - a.score);\n\n if (elementsAtLine[0].score > 0) {\n return {\n startLine: elementsAtLine[0].startLine,\n endLine: elementsAtLine[0].endLine,\n componentStart,\n componentEnd,\n };\n }\n }\n\n // No element context or no good match, just use first element\n return {\n startLine: elementsAtLine[0].startLine,\n endLine: elementsAtLine[0].endLine,\n componentStart,\n componentEnd,\n };\n }\n\n // Strategy 2: Use element context to match (when no exact line match)\n if (elementContext?.tagName) {\n const allOfTag = allElementsByTag.get(elementContext.tagName);\n if (allOfTag && allOfTag.length > 0) {\n // If we have textContent or other context, score all elements and pick the best match\n if (elementContext.textContent || elementContext.className) {\n for (const elem of allOfTag) {\n if (t.isJSXElement(elem.node)) {\n elem.score = scoreElementMatch(elem.node, elementContext, fileContent);\n }\n }\n allOfTag.sort((a, b) => b.score - a.score);\n\n // Return the best match if it has a good score\n if (allOfTag[0].score > 50) { // 50 is the base score for tag name match\n return {\n startLine: allOfTag[0].startLine,\n endLine: allOfTag[0].endLine,\n componentStart,\n componentEnd,\n };\n }\n }\n\n // Otherwise, use nthOfType if provided\n if (elementContext.nthOfType && allOfTag.length >= elementContext.nthOfType) {\n const target = allOfTag[elementContext.nthOfType - 1];\n return {\n startLine: target.startLine,\n endLine: target.endLine,\n componentStart,\n componentEnd,\n };\n }\n }\n }\n\n // Strategy 3: Fallback - search nearby\n const nearbyElements: ElementMatch[] = [];\n\n traverse(ast, {\n JSXElement(path: NodePath<t.JSXElement>) {\n const loc = path.node.loc;\n if (!loc) return;\n\n const startLine = loc.start.line;\n const endLine = loc.end.line;\n\n if (startLine < componentStart || endLine > componentEnd) return;\n\n // Within 5 lines\n if (Math.abs(startLine - lineNumber) <= 5) {\n const score = elementContext\n ? scoreElementMatch(path.node, elementContext, fileContent)\n : 100 - Math.abs(startLine - lineNumber);\n nearbyElements.push({ node: path.node, startLine, endLine, score });\n }\n },\n });\n\n if (nearbyElements.length > 0) {\n nearbyElements.sort((a, b) => b.score - a.score);\n return {\n startLine: nearbyElements[0].startLine,\n endLine: nearbyElements[0].endLine,\n componentStart,\n componentEnd,\n };\n }\n\n // Strategy 4: Ultimate fallback - return component bounds\n if (componentNode && componentStart > 0) {\n return {\n startLine: componentStart,\n endLine: componentEnd,\n componentStart,\n componentEnd,\n };\n }\n\n return null;\n}\n\n// =============================================================================\n// ELEMENT MATCHING\n// =============================================================================\n\n/**\n * Score an element match against the provided context\n */\nexport function scoreElementMatch(\n node: t.JSXElement,\n context: ElementContext,\n fileContent: string,\n): number {\n let score = 0;\n const opening = node.openingElement;\n\n // Check tag name\n if (t.isJSXIdentifier(opening.name)) {\n if (opening.name.name === context.tagName) {\n score += 50;\n } else {\n return 0; // Tag must match\n }\n } else if (t.isJSXMemberExpression(opening.name)) {\n // Handle things like Motion.div\n const fullName = getJSXMemberName(opening.name);\n if (\n fullName === context.tagName ||\n fullName.endsWith(`.${context.tagName}`)\n ) {\n score += 50;\n } else {\n return 0;\n }\n }\n\n // Check className\n if (context.className) {\n const classAttr = opening.attributes.find(\n (attr: t.JSXAttribute | t.JSXSpreadAttribute) =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === \"className\",\n );\n if (classAttr && t.isJSXAttribute(classAttr)) {\n const classValue = getAttributeValue(classAttr);\n if (\n classValue &&\n context.className.split(/\\s+/).some((c) => classValue.includes(c))\n ) {\n score += 20;\n }\n }\n }\n\n // Check text content\n if (context.textContent && node.loc) {\n const elementCode = fileContent\n .split(\"\\n\")\n .slice(node.loc.start.line - 1, node.loc.end.line)\n .join(\"\\n\");\n const normalizedContent = context.textContent.toLowerCase().trim();\n const normalizedElement = elementCode.toLowerCase();\n if (normalizedElement.includes(normalizedContent)) {\n score += 30;\n }\n }\n\n // Check props\n if (context.props) {\n for (const [key, value] of Object.entries(context.props)) {\n if (key.startsWith(\"_\")) continue;\n const attr = opening.attributes.find(\n (a: t.JSXAttribute | t.JSXSpreadAttribute) =>\n t.isJSXAttribute(a) &&\n t.isJSXIdentifier(a.name) &&\n a.name.name === key,\n );\n if (attr) {\n score += 5;\n if (typeof value === \"string\" && t.isJSXAttribute(attr)) {\n const attrValue = getAttributeValue(attr);\n if (attrValue === value) score += 10;\n }\n }\n }\n }\n\n return score;\n}\n\n/**\n * Get the full name of a JSX member expression (e.g., \"Motion.div\")\n */\nexport function getJSXMemberName(node: t.JSXMemberExpression): string {\n if (t.isJSXIdentifier(node.object)) {\n return `${node.object.name}.${node.property.name}`;\n }\n if (t.isJSXMemberExpression(node.object)) {\n return `${getJSXMemberName(node.object)}.${node.property.name}`;\n }\n return node.property.name;\n}\n\n/**\n * Get the value of a JSX attribute\n */\nexport function getAttributeValue(attr: t.JSXAttribute): string | null {\n if (!attr.value) return null;\n if (t.isStringLiteral(attr.value)) return attr.value.value;\n if (\n t.isJSXExpressionContainer(attr.value) &&\n t.isStringLiteral(attr.value.expression)\n ) {\n return attr.value.expression.value;\n }\n return null;\n}\n","// =============================================================================\n// FILE: app/api/ai-editor/read/route.ts\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport fs from \"fs/promises\";\nimport {\n validateDevMode,\n normalizePath,\n resolveFilePath,\n} from \"../utils/file-system\";\nimport { parseDebugStack, resolveOriginalPosition, extractComponentNameFromStack } from \"../utils/source-map\";\nimport {\n parseFile,\n findTargetElement,\n extractComponentName,\n} from \"../utils/ast\";\nimport type { ElementContext } from \"../../shared/types\";\n\nexport async function handleRead(req: NextRequest): Promise<NextResponse> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n const { searchParams } = new URL(req.url);\n let filePath = searchParams.get(\"path\") || \"\";\n let lineNumber = parseInt(searchParams.get(\"line\") || \"1\");\n const debugStack = searchParams.get(\"debugStack\") || \"\";\n\n // Parse element context from query params\n const tagName = searchParams.get(\"tagName\") || \"\";\n const nthOfType = parseInt(searchParams.get(\"nthOfType\") || \"0\");\n const textContent = searchParams.get(\"textContent\") || \"\";\n const className = searchParams.get(\"className\") || \"\";\n\n const elementContext: ElementContext | undefined = tagName\n ? {\n tagName,\n nthOfType: nthOfType > 0 ? nthOfType : undefined,\n textContent: textContent || undefined,\n className: className || undefined,\n }\n : undefined;\n\n // Parse parent component from query params (from Fiber tree traversal)\n const parentFilePath = searchParams.get(\"parentFilePath\") || \"\";\n const parentLine = parseInt(searchParams.get(\"parentLine\") || \"0\");\n const parentComponentName = searchParams.get(\"parentComponentName\") || \"\";\n const parentDebugStack = searchParams.get(\"parentDebugStack\") || \"\";\n const childKey = searchParams.get(\"childKey\") || \"\"; // React key of child component instance\n\n const projectRoot = process.cwd();\n\n // If debugStack is provided, try to resolve original position using source maps\n if (debugStack) {\n const compiledPos = parseDebugStack(debugStack);\n if (compiledPos) {\n const originalPos = await resolveOriginalPosition(\n compiledPos,\n projectRoot,\n );\n if (originalPos) {\n filePath = originalPos.source;\n lineNumber = originalPos.line;\n }\n }\n }\n\n // Normalize and resolve file path\n const normalizedPath = normalizePath(filePath);\n const absolutePath = await resolveFilePath(projectRoot, normalizedPath);\n if (!absolutePath) {\n return NextResponse.json(\n { success: false, error: \"File not found\" },\n { status: 404 },\n );\n }\n\n const content = await fs.readFile(absolutePath, \"utf-8\");\n\n // Parse with Babel to find component and element\n const ast = parseFile(content);\n if (!ast) {\n return NextResponse.json(\n { success: false, error: \"Failed to parse file\" },\n { status: 400 },\n );\n }\n\n // Extract component name from file (try both default and named exports)\n const componentName = extractComponentName(ast);\n\n if (!componentName) {\n // Fallback: return full file\n return NextResponse.json({\n success: true,\n content,\n lineStart: 1,\n lineEnd: content.split(\"\\n\").length,\n });\n }\n\n // Find component and target element using same logic as /edit\n const target = findTargetElement(ast, content, {\n componentName,\n lineNumber,\n elementContext,\n });\n\n if (!target) {\n return NextResponse.json({\n success: true,\n content,\n lineStart: 1,\n lineEnd: content.split(\"\\n\").length,\n });\n }\n\n\n // Return full component without markers (client will highlight visually)\n const lines = content.split(\"\\n\");\n const componentLines = lines.slice(\n target.componentStart - 1,\n target.componentEnd,\n );\n\n const preview = componentLines.join(\"\\n\");\n\n // Get parent instance context from client-provided data (Fiber tree traversal)\n let parentInstance = null;\n if (parentDebugStack) {\n try {\n // Resolve parent file path from debugStack\n let resolvedParentPath = parentFilePath;\n let resolvedParentLine = parentLine;\n let resolvedParentComponentName = parentComponentName;\n\n // Extract component name from debugStack if not provided by client\n if (!resolvedParentComponentName && parentDebugStack) {\n resolvedParentComponentName = extractComponentNameFromStack(parentDebugStack) || '';\n }\n\n // Parse debugStack to resolve the parent's position from its debugLocation\n if (parentDebugStack) {\n const compiledPos = parseDebugStack(parentDebugStack);\n if (compiledPos) {\n const originalPos = await resolveOriginalPosition(\n compiledPos,\n projectRoot,\n );\n if (originalPos) {\n resolvedParentPath = originalPos.source;\n resolvedParentLine = originalPos.line;\n }\n }\n }\n\n const normalizedParentPath = normalizePath(resolvedParentPath);\n const absoluteParentPath = await resolveFilePath(\n projectRoot,\n normalizedParentPath,\n );\n\n if (absoluteParentPath && resolvedParentComponentName) {\n const parentContent = await fs.readFile(absoluteParentPath, \"utf-8\");\n const parentAst = parseFile(parentContent);\n\n if (parentAst) {\n // Search for the specific child component usage within the parent\n // e.g., find <InfoBox /> or <Header /> within Home component\n\n // If childKey is provided and numeric, use it to find the specific instance\n let nthOfType: number | undefined = undefined;\n if (childKey) {\n const keyAsNumber = parseInt(childKey, 10);\n if (!isNaN(keyAsNumber)) {\n // Key is numeric (e.g., \"0\", \"1\", \"2\" from array.map((item, index) => ...))\n // Convert to 1-indexed nthOfType\n nthOfType = keyAsNumber + 1;\n }\n }\n\n const parentTarget = findTargetElement(parentAst, parentContent, {\n componentName: resolvedParentComponentName,\n lineNumber: 0, // Don't use line number - rely on element context to find correct instance\n elementContext: {\n tagName: componentName, // Search for child component usage\n nthOfType, // Find specific instance if key is numeric\n textContent: textContent || undefined, // Use text content to match the specific instance\n },\n });\n\n if (parentTarget) {\n const parentLines = parentContent.split(\"\\n\");\n const parentComponentLines = parentLines.slice(\n parentTarget.componentStart - 1,\n parentTarget.componentEnd,\n );\n\n parentInstance = {\n filePath: resolvedParentPath,\n content: parentComponentLines.join(\"\\n\"),\n lineStart: parentTarget.componentStart,\n lineEnd: parentTarget.componentEnd,\n usageLineStart: parentTarget.startLine,\n usageLineEnd: parentTarget.endLine,\n componentName: resolvedParentComponentName,\n };\n }\n }\n }\n } catch (error) {\n // Non-fatal, continue without parent instance\n console.error(\"Error resolving parent instance:\", error);\n }\n }\n\n return NextResponse.json({\n success: true,\n content: preview,\n lineStart: target.componentStart,\n lineEnd: target.componentEnd,\n targetStartLine: target.startLine,\n targetEndLine: target.endLine,\n componentName, // Return the actual component name parsed from code\n parentInstance, // Optional: where this component is used\n });\n}\n","// =============================================================================\n// FILE: app/api/ai-editor/undo/route.ts\n// Undo endpoint - restores file content from snapshot\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport fs from \"fs/promises\";\nimport {\n validateDevMode,\n normalizePath,\n resolveFilePath,\n isPathSecure,\n} from \"../utils/file-system\";\n\ninterface UndoRequest {\n filePath: string;\n content: string;\n}\n\nexport async function handleUndo(req: NextRequest): Promise<NextResponse> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n try {\n const body: UndoRequest = await req.json();\n const { filePath, content } = body;\n\n if (!filePath || typeof content !== \"string\") {\n return NextResponse.json(\n {\n success: false,\n error: \"Invalid request: filePath and content required\",\n },\n { status: 400 },\n );\n }\n\n const projectRoot = process.cwd();\n const normalizedPath = normalizePath(filePath);\n const absolutePath = await resolveFilePath(projectRoot, normalizedPath);\n\n if (!absolutePath) {\n return NextResponse.json(\n { success: false, error: `File not found: ${normalizedPath}` },\n { status: 404 },\n );\n }\n\n // Security: Ensure file is within project root\n if (!isPathSecure(absolutePath, projectRoot)) {\n return NextResponse.json(\n { success: false, error: \"Access denied: File outside project root\" },\n { status: 403 },\n );\n }\n\n // Write the snapshot content back to the file\n await fs.writeFile(absolutePath, content, \"utf-8\");\n\n console.log(`✅ Undo: Restored ${normalizedPath}`);\n return NextResponse.json({ success: true });\n } catch (error) {\n console.error(\"Undo error:\", error);\n return NextResponse.json(\n { success: false, error: String(error) },\n { status: 500 },\n );\n }\n}\n","// =============================================================================\n// FILE: app/api/ai-editor/resolve/route.ts\n// Resolves compiled stack positions to original source locations\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { validateDevMode } from \"../utils/file-system\";\nimport {\n parseDebugStack,\n parseDebugStackFrames,\n resolveOriginalPosition,\n} from \"../utils/source-map\";\n\nexport async function handleResolve(req: NextRequest): Promise<NextResponse> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n try {\n const body = await req.json();\n const debugStack = body?.debugStack;\n\n if (!debugStack || typeof debugStack !== \"string\") {\n return NextResponse.json(\n { success: false, error: \"Missing debugStack\" },\n { status: 400 },\n );\n }\n\n // Parse multiple frames to get both component definition and parent instance\n const compiledFrames = parseDebugStackFrames(debugStack);\n\n if (compiledFrames.length === 0) {\n // Fallback to single frame parsing for backward compatibility\n const compiledPos = parseDebugStack(debugStack);\n if (!compiledPos) {\n console.error(\"Could not parse debug stack:\", debugStack);\n return NextResponse.json(\n { success: false, error: \"Could not parse stack\" },\n { status: 422 },\n );\n }\n\n const originalPos = await resolveOriginalPosition(\n compiledPos,\n process.cwd(),\n );\n\n if (!originalPos) {\n return NextResponse.json(\n { success: false, error: \"Source map lookup failed\" },\n { status: 404 },\n );\n }\n\n return NextResponse.json({\n success: true,\n filePath: originalPos.source,\n lineNumber: originalPos.line,\n columnNumber: originalPos.column ?? 0,\n });\n }\n\n // Resolve all frames\n const resolvedFrames = [];\n for (const frame of compiledFrames) {\n const originalPos = await resolveOriginalPosition(frame, process.cwd());\n if (originalPos) {\n resolvedFrames.push({\n filePath: originalPos.source,\n lineNumber: originalPos.line,\n columnNumber: originalPos.column ?? 0,\n });\n }\n }\n\n if (resolvedFrames.length === 0) {\n return NextResponse.json(\n { success: false, error: \"Source map lookup failed for all frames\" },\n { status: 404 },\n );\n }\n\n console.log(\"Resolved frames:\", resolvedFrames);\n\n // Return primary frame for backward compatibility, plus all frames\n return NextResponse.json({\n success: true,\n filePath: resolvedFrames[0].filePath,\n lineNumber: resolvedFrames[0].lineNumber,\n columnNumber: resolvedFrames[0].columnNumber,\n frames: resolvedFrames, // [componentDefinition, parentInstance]\n });\n } catch (error) {\n console.error(\"Source resolve error:\", error);\n return NextResponse.json(\n { success: false, error: \"Internal error\" },\n { status: 500 },\n );\n }\n}\n","// =============================================================================\n// FILE: app/api/ai-editor/absolute-path/route.ts\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport {\n validateDevMode,\n normalizePath,\n resolveFilePath,\n} from \"../utils/file-system\";\n\nexport async function handleAbsolutePath(req: NextRequest): Promise<NextResponse> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n const { searchParams } = new URL(req.url);\n const filePath = searchParams.get(\"path\") || \"\";\n\n if (!filePath) {\n return NextResponse.json(\n { success: false, error: \"Missing path\" },\n { status: 400 },\n );\n }\n\n const projectRoot = process.cwd();\n const normalizedPath = normalizePath(filePath);\n const absolutePath = await resolveFilePath(projectRoot, normalizedPath);\n\n if (!absolutePath) {\n return NextResponse.json(\n { success: false, error: \"File not found\" },\n { status: 404 },\n );\n }\n\n return NextResponse.json({\n success: true,\n absolutePath,\n });\n}\n","// =============================================================================\n// FILE: app/api/ai-editor/validate-session/route.ts\n// Validates session by checking if file has been modified externally\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport fs from \"fs/promises\";\nimport crypto from \"crypto\";\nimport {\n validateDevMode,\n normalizePath,\n resolveFilePath,\n isPathSecure,\n} from \"../utils/file-system\";\n\nexport async function handleValidateSession(req: NextRequest): Promise<NextResponse> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n try {\n const body = await req.json();\n const { filePath, lastKnownHash, lastKnownSize } = body;\n\n if (!filePath || !lastKnownHash || lastKnownSize === undefined) {\n return NextResponse.json(\n { success: false, error: \"Missing required fields\" },\n { status: 400 }\n );\n }\n\n const projectRoot = process.cwd();\n const normalizedPath = normalizePath(filePath);\n const absolutePath = await resolveFilePath(projectRoot, normalizedPath);\n\n if (!absolutePath) {\n return NextResponse.json(\n { success: false, error: \"File not found\" },\n { status: 404 }\n );\n }\n\n if (!isPathSecure(absolutePath, projectRoot)) {\n return NextResponse.json(\n { success: false, error: \"Access denied\" },\n { status: 403 }\n );\n }\n\n // Read file content\n const content = await fs.readFile(absolutePath, \"utf-8\");\n\n // Compute SHA-256 hash\n const hash = crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n\n // Get file stats\n const stats = await fs.stat(absolutePath);\n\n // Check if file has changed\n const isValid =\n hash === lastKnownHash && content.length === lastKnownSize;\n\n console.log(`[validate-session] ${filePath}:`);\n console.log(` Hash match: ${hash === lastKnownHash}`);\n console.log(` Size match: ${content.length === lastKnownSize}`);\n console.log(` Is valid: ${isValid}`);\n\n return NextResponse.json({\n success: true,\n isValid,\n currentHash: hash,\n currentSize: content.length,\n lastModifiedTime: stats.mtimeMs,\n });\n } catch (error) {\n console.error(\"Validation error:\", error);\n return NextResponse.json(\n { success: false, error: String(error) },\n { status: 500 }\n );\n }\n}\n","import {\n unstable_v2_createSession,\n unstable_v2_resumeSession,\n type SDKSession,\n type SDKSessionOptions,\n type SDKMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\n\n/**\n * Configuration for the AI editor agent\n */\nexport interface AIEditorAgentConfig {\n apiKey: string;\n projectRoot: string;\n sessionId?: string; // For resuming sessions\n allowedTools?: string[];\n disallowedTools?: string[];\n}\n\n/**\n * Context about the selected component (optional)\n */\nexport interface ComponentContext {\n filePath: string;\n lineNumber: number;\n componentName: string;\n elementContext?: {\n tagName?: string;\n className?: string;\n textContent?: string;\n [key: string]: any;\n };\n}\n\n/**\n * Wrapper around Claude Agent SDK for the AI editor\n */\nexport class AIEditorAgent {\n private session: SDKSession;\n private projectRoot: string;\n\n private constructor(session: SDKSession, projectRoot: string) {\n this.session = session;\n this.projectRoot = projectRoot;\n }\n\n /**\n * Create a new agent instance\n */\n static async create(config: AIEditorAgentConfig): Promise<AIEditorAgent> {\n const sessionOptions: SDKSessionOptions = {\n model: \"claude-sonnet-4-5-20250929\",\n // Enable auto-apply for edits without permission prompts\n permissionMode: \"acceptEdits\",\n env: {\n ...process.env,\n ANTHROPIC_API_KEY: config.apiKey,\n // Set working directory\n PWD: config.projectRoot,\n },\n // Explicitly allow core development tools\n allowedTools: config.allowedTools || [\"Read\", \"Edit\", \"Glob\", \"Grep\"],\n disallowedTools: config.disallowedTools || [],\n };\n\n let session: SDKSession;\n if (config.sessionId) {\n // Resume existing session\n session = unstable_v2_resumeSession(config.sessionId, sessionOptions);\n } else {\n // Create new session\n session = unstable_v2_createSession(sessionOptions);\n }\n\n return new AIEditorAgent(session, config.projectRoot);\n }\n\n /**\n * Send a message to the agent and stream responses\n */\n async *sendMessage(\n message: string,\n componentContext?: ComponentContext\n ): AsyncGenerator<SDKMessage, void, unknown> {\n // Build the full message with terse response instructions\n let fullMessage = `<response_style>\nKEEP RESPONSES EXTREMELY BRIEF AND STATUS-LIKE.\n- Use terse status messages: \"Reading file.tsx\", \"Changing color\", \"Done\"\n- NO conversational language (avoid: \"I'll\", \"Let me\", \"Sure\", \"Great\", \"I can see\")\n- NO explanations unless explicitly asked\n- State ONLY what you're doing, nothing more\n- Format: Action + target (e.g., \"Updating StatsCard.tsx:24\")\n</response_style>\n\n`;\n\n // If component context is provided, add it to the message\n if (componentContext) {\n fullMessage += `[Component: ${componentContext.componentName} at ${componentContext.filePath}:${componentContext.lineNumber}]\\n\\n`;\n }\n\n fullMessage += message;\n\n // Send the message\n await this.session.send(fullMessage);\n\n // Stream responses\n for await (const event of this.session.stream()) {\n yield event;\n }\n }\n\n /**\n * Get the session ID\n */\n getSessionId(): string {\n return this.session.sessionId;\n }\n\n /**\n * Close the session\n */\n close(): void {\n this.session.close();\n }\n\n /**\n * Async disposal support\n */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.session[Symbol.asyncDispose]();\n }\n}\n","import { AIEditorAgent, type AIEditorAgentConfig } from \"./sdk-client.js\";\n\n/**\n * Represents an active agent session\n */\nexport interface AgentSession {\n sessionId: string;\n threadId: string;\n agent: AIEditorAgent;\n createdAt: number;\n lastActive: number;\n isLocked: boolean;\n}\n\n/**\n * Configuration for creating a new session\n */\nexport interface CreateSessionConfig {\n sessionId?: string; // If provided, resume existing session\n threadId: string;\n apiKey: string;\n projectRoot: string;\n allowedTools?: string[];\n disallowedTools?: string[];\n}\n\n/**\n * Manages agent sessions across requests\n * Sessions are stored in-memory and automatically cleaned up after inactivity\n */\nexport class AgentSessionStore {\n private sessions: Map<string, AgentSession> = new Map();\n private readonly SESSION_TIMEOUT = 1000 * 60 * 30; // 30 minutes\n private readonly CLEANUP_INTERVAL = 1000 * 60 * 5; // 5 minutes\n\n constructor() {\n // Start periodic cleanup of expired sessions\n this.startCleanupTimer();\n }\n\n /**\n * Create or resume a session\n */\n async createSession(config: CreateSessionConfig): Promise<AgentSession> {\n const sessionId = config.sessionId || this.generateSessionId();\n\n // Check if session already exists\n const existing = this.sessions.get(sessionId);\n if (existing) {\n // Update last active time and return existing session\n existing.lastActive = Date.now();\n existing.threadId = config.threadId; // Allow switching threads\n return existing;\n }\n\n // Create new agent instance\n const agent = await AIEditorAgent.create({\n apiKey: config.apiKey,\n projectRoot: config.projectRoot,\n sessionId: config.sessionId,\n allowedTools: config.allowedTools,\n disallowedTools: config.disallowedTools,\n });\n\n // Create session record\n // Note: We use our own sessionId here because the SDK sessionId\n // is not available until after the first message is sent\n const session: AgentSession = {\n sessionId: sessionId,\n threadId: config.threadId,\n agent,\n createdAt: Date.now(),\n lastActive: Date.now(),\n isLocked: false,\n };\n\n this.sessions.set(sessionId, session);\n return session;\n }\n\n /**\n * Get a session by ID\n */\n getSession(sessionId: string): AgentSession | undefined {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.lastActive = Date.now();\n }\n return session;\n }\n\n /**\n * Acquire a lock on a session to prevent concurrent edits\n * Returns true if lock was acquired, false if already locked\n */\n acquireLock(sessionId: string): boolean {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n if (session.isLocked) {\n return false;\n }\n\n session.isLocked = true;\n session.lastActive = Date.now();\n return true;\n }\n\n /**\n * Release a lock on a session\n */\n releaseLock(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.isLocked = false;\n session.lastActive = Date.now();\n }\n }\n\n /**\n * Check if any session is currently locked (to prevent concurrent edits)\n */\n hasActiveLock(): boolean {\n for (const session of this.sessions.values()) {\n if (session.isLocked) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get all active sessions for a thread\n */\n getSessionsByThread(threadId: string): AgentSession[] {\n const sessions: AgentSession[] = [];\n for (const session of this.sessions.values()) {\n if (session.threadId === threadId) {\n sessions.push(session);\n }\n }\n return sessions;\n }\n\n /**\n * Delete a session\n */\n deleteSession(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.agent.close();\n this.sessions.delete(sessionId);\n }\n }\n\n /**\n * Delete all sessions for a thread\n */\n deleteSessionsByThread(threadId: string): void {\n for (const [sessionId, session] of this.sessions.entries()) {\n if (session.threadId === threadId) {\n session.agent.close();\n this.sessions.delete(sessionId);\n }\n }\n }\n\n /**\n * Get all active sessions\n */\n getAllSessions(): AgentSession[] {\n return Array.from(this.sessions.values());\n }\n\n /**\n * Clean up expired sessions\n */\n private cleanupExpiredSessions(): void {\n const now = Date.now();\n const expiredSessions: string[] = [];\n\n for (const [sessionId, session] of this.sessions.entries()) {\n const inactiveTime = now - session.lastActive;\n if (inactiveTime > this.SESSION_TIMEOUT && !session.isLocked) {\n expiredSessions.push(sessionId);\n }\n }\n\n for (const sessionId of expiredSessions) {\n console.log(\n `[AgentSessionStore] Cleaning up expired session: ${sessionId}`\n );\n this.deleteSession(sessionId);\n }\n\n if (expiredSessions.length > 0) {\n console.log(\n `[AgentSessionStore] Cleaned up ${expiredSessions.length} expired sessions`\n );\n }\n }\n\n /**\n * Start periodic cleanup timer\n */\n private startCleanupTimer(): void {\n setInterval(() => {\n this.cleanupExpiredSessions();\n }, this.CLEANUP_INTERVAL);\n }\n\n /**\n * Generate a unique session ID\n */\n private generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n }\n\n /**\n * Get statistics about the session store\n */\n getStats() {\n return {\n totalSessions: this.sessions.size,\n lockedSessions: Array.from(this.sessions.values()).filter(\n (s) => s.isLocked\n ).length,\n sessions: Array.from(this.sessions.values()).map((s) => ({\n sessionId: s.sessionId,\n threadId: s.threadId,\n isLocked: s.isLocked,\n ageMinutes: Math.floor((Date.now() - s.createdAt) / 1000 / 60),\n inactiveMinutes: Math.floor((Date.now() - s.lastActive) / 1000 / 60),\n })),\n };\n }\n}\n\n// Singleton instance\nlet sessionStore: AgentSessionStore | null = null;\n\n/**\n * Get the global session store instance\n */\nexport function getSessionStore(): AgentSessionStore {\n if (!sessionStore) {\n sessionStore = new AgentSessionStore();\n }\n return sessionStore;\n}\n","// =============================================================================\n// FILE: src/server/handlers/chat.ts\n// SSE streaming endpoint for AI chat using Agent SDK\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { validateDevMode } from \"../utils/file-system.js\";\nimport { getSessionStore } from \"../agent/session-store.js\";\nimport type { ComponentContext } from \"../agent/sdk-client.js\";\n\ninterface ChatRequest {\n sessionId?: string;\n threadId: string;\n message: string;\n componentContext?: ComponentContext;\n}\n\n/**\n * Handle chat requests with SSE streaming\n */\nexport async function handleChat(req: NextRequest): Promise<Response> {\n const devModeError = validateDevMode();\n if (devModeError) return devModeError;\n\n try {\n const body: ChatRequest = await req.json();\n const { sessionId, threadId, message, componentContext } = body;\n\n // Validate request\n if (!threadId || !message) {\n return NextResponse.json(\n { error: \"threadId and message are required\" },\n { status: 400 }\n );\n }\n\n // Get API key from environment\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n return NextResponse.json(\n { error: \"ANTHROPIC_API_KEY not configured\" },\n { status: 500 }\n );\n }\n\n // Get or create session\n const sessionStore = getSessionStore();\n const projectRoot = process.cwd();\n\n const session = await sessionStore.createSession({\n sessionId,\n threadId,\n apiKey,\n projectRoot,\n });\n\n // Try to acquire lock\n if (!sessionStore.acquireLock(session.sessionId)) {\n return NextResponse.json(\n {\n error:\n \"Another operation is in progress. Please wait for it to complete.\",\n },\n { status: 409 }\n );\n }\n\n // Create SSE stream\n const encoder = new TextEncoder();\n const stream = new ReadableStream({\n async start(controller) {\n try {\n // Send initial event\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"connected\", sessionId: session.sessionId })}\\n\\n`\n )\n );\n\n // Stream agent responses\n for await (const event of session.agent.sendMessage(\n message,\n componentContext\n )) {\n // Log all events for debugging\n console.log(\"[AGENT EVENT]\", event.type, JSON.stringify(event, null, 2));\n\n // Send event to client\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`)\n );\n }\n\n // Send completion event\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify({ type: \"done\" })}\\n\\n`)\n );\n\n controller.close();\n } catch (error: any) {\n console.error(\"[handleChat] Error:\", error);\n\n // Send error event\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"error\", error: error.message || String(error) })}\\n\\n`\n )\n );\n\n controller.close();\n } finally {\n // Release lock\n sessionStore.releaseLock(session.sessionId);\n }\n },\n });\n\n // Return SSE response\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n console.error(\"[handleChat] Request error:\", error);\n return NextResponse.json(\n { error: String(error) },\n { status: 500 }\n );\n }\n}\n","// =============================================================================\n// FILE: src/server/handlers/config.ts\n// Returns editor configuration including enabled status\n// =============================================================================\n\nimport { NextResponse } from \"next/server\";\n\n/**\n * Returns the editor configuration.\n * The enabled status is determined by environment variables on the server side.\n */\nexport async function handleConfig(): Promise<NextResponse> {\n // Check env vars on server side where they're actually available\n const enabled =\n process.env.NEXT_PUBLIC_AI_EDITOR_ENABLED === \"true\" ||\n process.env.VITE_AI_EDITOR_ENABLED === \"true\" ||\n process.env.REACT_APP_AI_EDITOR_ENABLED === \"true\";\n\n return NextResponse.json({\n enabled,\n // Include NODE_ENV for debugging\n nodeEnv: process.env.NODE_ENV,\n });\n}\n","// =============================================================================\n// FILE: src/server/handlers/index.ts\n// Unified catch-all handler for AI editor routes\n// =============================================================================\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { handleRead } from \"./read\";\nimport { handleUndo } from \"./undo\";\nimport { handleResolve } from \"./resolve\";\nimport { handleAbsolutePath } from \"./absolute-path\";\nimport { handleValidateSession } from \"./validate-session\";\nimport { handleChat } from \"./chat\";\nimport { handleConfig } from \"./config\";\n\n/**\n * Catch-all handler for AI editor routes\n *\n * Route mapping:\n * - GET /api/ai-editor/read -> handleRead\n * - POST /api/ai-editor/undo -> handleUndo\n * - POST /api/ai-editor/resolve -> handleResolve\n * - GET /api/ai-editor/absolute-path -> handleAbsolutePath\n * - POST /api/ai-editor/validate-session -> handleValidateSession\n * - POST /api/ai-editor/chat -> handleChat (SSE)\n */\nexport async function handleAIEditorRequest(\n req: NextRequest,\n context: { params: Promise<{ path: string[] }> }\n): Promise<NextResponse | Response> {\n const { path } = await context.params;\n const endpoint = path[0];\n const method = req.method;\n\n switch (endpoint) {\n case \"read\":\n if (method === \"GET\") return handleRead(req);\n break;\n case \"undo\":\n if (method === \"POST\") return handleUndo(req);\n break;\n case \"resolve\":\n if (method === \"POST\") return handleResolve(req);\n break;\n case \"absolute-path\":\n if (method === \"GET\") return handleAbsolutePath(req);\n break;\n case \"validate-session\":\n if (method === \"POST\") return handleValidateSession(req);\n break;\n case \"chat\":\n if (method === \"POST\") return handleChat(req);\n break;\n case \"config\":\n if (method === \"GET\") return handleConfig();\n break;\n }\n\n return NextResponse.json(\n { error: `Unknown endpoint: ${endpoint}` },\n { status: 404 }\n );\n}\n","// =============================================================================\n// FILE: src/server/handlers/pages-router.ts\n// Pages Router adapter for AI editor routes\n// =============================================================================\n\nimport type { NextApiRequest, NextApiResponse } from \"next\";\nimport { handleRead } from \"./read\";\nimport { handleUndo } from \"./undo\";\nimport { handleResolve } from \"./resolve\";\nimport { handleAbsolutePath } from \"./absolute-path\";\nimport { handleValidateSession } from \"./validate-session\";\nimport { handleChat } from \"./chat\";\nimport { handleConfig } from \"./config\";\n\n/**\n * Catch-all handler for AI editor routes (Pages Router)\n *\n * Usage:\n * ```ts\n * // pages/api/ai-editor/[...path].ts\n * import { handleAIEditorPagesRequest } from \"next-ai-editor/server\";\n * export default handleAIEditorPagesRequest;\n * ```\n *\n * Route mapping:\n * - GET /api/ai-editor/read -> handleRead\n * - POST /api/ai-editor/undo -> handleUndo\n * - POST /api/ai-editor/resolve -> handleResolve\n * - GET /api/ai-editor/absolute-path -> handleAbsolutePath\n * - POST /api/ai-editor/validate-session -> handleValidateSession\n * - POST /api/ai-editor/chat -> handleChat (SSE)\n */\nexport async function handleAIEditorPagesRequest(\n req: NextApiRequest,\n res: NextApiResponse\n): Promise<void> {\n const { path } = req.query;\n const endpoint = Array.isArray(path) ? path[0] : path;\n const method = req.method;\n\n // Convert NextApiRequest to NextRequest for internal handlers\n const url = `http://localhost:3000${req.url}`;\n const headers = new Headers();\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(\", \") : value);\n }\n });\n\n const nextRequest = new Request(url, {\n method: req.method || \"GET\",\n headers,\n body: method !== \"GET\" && method !== \"HEAD\" ? JSON.stringify(req.body) : undefined,\n }) as any; // NextRequest compatible\n\n let response: Response;\n\n switch (endpoint) {\n case \"read\":\n if (method === \"GET\") response = await handleRead(nextRequest);\n else break;\n break;\n case \"undo\":\n if (method === \"POST\") response = await handleUndo(nextRequest);\n else break;\n break;\n case \"resolve\":\n if (method === \"POST\") response = await handleResolve(nextRequest);\n else break;\n break;\n case \"absolute-path\":\n if (method === \"GET\") response = await handleAbsolutePath(nextRequest);\n else break;\n break;\n case \"validate-session\":\n if (method === \"POST\") response = await handleValidateSession(nextRequest);\n else break;\n break;\n case \"chat\":\n if (method === \"POST\") response = await handleChat(nextRequest);\n else break;\n break;\n case \"config\":\n if (method === \"GET\") response = await handleConfig();\n else break;\n break;\n default:\n res.status(404).json({ error: `Unknown endpoint: ${endpoint}` });\n return;\n }\n\n // @ts-ignore - response is assigned if any case matches\n if (!response) {\n res.status(405).json({ error: `Method ${method} not allowed for ${endpoint}` });\n return;\n }\n\n // Convert Response to NextApiResponse\n const data = await response.json();\n res.status(response.status).json(data);\n}\n","/**\n * Comment persistence handler\n * Saves/loads comments to/from .ai-editor/comments.json\n */\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { readFile, writeFile, mkdir } from \"fs/promises\";\nimport { join } from \"path\";\nimport { existsSync } from \"fs\";\n\nconst STORAGE_DIR = \".ai-editor\";\nconst STORAGE_FILE = \"comments.json\";\n\n/**\n * Get the project root directory\n */\nfunction getProjectRoot(): string {\n return process.cwd();\n}\n\n/**\n * Get the comments storage path\n */\nfunction getStoragePath(): string {\n return join(getProjectRoot(), STORAGE_DIR, STORAGE_FILE);\n}\n\n/**\n * Ensure storage directory exists\n */\nasync function ensureStorageDir(): Promise<void> {\n const dir = join(getProjectRoot(), STORAGE_DIR);\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n }\n}\n\n/**\n * Handle comment persistence requests\n */\nexport async function handleCommentsRequest(\n request: NextRequest\n): Promise<NextResponse> {\n // Only allow in development mode\n if (process.env.NODE_ENV !== \"development\") {\n return NextResponse.json(\n { error: \"Comments API only available in development\" },\n { status: 403 }\n );\n }\n\n try {\n if (request.method === \"GET\") {\n // Load comments\n const storagePath = getStoragePath();\n\n if (!existsSync(storagePath)) {\n return NextResponse.json({ comments: [] });\n }\n\n const data = await readFile(storagePath, \"utf-8\");\n const comments = JSON.parse(data);\n\n return NextResponse.json({ comments });\n }\n\n if (request.method === \"POST\") {\n const body = await request.json();\n const { action } = body;\n\n if (action === \"save\") {\n // Save comments\n const { comments } = body;\n\n await ensureStorageDir();\n const storagePath = getStoragePath();\n\n await writeFile(storagePath, JSON.stringify(comments, null, 2), \"utf-8\");\n\n return NextResponse.json({ success: true });\n }\n\n if (action === \"clear\") {\n // Clear comments\n await ensureStorageDir();\n const storagePath = getStoragePath();\n\n await writeFile(storagePath, JSON.stringify([]), \"utf-8\");\n\n return NextResponse.json({ success: true });\n }\n\n return NextResponse.json(\n { error: \"Invalid action\" },\n { status: 400 }\n );\n }\n\n return NextResponse.json(\n { error: \"Method not allowed\" },\n { status: 405 }\n );\n } catch (error) {\n console.error(\"Comment storage error:\", error);\n return NextResponse.json(\n { error: \"Internal server error\" },\n { status: 500 }\n );\n }\n}\n"],"names":["fileExists","consumer","path","nthOfType","sessionStore"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ require("react/jsx-runtime");
5
5
  require("react");
6
6
  require("react-markdown");
7
7
  require("remark-gfm");
8
- const comments = require("./comments-2HX-AAwu.cjs");
8
+ const comments = require("./comments-BQ6AQ-eC.cjs");
9
9
  exports.AIEditorProvider = AIEditorProvider.AIEditorProvider;
10
10
  exports.ChatPanel = AIEditorProvider.ChatPanel;
11
11
  exports.ControlPill = AIEditorProvider.ControlPill;
@@ -16,6 +16,7 @@ exports.findTargetElement = comments.findTargetElement;
16
16
  exports.getAttributeValue = comments.getAttributeValue;
17
17
  exports.getJSXMemberName = comments.getJSXMemberName;
18
18
  exports.getOriginalPositionFromDebugStack = comments.getOriginalPositionFromDebugStack;
19
+ exports.handleAIEditorPagesRequest = comments.handleAIEditorPagesRequest;
19
20
  exports.handleAIEditorRequest = comments.handleAIEditorRequest;
20
21
  exports.handleAbsolutePath = comments.handleAbsolutePath;
21
22
  exports.handleCommentsRequest = comments.handleCommentsRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.js CHANGED
@@ -3,34 +3,35 @@ import "react/jsx-runtime";
3
3
  import "react";
4
4
  import "react-markdown";
5
5
  import "remark-gfm";
6
- import { j, t, g, l, o, m, x, h, d, f, a as a2, c, b, e, i, n, q, u, p, r, w, s, v, k } from "./comments-BYFEhf6K.js";
6
+ import { k, u, j, m, q, o, y, a as a2, h, e, g, b, d, c, f, i, n, t, w, p, r, x, s, v, l } from "./comments-CjBQxjDP.js";
7
7
  export {
8
8
  A as AIEditorProvider,
9
9
  C as ChatPanel,
10
10
  a as ControlPill,
11
- j as extractComponentName,
12
- t as extractComponentNameFromStack,
13
- g as fileExists,
14
- l as findTargetElement,
15
- o as getAttributeValue,
16
- m as getJSXMemberName,
17
- x as getOriginalPositionFromDebugStack,
11
+ k as extractComponentName,
12
+ u as extractComponentNameFromStack,
13
+ j as fileExists,
14
+ m as findTargetElement,
15
+ q as getAttributeValue,
16
+ o as getJSXMemberName,
17
+ y as getOriginalPositionFromDebugStack,
18
+ a2 as handleAIEditorPagesRequest,
18
19
  h as handleAIEditorRequest,
19
- d as handleAbsolutePath,
20
- f as handleCommentsRequest,
21
- a2 as handleRead,
22
- c as handleResolve,
23
- b as handleUndo,
24
- e as handleValidateSession,
20
+ e as handleAbsolutePath,
21
+ g as handleCommentsRequest,
22
+ b as handleRead,
23
+ d as handleResolve,
24
+ c as handleUndo,
25
+ f as handleValidateSession,
25
26
  i as isPathSecure,
26
27
  n as normalizePath,
27
- q as parseDebugStack,
28
- u as parseDebugStackFrames,
28
+ t as parseDebugStack,
29
+ w as parseDebugStackFrames,
29
30
  p as parseFile,
30
31
  r as resolveFilePath,
31
- w as resolveOriginalPosition,
32
+ x as resolveOriginalPosition,
32
33
  s as scoreElementMatch,
33
34
  v as validateDevMode,
34
- k as validateGeneratedCode
35
+ l as validateGeneratedCode
35
36
  };
36
37
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,21 @@
1
+ import type { NextApiRequest, NextApiResponse } from "next";
2
+ /**
3
+ * Catch-all handler for AI editor routes (Pages Router)
4
+ *
5
+ * Usage:
6
+ * ```ts
7
+ * // pages/api/ai-editor/[...path].ts
8
+ * import { handleAIEditorPagesRequest } from "next-ai-editor/server";
9
+ * export default handleAIEditorPagesRequest;
10
+ * ```
11
+ *
12
+ * Route mapping:
13
+ * - GET /api/ai-editor/read -> handleRead
14
+ * - POST /api/ai-editor/undo -> handleUndo
15
+ * - POST /api/ai-editor/resolve -> handleResolve
16
+ * - GET /api/ai-editor/absolute-path -> handleAbsolutePath
17
+ * - POST /api/ai-editor/validate-session -> handleValidateSession
18
+ * - POST /api/ai-editor/chat -> handleChat (SSE)
19
+ */
20
+ export declare function handleAIEditorPagesRequest(req: NextApiRequest, res: NextApiResponse): Promise<void>;
21
+ //# sourceMappingURL=pages-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages-router.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/pages-router.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAS5D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAiEf"}
@@ -1,4 +1,5 @@
1
1
  export { handleAIEditorRequest } from "./handlers";
2
+ export { handleAIEditorPagesRequest } from "./handlers/pages-router";
2
3
  export { handleRead } from "./handlers/read";
3
4
  export { handleUndo } from "./handlers/undo";
4
5
  export { handleResolve } from "./handlers/resolve";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC"}
package/dist/server.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const comments = require("./comments-2HX-AAwu.cjs");
3
+ const comments = require("./comments-BQ6AQ-eC.cjs");
4
4
  exports.extractComponentName = comments.extractComponentName;
5
5
  exports.extractComponentNameFromStack = comments.extractComponentNameFromStack;
6
6
  exports.fileExists = comments.fileExists;
@@ -8,6 +8,7 @@ exports.findTargetElement = comments.findTargetElement;
8
8
  exports.getAttributeValue = comments.getAttributeValue;
9
9
  exports.getJSXMemberName = comments.getJSXMemberName;
10
10
  exports.getOriginalPositionFromDebugStack = comments.getOriginalPositionFromDebugStack;
11
+ exports.handleAIEditorPagesRequest = comments.handleAIEditorPagesRequest;
11
12
  exports.handleAIEditorRequest = comments.handleAIEditorRequest;
12
13
  exports.handleAbsolutePath = comments.handleAbsolutePath;
13
14
  exports.handleCommentsRequest = comments.handleCommentsRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"server.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"server.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/server.js CHANGED
@@ -1,28 +1,29 @@
1
- import { j, t, g, l, o, m, x, h, d, f, a, c, b, e, i, n, q, u, p, r, w, s, v, k } from "./comments-BYFEhf6K.js";
1
+ import { k, u, j, m, q, o, y, a, h, e, g, b, d, c, f, i, n, t, w, p, r, x, s, v, l } from "./comments-CjBQxjDP.js";
2
2
  export {
3
- j as extractComponentName,
4
- t as extractComponentNameFromStack,
5
- g as fileExists,
6
- l as findTargetElement,
7
- o as getAttributeValue,
8
- m as getJSXMemberName,
9
- x as getOriginalPositionFromDebugStack,
3
+ k as extractComponentName,
4
+ u as extractComponentNameFromStack,
5
+ j as fileExists,
6
+ m as findTargetElement,
7
+ q as getAttributeValue,
8
+ o as getJSXMemberName,
9
+ y as getOriginalPositionFromDebugStack,
10
+ a as handleAIEditorPagesRequest,
10
11
  h as handleAIEditorRequest,
11
- d as handleAbsolutePath,
12
- f as handleCommentsRequest,
13
- a as handleRead,
14
- c as handleResolve,
15
- b as handleUndo,
16
- e as handleValidateSession,
12
+ e as handleAbsolutePath,
13
+ g as handleCommentsRequest,
14
+ b as handleRead,
15
+ d as handleResolve,
16
+ c as handleUndo,
17
+ f as handleValidateSession,
17
18
  i as isPathSecure,
18
19
  n as normalizePath,
19
- q as parseDebugStack,
20
- u as parseDebugStackFrames,
20
+ t as parseDebugStack,
21
+ w as parseDebugStackFrames,
21
22
  p as parseFile,
22
23
  r as resolveFilePath,
23
- w as resolveOriginalPosition,
24
+ x as resolveOriginalPosition,
24
25
  s as scoreElementMatch,
25
26
  v as validateDevMode,
26
- k as validateGeneratedCode
27
+ l as validateGeneratedCode
27
28
  };
28
29
  //# sourceMappingURL=server.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-ai-editor",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "AI-powered React component editor for Next.js - edit your components with natural language in development mode",
5
5
  "author": "Jesse Halpern",
6
6
  "type": "module",
@@ -27,6 +27,8 @@
27
27
  },
28
28
  "files": [
29
29
  "dist",
30
+ "client",
31
+ "server",
30
32
  "README.md",
31
33
  "LICENSE"
32
34
  ],
@@ -0,0 +1,5 @@
1
+ {
2
+ "main": "../dist/server.cjs",
3
+ "module": "../dist/server.js",
4
+ "types": "../dist/server/index.d.ts"
5
+ }