qat-cli 0.3.4 → 0.3.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.
package/dist/index.d.cts CHANGED
@@ -32,6 +32,11 @@ interface SourceAnalysisSummary {
32
32
  methods?: string[];
33
33
  /** computed 属性 */
34
34
  computed?: string[];
35
+ /** import 依赖的一跳签名(仅项目内依赖) */
36
+ importSignatures?: Array<{
37
+ source: string;
38
+ signatures: Record<string, string>;
39
+ }>;
35
40
  }
36
41
  /** AI 生成测试请求 */
37
42
  interface AIGenerateTestRequest {
@@ -743,6 +748,9 @@ declare class OpenAICompatibleProvider implements AIProvider {
743
748
  /**
744
749
  * 压缩源码:保留签名和关键逻辑,剔除注释、空行、样式块
745
750
  * 目标:在保留准确性的前提下减少 token 消耗
751
+ * @param code 源码内容
752
+ * @param maxLength 最大长度
753
+ * @param importPathRewrites import 路径重写映射(原路径→正确路径)
746
754
  */
747
755
  private compressSourceCode;
748
756
  private buildGenerateTestSystemPrompt;
@@ -751,6 +759,16 @@ declare class OpenAICompatibleProvider implements AIProvider {
751
759
  * 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
752
760
  */
753
761
  private computeTestImportPath;
762
+ /**
763
+ * 构建 import 路径重写映射
764
+ * 将源码中可能引用自身的各种写法,映射到测试文件中正确的导入路径
765
+ */
766
+ private buildImportPathRewrites;
767
+ /**
768
+ * 重写源码中的 import 路径
769
+ * 将 from 'oldPath' / from "oldPath" 替换为正确的路径
770
+ */
771
+ private rewriteImportPaths;
754
772
  private parseGenerateTestResponse;
755
773
  private buildReviewTestSystemPrompt;
756
774
  private buildReviewTestUserPrompt;
@@ -966,12 +984,34 @@ interface APICallInfo {
966
984
  /** 来源文件 */
967
985
  sourceFile: string;
968
986
  }
987
+ /** import 语句信息 */
988
+ interface ImportInfo {
989
+ /** 导入的名称列表 */
990
+ names: string[];
991
+ /** 来源模块路径 */
992
+ source: string;
993
+ /** 是否是默认导入 */
994
+ isDefault: boolean;
995
+ /** 是否是命名空间导入 (import * as) */
996
+ isNamespace: boolean;
997
+ }
998
+ /** import 依赖的一跳签名摘要 */
999
+ interface ImportSignature {
1000
+ /** 来源模块路径 */
1001
+ source: string;
1002
+ /** 导入名称 → 签名(类型/参数等) */
1003
+ signatures: Record<string, string>;
1004
+ }
969
1005
  /** TS/JS 文件分析结果 */
970
1006
  interface ModuleAnalysis {
971
1007
  /** 文件路径 */
972
1008
  filePath: string;
973
1009
  /** 导出项列表 */
974
1010
  exports: ExportInfo[];
1011
+ /** import 语句列表 */
1012
+ imports: ImportInfo[];
1013
+ /** import 依赖的一跳签名摘要 */
1014
+ importSignatures: ImportSignature[];
975
1015
  /** Vue 组件分析(仅 .vue 文件) */
976
1016
  vueAnalysis?: VueComponentAnalysis;
977
1017
  /** 发现的 API 调用 */
@@ -1004,4 +1044,4 @@ interface MockRouteCandidate {
1004
1044
  sourceFile: string;
1005
1045
  }
1006
1046
 
1007
- export { type AIAnalyzeResultRequest, type AIAnalyzeResultResponse, type AICapability, type AIConfig, type AIGenerateTestRequest, type AIGenerateTestResponse, type AIPresetProvider, type AIProvider, type AIProviderConstructor, AI_PRESET_PROVIDERS, type APICallInfo, type ComponentTestSetup, type CoverageResult, type CreateOptions, DEFAULT_CONFIG, type DetectContext, type DiffResult, type EmitInfo, type ExportInfo, type ExportKind, type FrameworkDefinition, type FrameworkDetectResult, type FrameworkType, type GlobalOptions, type InitOptions, type LighthouseRunnerOptions, type LoadExternalFrameworksResult, type MockOptions, type MockRoute, type MockRouteCandidate, type MockServerState, type ModuleAnalysis, type MonorepoType, NoopAIProvider, OpenAICompatibleProvider, type PerformanceMetrics, type PlaywrightRunnerOptions, type ProjectInfo, type PropInfo, type QATConfig, type ReportData, type ReportOptions, type RunOptions, type SetupOptions, type SourceAnalysisSummary, type TemplateContext, type TestCaseResult, type TestError, type TestRunResult, type TestStatus, type TestSuiteResult, type TestType, type UILibrary, type VisualOptions, type VitestRunnerOptions, type VueComponentAnalysis, aggregateResults, analyzeFile, analyzeFiles, cleanBaselines, cleanDiffs, clearConfigCache, compareDirectories, compareImages, createBaseline, createDefaultRoutes, defineConfig, detectFramework, detectMonorepo, detectProject, detectUILibrary, discoverAppDirs, discoverUtilityFiles, discoverVueComponents, generateConfigFile, generateHTMLReport, generateMockRouteTemplate, generateMockRoutesFromAPICalls, generateTestFile, getAIProvider, getMockServerState, getRegisteredFrameworks, getRegisteredProviders, initMockRoutesDir, isAIAvailable, listBaselines, listDiffs, loadConfig, loadExternalFrameworks, loadMockRoutes, registerAIProvider, registerFramework, registerTemplate, renderTemplate, resetAIProvider, resetRegistry, runLighthouse, runPlaywright, runVitest, scanAPICalls, startMockServer, stopMockServer, testAIConnection, updateAllBaselines, updateBaseline, validateConfig, writeConfigFile, writeReportToDisk };
1047
+ export { type AIAnalyzeResultRequest, type AIAnalyzeResultResponse, type AICapability, type AIConfig, type AIGenerateTestRequest, type AIGenerateTestResponse, type AIPresetProvider, type AIProvider, type AIProviderConstructor, AI_PRESET_PROVIDERS, type APICallInfo, type ComponentTestSetup, type CoverageResult, type CreateOptions, DEFAULT_CONFIG, type DetectContext, type DiffResult, type EmitInfo, type ExportInfo, type ExportKind, type FrameworkDefinition, type FrameworkDetectResult, type FrameworkType, type GlobalOptions, type ImportInfo, type ImportSignature, type InitOptions, type LighthouseRunnerOptions, type LoadExternalFrameworksResult, type MockOptions, type MockRoute, type MockRouteCandidate, type MockServerState, type ModuleAnalysis, type MonorepoType, NoopAIProvider, OpenAICompatibleProvider, type PerformanceMetrics, type PlaywrightRunnerOptions, type ProjectInfo, type PropInfo, type QATConfig, type ReportData, type ReportOptions, type RunOptions, type SetupOptions, type SourceAnalysisSummary, type TemplateContext, type TestCaseResult, type TestError, type TestRunResult, type TestStatus, type TestSuiteResult, type TestType, type UILibrary, type VisualOptions, type VitestRunnerOptions, type VueComponentAnalysis, aggregateResults, analyzeFile, analyzeFiles, cleanBaselines, cleanDiffs, clearConfigCache, compareDirectories, compareImages, createBaseline, createDefaultRoutes, defineConfig, detectFramework, detectMonorepo, detectProject, detectUILibrary, discoverAppDirs, discoverUtilityFiles, discoverVueComponents, generateConfigFile, generateHTMLReport, generateMockRouteTemplate, generateMockRoutesFromAPICalls, generateTestFile, getAIProvider, getMockServerState, getRegisteredFrameworks, getRegisteredProviders, initMockRoutesDir, isAIAvailable, listBaselines, listDiffs, loadConfig, loadExternalFrameworks, loadMockRoutes, registerAIProvider, registerFramework, registerTemplate, renderTemplate, resetAIProvider, resetRegistry, runLighthouse, runPlaywright, runVitest, scanAPICalls, startMockServer, stopMockServer, testAIConnection, updateAllBaselines, updateBaseline, validateConfig, writeConfigFile, writeReportToDisk };
package/dist/index.d.ts CHANGED
@@ -32,6 +32,11 @@ interface SourceAnalysisSummary {
32
32
  methods?: string[];
33
33
  /** computed 属性 */
34
34
  computed?: string[];
35
+ /** import 依赖的一跳签名(仅项目内依赖) */
36
+ importSignatures?: Array<{
37
+ source: string;
38
+ signatures: Record<string, string>;
39
+ }>;
35
40
  }
36
41
  /** AI 生成测试请求 */
37
42
  interface AIGenerateTestRequest {
@@ -743,6 +748,9 @@ declare class OpenAICompatibleProvider implements AIProvider {
743
748
  /**
744
749
  * 压缩源码:保留签名和关键逻辑,剔除注释、空行、样式块
745
750
  * 目标:在保留准确性的前提下减少 token 消耗
751
+ * @param code 源码内容
752
+ * @param maxLength 最大长度
753
+ * @param importPathRewrites import 路径重写映射(原路径→正确路径)
746
754
  */
747
755
  private compressSourceCode;
748
756
  private buildGenerateTestSystemPrompt;
@@ -751,6 +759,16 @@ declare class OpenAICompatibleProvider implements AIProvider {
751
759
  * 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
752
760
  */
753
761
  private computeTestImportPath;
762
+ /**
763
+ * 构建 import 路径重写映射
764
+ * 将源码中可能引用自身的各种写法,映射到测试文件中正确的导入路径
765
+ */
766
+ private buildImportPathRewrites;
767
+ /**
768
+ * 重写源码中的 import 路径
769
+ * 将 from 'oldPath' / from "oldPath" 替换为正确的路径
770
+ */
771
+ private rewriteImportPaths;
754
772
  private parseGenerateTestResponse;
755
773
  private buildReviewTestSystemPrompt;
756
774
  private buildReviewTestUserPrompt;
@@ -966,12 +984,34 @@ interface APICallInfo {
966
984
  /** 来源文件 */
967
985
  sourceFile: string;
968
986
  }
987
+ /** import 语句信息 */
988
+ interface ImportInfo {
989
+ /** 导入的名称列表 */
990
+ names: string[];
991
+ /** 来源模块路径 */
992
+ source: string;
993
+ /** 是否是默认导入 */
994
+ isDefault: boolean;
995
+ /** 是否是命名空间导入 (import * as) */
996
+ isNamespace: boolean;
997
+ }
998
+ /** import 依赖的一跳签名摘要 */
999
+ interface ImportSignature {
1000
+ /** 来源模块路径 */
1001
+ source: string;
1002
+ /** 导入名称 → 签名(类型/参数等) */
1003
+ signatures: Record<string, string>;
1004
+ }
969
1005
  /** TS/JS 文件分析结果 */
970
1006
  interface ModuleAnalysis {
971
1007
  /** 文件路径 */
972
1008
  filePath: string;
973
1009
  /** 导出项列表 */
974
1010
  exports: ExportInfo[];
1011
+ /** import 语句列表 */
1012
+ imports: ImportInfo[];
1013
+ /** import 依赖的一跳签名摘要 */
1014
+ importSignatures: ImportSignature[];
975
1015
  /** Vue 组件分析(仅 .vue 文件) */
976
1016
  vueAnalysis?: VueComponentAnalysis;
977
1017
  /** 发现的 API 调用 */
@@ -1004,4 +1044,4 @@ interface MockRouteCandidate {
1004
1044
  sourceFile: string;
1005
1045
  }
1006
1046
 
1007
- export { type AIAnalyzeResultRequest, type AIAnalyzeResultResponse, type AICapability, type AIConfig, type AIGenerateTestRequest, type AIGenerateTestResponse, type AIPresetProvider, type AIProvider, type AIProviderConstructor, AI_PRESET_PROVIDERS, type APICallInfo, type ComponentTestSetup, type CoverageResult, type CreateOptions, DEFAULT_CONFIG, type DetectContext, type DiffResult, type EmitInfo, type ExportInfo, type ExportKind, type FrameworkDefinition, type FrameworkDetectResult, type FrameworkType, type GlobalOptions, type InitOptions, type LighthouseRunnerOptions, type LoadExternalFrameworksResult, type MockOptions, type MockRoute, type MockRouteCandidate, type MockServerState, type ModuleAnalysis, type MonorepoType, NoopAIProvider, OpenAICompatibleProvider, type PerformanceMetrics, type PlaywrightRunnerOptions, type ProjectInfo, type PropInfo, type QATConfig, type ReportData, type ReportOptions, type RunOptions, type SetupOptions, type SourceAnalysisSummary, type TemplateContext, type TestCaseResult, type TestError, type TestRunResult, type TestStatus, type TestSuiteResult, type TestType, type UILibrary, type VisualOptions, type VitestRunnerOptions, type VueComponentAnalysis, aggregateResults, analyzeFile, analyzeFiles, cleanBaselines, cleanDiffs, clearConfigCache, compareDirectories, compareImages, createBaseline, createDefaultRoutes, defineConfig, detectFramework, detectMonorepo, detectProject, detectUILibrary, discoverAppDirs, discoverUtilityFiles, discoverVueComponents, generateConfigFile, generateHTMLReport, generateMockRouteTemplate, generateMockRoutesFromAPICalls, generateTestFile, getAIProvider, getMockServerState, getRegisteredFrameworks, getRegisteredProviders, initMockRoutesDir, isAIAvailable, listBaselines, listDiffs, loadConfig, loadExternalFrameworks, loadMockRoutes, registerAIProvider, registerFramework, registerTemplate, renderTemplate, resetAIProvider, resetRegistry, runLighthouse, runPlaywright, runVitest, scanAPICalls, startMockServer, stopMockServer, testAIConnection, updateAllBaselines, updateBaseline, validateConfig, writeConfigFile, writeReportToDisk };
1047
+ export { type AIAnalyzeResultRequest, type AIAnalyzeResultResponse, type AICapability, type AIConfig, type AIGenerateTestRequest, type AIGenerateTestResponse, type AIPresetProvider, type AIProvider, type AIProviderConstructor, AI_PRESET_PROVIDERS, type APICallInfo, type ComponentTestSetup, type CoverageResult, type CreateOptions, DEFAULT_CONFIG, type DetectContext, type DiffResult, type EmitInfo, type ExportInfo, type ExportKind, type FrameworkDefinition, type FrameworkDetectResult, type FrameworkType, type GlobalOptions, type ImportInfo, type ImportSignature, type InitOptions, type LighthouseRunnerOptions, type LoadExternalFrameworksResult, type MockOptions, type MockRoute, type MockRouteCandidate, type MockServerState, type ModuleAnalysis, type MonorepoType, NoopAIProvider, OpenAICompatibleProvider, type PerformanceMetrics, type PlaywrightRunnerOptions, type ProjectInfo, type PropInfo, type QATConfig, type ReportData, type ReportOptions, type RunOptions, type SetupOptions, type SourceAnalysisSummary, type TemplateContext, type TestCaseResult, type TestError, type TestRunResult, type TestStatus, type TestSuiteResult, type TestType, type UILibrary, type VisualOptions, type VitestRunnerOptions, type VueComponentAnalysis, aggregateResults, analyzeFile, analyzeFiles, cleanBaselines, cleanDiffs, clearConfigCache, compareDirectories, compareImages, createBaseline, createDefaultRoutes, defineConfig, detectFramework, detectMonorepo, detectProject, detectUILibrary, discoverAppDirs, discoverUtilityFiles, discoverVueComponents, generateConfigFile, generateHTMLReport, generateMockRouteTemplate, generateMockRoutesFromAPICalls, generateTestFile, getAIProvider, getMockServerState, getRegisteredFrameworks, getRegisteredProviders, initMockRoutesDir, isAIAvailable, listBaselines, listDiffs, loadConfig, loadExternalFrameworks, loadMockRoutes, registerAIProvider, registerFramework, registerTemplate, renderTemplate, resetAIProvider, resetRegistry, runLighthouse, runPlaywright, runVitest, scanAPICalls, startMockServer, stopMockServer, testAIConnection, updateAllBaselines, updateBaseline, validateConfig, writeConfigFile, writeReportToDisk };
package/dist/index.js CHANGED
@@ -2769,9 +2769,15 @@ ${errorDetails}`;
2769
2769
  /**
2770
2770
  * 压缩源码:保留签名和关键逻辑,剔除注释、空行、样式块
2771
2771
  * 目标:在保留准确性的前提下减少 token 消耗
2772
+ * @param code 源码内容
2773
+ * @param maxLength 最大长度
2774
+ * @param importPathRewrites import 路径重写映射(原路径→正确路径)
2772
2775
  */
2773
- compressSourceCode(code, maxLength = 3e3) {
2776
+ compressSourceCode(code, maxLength = 3e3, importPathRewrites) {
2774
2777
  let compressed = code;
2778
+ if (importPathRewrites && importPathRewrites.size > 0) {
2779
+ compressed = this.rewriteImportPaths(compressed, importPathRewrites);
2780
+ }
2775
2781
  compressed = compressed.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
2776
2782
  compressed = compressed.replace(/<template[^>]*>([\s\S]*?)<\/template>/gi, (_match, content) => {
2777
2783
  return `<template>${content.replace(/\s*(?:class|style)\s*=\s*["'][^"']*["']/gi, "")}</template>`;
@@ -2809,7 +2815,8 @@ ${errorDetails}`;
2809
2815
  }
2810
2816
  buildGenerateTestUserPrompt(req) {
2811
2817
  const importPath = this.computeTestImportPath(req.type, req.target);
2812
- let prompt = `\u4E3A${req.target}\u751F\u6210${req.type}\u6D4B\u8BD5\u3002import\u8DEF\u5F84:${importPath}
2818
+ let prompt = `\u4E3A${req.target}\u751F\u6210${req.type}\u6D4B\u8BD5\u3002
2819
+ \u3010\u5F3A\u5236\u3011import\u88AB\u6D4B\u6A21\u5757\u5FC5\u987B\u7528: ${importPath}
2813
2820
  `;
2814
2821
  if (req.analysis) {
2815
2822
  const parts = [];
@@ -2831,13 +2838,19 @@ ${errorDetails}`;
2831
2838
  if (req.analysis.computed?.length) {
2832
2839
  parts.push(`Computed:${req.analysis.computed.join(",")}`);
2833
2840
  }
2841
+ if (req.analysis.importSignatures?.length) {
2842
+ parts.push(`\u4F9D\u8D56\u7B7E\u540D:${req.analysis.importSignatures.map(
2843
+ (imp) => `${imp.source}{${Object.entries(imp.signatures).map(([k, v]) => `${k}:${v}`).join(",")}}`
2844
+ ).join(";")}`);
2845
+ }
2834
2846
  prompt += parts.join("\n") + "\n";
2835
2847
  }
2836
2848
  if (req.context) {
2849
+ const importPathRewrites = this.buildImportPathRewrites(req.type, req.target);
2837
2850
  prompt += `
2838
2851
  \u6E90\u7801:
2839
2852
  \`\`\`
2840
- ${this.compressSourceCode(req.context)}
2853
+ ${this.compressSourceCode(req.context, 3e3, importPathRewrites)}
2841
2854
  \`\`\`
2842
2855
  `;
2843
2856
  }
@@ -2872,6 +2885,58 @@ ${this.compressSourceCode(req.context)}
2872
2885
  }
2873
2886
  return `${prefix}${cleanPath}`;
2874
2887
  }
2888
+ /**
2889
+ * 构建 import 路径重写映射
2890
+ * 将源码中可能引用自身的各种写法,映射到测试文件中正确的导入路径
2891
+ */
2892
+ buildImportPathRewrites(testType, targetPath) {
2893
+ const rewrites = /* @__PURE__ */ new Map();
2894
+ if (!targetPath) return rewrites;
2895
+ const correctImportPath = this.computeTestImportPath(testType, targetPath);
2896
+ const variations = /* @__PURE__ */ new Set();
2897
+ variations.add(targetPath);
2898
+ variations.add(targetPath.replace(/^\.\//, ""));
2899
+ const withoutExt = targetPath.replace(/\.(ts|js|tsx|jsx)$/, "");
2900
+ variations.add(withoutExt);
2901
+ const srcDirMatch = targetPath.match(/^(?:\.\/)?(src\/.+)$/);
2902
+ if (srcDirMatch) {
2903
+ variations.add(`@/${srcDirMatch[1]}`);
2904
+ variations.add(`@/${srcDirMatch[1].replace(/\.(ts|js|tsx|jsx)$/, "")}`);
2905
+ variations.add(`#/${srcDirMatch[1]}`);
2906
+ variations.add(`#/${srcDirMatch[1].replace(/\.(ts|js|tsx|jsx)$/, "")}`);
2907
+ }
2908
+ const pathParts = targetPath.replace(/^\.\//, "").split("/");
2909
+ const fileName = pathParts[pathParts.length - 1];
2910
+ const fileNameNoExt = fileName.replace(/\.(ts|js|tsx|jsx|vue)$/, "");
2911
+ variations.add(`./${fileName}`);
2912
+ variations.add(`./${fileNameNoExt}`);
2913
+ for (let i = 1; i < pathParts.length; i++) {
2914
+ const relPath = "../".repeat(i) + pathParts.slice(i).join("/");
2915
+ variations.add(relPath);
2916
+ variations.add(relPath.replace(/\.(ts|js|tsx|jsx)$/, ""));
2917
+ }
2918
+ for (const variant of variations) {
2919
+ if (variant && variant !== correctImportPath) {
2920
+ rewrites.set(variant, correctImportPath);
2921
+ }
2922
+ }
2923
+ return rewrites;
2924
+ }
2925
+ /**
2926
+ * 重写源码中的 import 路径
2927
+ * 将 from 'oldPath' / from "oldPath" 替换为正确的路径
2928
+ */
2929
+ rewriteImportPaths(code, rewrites) {
2930
+ let result = code;
2931
+ for (const [oldPath, newPath] of rewrites) {
2932
+ const escaped = oldPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2933
+ const singleQuoteRegex = new RegExp(`(from\\s+')${escaped}(')`, "g");
2934
+ const doubleQuoteRegex = new RegExp(`(from\\s+")${escaped}(")`, "g");
2935
+ result = result.replace(singleQuoteRegex, `$1${newPath}$2`);
2936
+ result = result.replace(doubleQuoteRegex, `$1${newPath}$2`);
2937
+ }
2938
+ return result;
2939
+ }
2875
2940
  parseGenerateTestResponse(content) {
2876
2941
  const codeBlockMatch = content.match(/```(?:typescript|ts|javascript|js)?\s*\n([\s\S]*?)```/);
2877
2942
  const code = codeBlockMatch ? codeBlockMatch[1].trim() : content.replace(/^(?:```[\s\S]*?\n)?/, "").replace(/\n?```$/, "").trim();
@@ -2894,12 +2959,14 @@ SUGGESTIONS:- \u5EFA\u8BAE(\u6BCF\u884C\u4E00\u4E2A)`;
2894
2959
  }
2895
2960
  buildReviewTestUserPrompt(req) {
2896
2961
  const importPath = this.computeTestImportPath(req.testType, req.target);
2897
- let prompt = `\u5BA1\u67E5\u6D4B\u8BD5\u4EE3\u7801\u3002\u88AB\u6D4B:${req.target} \u7C7B\u578B:${req.testType} import\u8DEF\u5F84:${importPath}
2962
+ let prompt = `\u5BA1\u67E5\u6D4B\u8BD5\u4EE3\u7801\u3002\u88AB\u6D4B:${req.target} \u7C7B\u578B:${req.testType}
2963
+ \u3010\u5F3A\u5236\u3011import\u88AB\u6D4B\u6A21\u5757\u5FC5\u987B\u7528: ${importPath}
2898
2964
  `;
2965
+ const importPathRewrites = this.buildImportPathRewrites(req.testType, req.target);
2899
2966
  prompt += `
2900
2967
  \u6E90\u7801:
2901
2968
  \`\`\`
2902
- ${this.compressSourceCode(req.sourceCode, 2e3)}
2969
+ ${this.compressSourceCode(req.sourceCode, 2e3, importPathRewrites)}
2903
2970
  \`\`\`
2904
2971
  `;
2905
2972
  prompt += `
@@ -2918,6 +2985,11 @@ ${req.testCode}
2918
2985
  if (req.analysis.emits?.length) {
2919
2986
  parts.push(`Emits:${req.analysis.emits.map((e) => `${e.name}(${e.params?.join(",") || ""})`).join(",")}`);
2920
2987
  }
2988
+ if (req.analysis.importSignatures?.length) {
2989
+ parts.push(`\u4F9D\u8D56:${req.analysis.importSignatures.map(
2990
+ (imp) => `${imp.source}{${Object.entries(imp.signatures).map(([k, v]) => `${k}:${v}`).join(",")}}`
2991
+ ).join(";")}`);
2992
+ }
2921
2993
  if (parts.length > 0) {
2922
2994
  prompt += `
2923
2995
  \u5206\u6790:${parts.join("|")}`;
@@ -3529,15 +3601,18 @@ import path9 from "path";
3529
3601
  function analyzeFile(filePath) {
3530
3602
  const absolutePath = path9.resolve(process.cwd(), filePath);
3531
3603
  if (!fs9.existsSync(absolutePath)) {
3532
- return { filePath, exports: [], apiCalls: [] };
3604
+ return { filePath, exports: [], imports: [], importSignatures: [], apiCalls: [] };
3533
3605
  }
3534
3606
  const content = fs9.readFileSync(absolutePath, "utf-8");
3535
3607
  const ext = path9.extname(filePath);
3536
3608
  const result = {
3537
3609
  filePath,
3538
3610
  exports: extractExports(content, ext),
3611
+ imports: extractImports(content),
3612
+ importSignatures: [],
3539
3613
  apiCalls: extractAPICalls(content, filePath)
3540
3614
  };
3615
+ result.importSignatures = analyzeImportSignatures(result.imports, path9.dirname(absolutePath));
3541
3616
  if (ext === ".vue") {
3542
3617
  result.vueAnalysis = analyzeVueComponent(content, path9.basename(filePath, ".vue"));
3543
3618
  const scriptMatch = content.match(/<script[^>]*>([\s\S]*?)<\/script>/);
@@ -3960,6 +4035,90 @@ function generateMockRoutesFromAPICalls(apiCalls) {
3960
4035
  }
3961
4036
  return routes;
3962
4037
  }
4038
+ function extractImports(content) {
4039
+ const imports = [];
4040
+ const namedImportRegex = /import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/g;
4041
+ let match;
4042
+ while ((match = namedImportRegex.exec(content)) !== null) {
4043
+ const names = match[1].split(",").map((n) => {
4044
+ const parts = n.trim().split(/\s+as\s+/);
4045
+ return parts[0].trim();
4046
+ }).filter(Boolean);
4047
+ imports.push({ names, source: match[2], isDefault: false, isNamespace: false });
4048
+ }
4049
+ const defaultImportRegex = /import\s+(\w+)\s+from\s*['"]([^'"]+)['"]/g;
4050
+ while ((match = defaultImportRegex.exec(content)) !== null) {
4051
+ const fullLine = content.slice(Math.max(0, match.index - 5), match.index + match[0].length);
4052
+ if (fullLine.includes("{")) continue;
4053
+ imports.push({ names: [match[1]], source: match[2], isDefault: true, isNamespace: false });
4054
+ }
4055
+ const namespaceImportRegex = /import\s*\*\s*as\s+(\w+)\s*from\s*['"]([^'"]+)['"]/g;
4056
+ while ((match = namespaceImportRegex.exec(content)) !== null) {
4057
+ imports.push({ names: [match[1]], source: match[2], isDefault: false, isNamespace: true });
4058
+ }
4059
+ return imports;
4060
+ }
4061
+ function analyzeImportSignatures(imports, baseDir) {
4062
+ const signatures = [];
4063
+ for (const imp of imports) {
4064
+ if (!imp.source.startsWith(".") && !imp.source.startsWith("@/") && !imp.source.startsWith("#/") && !imp.source.startsWith("~")) {
4065
+ continue;
4066
+ }
4067
+ const resolvedPath = resolveImportPath2(imp.source, baseDir);
4068
+ if (!resolvedPath || !fs9.existsSync(resolvedPath)) continue;
4069
+ try {
4070
+ const content = fs9.readFileSync(resolvedPath, "utf-8");
4071
+ const ext = path9.extname(resolvedPath);
4072
+ const exports = extractExports(content, ext);
4073
+ const sigMap = {};
4074
+ for (const name of imp.names) {
4075
+ const exp = exports.find((e) => e.name === name);
4076
+ if (exp) {
4077
+ const params = exp.params.length > 0 ? `(${exp.params.join(", ")})` : "";
4078
+ const ret = exp.returnType ? `: ${exp.returnType}` : "";
4079
+ const async = exp.isAsync ? "async " : "";
4080
+ sigMap[name] = `${async}${exp.kind}${params}${ret}`;
4081
+ } else if (imp.isDefault) {
4082
+ const defaultExp = exports.find((e) => e.kind === "default");
4083
+ if (defaultExp) {
4084
+ sigMap[name] = `default[${defaultExp.name || "anonymous"}]`;
4085
+ }
4086
+ } else if (imp.isNamespace) {
4087
+ sigMap[name] = `{${exports.map((e) => e.name).join(", ")}}`;
4088
+ }
4089
+ }
4090
+ if (ext === ".vue") {
4091
+ const vueAnalysis = analyzeVueComponent(content, path9.basename(resolvedPath, ".vue"));
4092
+ if (vueAnalysis.props.length > 0) {
4093
+ sigMap["__props__"] = vueAnalysis.props.map((p) => `${p.name}:${p.type}${p.required ? "!" : "?"}`).join(",");
4094
+ }
4095
+ }
4096
+ if (Object.keys(sigMap).length > 0) {
4097
+ signatures.push({ source: imp.source, signatures: sigMap });
4098
+ }
4099
+ } catch {
4100
+ }
4101
+ }
4102
+ return signatures;
4103
+ }
4104
+ function resolveImportPath2(importSource, baseDir) {
4105
+ let resolved;
4106
+ if (importSource.startsWith("@/") || importSource.startsWith("#/") || importSource.startsWith("~")) {
4107
+ const relativePath = importSource.replace(/^[@#~]\//, "src/");
4108
+ resolved = path9.resolve(process.cwd(), relativePath);
4109
+ } else if (importSource.startsWith(".")) {
4110
+ resolved = path9.resolve(baseDir, importSource);
4111
+ } else {
4112
+ return null;
4113
+ }
4114
+ const extensions = [".ts", ".tsx", ".js", ".jsx", ".vue", "/index.ts", "/index.js"];
4115
+ if (fs9.existsSync(resolved)) return resolved;
4116
+ for (const ext of extensions) {
4117
+ const withExt = resolved + ext;
4118
+ if (fs9.existsSync(withExt)) return withExt;
4119
+ }
4120
+ return null;
4121
+ }
3963
4122
  export {
3964
4123
  AI_PRESET_PROVIDERS,
3965
4124
  DEFAULT_CONFIG,