vite-plugin-ai-diagnostic 1.0.6 → 1.0.8

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/langgraph.ts","../src/diagnostic.ts","../src/reporter.ts"],"sourcesContent":["/**\r\n * AI 诊断插件入口\r\n *\r\n * 功能:\r\n * - 自动诊断构建错误\r\n * - 提供修复建议\r\n * - 自动修复代码\r\n */\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { AIErrorDiagnostic } from \"./diagnostic\";\r\nimport { extractSourceFile } from \"vite-plugin-ai-shared\";\r\nimport { DiagnosticReporter, type DiagnosticReport } from \"./reporter\";\r\n\r\nexport interface AIPluginOptions {\r\n apiKey?: string;\r\n apiUrl?: string;\r\n autoFix?: boolean;\r\n model?: string;\r\n maxRetries?: number;\r\n output?: {\r\n console?: boolean;\r\n html?: boolean;\r\n markdown?: boolean;\r\n json?: boolean;\r\n };\r\n}\r\n\r\nexport function vitePluginAIDiagnostic(options: AIPluginOptions = {}): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n autoFix = false,\r\n model = \"gpt-4\",\r\n maxRetries = 3,\r\n output = {\r\n console: true,\r\n html: true,\r\n markdown: false,\r\n json: false,\r\n },\r\n } = options;\r\n\r\n const diagnostic = new AIErrorDiagnostic({\r\n apiKey,\r\n apiUrl,\r\n model,\r\n maxRetries,\r\n });\r\n\r\n let buildErrors: any[] = [];\r\n let lastTransformFile: string | null = null;\r\n let processedErrors = new Set<string>(); // 记录已处理的错误\r\n\r\n // 处理错误的函数\r\n async function processError(error: any) {\r\n // 生成错误的唯一标识\r\n const errorKey = `${error.file}:${error.message}`;\r\n\r\n // 如果已经处理过,跳过\r\n if (processedErrors.has(errorKey)) {\r\n console.log(\"🔍 [调试] 跳过重复错误:\", errorKey);\r\n return;\r\n }\r\n\r\n processedErrors.add(errorKey);\r\n\r\n try {\r\n console.log(\"\\n⚠️ 检测到错误,正在使用 AI 分析...\\n\");\r\n console.log(`📝 错误信息: ${error.message}`);\r\n console.log(`📂 文件路径: ${error.file || \"未知\"}`);\r\n console.log(\r\n `📄 代码长度: ${error.code ? error.code.length + \" 字符\" : \"无\"}`,\r\n );\r\n console.log(`🔧 自动修复: ${autoFix ? \"是\" : \"否\"}\\n`);\r\n\r\n if (!error.file || !error.code) {\r\n console.log(\"⚠️ 跳过此错误:缺少文件路径或代码内容\\n\");\r\n return;\r\n }\r\n\r\n const result = await diagnostic.diagnose(error, autoFix);\r\n\r\n // 控制台输出\r\n if (output.console !== false) {\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\");\r\n console.log(\"🔍 错误分析:\");\r\n console.log(result.analysis);\r\n console.log(\"\\n💡 修复建议:\");\r\n console.log(result.suggestion);\r\n\r\n if (result.fixedCode && result.filePath) {\r\n console.log(\"\\n✅ 已自动修复代码\");\r\n console.log(\"修复的文件:\", result.filePath);\r\n console.log(\"\\n💡 请重新运行构建命令\");\r\n } else if (autoFix) {\r\n console.log(\"\\n⚠️ 无法自动修复:AI 未生成修复代码\");\r\n }\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n }\r\n\r\n // 生成报告\r\n const report: DiagnosticReport = {\r\n timestamp: new Date().toLocaleString(\"zh-CN\"),\r\n error: {\r\n type: error.type || \"unknown\",\r\n message: error.message,\r\n file: error.file,\r\n stack: error.stack,\r\n },\r\n analysis: result.analysis,\r\n suggestion: result.suggestion,\r\n fixed: !!(result.fixedCode && result.filePath),\r\n fixedFilePath: result.filePath,\r\n };\r\n\r\n await DiagnosticReporter.generate(report, output);\r\n } catch (err: any) {\r\n console.error(\"❌ AI 诊断失败:\", err.message);\r\n }\r\n }\r\n\r\n return {\r\n name: \"vite-plugin-ai-diagnostic\",\r\n\r\n // 确保插件在其他插件之后执行,以捕获更多错误\r\n enforce: \"post\",\r\n\r\n configResolved(config) {\r\n console.log(\"\\n🤖 AI 诊断助手已启动...\");\r\n console.log(`⚙️ 自动修复: ${autoFix ? \"✅ 已启用\" : \"❌ 未启用\"}`);\r\n console.log(`📝 根目录: ${config.root}`);\r\n console.log(\r\n `📝 入口: ${config.build.rollupOptions?.input || \"index.html\"}\\n`,\r\n );\r\n },\r\n\r\n buildStart() {\r\n buildErrors = [];\r\n processedErrors.clear();\r\n console.log(\"🔍 [调试] buildStart 已执行\");\r\n },\r\n\r\n // 解析模块时捕获错误\r\n async resolveId(source, importer, options) {\r\n // 不要在这里 try-catch,让错误自然传播到 buildEnd\r\n return null;\r\n },\r\n\r\n // 加载模块时捕获错误\r\n async load(id) {\r\n // 不要在这里 try-catch,让错误自然传播到 buildEnd\r\n return null;\r\n },\r\n\r\n // Rollup 钩子:模块解析完成后调用\r\n moduleParsed(moduleInfo) {\r\n // 检查模块是否有导入错误\r\n if (moduleInfo.meta && moduleInfo.meta.error) {\r\n console.log(\"\\n⚠️ moduleParsed 检测到错误:\", moduleInfo.id);\r\n\r\n let code = undefined;\r\n if (moduleInfo.id && fs.existsSync(moduleInfo.id)) {\r\n code = fs.readFileSync(moduleInfo.id, \"utf-8\");\r\n }\r\n\r\n const errorInfo = {\r\n type: \"module\",\r\n message: moduleInfo.meta.error,\r\n stack: \"\",\r\n file: moduleInfo.id,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n }\r\n },\r\n\r\n buildEnd(error?: Error) {\r\n console.log(\"🔍 [调试] buildEnd 已执行, 有错误:\", !!error);\r\n\r\n if (error) {\r\n console.log(\"\\n⚠️ buildEnd 捕获到错误:\", error.message);\r\n\r\n const realFilePath = extractSourceFile(error, lastTransformFile);\r\n\r\n let code = undefined;\r\n if (realFilePath && fs.existsSync(realFilePath)) {\r\n try {\r\n code = fs.readFileSync(realFilePath, \"utf-8\");\r\n console.log(`📂 读取源文件成功: ${realFilePath}`);\r\n console.log(`📄 源文件长度: ${code.length} 字符`);\r\n } catch (e) {\r\n console.warn(\"⚠️ 无法读取文件:\", realFilePath);\r\n }\r\n }\r\n\r\n const errorInfo = {\r\n type: \"build\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: realFilePath,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n }\r\n },\r\n\r\n // Rollup 输出生成阶段的钩子\r\n renderStart(outputOptions, inputOptions) {\r\n console.log(\"🔍 [调试] renderStart 已执行\");\r\n },\r\n\r\n renderError(error?: Error) {\r\n console.log(\"🔍 [调试] renderError 已执行\");\r\n if (!error) return;\r\n\r\n console.log(\"\\n⚠️ renderError 捕获到错误:\", error.message);\r\n\r\n const realFilePath = extractSourceFile(error, lastTransformFile);\r\n\r\n let code = undefined;\r\n if (realFilePath && fs.existsSync(realFilePath)) {\r\n try {\r\n code = fs.readFileSync(realFilePath, \"utf-8\");\r\n console.log(`📂 读取源文件成功: ${realFilePath}`);\r\n console.log(`📄 源文件长度: ${code.length} 字符`);\r\n } catch (e) {\r\n console.warn(\"⚠️ 无法读取文件:\", realFilePath);\r\n }\r\n }\r\n\r\n const errorInfo = {\r\n type: \"render\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: realFilePath,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n },\r\n\r\n // 监听所有阶段的错误\r\n watchChange(id, change) {\r\n console.log(\"🔍 [调试] watchChange:\", id);\r\n },\r\n\r\n async closeBundle() {\r\n if (buildErrors.length > 0) {\r\n console.log(\r\n `\\n🔍 [调试] closeBundle 检测到 ${buildErrors.length} 个错误\\n`,\r\n );\r\n\r\n // 处理所有收集到的错误(去重由 processError 函数处理)\r\n for (const error of buildErrors) {\r\n await processError(error);\r\n }\r\n } else {\r\n console.log(\"✨ 构建完成,未检测到错误\\n\");\r\n }\r\n },\r\n\r\n transform(code: string, id: string) {\r\n lastTransformFile = id;\r\n\r\n try {\r\n return null;\r\n } catch (error: any) {\r\n console.log(\"\\n⚠️ transform 捕获到错误:\", error.message);\r\n buildErrors.push({\r\n type: \"transform\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: id,\r\n code: code,\r\n });\r\n throw error;\r\n }\r\n },\r\n };\r\n}\r\n\r\n// 默认导出\r\nexport default vitePluginAIDiagnostic;\r\n","/**\r\n * LangGraph 工作流实现\r\n */\r\n\r\nimport { StateGraph, END, START } from \"@langchain/langgraph\";\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\n\r\nexport interface DiagnosticState {\r\n error: any;\r\n analysis: string;\r\n suggestion: string;\r\n fixedCode: string;\r\n filePath: string;\r\n autoFix: boolean;\r\n retryCount: number;\r\n messages: any[];\r\n}\r\n\r\nexport class DiagnosticGraph {\r\n private llm: ChatOpenAI;\r\n private graph: any;\r\n private maxRetries: number;\r\n\r\n constructor(\r\n apiKey: string,\r\n apiUrl: string,\r\n model: string = \"gpt-4\",\r\n maxRetries: number = 3\r\n ) {\r\n this.maxRetries = maxRetries;\r\n\r\n console.log(\"🔧 [LangGraph] 初始化 LLM...\");\r\n console.log(\"📝 [配置] 模型:\", model);\r\n console.log(\"📝 [配置] API URL:\", apiUrl);\r\n console.log(\"📝 [配置] API Key:\", apiKey ? \"已配置\" : \"未配置\");\r\n\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: apiKey,\r\n configuration: {\r\n baseURL: apiUrl,\r\n },\r\n modelName: model,\r\n temperature: 0.1,\r\n maxTokens: 4000,\r\n });\r\n\r\n this.graph = this.buildGraph();\r\n }\r\n\r\n private buildGraph() {\r\n const workflow = new StateGraph<DiagnosticState>({\r\n channels: {\r\n error: null,\r\n analysis: null,\r\n suggestion: null,\r\n fixedCode: null,\r\n filePath: null,\r\n autoFix: null,\r\n retryCount: null,\r\n messages: null,\r\n },\r\n });\r\n\r\n workflow.addNode(\"analyze\", this.analyzeNode.bind(this));\r\n workflow.addNode(\"suggest\", this.suggestNode.bind(this));\r\n // 自动修复节点已注释(功能不够稳定)\r\n // workflow.addNode(\"fix\", this.fixNode.bind(this));\r\n // workflow.addNode(\"validate\", this.validateNode.bind(this));\r\n\r\n workflow.addEdge(START, \"analyze\");\r\n workflow.addEdge(\"analyze\", \"suggest\");\r\n // 直接结束,不再进行自动修复\r\n workflow.addEdge(\"suggest\", END);\r\n\r\n // 自动修复流程已注释\r\n // workflow.addConditionalEdges(\"suggest\", this.shouldFix.bind(this), {\r\n // fix: \"fix\",\r\n // end: END,\r\n // });\r\n // workflow.addEdge(\"fix\", \"validate\");\r\n // workflow.addConditionalEdges(\"validate\", this.shouldRetry.bind(this), {\r\n // retry: \"analyze\",\r\n // end: END,\r\n // });\r\n\r\n return workflow.compile();\r\n }\r\n\r\n private async analyzeNode(\r\n state: DiagnosticState\r\n ): Promise<Partial<DiagnosticState>> {\r\n console.log(\"🔍 [LangGraph] 正在分析错误...\");\r\n\r\n const systemPrompt = new SystemMessage(\r\n \"你是一个专业的前端代码诊断专家,精通 Vue3、TypeScript、Vite 和 uni-app。请简洁明了地分析问题。\"\r\n );\r\n\r\n const userPrompt = new HumanMessage(`\r\n请分析以下构建错误:\r\n\r\n错误类型: ${state.error.type}\r\n错误信息: ${state.error.message}\r\n文件路径: ${state.error.file || \"未知\"}\r\n\r\n请简洁地说明(3-5句话):\r\n1. 错误的根本原因\r\n2. 影响范围\r\n3. 严重程度\r\n`);\r\n\r\n const response = await this.llm.invoke([systemPrompt, userPrompt]);\r\n const analysis = response.content.toString();\r\n\r\n return {\r\n analysis,\r\n messages: [...(state.messages || []), systemPrompt, userPrompt, response],\r\n };\r\n }\r\n\r\n private async suggestNode(\r\n state: DiagnosticState\r\n ): Promise<Partial<DiagnosticState>> {\r\n console.log(\"💡 [LangGraph] 正在生成修复建议...\");\r\n\r\n const userPrompt = new HumanMessage(`\r\n基于以下错误分析,请提供具体的修复建议:\r\n\r\n错误分析:\r\n${state.analysis}\r\n\r\n错误详情:\r\n- 类型: ${state.error.type}\r\n- 信息: ${state.error.message}\r\n- 文件: ${state.error.file || \"未知\"}\r\n\r\n请简洁地提供:\r\n1. 具体的修复步骤(3-5步即可)\r\n2. 需要修改的代码位置(行号)\r\n3. 修改后的代码示例(只显示关键部分)\r\n4. 一句话预防建议\r\n\r\n注意:请直接给出建议,不要重复错误分析的内容。\r\n`);\r\n\r\n const response = await this.llm.invoke([...state.messages, userPrompt]);\r\n const suggestion = response.content.toString();\r\n\r\n return {\r\n suggestion,\r\n messages: [...state.messages, userPrompt, response],\r\n };\r\n }\r\n\r\n // 自动修复节点已注释(功能不够稳定)\r\n // private async fixNode(\r\n // state: DiagnosticState\r\n // ): Promise<Partial<DiagnosticState>> {\r\n // console.log(\"🔧 [LangGraph] 正在生成修复代码...\");\r\n\r\n // if (!state.error.code || !state.error.file) {\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n\r\n // try {\r\n // const systemPrompt = new SystemMessage(\r\n // `你是代码修复助手。返回修复后的完整文件内容,不要解释。`\r\n // );\r\n\r\n // const userPrompt = new HumanMessage(`\r\n // 文件(${state.error.code.split(\"\\n\").length} 行):\r\n // ${state.error.code}\r\n\r\n // 错误:${state.error.message}\r\n\r\n // 输出修复后的完整文件:\r\n // `);\r\n\r\n // console.log(\"📤 [调试] 发送修复请求...\");\r\n // console.log(\r\n // \"📤 [调试] 原始文件行数:\",\r\n // state.error.code.split(\"\\n\").length\r\n // );\r\n\r\n // const response = await this.llm.invoke([systemPrompt, userPrompt]);\r\n // let fixedCode = response.content.toString().trim();\r\n\r\n // console.log(\"📥 [调试] AI 返回内容长度:\", fixedCode.length);\r\n // console.log(\"📥 [调试] 原始代码长度:\", state.error.code.length);\r\n // console.log(\"📥 [调试] 返回内容行数:\", fixedCode.split(\"\\n\").length);\r\n\r\n // if (fixedCode.length === 0) {\r\n // console.error(\"❌ [调试] AI 返回空内容,可能是 API 调用失败\");\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n\r\n // fixedCode = fixedCode\r\n // .replace(/^```[\\w]*\\n?/gm, \"\")\r\n // .replace(/\\n?```$/gm, \"\")\r\n // .trim();\r\n\r\n // console.log(\"📥 [调试] 清理后内容长度:\", fixedCode.length);\r\n\r\n // const finalLengthRatio = fixedCode.length / state.error.code.length;\r\n // console.log(\r\n // `✅ [调试] 最终代码长度比例: ${(finalLengthRatio * 100).toFixed(0)}%`\r\n // );\r\n\r\n // return {\r\n // fixedCode,\r\n // filePath: state.error.file,\r\n // messages: [...state.messages, userPrompt, response],\r\n // };\r\n // } catch (error: any) {\r\n // console.error(\"❌ [调试] fixNode 执行失败:\", error.message);\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n // }\r\n\r\n // private async validateNode(\r\n // state: DiagnosticState\r\n // ): Promise<Partial<DiagnosticState>> {\r\n // console.log(\"✅ [LangGraph] 正在验证修复...\");\r\n // return state;\r\n // }\r\n\r\n // private shouldFix(state: DiagnosticState): string {\r\n // if (state.autoFix && state.error.file && state.error.code) {\r\n // return \"fix\";\r\n // }\r\n // return \"end\";\r\n // }\r\n\r\n // private shouldRetry(state: DiagnosticState): string {\r\n // if (state.retryCount < this.maxRetries && !state.fixedCode) {\r\n // return \"retry\";\r\n // }\r\n // return \"end\";\r\n // }\r\n\r\n async run(error: any, autoFix: boolean = false): Promise<DiagnosticState> {\r\n const initialState: DiagnosticState = {\r\n error,\r\n analysis: \"\",\r\n suggestion: \"\",\r\n fixedCode: \"\",\r\n filePath: \"\",\r\n autoFix,\r\n retryCount: 0,\r\n messages: [],\r\n };\r\n\r\n try {\r\n console.log(\"🚀 [LangGraph] 启动诊断工作流...\\n\");\r\n const result = await this.graph.invoke(initialState);\r\n console.log(\"✨ [LangGraph] 诊断工作流完成\\n\");\r\n return result;\r\n } catch (error: any) {\r\n console.error(\"❌ [LangGraph] 工作流执行失败:\", error.message);\r\n throw error;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI 诊断核心逻辑\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport { DiagnosticGraph } from \"./langgraph\";\r\nimport { CodeValidator } from \"./validator\";\r\n\r\nexport interface DiagnosticOptions {\r\n apiKey: string;\r\n apiUrl: string;\r\n model: string;\r\n maxRetries: number;\r\n}\r\n\r\nexport interface DiagnosticResult {\r\n analysis: string;\r\n suggestion: string;\r\n fixedCode?: string;\r\n filePath?: string;\r\n}\r\n\r\nexport class AIErrorDiagnostic {\r\n private options: DiagnosticOptions;\r\n private graph: DiagnosticGraph;\r\n\r\n constructor(options: DiagnosticOptions) {\r\n this.options = options;\r\n\r\n this.graph = new DiagnosticGraph(\r\n options.apiKey,\r\n options.apiUrl,\r\n options.model,\r\n options.maxRetries\r\n );\r\n }\r\n\r\n async diagnose(\r\n error: any,\r\n autoFix: boolean = false\r\n ): Promise<DiagnosticResult> {\r\n if (!this.options.apiKey) {\r\n return {\r\n analysis: \"未配置 API Key,无法使用 AI 诊断功能\",\r\n suggestion: \"请在 .env 文件中配置 OPENAI_API_KEY\",\r\n fixedCode: undefined,\r\n filePath: undefined,\r\n };\r\n }\r\n\r\n try {\r\n // 注意:自动修复功能已暂时禁用,因为不够稳定\r\n // 强制设置 autoFix 为 false\r\n const result = await this.graph.run(error, false);\r\n\r\n // 自动修复功能已注释(不够稳定)\r\n // if (autoFix && result.fixedCode && result.filePath) {\r\n // console.log(\"\\n🔍 [验证] 正在验证修复后的代码...\");\r\n\r\n // const validation = CodeValidator.validateFix(\r\n // error.code,\r\n // result.fixedCode\r\n // );\r\n\r\n // if (!validation.valid) {\r\n // console.warn(`⚠️ [验证失败] ${validation.reason}`);\r\n // console.log(\"📝 [提示] 将只提供修复建议,不自动应用修复\\n\");\r\n\r\n // return {\r\n // analysis: result.analysis,\r\n // suggestion:\r\n // result.suggestion +\r\n // \"\\n\\n⚠️ 自动修复验证失败:\" +\r\n // validation.reason,\r\n // fixedCode: undefined,\r\n // filePath: undefined,\r\n // };\r\n // }\r\n\r\n // console.log(\"✅ [验证通过] 代码验证成功\\n\");\r\n // this.applyFix(result.filePath, result.fixedCode);\r\n // }\r\n\r\n return {\r\n analysis: result.analysis,\r\n suggestion: result.suggestion,\r\n fixedCode: undefined, // 暂时不返回修复代码\r\n filePath: undefined,\r\n };\r\n } catch (error: any) {\r\n console.error(\"❌ AI 诊断失败:\", error.message);\r\n return {\r\n analysis: `诊断过程出错: ${error.message}`,\r\n suggestion: \"请检查 API 配置和网络连接\",\r\n fixedCode: undefined,\r\n filePath: undefined,\r\n };\r\n }\r\n }\r\n\r\n // 自动修复功能已注释(不够稳定)\r\n // private applyFix(filePath: string, fixedCode: string): void {\r\n // try {\r\n // const backupPath = `${filePath}.backup`;\r\n // if (fs.existsSync(filePath)) {\r\n // fs.copyFileSync(filePath, backupPath);\r\n // console.log(`📦 [备份] 已创建备份: ${backupPath}`);\r\n // }\r\n\r\n // fs.writeFileSync(filePath, fixedCode, \"utf-8\");\r\n // console.log(`✅ [修复] 已修复文件: ${filePath}`);\r\n // console.log(`💡 [提示] 如需恢复,运行: cp \"${backupPath}\" \"${filePath}\"`);\r\n // } catch (error: any) {\r\n // console.error(`❌ [修复失败] ${error.message}`);\r\n // }\r\n // }\r\n}\r\n","/**\r\n * AI 诊断报告生成器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\n\r\nexport interface DiagnosticReport {\r\n timestamp: string;\r\n error: {\r\n type: string;\r\n message: string;\r\n file: string;\r\n stack?: string;\r\n };\r\n analysis: string;\r\n suggestion: string;\r\n fixed: boolean;\r\n fixedFilePath?: string;\r\n}\r\n\r\nexport interface ReporterOptions {\r\n console?: boolean;\r\n html?: boolean;\r\n markdown?: boolean;\r\n json?: boolean;\r\n}\r\n\r\nexport class DiagnosticReporter {\r\n /**\r\n * 生成报告(根据配置生成多种格式)\r\n */\r\n static async generate(\r\n report: DiagnosticReport,\r\n options: ReporterOptions = {}\r\n ): Promise<void> {\r\n // HTML 报告\r\n if (options.html) {\r\n await this.generateHTMLReport(report);\r\n }\r\n\r\n // Markdown 报告\r\n if (options.markdown) {\r\n await this.generateMarkdownReport(report);\r\n }\r\n\r\n // JSON 报告\r\n if (options.json) {\r\n await this.generateJSONReport(report);\r\n }\r\n }\r\n\r\n /**\r\n * 生成 HTML 报告\r\n */\r\n static async generateHTMLReport(report: DiagnosticReport): Promise<void> {\r\n const html = `\r\n<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>AI 诊断报告</title>\r\n <style>\r\n * { margin: 0; padding: 0; box-sizing: border-box; }\r\n body {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n padding: 20px;\r\n min-height: 100vh;\r\n }\r\n .container {\r\n max-width: 1000px;\r\n margin: 0 auto;\r\n background: white;\r\n border-radius: 12px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.2);\r\n overflow: hidden;\r\n }\r\n .header {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 30px;\r\n text-align: center;\r\n }\r\n .header h1 {\r\n font-size: 32px;\r\n margin-bottom: 10px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 10px;\r\n }\r\n .header .time {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .content {\r\n padding: 30px;\r\n }\r\n .section {\r\n margin-bottom: 30px;\r\n }\r\n .section-title {\r\n font-size: 20px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 15px;\r\n padding-bottom: 10px;\r\n border-bottom: 2px solid #667eea;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n }\r\n .error-box {\r\n background: #fff5f5;\r\n border-left: 4px solid #f56565;\r\n padding: 20px;\r\n border-radius: 8px;\r\n margin-bottom: 20px;\r\n }\r\n .error-type {\r\n display: inline-block;\r\n background: #f56565;\r\n color: white;\r\n padding: 4px 12px;\r\n border-radius: 12px;\r\n font-size: 12px;\r\n font-weight: bold;\r\n margin-bottom: 10px;\r\n }\r\n .error-message {\r\n font-size: 16px;\r\n color: #c53030;\r\n font-weight: 500;\r\n margin-bottom: 10px;\r\n line-height: 1.6;\r\n }\r\n .error-file {\r\n font-size: 14px;\r\n color: #666;\r\n font-family: 'Courier New', monospace;\r\n background: #f7fafc;\r\n padding: 8px 12px;\r\n border-radius: 4px;\r\n display: inline-block;\r\n }\r\n .analysis-box {\r\n background: #f0f9ff;\r\n border-left: 4px solid #3b82f6;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #1e40af;\r\n }\r\n .suggestion-box {\r\n background: #f0fdf4;\r\n border-left: 4px solid #10b981;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #065f46;\r\n }\r\n .suggestion-box pre {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n margin: 10px 0;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n }\r\n .fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #10b981;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .not-fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #f59e0b;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .footer {\r\n background: #f7fafc;\r\n padding: 20px;\r\n text-align: center;\r\n color: #718096;\r\n font-size: 14px;\r\n border-top: 1px solid #e2e8f0;\r\n }\r\n .stack-trace {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n font-family: 'Courier New', monospace;\r\n font-size: 12px;\r\n line-height: 1.5;\r\n margin-top: 10px;\r\n max-height: 300px;\r\n overflow-y: auto;\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <div class=\"header\">\r\n <h1>🤖 AI 诊断报告</h1>\r\n <div class=\"time\">生成时间: ${report.timestamp}</div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n <!-- 错误信息 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">❌ 错误信息</div>\r\n <div class=\"error-box\">\r\n <span class=\"error-type\">${report.error.type}</span>\r\n <div class=\"error-message\">${this.escapeHtml(\r\n report.error.message\r\n )}</div>\r\n <div class=\"error-file\">📂 ${report.error.file}</div>\r\n ${\r\n report.error.stack\r\n ? `<div class=\"stack-trace\">${this.escapeHtml(\r\n report.error.stack\r\n )}</div>`\r\n : \"\"\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- AI 分析 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔍 AI 分析</div>\r\n <div class=\"analysis-box\">\r\n ${this.formatText(report.analysis)}\r\n </div>\r\n </div>\r\n\r\n <!-- 修复建议 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">💡 修复建议</div>\r\n <div class=\"suggestion-box\">\r\n ${this.formatText(report.suggestion)}\r\n </div>\r\n </div>\r\n\r\n <!-- 修复状态 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔧 修复状态</div>\r\n ${\r\n report.fixed\r\n ? `<div class=\"fixed-badge\">✅ 已自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">修复文件: <code>${report.fixedFilePath}</code></div>`\r\n : `<div class=\"not-fixed-badge\">⚠️ 未自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">请根据上述建议手动修复</div>`\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"footer\">\r\n <p>AI Diagnostic Plugin v1.0.0</p>\r\n <p>Powered by LangGraph & OpenAI</p>\r\n </div>\r\n </div>\r\n</body>\r\n</html>\r\n `.trim();\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.html\");\r\n fs.writeFileSync(reportPath, html, \"utf-8\");\r\n console.log(`\\n📄 诊断报告已生成: ${reportPath}\\n`);\r\n }\r\n\r\n /**\r\n * 转义 HTML 特殊字符\r\n */\r\n private static escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#039;\",\r\n };\r\n return text.replace(/[&<>\"']/g, (m) => map[m]);\r\n }\r\n\r\n /**\r\n * 格式化文本(支持代码块和换行)\r\n */\r\n private static formatText(text: string): string {\r\n // 转义 HTML\r\n let formatted = this.escapeHtml(text);\r\n\r\n // 处理代码块\r\n formatted = formatted.replace(\r\n /```(\\w*)\\n([\\s\\S]*?)```/g,\r\n (_, lang, code) => {\r\n return `<pre><code>${code.trim()}</code></pre>`;\r\n }\r\n );\r\n\r\n // 处理行内代码\r\n formatted = formatted.replace(\r\n /`([^`]+)`/g,\r\n '<code style=\"background: #e2e8f0; padding: 2px 6px; border-radius: 3px; font-family: monospace;\">$1</code>'\r\n );\r\n\r\n // 处理换行\r\n formatted = formatted.replace(/\\n/g, \"<br>\");\r\n\r\n return formatted;\r\n }\r\n\r\n /**\r\n * 生成 Markdown 报告\r\n */\r\n static async generateMarkdownReport(report: DiagnosticReport): Promise<void> {\r\n const markdown = `# 🤖 AI 诊断报告\r\n\r\n**生成时间**: ${report.timestamp}\r\n\r\n---\r\n\r\n## ❌ 错误信息\r\n\r\n**类型**: \\`${report.error.type}\\` \r\n**文件**: \\`${report.error.file}\\` \r\n**消息**: \r\n\\`\\`\\`\r\n${report.error.message}\r\n\\`\\`\\`\r\n\r\n${\r\n report.error.stack\r\n ? `**堆栈跟踪**:\\n\\`\\`\\`\\n${report.error.stack}\\n\\`\\`\\`\\n`\r\n : \"\"\r\n}\r\n\r\n---\r\n\r\n## 🔍 AI 分析\r\n\r\n${report.analysis}\r\n\r\n---\r\n\r\n## 💡 修复建议\r\n\r\n${report.suggestion}\r\n\r\n---\r\n\r\n## 🔧 修复状态\r\n\r\n${\r\n report.fixed\r\n ? `✅ **已自动修复**\\n\\n修复文件: \\`${report.fixedFilePath}\\``\r\n : `⚠️ **未自动修复**\\n\\n请根据上述建议手动修复`\r\n}\r\n\r\n---\r\n\r\n*AI Diagnostic Plugin v1.0.0* \r\n*Powered by LangGraph & OpenAI*\r\n`;\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.md\");\r\n fs.writeFileSync(reportPath, markdown, \"utf-8\");\r\n console.log(`📄 Markdown 报告已生成: ${reportPath}`);\r\n }\r\n\r\n /**\r\n * 生成 JSON 报告\r\n */\r\n static async generateJSONReport(report: DiagnosticReport): Promise<void> {\r\n const jsonReport = {\r\n version: \"1.0.0\",\r\n timestamp: report.timestamp,\r\n error: {\r\n type: report.error.type,\r\n message: report.error.message,\r\n file: report.error.file,\r\n stack: report.error.stack || null,\r\n },\r\n diagnosis: {\r\n analysis: report.analysis,\r\n suggestion: report.suggestion,\r\n },\r\n fix: {\r\n applied: report.fixed,\r\n filePath: report.fixedFilePath || null,\r\n },\r\n };\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.json\");\r\n fs.writeFileSync(reportPath, JSON.stringify(jsonReport, null, 2), \"utf-8\");\r\n console.log(`📄 JSON 报告已生成: ${reportPath}`);\r\n }\r\n}\r\n"],"mappings":"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","names":["import_fs","error","error","path","fs","options","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/langgraph.ts","../src/diagnostic.ts","../src/reporter.ts"],"sourcesContent":["/**\r\n * AI 诊断插件入口\r\n *\r\n * 功能:\r\n * - 自动诊断构建错误\r\n * - 提供修复建议\r\n * - 自动修复代码\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig } from \"vite\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { AIErrorDiagnostic } from \"./diagnostic\";\r\nimport { extractSourceFile } from \"vite-plugin-ai-shared\";\r\nimport { DiagnosticReporter, type DiagnosticReport } from \"./reporter\";\r\nimport { glob } from \"glob\";\r\n\r\nexport interface AIPluginOptions {\r\n apiKey?: string;\r\n apiUrl?: string;\r\n autoFix?: boolean;\r\n model?: string;\r\n maxRetries?: number;\r\n output?: {\r\n console?: boolean;\r\n html?: boolean;\r\n markdown?: boolean;\r\n json?: boolean;\r\n };\r\n}\r\n\r\nexport function vitePluginAIDiagnostic(options: AIPluginOptions = {}): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n autoFix = false,\r\n model = \"gpt-4\",\r\n maxRetries = 3,\r\n output = {\r\n console: true,\r\n html: true,\r\n markdown: false,\r\n json: false,\r\n },\r\n } = options;\r\n\r\n const diagnostic = new AIErrorDiagnostic({\r\n apiKey,\r\n apiUrl,\r\n model,\r\n maxRetries,\r\n });\r\n\r\n let buildErrors: any[] = [];\r\n let lastTransformFile: string | null = null;\r\n let processedErrors = new Set<string>(); // 记录已处理的错误\r\n let config: ResolvedConfig;\r\n let diagnosticResults: DiagnosticReport[] = []; // 收集所有诊断结果\r\n\r\n // 处理错误的函数\r\n async function processError(error: any) {\r\n // 生成错误的唯一标识\r\n const errorKey = `${error.file}:${error.message}`;\r\n\r\n // 如果已经处理过,跳过\r\n if (processedErrors.has(errorKey)) {\r\n console.log(\"🔍 [调试] 跳过重复错误:\", errorKey);\r\n return;\r\n }\r\n\r\n processedErrors.add(errorKey);\r\n\r\n try {\r\n console.log(\"\\n⚠️ 检测到错误,正在使用 AI 分析...\\n\");\r\n console.log(`📝 错误信息: ${error.message}`);\r\n console.log(`📂 文件路径: ${error.file || \"未知\"}`);\r\n console.log(\r\n `📄 代码长度: ${error.code ? error.code.length + \" 字符\" : \"无\"}`,\r\n );\r\n console.log(`🔧 自动修复: ${autoFix ? \"是\" : \"否\"}\\n`);\r\n\r\n if (!error.file || !error.code) {\r\n console.log(\"⚠️ 跳过此错误:缺少文件路径或代码内容\\n\");\r\n return;\r\n }\r\n\r\n const result = await diagnostic.diagnose(error, autoFix);\r\n\r\n // 控制台输出\r\n if (output.console !== false) {\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\");\r\n console.log(\"🔍 错误分析:\");\r\n console.log(result.analysis);\r\n console.log(\"\\n💡 修复建议:\");\r\n console.log(result.suggestion);\r\n\r\n if (result.fixedCode && result.filePath) {\r\n console.log(\"\\n✅ 已自动修复代码\");\r\n console.log(\"修复的文件:\", result.filePath);\r\n console.log(\"\\n💡 请重新运行构建命令\");\r\n } else if (autoFix) {\r\n console.log(\"\\n⚠️ 无法自动修复:AI 未生成修复代码\");\r\n }\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n }\r\n\r\n // 生成报告对象\r\n const report: DiagnosticReport = {\r\n timestamp: new Date().toLocaleString(\"zh-CN\"),\r\n error: {\r\n type: error.type || \"unknown\",\r\n message: error.message,\r\n file: error.file,\r\n stack: error.stack,\r\n },\r\n analysis: result.analysis,\r\n suggestion: result.suggestion,\r\n fixed: !!(result.fixedCode && result.filePath),\r\n fixedFilePath: result.filePath,\r\n };\r\n\r\n // 收集诊断结果,稍后统一生成报告\r\n diagnosticResults.push(report);\r\n } catch (err: any) {\r\n console.error(\"❌ AI 诊断失败:\", err.message);\r\n }\r\n }\r\n\r\n return {\r\n name: \"vite-plugin-ai-diagnostic\",\r\n\r\n // 确保插件在其他插件之后执行,以捕获更多错误\r\n enforce: \"post\",\r\n\r\n configResolved(resolvedConfig) {\r\n config = resolvedConfig;\r\n console.log(\"\\n🤖 AI 诊断助手已启动...\");\r\n console.log(`⚙️ 自动修复: ${autoFix ? \"✅ 已启用\" : \"❌ 未启用\"}`);\r\n console.log(`📝 根目录: ${config.root}`);\r\n console.log(\r\n `📝 入口: ${config.build.rollupOptions?.input || \"index.html\"}\\n`,\r\n );\r\n },\r\n\r\n async buildStart() {\r\n buildErrors = [];\r\n processedErrors.clear();\r\n diagnosticResults = []; // 清空诊断结果\r\n console.log(\"🔍 开始扫描源文件...\");\r\n\r\n // 扫描 src 目录下的所有源文件\r\n const srcDir = path.join(config.root, \"src\");\r\n if (!fs.existsSync(srcDir)) {\r\n console.log(\"⚠️ src 目录不存在,跳过文件扫描\");\r\n return;\r\n }\r\n\r\n try {\r\n // 使用 glob 查找所有源文件\r\n const files = await glob(\"**/*.{vue,ts,tsx,js,jsx}\", {\r\n cwd: srcDir,\r\n absolute: true,\r\n ignore: [\"**/node_modules/**\", \"**/*.d.ts\"],\r\n });\r\n\r\n console.log(`📂 找到 ${files.length} 个源文件`);\r\n\r\n // 检查每个文件的语法\r\n for (const file of files) {\r\n try {\r\n const code = fs.readFileSync(file, \"utf-8\");\r\n\r\n // 基本语法检查\r\n if (file.endsWith(\".vue\")) {\r\n // 检查 Vue 文件的基本结构\r\n if (!code.includes(\"<template>\") && !code.includes(\"<script>\")) {\r\n buildErrors.push({\r\n type: \"syntax\",\r\n message: \"Vue 文件缺少 <template> 或 <script> 标签\",\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n\r\n // 检查未闭合的标签\r\n const templateMatch = code.match(/<template[^>]*>/);\r\n if (templateMatch && !code.includes(\"</template>\")) {\r\n buildErrors.push({\r\n type: \"syntax\",\r\n message: \"Vue 文件中 <template> 标签未闭合\",\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n\r\n const scriptMatch = code.match(/<script[^>]*>/);\r\n if (scriptMatch && !code.includes(\"</script>\")) {\r\n buildErrors.push({\r\n type: \"syntax\",\r\n message: \"Vue 文件中 <script> 标签未闭合\",\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n }\r\n\r\n // 检查 JavaScript/TypeScript 语法错误(简单检查)\r\n if (\r\n file.endsWith(\".ts\") ||\r\n file.endsWith(\".tsx\") ||\r\n file.endsWith(\".js\") ||\r\n file.endsWith(\".jsx\")\r\n ) {\r\n // 检查括号匹配\r\n const openBraces = (code.match(/\\{/g) || []).length;\r\n const closeBraces = (code.match(/\\}/g) || []).length;\r\n if (openBraces !== closeBraces) {\r\n buildErrors.push({\r\n type: \"syntax\",\r\n message: `括号不匹配:{ 有 ${openBraces} 个,} 有 ${closeBraces} 个`,\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n\r\n const openParens = (code.match(/\\(/g) || []).length;\r\n const closeParens = (code.match(/\\)/g) || []).length;\r\n if (openParens !== closeParens) {\r\n buildErrors.push({\r\n type: \"syntax\",\r\n message: `圆括号不匹配:( 有 ${openParens} 个,) 有 ${closeParens} 个`,\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n }\r\n\r\n // 检查导入语句中的不存在模块(这个会在后续构建中被捕获)\r\n const importRegex = /import\\s+.*?\\s+from\\s+['\"](.+?)['\"]/g;\r\n let match;\r\n while ((match = importRegex.exec(code)) !== null) {\r\n const importPath = match[1];\r\n\r\n // 跳过 node_modules 和别名导入\r\n if (importPath.startsWith(\".\") || importPath.startsWith(\"/\")) {\r\n const resolvedPath = path.resolve(\r\n path.dirname(file),\r\n importPath,\r\n );\r\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".vue\", \"\"];\r\n\r\n let exists = false;\r\n for (const ext of extensions) {\r\n const fullPath = resolvedPath + ext;\r\n if (fs.existsSync(fullPath)) {\r\n exists = true;\r\n break;\r\n }\r\n // 检查是否为目录,且包含 index 文件\r\n if (\r\n fs.existsSync(resolvedPath) &&\r\n fs.statSync(resolvedPath).isDirectory()\r\n ) {\r\n const indexPath = path.join(resolvedPath, \"index\" + ext);\r\n if (fs.existsSync(indexPath)) {\r\n exists = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (!exists) {\r\n buildErrors.push({\r\n type: \"module\",\r\n message: `找不到模块: ${importPath}`,\r\n file: file,\r\n code: code,\r\n });\r\n }\r\n }\r\n }\r\n } catch (err: any) {\r\n console.warn(`⚠️ 无法读取文件 ${file}: ${err.message}`);\r\n }\r\n }\r\n\r\n if (buildErrors.length > 0) {\r\n console.log(`⚠️ 扫描发现 ${buildErrors.length} 个潜在问题`);\r\n } else {\r\n console.log(\"✅ 文件扫描完成,未发现明显问题\");\r\n }\r\n } catch (err: any) {\r\n console.error(`❌ 文件扫描失败: ${err.message}`);\r\n }\r\n },\r\n\r\n // 解析模块时捕获错误\r\n async resolveId(source, importer, options) {\r\n // 不要在这里 try-catch,让错误自然传播到 buildEnd\r\n return null;\r\n },\r\n\r\n // 加载模块时捕获错误\r\n async load(id) {\r\n // 不要在这里 try-catch,让错误自然传播到 buildEnd\r\n return null;\r\n },\r\n\r\n // Rollup 钩子:模块解析完成后调用\r\n moduleParsed(moduleInfo) {\r\n // 检查模块是否有导入错误\r\n if (moduleInfo.meta && moduleInfo.meta.error) {\r\n console.log(\"\\n⚠️ moduleParsed 检测到错误:\", moduleInfo.id);\r\n\r\n let code = undefined;\r\n if (moduleInfo.id && fs.existsSync(moduleInfo.id)) {\r\n code = fs.readFileSync(moduleInfo.id, \"utf-8\");\r\n }\r\n\r\n const errorInfo = {\r\n type: \"module\",\r\n message: moduleInfo.meta.error,\r\n stack: \"\",\r\n file: moduleInfo.id,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n }\r\n },\r\n\r\n buildEnd(error?: Error) {\r\n console.log(\"🔍 [调试] buildEnd 已执行, 有错误:\", !!error);\r\n\r\n if (error) {\r\n console.log(\"\\n⚠️ buildEnd 捕获到错误:\", error.message);\r\n\r\n const realFilePath = extractSourceFile(error, lastTransformFile);\r\n\r\n let code = undefined;\r\n if (realFilePath && fs.existsSync(realFilePath)) {\r\n try {\r\n code = fs.readFileSync(realFilePath, \"utf-8\");\r\n console.log(`📂 读取源文件成功: ${realFilePath}`);\r\n console.log(`📄 源文件长度: ${code.length} 字符`);\r\n } catch (e) {\r\n console.warn(\"⚠️ 无法读取文件:\", realFilePath);\r\n }\r\n }\r\n\r\n const errorInfo = {\r\n type: \"build\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: realFilePath,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n }\r\n },\r\n\r\n // Rollup 输出生成阶段的钩子\r\n renderStart(outputOptions, inputOptions) {\r\n console.log(\"🔍 [调试] renderStart 已执行\");\r\n },\r\n\r\n renderError(error?: Error) {\r\n console.log(\"🔍 [调试] renderError 已执行\");\r\n if (!error) return;\r\n\r\n console.log(\"\\n⚠️ renderError 捕获到错误:\", error.message);\r\n\r\n const realFilePath = extractSourceFile(error, lastTransformFile);\r\n\r\n let code = undefined;\r\n if (realFilePath && fs.existsSync(realFilePath)) {\r\n try {\r\n code = fs.readFileSync(realFilePath, \"utf-8\");\r\n console.log(`📂 读取源文件成功: ${realFilePath}`);\r\n console.log(`📄 源文件长度: ${code.length} 字符`);\r\n } catch (e) {\r\n console.warn(\"⚠️ 无法读取文件:\", realFilePath);\r\n }\r\n }\r\n\r\n const errorInfo = {\r\n type: \"render\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: realFilePath,\r\n code: code,\r\n };\r\n\r\n buildErrors.push(errorInfo);\r\n },\r\n\r\n // 监听所有阶段的错误\r\n watchChange(id, change) {\r\n console.log(\"🔍 [调试] watchChange:\", id);\r\n },\r\n\r\n async closeBundle() {\r\n if (buildErrors.length > 0) {\r\n console.log(\r\n `\\n🔍 [调试] closeBundle 检测到 ${buildErrors.length} 个错误\\n`,\r\n );\r\n\r\n // 处理所有收集到的错误(去重由 processError 函数处理)\r\n for (const error of buildErrors) {\r\n await processError(error);\r\n }\r\n\r\n // 统一生成合并报告\r\n if (diagnosticResults.length > 0) {\r\n console.log(\r\n `\\n📊 正在生成合并诊断报告 (${diagnosticResults.length} 个错误)...\\n`,\r\n );\r\n await DiagnosticReporter.generateMultiReport(\r\n diagnosticResults,\r\n output,\r\n );\r\n }\r\n } else {\r\n console.log(\"✨ 构建完成,未检测到错误\\n\");\r\n }\r\n },\r\n\r\n transform(code: string, id: string) {\r\n lastTransformFile = id;\r\n\r\n try {\r\n return null;\r\n } catch (error: any) {\r\n console.log(\"\\n⚠️ transform 捕获到错误:\", error.message);\r\n buildErrors.push({\r\n type: \"transform\",\r\n message: error.message,\r\n stack: error.stack,\r\n file: id,\r\n code: code,\r\n });\r\n throw error;\r\n }\r\n },\r\n };\r\n}\r\n\r\n// 默认导出\r\nexport default vitePluginAIDiagnostic;\r\n","/**\r\n * LangGraph 工作流实现\r\n */\r\n\r\nimport { StateGraph, END, START } from \"@langchain/langgraph\";\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\n\r\nexport interface DiagnosticState {\r\n error: any;\r\n analysis: string;\r\n suggestion: string;\r\n fixedCode: string;\r\n filePath: string;\r\n autoFix: boolean;\r\n retryCount: number;\r\n messages: any[];\r\n}\r\n\r\nexport class DiagnosticGraph {\r\n private llm: ChatOpenAI;\r\n private graph: any;\r\n private maxRetries: number;\r\n\r\n constructor(\r\n apiKey: string,\r\n apiUrl: string,\r\n model: string = \"gpt-4\",\r\n maxRetries: number = 3\r\n ) {\r\n this.maxRetries = maxRetries;\r\n\r\n console.log(\"🔧 [LangGraph] 初始化 LLM...\");\r\n console.log(\"📝 [配置] 模型:\", model);\r\n console.log(\"📝 [配置] API URL:\", apiUrl);\r\n console.log(\"📝 [配置] API Key:\", apiKey ? \"已配置\" : \"未配置\");\r\n\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: apiKey,\r\n configuration: {\r\n baseURL: apiUrl,\r\n },\r\n modelName: model,\r\n temperature: 0.1,\r\n maxTokens: 4000,\r\n });\r\n\r\n this.graph = this.buildGraph();\r\n }\r\n\r\n private buildGraph() {\r\n const workflow = new StateGraph<DiagnosticState>({\r\n channels: {\r\n error: null,\r\n analysis: null,\r\n suggestion: null,\r\n fixedCode: null,\r\n filePath: null,\r\n autoFix: null,\r\n retryCount: null,\r\n messages: null,\r\n },\r\n });\r\n\r\n workflow.addNode(\"analyze\", this.analyzeNode.bind(this));\r\n workflow.addNode(\"suggest\", this.suggestNode.bind(this));\r\n // 自动修复节点已注释(功能不够稳定)\r\n // workflow.addNode(\"fix\", this.fixNode.bind(this));\r\n // workflow.addNode(\"validate\", this.validateNode.bind(this));\r\n\r\n workflow.addEdge(START, \"analyze\");\r\n workflow.addEdge(\"analyze\", \"suggest\");\r\n // 直接结束,不再进行自动修复\r\n workflow.addEdge(\"suggest\", END);\r\n\r\n // 自动修复流程已注释\r\n // workflow.addConditionalEdges(\"suggest\", this.shouldFix.bind(this), {\r\n // fix: \"fix\",\r\n // end: END,\r\n // });\r\n // workflow.addEdge(\"fix\", \"validate\");\r\n // workflow.addConditionalEdges(\"validate\", this.shouldRetry.bind(this), {\r\n // retry: \"analyze\",\r\n // end: END,\r\n // });\r\n\r\n return workflow.compile();\r\n }\r\n\r\n private async analyzeNode(\r\n state: DiagnosticState\r\n ): Promise<Partial<DiagnosticState>> {\r\n console.log(\"🔍 [LangGraph] 正在分析错误...\");\r\n\r\n const systemPrompt = new SystemMessage(\r\n \"你是一个专业的前端代码诊断专家,精通 Vue3、TypeScript、Vite 和 uni-app。请简洁明了地分析问题。\"\r\n );\r\n\r\n const userPrompt = new HumanMessage(`\r\n请分析以下构建错误:\r\n\r\n错误类型: ${state.error.type}\r\n错误信息: ${state.error.message}\r\n文件路径: ${state.error.file || \"未知\"}\r\n\r\n请简洁地说明(3-5句话):\r\n1. 错误的根本原因\r\n2. 影响范围\r\n3. 严重程度\r\n`);\r\n\r\n const response = await this.llm.invoke([systemPrompt, userPrompt]);\r\n const analysis = response.content.toString();\r\n\r\n return {\r\n analysis,\r\n messages: [...(state.messages || []), systemPrompt, userPrompt, response],\r\n };\r\n }\r\n\r\n private async suggestNode(\r\n state: DiagnosticState\r\n ): Promise<Partial<DiagnosticState>> {\r\n console.log(\"💡 [LangGraph] 正在生成修复建议...\");\r\n\r\n const userPrompt = new HumanMessage(`\r\n基于以下错误分析,请提供具体的修复建议:\r\n\r\n错误分析:\r\n${state.analysis}\r\n\r\n错误详情:\r\n- 类型: ${state.error.type}\r\n- 信息: ${state.error.message}\r\n- 文件: ${state.error.file || \"未知\"}\r\n\r\n请简洁地提供:\r\n1. 具体的修复步骤(3-5步即可)\r\n2. 需要修改的代码位置(行号)\r\n3. 修改后的代码示例(只显示关键部分)\r\n4. 一句话预防建议\r\n\r\n注意:请直接给出建议,不要重复错误分析的内容。\r\n`);\r\n\r\n const response = await this.llm.invoke([...state.messages, userPrompt]);\r\n const suggestion = response.content.toString();\r\n\r\n return {\r\n suggestion,\r\n messages: [...state.messages, userPrompt, response],\r\n };\r\n }\r\n\r\n // 自动修复节点已注释(功能不够稳定)\r\n // private async fixNode(\r\n // state: DiagnosticState\r\n // ): Promise<Partial<DiagnosticState>> {\r\n // console.log(\"🔧 [LangGraph] 正在生成修复代码...\");\r\n\r\n // if (!state.error.code || !state.error.file) {\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n\r\n // try {\r\n // const systemPrompt = new SystemMessage(\r\n // `你是代码修复助手。返回修复后的完整文件内容,不要解释。`\r\n // );\r\n\r\n // const userPrompt = new HumanMessage(`\r\n // 文件(${state.error.code.split(\"\\n\").length} 行):\r\n // ${state.error.code}\r\n\r\n // 错误:${state.error.message}\r\n\r\n // 输出修复后的完整文件:\r\n // `);\r\n\r\n // console.log(\"📤 [调试] 发送修复请求...\");\r\n // console.log(\r\n // \"📤 [调试] 原始文件行数:\",\r\n // state.error.code.split(\"\\n\").length\r\n // );\r\n\r\n // const response = await this.llm.invoke([systemPrompt, userPrompt]);\r\n // let fixedCode = response.content.toString().trim();\r\n\r\n // console.log(\"📥 [调试] AI 返回内容长度:\", fixedCode.length);\r\n // console.log(\"📥 [调试] 原始代码长度:\", state.error.code.length);\r\n // console.log(\"📥 [调试] 返回内容行数:\", fixedCode.split(\"\\n\").length);\r\n\r\n // if (fixedCode.length === 0) {\r\n // console.error(\"❌ [调试] AI 返回空内容,可能是 API 调用失败\");\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n\r\n // fixedCode = fixedCode\r\n // .replace(/^```[\\w]*\\n?/gm, \"\")\r\n // .replace(/\\n?```$/gm, \"\")\r\n // .trim();\r\n\r\n // console.log(\"📥 [调试] 清理后内容长度:\", fixedCode.length);\r\n\r\n // const finalLengthRatio = fixedCode.length / state.error.code.length;\r\n // console.log(\r\n // `✅ [调试] 最终代码长度比例: ${(finalLengthRatio * 100).toFixed(0)}%`\r\n // );\r\n\r\n // return {\r\n // fixedCode,\r\n // filePath: state.error.file,\r\n // messages: [...state.messages, userPrompt, response],\r\n // };\r\n // } catch (error: any) {\r\n // console.error(\"❌ [调试] fixNode 执行失败:\", error.message);\r\n // return { fixedCode: \"\", filePath: \"\" };\r\n // }\r\n // }\r\n\r\n // private async validateNode(\r\n // state: DiagnosticState\r\n // ): Promise<Partial<DiagnosticState>> {\r\n // console.log(\"✅ [LangGraph] 正在验证修复...\");\r\n // return state;\r\n // }\r\n\r\n // private shouldFix(state: DiagnosticState): string {\r\n // if (state.autoFix && state.error.file && state.error.code) {\r\n // return \"fix\";\r\n // }\r\n // return \"end\";\r\n // }\r\n\r\n // private shouldRetry(state: DiagnosticState): string {\r\n // if (state.retryCount < this.maxRetries && !state.fixedCode) {\r\n // return \"retry\";\r\n // }\r\n // return \"end\";\r\n // }\r\n\r\n async run(error: any, autoFix: boolean = false): Promise<DiagnosticState> {\r\n const initialState: DiagnosticState = {\r\n error,\r\n analysis: \"\",\r\n suggestion: \"\",\r\n fixedCode: \"\",\r\n filePath: \"\",\r\n autoFix,\r\n retryCount: 0,\r\n messages: [],\r\n };\r\n\r\n try {\r\n console.log(\"🚀 [LangGraph] 启动诊断工作流...\\n\");\r\n const result = await this.graph.invoke(initialState);\r\n console.log(\"✨ [LangGraph] 诊断工作流完成\\n\");\r\n return result;\r\n } catch (error: any) {\r\n console.error(\"❌ [LangGraph] 工作流执行失败:\", error.message);\r\n throw error;\r\n }\r\n }\r\n}\r\n","/**\r\n * AI 诊断核心逻辑\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport { DiagnosticGraph } from \"./langgraph\";\r\nimport { CodeValidator } from \"./validator\";\r\n\r\nexport interface DiagnosticOptions {\r\n apiKey: string;\r\n apiUrl: string;\r\n model: string;\r\n maxRetries: number;\r\n}\r\n\r\nexport interface DiagnosticResult {\r\n analysis: string;\r\n suggestion: string;\r\n fixedCode?: string;\r\n filePath?: string;\r\n}\r\n\r\nexport class AIErrorDiagnostic {\r\n private options: DiagnosticOptions;\r\n private graph: DiagnosticGraph;\r\n\r\n constructor(options: DiagnosticOptions) {\r\n this.options = options;\r\n\r\n this.graph = new DiagnosticGraph(\r\n options.apiKey,\r\n options.apiUrl,\r\n options.model,\r\n options.maxRetries\r\n );\r\n }\r\n\r\n async diagnose(\r\n error: any,\r\n autoFix: boolean = false\r\n ): Promise<DiagnosticResult> {\r\n if (!this.options.apiKey) {\r\n return {\r\n analysis: \"未配置 API Key,无法使用 AI 诊断功能\",\r\n suggestion: \"请在 .env 文件中配置 OPENAI_API_KEY\",\r\n fixedCode: undefined,\r\n filePath: undefined,\r\n };\r\n }\r\n\r\n try {\r\n // 注意:自动修复功能已暂时禁用,因为不够稳定\r\n // 强制设置 autoFix 为 false\r\n const result = await this.graph.run(error, false);\r\n\r\n // 自动修复功能已注释(不够稳定)\r\n // if (autoFix && result.fixedCode && result.filePath) {\r\n // console.log(\"\\n🔍 [验证] 正在验证修复后的代码...\");\r\n\r\n // const validation = CodeValidator.validateFix(\r\n // error.code,\r\n // result.fixedCode\r\n // );\r\n\r\n // if (!validation.valid) {\r\n // console.warn(`⚠️ [验证失败] ${validation.reason}`);\r\n // console.log(\"📝 [提示] 将只提供修复建议,不自动应用修复\\n\");\r\n\r\n // return {\r\n // analysis: result.analysis,\r\n // suggestion:\r\n // result.suggestion +\r\n // \"\\n\\n⚠️ 自动修复验证失败:\" +\r\n // validation.reason,\r\n // fixedCode: undefined,\r\n // filePath: undefined,\r\n // };\r\n // }\r\n\r\n // console.log(\"✅ [验证通过] 代码验证成功\\n\");\r\n // this.applyFix(result.filePath, result.fixedCode);\r\n // }\r\n\r\n return {\r\n analysis: result.analysis,\r\n suggestion: result.suggestion,\r\n fixedCode: undefined, // 暂时不返回修复代码\r\n filePath: undefined,\r\n };\r\n } catch (error: any) {\r\n console.error(\"❌ AI 诊断失败:\", error.message);\r\n return {\r\n analysis: `诊断过程出错: ${error.message}`,\r\n suggestion: \"请检查 API 配置和网络连接\",\r\n fixedCode: undefined,\r\n filePath: undefined,\r\n };\r\n }\r\n }\r\n\r\n // 自动修复功能已注释(不够稳定)\r\n // private applyFix(filePath: string, fixedCode: string): void {\r\n // try {\r\n // const backupPath = `${filePath}.backup`;\r\n // if (fs.existsSync(filePath)) {\r\n // fs.copyFileSync(filePath, backupPath);\r\n // console.log(`📦 [备份] 已创建备份: ${backupPath}`);\r\n // }\r\n\r\n // fs.writeFileSync(filePath, fixedCode, \"utf-8\");\r\n // console.log(`✅ [修复] 已修复文件: ${filePath}`);\r\n // console.log(`💡 [提示] 如需恢复,运行: cp \"${backupPath}\" \"${filePath}\"`);\r\n // } catch (error: any) {\r\n // console.error(`❌ [修复失败] ${error.message}`);\r\n // }\r\n // }\r\n}\r\n","/**\r\n * AI 诊断报告生成器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\n\r\nexport interface DiagnosticReport {\r\n timestamp: string;\r\n error: {\r\n type: string;\r\n message: string;\r\n file: string;\r\n stack?: string;\r\n };\r\n analysis: string;\r\n suggestion: string;\r\n fixed: boolean;\r\n fixedFilePath?: string;\r\n}\r\n\r\nexport interface MultiDiagnosticReport {\r\n timestamp: string;\r\n totalErrors: number;\r\n errors: DiagnosticReport[];\r\n}\r\n\r\nexport interface ReporterOptions {\r\n console?: boolean;\r\n html?: boolean;\r\n markdown?: boolean;\r\n json?: boolean;\r\n}\r\n\r\nexport class DiagnosticReporter {\r\n /**\r\n * 生成报告(根据配置生成多种格式)\r\n */\r\n static async generate(\r\n report: DiagnosticReport,\r\n options: ReporterOptions = {},\r\n ): Promise<void> {\r\n // HTML 报告\r\n if (options.html) {\r\n await this.generateHTMLReport(report);\r\n }\r\n\r\n // Markdown 报告\r\n if (options.markdown) {\r\n await this.generateMarkdownReport(report);\r\n }\r\n\r\n // JSON 报告\r\n if (options.json) {\r\n await this.generateJSONReport(report);\r\n }\r\n }\r\n\r\n /**\r\n * 生成 HTML 报告\r\n */\r\n static async generateHTMLReport(report: DiagnosticReport): Promise<void> {\r\n const html = `\r\n<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>AI 诊断报告</title>\r\n <style>\r\n * { margin: 0; padding: 0; box-sizing: border-box; }\r\n body {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n padding: 20px;\r\n min-height: 100vh;\r\n }\r\n .container {\r\n max-width: 1000px;\r\n margin: 0 auto;\r\n background: white;\r\n border-radius: 12px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.2);\r\n overflow: hidden;\r\n }\r\n .header {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 30px;\r\n text-align: center;\r\n }\r\n .header h1 {\r\n font-size: 32px;\r\n margin-bottom: 10px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 10px;\r\n }\r\n .header .time {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .content {\r\n padding: 30px;\r\n }\r\n .section {\r\n margin-bottom: 30px;\r\n }\r\n .section-title {\r\n font-size: 20px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 15px;\r\n padding-bottom: 10px;\r\n border-bottom: 2px solid #667eea;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n }\r\n .error-box {\r\n background: #fff5f5;\r\n border-left: 4px solid #f56565;\r\n padding: 20px;\r\n border-radius: 8px;\r\n margin-bottom: 20px;\r\n }\r\n .error-type {\r\n display: inline-block;\r\n background: #f56565;\r\n color: white;\r\n padding: 4px 12px;\r\n border-radius: 12px;\r\n font-size: 12px;\r\n font-weight: bold;\r\n margin-bottom: 10px;\r\n }\r\n .error-message {\r\n font-size: 16px;\r\n color: #c53030;\r\n font-weight: 500;\r\n margin-bottom: 10px;\r\n line-height: 1.6;\r\n }\r\n .error-file {\r\n font-size: 14px;\r\n color: #666;\r\n font-family: 'Courier New', monospace;\r\n background: #f7fafc;\r\n padding: 8px 12px;\r\n border-radius: 4px;\r\n display: inline-block;\r\n }\r\n .analysis-box {\r\n background: #f0f9ff;\r\n border-left: 4px solid #3b82f6;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #1e40af;\r\n }\r\n .suggestion-box {\r\n background: #f0fdf4;\r\n border-left: 4px solid #10b981;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #065f46;\r\n }\r\n .suggestion-box pre {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n margin: 10px 0;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n }\r\n .fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #10b981;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .not-fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #f59e0b;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .footer {\r\n background: #f7fafc;\r\n padding: 20px;\r\n text-align: center;\r\n color: #718096;\r\n font-size: 14px;\r\n border-top: 1px solid #e2e8f0;\r\n }\r\n .stack-trace {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n font-family: 'Courier New', monospace;\r\n font-size: 12px;\r\n line-height: 1.5;\r\n margin-top: 10px;\r\n max-height: 300px;\r\n overflow-y: auto;\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <div class=\"header\">\r\n <h1>🤖 AI 诊断报告</h1>\r\n <div class=\"time\">生成时间: ${report.timestamp}</div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n <!-- 错误信息 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">❌ 错误信息</div>\r\n <div class=\"error-box\">\r\n <span class=\"error-type\">${report.error.type}</span>\r\n <div class=\"error-message\">${this.escapeHtml(\r\n report.error.message,\r\n )}</div>\r\n <div class=\"error-file\">📂 ${report.error.file}</div>\r\n ${\r\n report.error.stack\r\n ? `<div class=\"stack-trace\">${this.escapeHtml(\r\n report.error.stack,\r\n )}</div>`\r\n : \"\"\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- AI 分析 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔍 AI 分析</div>\r\n <div class=\"analysis-box\">\r\n ${this.formatText(report.analysis)}\r\n </div>\r\n </div>\r\n\r\n <!-- 修复建议 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">💡 修复建议</div>\r\n <div class=\"suggestion-box\">\r\n ${this.formatText(report.suggestion)}\r\n </div>\r\n </div>\r\n\r\n <!-- 修复状态 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔧 修复状态</div>\r\n ${\r\n report.fixed\r\n ? `<div class=\"fixed-badge\">✅ 已自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">修复文件: <code>${report.fixedFilePath}</code></div>`\r\n : `<div class=\"not-fixed-badge\">⚠️ 未自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">请根据上述建议手动修复</div>`\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"footer\">\r\n <p>AI Diagnostic Plugin v1.0.0</p>\r\n <p>Powered by LangGraph & OpenAI</p>\r\n </div>\r\n </div>\r\n</body>\r\n</html>\r\n `.trim();\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.html\");\r\n fs.writeFileSync(reportPath, html, \"utf-8\");\r\n console.log(`\\n📄 诊断报告已生成: ${reportPath}\\n`);\r\n }\r\n\r\n /**\r\n * 转义 HTML 特殊字符\r\n */\r\n private static escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#039;\",\r\n };\r\n return text.replace(/[&<>\"']/g, (m) => map[m]);\r\n }\r\n\r\n /**\r\n * 格式化文本(支持代码块和换行)\r\n */\r\n private static formatText(text: string): string {\r\n // 转义 HTML\r\n let formatted = this.escapeHtml(text);\r\n\r\n // 处理代码块\r\n formatted = formatted.replace(\r\n /```(\\w*)\\n([\\s\\S]*?)```/g,\r\n (_, lang, code) => {\r\n return `<pre><code>${code.trim()}</code></pre>`;\r\n },\r\n );\r\n\r\n // 处理行内代码\r\n formatted = formatted.replace(\r\n /`([^`]+)`/g,\r\n '<code style=\"background: #e2e8f0; padding: 2px 6px; border-radius: 3px; font-family: monospace;\">$1</code>',\r\n );\r\n\r\n // 处理换行\r\n formatted = formatted.replace(/\\n/g, \"<br>\");\r\n\r\n return formatted;\r\n }\r\n\r\n /**\r\n * 生成 Markdown 报告\r\n */\r\n static async generateMarkdownReport(report: DiagnosticReport): Promise<void> {\r\n const markdown = `# 🤖 AI 诊断报告\r\n\r\n**生成时间**: ${report.timestamp}\r\n\r\n---\r\n\r\n## ❌ 错误信息\r\n\r\n**类型**: \\`${report.error.type}\\` \r\n**文件**: \\`${report.error.file}\\` \r\n**消息**: \r\n\\`\\`\\`\r\n${report.error.message}\r\n\\`\\`\\`\r\n\r\n${\r\n report.error.stack\r\n ? `**堆栈跟踪**:\\n\\`\\`\\`\\n${report.error.stack}\\n\\`\\`\\`\\n`\r\n : \"\"\r\n}\r\n\r\n---\r\n\r\n## 🔍 AI 分析\r\n\r\n${report.analysis}\r\n\r\n---\r\n\r\n## 💡 修复建议\r\n\r\n${report.suggestion}\r\n\r\n---\r\n\r\n## 🔧 修复状态\r\n\r\n${\r\n report.fixed\r\n ? `✅ **已自动修复**\\n\\n修复文件: \\`${report.fixedFilePath}\\``\r\n : `⚠️ **未自动修复**\\n\\n请根据上述建议手动修复`\r\n}\r\n\r\n---\r\n\r\n*AI Diagnostic Plugin v1.0.0* \r\n*Powered by LangGraph & OpenAI*\r\n`;\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.md\");\r\n fs.writeFileSync(reportPath, markdown, \"utf-8\");\r\n console.log(`📄 Markdown 报告已生成: ${reportPath}`);\r\n }\r\n\r\n /**\r\n * 生成 JSON 报告\r\n */\r\n static async generateJSONReport(report: DiagnosticReport): Promise<void> {\r\n const jsonReport = {\r\n version: \"1.0.0\",\r\n timestamp: report.timestamp,\r\n error: {\r\n type: report.error.type,\r\n message: report.error.message,\r\n file: report.error.file,\r\n stack: report.error.stack || null,\r\n },\r\n diagnosis: {\r\n analysis: report.analysis,\r\n suggestion: report.suggestion,\r\n },\r\n fix: {\r\n applied: report.fixed,\r\n filePath: report.fixedFilePath || null,\r\n },\r\n };\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.json\");\r\n fs.writeFileSync(reportPath, JSON.stringify(jsonReport, null, 2), \"utf-8\");\r\n console.log(`📄 JSON 报告已生成: ${reportPath}`);\r\n }\r\n\r\n /**\r\n * 生成多错误合并报告\r\n */\r\n static async generateMultiReport(\r\n reports: DiagnosticReport[],\r\n options: ReporterOptions = {},\r\n ): Promise<void> {\r\n const multiReport: MultiDiagnosticReport = {\r\n timestamp: new Date().toLocaleString(\"zh-CN\"),\r\n totalErrors: reports.length,\r\n errors: reports,\r\n };\r\n\r\n // HTML 报告\r\n if (options.html) {\r\n await this.generateMultiHTMLReport(multiReport);\r\n }\r\n\r\n // Markdown 报告\r\n if (options.markdown) {\r\n await this.generateMultiMarkdownReport(multiReport);\r\n }\r\n\r\n // JSON 报告\r\n if (options.json) {\r\n await this.generateMultiJSONReport(multiReport);\r\n }\r\n }\r\n\r\n /**\r\n * 生成多错误 HTML 报告\r\n */\r\n static async generateMultiHTMLReport(\r\n report: MultiDiagnosticReport,\r\n ): Promise<void> {\r\n const errorsHtml = report.errors\r\n .map(\r\n (error, index) => `\r\n <div class=\"error-item\">\r\n <div class=\"error-number\">错误 ${index + 1} / ${\r\n report.totalErrors\r\n }</div>\r\n <div class=\"error-box\">\r\n <span class=\"error-type\">${error.error.type}</span>\r\n <div class=\"error-message\">${this.escapeHtml(\r\n error.error.message,\r\n )}</div>\r\n <div class=\"error-file\">📂 ${error.error.file}</div>\r\n ${\r\n error.error.stack\r\n ? `<div class=\"stack-trace\">${this.escapeHtml(\r\n error.error.stack,\r\n )}</div>`\r\n : \"\"\r\n }\r\n </div>\r\n\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔍 AI 分析</div>\r\n <div class=\"analysis-box\">\r\n ${this.formatText(error.analysis)}\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <div class=\"section-title\">💡 修复建议</div>\r\n <div class=\"suggestion-box\">\r\n ${this.formatText(error.suggestion)}\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔧 修复状态</div>\r\n ${\r\n error.fixed\r\n ? `<div class=\"fixed-badge\">✅ 已自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">修复文件: <code>${error.fixedFilePath}</code></div>`\r\n : `<div class=\"not-fixed-badge\">⚠️ 未自动修复</div>\r\n <div style=\"margin-top: 10px; color: #666;\">请根据上述建议手动修复</div>`\r\n }\r\n </div>\r\n </div>\r\n `,\r\n )\r\n .join(\"\");\r\n\r\n const html = `\r\n<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>AI 诊断报告 - ${report.totalErrors} 个错误</title>\r\n <style>\r\n * { margin: 0; padding: 0; box-sizing: border-box; }\r\n body {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n padding: 20px;\r\n min-height: 100vh;\r\n }\r\n .container {\r\n max-width: 1000px;\r\n margin: 0 auto;\r\n background: white;\r\n border-radius: 12px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.2);\r\n overflow: hidden;\r\n }\r\n .header {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 30px;\r\n text-align: center;\r\n }\r\n .header h1 {\r\n font-size: 32px;\r\n margin-bottom: 10px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 10px;\r\n }\r\n .header .time {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .header .error-count {\r\n font-size: 18px;\r\n margin-top: 10px;\r\n background: rgba(255,255,255,0.2);\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n display: inline-block;\r\n }\r\n .content {\r\n padding: 30px;\r\n }\r\n .error-item {\r\n margin-bottom: 40px;\r\n padding-bottom: 40px;\r\n border-bottom: 2px dashed #e2e8f0;\r\n }\r\n .error-item:last-child {\r\n border-bottom: none;\r\n margin-bottom: 0;\r\n padding-bottom: 0;\r\n }\r\n .error-number {\r\n font-size: 16px;\r\n font-weight: bold;\r\n color: #667eea;\r\n margin-bottom: 15px;\r\n padding: 8px 16px;\r\n background: #f0f9ff;\r\n border-radius: 8px;\r\n display: inline-block;\r\n }\r\n .section {\r\n margin-bottom: 20px;\r\n }\r\n .section-title {\r\n font-size: 18px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 12px;\r\n padding-bottom: 8px;\r\n border-bottom: 2px solid #667eea;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n }\r\n .error-box {\r\n background: #fff5f5;\r\n border-left: 4px solid #f56565;\r\n padding: 20px;\r\n border-radius: 8px;\r\n margin-bottom: 20px;\r\n }\r\n .error-type {\r\n display: inline-block;\r\n background: #f56565;\r\n color: white;\r\n padding: 4px 12px;\r\n border-radius: 12px;\r\n font-size: 12px;\r\n font-weight: bold;\r\n margin-bottom: 10px;\r\n }\r\n .error-message {\r\n font-size: 16px;\r\n color: #c53030;\r\n font-weight: 500;\r\n margin-bottom: 10px;\r\n line-height: 1.6;\r\n }\r\n .error-file {\r\n font-size: 14px;\r\n color: #666;\r\n font-family: 'Courier New', monospace;\r\n background: #f7fafc;\r\n padding: 8px 12px;\r\n border-radius: 4px;\r\n display: inline-block;\r\n }\r\n .analysis-box {\r\n background: #f0f9ff;\r\n border-left: 4px solid #3b82f6;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #1e40af;\r\n }\r\n .suggestion-box {\r\n background: #f0fdf4;\r\n border-left: 4px solid #10b981;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #065f46;\r\n }\r\n .suggestion-box pre {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n margin: 10px 0;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n }\r\n .fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #10b981;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .not-fixed-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: #f59e0b;\r\n color: white;\r\n padding: 8px 16px;\r\n border-radius: 20px;\r\n font-size: 14px;\r\n font-weight: bold;\r\n }\r\n .footer {\r\n background: #f7fafc;\r\n padding: 20px;\r\n text-align: center;\r\n color: #718096;\r\n font-size: 14px;\r\n border-top: 1px solid #e2e8f0;\r\n }\r\n .stack-trace {\r\n background: #1e293b;\r\n color: #e2e8f0;\r\n padding: 15px;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n font-family: 'Courier New', monospace;\r\n font-size: 12px;\r\n line-height: 1.5;\r\n margin-top: 10px;\r\n max-height: 300px;\r\n overflow-y: auto;\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <div class=\"header\">\r\n <h1>🤖 AI 诊断报告</h1>\r\n <div class=\"time\">生成时间: ${report.timestamp}</div>\r\n <div class=\"error-count\">共发现 ${report.totalErrors} 个错误</div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n ${errorsHtml}\r\n </div>\r\n\r\n <div class=\"footer\">\r\n <p>AI Diagnostic Plugin v1.0.7</p>\r\n <p>Powered by LangGraph & OpenAI</p>\r\n </div>\r\n </div>\r\n</body>\r\n</html>\r\n `.trim();\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.html\");\r\n fs.writeFileSync(reportPath, html, \"utf-8\");\r\n console.log(\r\n `\\n📄 诊断报告已生成: ${reportPath} (${report.totalErrors} 个错误)\\n`,\r\n );\r\n }\r\n\r\n /**\r\n * 生成多错误 Markdown 报告\r\n */\r\n static async generateMultiMarkdownReport(\r\n report: MultiDiagnosticReport,\r\n ): Promise<void> {\r\n const errorsMarkdown = report.errors\r\n .map(\r\n (error, index) => `\r\n## 错误 ${index + 1} / ${report.totalErrors}\r\n\r\n### ❌ 错误信息\r\n\r\n**类型**: \\`${error.error.type}\\` \r\n**文件**: \\`${error.error.file}\\` \r\n**消息**: \r\n\\`\\`\\`\r\n${error.error.message}\r\n\\`\\`\\`\r\n\r\n${\r\n error.error.stack\r\n ? `**堆栈跟踪**:\\n\\`\\`\\`\\n${error.error.stack}\\n\\`\\`\\`\\n`\r\n : \"\"\r\n}\r\n\r\n### 🔍 AI 分析\r\n\r\n${error.analysis}\r\n\r\n### 💡 修复建议\r\n\r\n${error.suggestion}\r\n\r\n### 🔧 修复状态\r\n\r\n${\r\n error.fixed\r\n ? `✅ **已自动修复**\\n\\n修复文件: \\`${error.fixedFilePath}\\``\r\n : `⚠️ **未自动修复**\\n\\n请根据上述建议手动修复`\r\n}\r\n\r\n---\r\n`,\r\n )\r\n .join(\"\\n\");\r\n\r\n const markdown = `# 🤖 AI 诊断报告\r\n\r\n**生成时间**: ${report.timestamp} \r\n**错误总数**: ${report.totalErrors}\r\n\r\n---\r\n\r\n${errorsMarkdown}\r\n\r\n*AI Diagnostic Plugin v1.0.7* \r\n*Powered by LangGraph & OpenAI*\r\n`;\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.md\");\r\n fs.writeFileSync(reportPath, markdown, \"utf-8\");\r\n console.log(`📄 Markdown 报告已生成: ${reportPath}`);\r\n }\r\n\r\n /**\r\n * 生成多错误 JSON 报告\r\n */\r\n static async generateMultiJSONReport(\r\n report: MultiDiagnosticReport,\r\n ): Promise<void> {\r\n const jsonReport = {\r\n version: \"1.0.7\",\r\n timestamp: report.timestamp,\r\n totalErrors: report.totalErrors,\r\n errors: report.errors.map((error) => ({\r\n error: {\r\n type: error.error.type,\r\n message: error.error.message,\r\n file: error.error.file,\r\n stack: error.error.stack || null,\r\n },\r\n diagnosis: {\r\n analysis: error.analysis,\r\n suggestion: error.suggestion,\r\n },\r\n fix: {\r\n applied: error.fixed,\r\n filePath: error.fixedFilePath || null,\r\n },\r\n })),\r\n };\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"diagnostic-report.json\");\r\n fs.writeFileSync(reportPath, JSON.stringify(jsonReport, null, 2), \"utf-8\");\r\n console.log(`📄 JSON 报告已生成: ${reportPath}`);\r\n }\r\n}\r\n"],"mappings":"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","names":["import_fs","import_path","error","error","path","fs","path","fs","options"]}