qat-cli 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -8,10 +8,10 @@ import {
8
8
 
9
9
  // src/cli.ts
10
10
  import { Command } from "commander";
11
- import chalk12 from "chalk";
11
+ import chalk13 from "chalk";
12
12
 
13
13
  // src/commands/init.ts
14
- import chalk2 from "chalk";
14
+ import chalk3 from "chalk";
15
15
  import inquirer from "inquirer";
16
16
  import ora from "ora";
17
17
  import fs6 from "fs";
@@ -843,6 +843,15 @@ var NoopAIProvider = class {
843
843
  };
844
844
 
845
845
  // src/ai/openai-provider.ts
846
+ import chalk2 from "chalk";
847
+ function isDebug() {
848
+ return process.env.QAT_DEBUG === "true";
849
+ }
850
+ function debugLog(tag, ...args) {
851
+ if (!isDebug()) return;
852
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
853
+ console.error(chalk2.gray(`[DEBUG ${timestamp}] [${tag}]`), ...args);
854
+ }
846
855
  var OpenAICompatibleProvider = class {
847
856
  constructor(config) {
848
857
  this.capabilities = {
@@ -856,25 +865,20 @@ var OpenAICompatibleProvider = class {
856
865
  this.baseUrl = config.baseUrl || this.getDefaultBaseUrl(config.provider);
857
866
  }
858
867
  async generateTest(req) {
868
+ debugLog("GENERATE", `type=${req.type} target=${req.target}`);
859
869
  const systemPrompt = this.buildGenerateTestSystemPrompt(req);
860
870
  const userPrompt = this.buildGenerateTestUserPrompt(req);
861
871
  const content = await this.chat(systemPrompt, userPrompt);
862
- return this.parseGenerateTestResponse(content);
872
+ const result = this.parseGenerateTestResponse(content);
873
+ debugLog("GENERATE", `done code=${result.code.length}chars confidence=${result.confidence}`);
874
+ return result;
863
875
  }
864
876
  async analyzeResult(req) {
865
- const systemPrompt = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u6D4B\u8BD5\u5206\u6790\u4E13\u5BB6\u3002\u5206\u6790\u6D4B\u8BD5\u8FD0\u884C\u7ED3\u679C\uFF0C\u627E\u51FA\u95EE\u9898\u6839\u56E0\uFF0C\u7ED9\u51FA\u5177\u4F53\u53EF\u64CD\u4F5C\u7684\u6539\u8FDB\u5EFA\u8BAE\u3002
866
- \u8F93\u51FA\u683C\u5F0F\uFF1A
867
- 1. \u5206\u6790\u6458\u8981\uFF081-3\u53E5\u8BDD\uFF09
868
- 2. \u6539\u8FDB\u5EFA\u8BAE\u5217\u8868\uFF08\u6BCF\u6761\u5EFA\u8BAE\u5177\u4F53\u3001\u53EF\u64CD\u4F5C\uFF09`;
869
- const resultSummary = req.testResults.map((r) => {
870
- const failed = r.suites.flatMap((s) => s.tests.filter((t) => t.status === "failed"));
871
- return `\u7C7B\u578B: ${r.type}, \u72B6\u6001: ${r.status}, \u8017\u65F6: ${r.duration}ms, \u5931\u8D25\u7528\u4F8B: ${failed.length}`;
872
- }).join("\n");
873
- const errorDetails = req.errorLogs?.join("\n") || req.testResults.flatMap((r) => r.suites.flatMap((s) => s.tests.filter((t) => t.status === "failed" && t.error))).map((t) => `[${t.name}] ${t.error?.message}`).join("\n") || "\u65E0\u9519\u8BEF\u8BE6\u60C5";
874
- const userPrompt = `\u6D4B\u8BD5\u7ED3\u679C:
875
- ${resultSummary}
876
-
877
- \u9519\u8BEF\u8BE6\u60C5:
877
+ const systemPrompt = `\u6D4B\u8BD5\u5206\u6790\u4E13\u5BB6\u3002\u627E\u95EE\u9898\u6839\u56E0\uFF0C\u7ED9\u53EF\u64CD\u4F5C\u5EFA\u8BAE\u3002
878
+ \u8F93\u51FA:1.\u6458\u8981(1-3\u53E5) 2.\u5EFA\u8BAE\u5217\u8868`;
879
+ const failed = req.testResults.flatMap((r) => r.suites.flatMap((s) => s.tests.filter((t) => t.status === "failed")));
880
+ const errorDetails = req.errorLogs?.join("\n") || failed.map((t) => `[${t.name}] ${t.error?.message}`).join("\n") || "\u65E0";
881
+ const userPrompt = `\u5931\u8D25:${failed.length}
878
882
  ${errorDetails}`;
879
883
  const content = await this.chat(systemPrompt, userPrompt);
880
884
  return {
@@ -884,23 +888,22 @@ ${errorDetails}`;
884
888
  };
885
889
  }
886
890
  async suggestFix(error) {
887
- const systemPrompt = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u4EE3\u7801\u4FEE\u590D\u4E13\u5BB6\u3002\u6839\u636E\u6D4B\u8BD5\u9519\u8BEF\u4FE1\u606F\uFF0C\u7ED9\u51FA\u5177\u4F53\u7684\u4FEE\u590D\u5EFA\u8BAE\u3002
888
- \u6BCF\u6761\u5EFA\u8BAE\u5E94\u8BE5\u5305\u542B\uFF1A
889
- 1. \u95EE\u9898\u5B9A\u4F4D
890
- 2. \u4FEE\u590D\u65B9\u6848
891
- 3. \u793A\u4F8B\u4EE3\u7801\uFF08\u5982\u679C\u9002\u7528\uFF09`;
892
- const userPrompt = `\u9519\u8BEF\u4FE1\u606F: ${error.message}
893
- ${error.stack ? `\u5806\u6808: ${error.stack}` : ""}
894
- ${error.expected ? `\u671F\u671B\u503C: ${error.expected}` : ""}
895
- ${error.actual ? `\u5B9E\u9645\u503C: ${error.actual}` : ""}`;
891
+ const systemPrompt = `\u4EE3\u7801\u4FEE\u590D\u4E13\u5BB6\u3002\u7ED9\u51FA:1.\u95EE\u9898\u5B9A\u4F4D 2.\u4FEE\u590D\u65B9\u6848 3.\u793A\u4F8B\u4EE3\u7801`;
892
+ const userPrompt = `\u9519\u8BEF:${error.message}${error.stack ? `
893
+ \u5806\u6808:${error.stack}` : ""}${error.expected ? `
894
+ \u671F\u671B:${error.expected}` : ""}${error.actual ? `
895
+ \u5B9E\u9645:${error.actual}` : ""}`;
896
896
  const content = await this.chat(systemPrompt, userPrompt);
897
897
  return content.split("\n").filter((l) => l.trim().startsWith("-") || l.trim().startsWith("\u2022") || l.trim().match(/^\d+\./)).map((l) => l.replace(/^[-•\d.]+\s*/, "").trim()).filter(Boolean);
898
898
  }
899
899
  async reviewTest(req) {
900
+ debugLog("REVIEW", `target=${req.target} type=${req.testType}`);
900
901
  const systemPrompt = this.buildReviewTestSystemPrompt(req);
901
902
  const userPrompt = this.buildReviewTestUserPrompt(req);
902
903
  const content = await this.chat(systemPrompt, userPrompt);
903
- return this.parseReviewTestResponse(content);
904
+ const result = this.parseReviewTestResponse(content);
905
+ debugLog("REVIEW", `approved=${result.approved} score=${result.score} feedback=${result.feedback}`);
906
+ return result;
904
907
  }
905
908
  // ─── 内部方法 ──────────────────────────────────────────────
906
909
  /**
@@ -964,8 +967,9 @@ ${error.actual ? `\u5B9E\u9645\u503C: ${error.actual}` : ""}`;
964
967
  return { ok: false, message: `\u8FDE\u63A5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`, latencyMs };
965
968
  }
966
969
  }
967
- async chat(systemPrompt, userPrompt) {
970
+ async chat(systemPrompt, userPrompt, retries = 2) {
968
971
  const url = `${this.baseUrl}/chat/completions`;
972
+ const useStream = isDebug();
969
973
  const body = {
970
974
  model: this.model,
971
975
  messages: [
@@ -975,99 +979,218 @@ ${error.actual ? `\u5B9E\u9645\u503C: ${error.actual}` : ""}`;
975
979
  temperature: 0.3,
976
980
  max_tokens: 4096
977
981
  };
982
+ if (useStream) {
983
+ body.stream = true;
984
+ }
978
985
  const headers = {
979
986
  "Content-Type": "application/json"
980
987
  };
981
988
  if (this.apiKey) {
982
989
  headers["Authorization"] = `Bearer ${this.apiKey}`;
983
990
  }
984
- const response = await fetch(url, {
985
- method: "POST",
986
- headers,
987
- body: JSON.stringify(body),
988
- signal: AbortSignal.timeout(6e4)
989
- // 60s timeout
990
- });
991
- if (!response.ok) {
992
- const text = await response.text().catch(() => "");
993
- throw new Error(`AI API \u8BF7\u6C42\u5931\u8D25 (${response.status}): ${text.slice(0, 500)}`);
991
+ debugLog("REQUEST", `POST ${url}`);
992
+ debugLog("REQUEST", `model=${this.model} stream=${useStream}`);
993
+ debugLog("SYSTEM", systemPrompt.length > 500 ? `${systemPrompt.slice(0, 500)}...` : systemPrompt);
994
+ debugLog("USER", userPrompt.length > 1e3 ? `${userPrompt.slice(0, 1e3)}...` : userPrompt);
995
+ let lastError = null;
996
+ for (let attempt = 0; attempt <= retries; attempt++) {
997
+ try {
998
+ if (attempt > 0) {
999
+ debugLog("RETRY", `\u7B2C${attempt}\u6B21\u91CD\u8BD5...`);
1000
+ }
1001
+ const response = await fetch(url, {
1002
+ method: "POST",
1003
+ headers,
1004
+ body: JSON.stringify(body),
1005
+ signal: AbortSignal.timeout(12e4)
1006
+ // 120s timeout
1007
+ });
1008
+ if (!response.ok) {
1009
+ const text = await response.text().catch(() => "");
1010
+ if ((response.status === 429 || response.status >= 500) && attempt < retries) {
1011
+ const delay = Math.min(1e3 * Math.pow(2, attempt), 8e3);
1012
+ debugLog("RETRY", `HTTP ${response.status}, ${delay}ms\u540E\u91CD\u8BD5`);
1013
+ await new Promise((r) => setTimeout(r, delay));
1014
+ lastError = new Error(`AI API \u8BF7\u6C42\u5931\u8D25 (${response.status}): ${text.slice(0, 200)}`);
1015
+ continue;
1016
+ }
1017
+ throw new Error(`AI API \u8BF7\u6C42\u5931\u8D25 (${response.status}): ${text.slice(0, 500)}`);
1018
+ }
1019
+ if (useStream && response.body) {
1020
+ const content = await this.readStream(response.body);
1021
+ debugLog("RESPONSE", content.length > 500 ? `${content.slice(0, 500)}...` : content);
1022
+ return content;
1023
+ }
1024
+ const data = await response.json();
1025
+ if (!data.choices?.[0]?.message?.content) {
1026
+ throw new Error("AI API \u8FD4\u56DE\u7A7A\u54CD\u5E94");
1027
+ }
1028
+ debugLog("RESPONSE", `tokens: prompt=${data.usage?.prompt_tokens} completion=${data.usage?.completion_tokens} total=${data.usage?.total_tokens}`);
1029
+ debugLog("RESPONSE", data.choices[0].message.content.length > 500 ? `${data.choices[0].message.content.slice(0, 500)}...` : data.choices[0].message.content);
1030
+ return data.choices[0].message.content;
1031
+ } catch (error) {
1032
+ if (error instanceof Error && error.name === "TimeoutError" && attempt < retries) {
1033
+ debugLog("TIMEOUT", `\u7B2C${attempt}\u6B21\u8D85\u65F6\uFF0C\u91CD\u8BD5\u4E2D...`);
1034
+ lastError = error;
1035
+ continue;
1036
+ }
1037
+ throw error;
1038
+ }
994
1039
  }
995
- const data = await response.json();
996
- if (!data.choices?.[0]?.message?.content) {
997
- throw new Error("AI API \u8FD4\u56DE\u7A7A\u54CD\u5E94");
1040
+ throw lastError || new Error("AI API \u8BF7\u6C42\u5931\u8D25");
1041
+ }
1042
+ /**
1043
+ * 读取 SSE 流式响应,实时输出内容
1044
+ */
1045
+ async readStream(body) {
1046
+ const chunks = [];
1047
+ const decoder = new TextDecoder();
1048
+ const reader = body.getReader();
1049
+ let buffer = "";
1050
+ let lineCount = 0;
1051
+ try {
1052
+ while (true) {
1053
+ const { done, value } = await reader.read();
1054
+ if (done) break;
1055
+ buffer += decoder.decode(value, { stream: true });
1056
+ const lines = buffer.split("\n");
1057
+ buffer = lines.pop() || "";
1058
+ for (const line of lines) {
1059
+ const trimmed = line.trim();
1060
+ if (!trimmed || trimmed === "data: [DONE]") continue;
1061
+ if (!trimmed.startsWith("data: ")) continue;
1062
+ try {
1063
+ const json = JSON.parse(trimmed.slice(6));
1064
+ const delta = json.choices?.[0]?.delta?.content;
1065
+ if (delta) {
1066
+ chunks.push(delta);
1067
+ lineCount++;
1068
+ process.stderr.write(chalk2.gray(delta));
1069
+ if (lineCount % 20 === 0) {
1070
+ process.stderr.write("\n");
1071
+ }
1072
+ }
1073
+ if (json.choices?.[0]?.finish_reason === "stop") {
1074
+ debugLog("STREAM", "\u5B8C\u6210");
1075
+ }
1076
+ } catch {
1077
+ }
1078
+ }
1079
+ }
1080
+ } finally {
1081
+ reader.releaseLock();
1082
+ }
1083
+ if (chunks.length > 0) {
1084
+ process.stderr.write("\n");
1085
+ }
1086
+ return chunks.join("");
1087
+ }
1088
+ /**
1089
+ * 压缩源码:保留签名和关键逻辑,剔除注释、空行、样式块
1090
+ * 目标:在保留准确性的前提下减少 token 消耗
1091
+ */
1092
+ compressSourceCode(code, maxLength = 3e3) {
1093
+ let compressed = code;
1094
+ compressed = compressed.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "");
1095
+ compressed = compressed.replace(/<template[^>]*>([\s\S]*?)<\/template>/gi, (_match, content) => {
1096
+ return `<template>${content.replace(/\s*(?:class|style)\s*=\s*["'][^"']*["']/gi, "")}</template>`;
1097
+ });
1098
+ compressed = compressed.replace(/\/\*[\s\S]*?\*\//g, "");
1099
+ compressed = compressed.replace(/(^|[^:])(\/\/.*$)/gm, "$1");
1100
+ compressed = compressed.replace(/\n\s*\n\s*\n/g, "\n\n");
1101
+ compressed = compressed.split("\n").map((line) => line.trimEnd()).join("\n").trim();
1102
+ if (compressed.length > maxLength) {
1103
+ const scriptMatch = compressed.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
1104
+ const templateMatch = compressed.match(/<template[^>]*>([\s\S]*?)<\/template>/i);
1105
+ if (scriptMatch) {
1106
+ let scriptPart = scriptMatch[1].trim();
1107
+ scriptPart = compressFunctionBodies(scriptPart, maxLength * 0.7);
1108
+ const templatePart = templateMatch ? `<template>${templateMatch[1].replace(/\s+/g, " ").trim().slice(0, 300)}...</template>` : "";
1109
+ compressed = `${templatePart}
1110
+ <script${scriptMatch[0].match(/<script[^>]*>/)?.[0]?.slice(7) || ">"}>${scriptPart}</script>`;
1111
+ } else {
1112
+ compressed = compressFunctionBodies(compressed, maxLength);
1113
+ }
998
1114
  }
999
- return data.choices[0].message.content;
1115
+ return compressed;
1000
1116
  }
1001
1117
  buildGenerateTestSystemPrompt(req) {
1002
1118
  const typeMap = {
1003
- unit: "\u5355\u5143\u6D4B\u8BD5\uFF08Vitest + @vue/test-utils\uFF09",
1004
- component: "\u7EC4\u4EF6\u6D4B\u8BD5\uFF08Vitest + @vue/test-utils + mount\uFF09",
1005
- e2e: "E2E\u7AEF\u5230\u7AEF\u6D4B\u8BD5\uFF08Playwright\uFF09",
1006
- api: "API\u63A5\u53E3\u6D4B\u8BD5\uFF08Vitest + fetch\uFF09",
1007
- visual: "\u89C6\u89C9\u56DE\u5F52\u6D4B\u8BD5\uFF08Playwright screenshot\uFF09",
1008
- performance: "\u6027\u80FD\u6D4B\u8BD5\uFF08Playwright + performance metrics\uFF09"
1119
+ unit: "\u5355\u5143\u6D4B\u8BD5(Vitest)",
1120
+ component: "\u7EC4\u4EF6\u6D4B\u8BD5(Vitest+@vue/test-utils)",
1121
+ e2e: "E2E\u6D4B\u8BD5(Playwright)",
1122
+ api: "API\u6D4B\u8BD5(Vitest+fetch)",
1123
+ visual: "\u89C6\u89C9\u56DE\u5F52\u6D4B\u8BD5(Playwright)",
1124
+ performance: "\u6027\u80FD\u6D4B\u8BD5(Playwright)"
1009
1125
  };
1010
- return `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u524D\u7AEF\u6D4B\u8BD5\u5DE5\u7A0B\u5E08\uFF0C\u64C5\u957F\u7F16\u5199\u9AD8\u8D28\u91CF\u7684${typeMap[req.type] || req.type}\u3002
1011
- \u8981\u6C42\uFF1A
1012
- 1. \u53EA\u8F93\u51FA\u6D4B\u8BD5\u4EE3\u7801\uFF0C\u4E0D\u8981\u591A\u4F59\u7684\u89E3\u91CA
1013
- 2. \u4EE3\u7801\u5FC5\u987B\u53EF\u76F4\u63A5\u8FD0\u884C\uFF0C\u5305\u542B\u6240\u6709\u5FC5\u8981\u7684 import
1014
- 3. \u6D4B\u8BD5\u7528\u4F8B\u8986\u76D6\uFF1A\u6B63\u5E38\u8DEF\u5F84\u3001\u8FB9\u754C\u6761\u4EF6\u3001\u9519\u8BEF\u5904\u7406
1015
- 4. \u4F7F\u7528\u4E2D\u6587\u63CF\u8FF0 it/test \u5757\u540D\u79F0
1016
- 5. Vue \u7EC4\u4EF6\u6D4B\u8BD5\u4F7F\u7528 @vue/test-utils \u7684 mount
1017
- 6. \u5982\u679C\u6709 props/emits \u4FE1\u606F\uFF0C\u52A1\u5FC5\u9488\u5BF9\u6BCF\u4E2A prop \u548C emit \u751F\u6210\u6D4B\u8BD5`;
1126
+ return `\u4F60\u662F\u524D\u7AEF\u6D4B\u8BD5\u5DE5\u7A0B\u5E08\uFF0C\u7F16\u5199${typeMap[req.type] || req.type}\u3002
1127
+ \u89C4\u5219:1.\u53EA\u8F93\u51FA\u6D4B\u8BD5\u4EE3\u7801 2.\u5305\u542B\u6240\u6709import 3.\u8986\u76D6\u6B63\u5E38/\u8FB9\u754C/\u9519\u8BEF 4.it\u540D\u7528\u4E2D\u6587 5.Vue\u7528mount 6.\u5FC5\u6D4B\u6BCF\u4E2Aprop\u548Cemit`;
1018
1128
  }
1019
1129
  buildGenerateTestUserPrompt(req) {
1020
- let prompt = `\u8BF7\u4E3A\u4EE5\u4E0B\u6587\u4EF6\u751F\u6210${req.type}\u6D4B\u8BD5\u4EE3\u7801:
1021
- \u76EE\u6807\u6587\u4EF6: ${req.target}
1130
+ const importPath = this.computeTestImportPath(req.type, req.target);
1131
+ let prompt = `\u4E3A${req.target}\u751F\u6210${req.type}\u6D4B\u8BD5\u3002import\u8DEF\u5F84:${importPath}
1022
1132
  `;
1023
1133
  if (req.analysis) {
1024
- prompt += "\n\u6E90\u7801\u5206\u6790\u7ED3\u679C:\n";
1134
+ const parts = [];
1025
1135
  if (req.analysis.exports?.length > 0) {
1026
- prompt += `\u5BFC\u51FA\u9879:
1027
- ${req.analysis.exports.map((e) => {
1028
- const params = e.params?.length ? `(${e.params.join(", ")})` : "";
1029
- const asyncFlag = e.isAsync ? "async " : "";
1030
- return ` - ${asyncFlag}${e.name}${params} [${e.kind}]`;
1031
- }).join("\n")}
1032
- `;
1136
+ parts.push(`\u5BFC\u51FA:${req.analysis.exports.map((e) => {
1137
+ const p = e.params?.length ? `(${e.params.join(",")})` : "";
1138
+ return `${e.isAsync ? "async " : ""}${e.name}${p}[${e.kind}]`;
1139
+ }).join(",")}`);
1033
1140
  }
1034
1141
  if (req.analysis.props?.length) {
1035
- prompt += `Props:
1036
- ${req.analysis.props.map(
1037
- (p) => ` - ${p.name}: ${p.type}${p.required ? " (\u5FC5\u586B)" : " (\u53EF\u9009)"}`
1038
- ).join("\n")}
1039
- `;
1142
+ parts.push(`Props:${req.analysis.props.map((p) => `${p.name}:${p.type}${p.required ? "!" : "?"}`).join(",")}`);
1040
1143
  }
1041
1144
  if (req.analysis.emits?.length) {
1042
- prompt += `Emits:
1043
- ${req.analysis.emits.map(
1044
- (e) => ` - ${e.name}${e.params?.length ? `(${e.params.join(", ")})` : ""}`
1045
- ).join("\n")}
1046
- `;
1145
+ parts.push(`Emits:${req.analysis.emits.map((e) => `${e.name}(${e.params?.join(",") || ""})`).join(",")}`);
1047
1146
  }
1048
1147
  if (req.analysis.methods?.length) {
1049
- prompt += `Methods: ${req.analysis.methods.join(", ")}
1050
- `;
1148
+ parts.push(`Methods:${req.analysis.methods.join(",")}`);
1051
1149
  }
1052
1150
  if (req.analysis.computed?.length) {
1053
- prompt += `Computed: ${req.analysis.computed.join(", ")}
1054
- `;
1151
+ parts.push(`Computed:${req.analysis.computed.join(",")}`);
1055
1152
  }
1153
+ prompt += parts.join("\n") + "\n";
1056
1154
  }
1057
1155
  if (req.context) {
1058
1156
  prompt += `
1059
- \u6E90\u7801\u5185\u5BB9:
1060
- \`\`\`typescript
1061
- ${req.context}
1157
+ \u6E90\u7801:
1158
+ \`\`\`
1159
+ ${this.compressSourceCode(req.context)}
1062
1160
  \`\`\`
1063
1161
  `;
1064
1162
  }
1065
1163
  if (req.framework) {
1066
- prompt += `
1067
- \u6846\u67B6: ${req.framework}`;
1164
+ prompt += `\u6846\u67B6:${req.framework}`;
1068
1165
  }
1069
1166
  return prompt;
1070
1167
  }
1168
+ /**
1169
+ * 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
1170
+ */
1171
+ computeTestImportPath(testType, targetPath) {
1172
+ if (!targetPath) return targetPath;
1173
+ const testDirMap = {
1174
+ unit: "tests/unit",
1175
+ component: "tests/component",
1176
+ e2e: "tests/e2e",
1177
+ api: "tests/api",
1178
+ visual: "tests/visual",
1179
+ performance: "tests/e2e"
1180
+ };
1181
+ const testDir = testDirMap[testType];
1182
+ if (!testDir) return targetPath;
1183
+ if (targetPath.startsWith("../") || targetPath.startsWith("./../")) {
1184
+ return targetPath;
1185
+ }
1186
+ const depth = testDir.split("/").length;
1187
+ const prefix = "../".repeat(depth);
1188
+ let cleanPath = targetPath.replace(/^\.\//, "");
1189
+ if (!cleanPath.endsWith(".vue")) {
1190
+ cleanPath = cleanPath.replace(/\.(ts|js|tsx|jsx)$/, "");
1191
+ }
1192
+ return `${prefix}${cleanPath}`;
1193
+ }
1071
1194
  parseGenerateTestResponse(content) {
1072
1195
  const codeBlockMatch = content.match(/```(?:typescript|ts|javascript|js)?\s*\n([\s\S]*?)```/);
1073
1196
  const code = codeBlockMatch ? codeBlockMatch[1].trim() : content.replace(/^(?:```[\s\S]*?\n)?/, "").replace(/\n?```$/, "").trim();
@@ -1079,67 +1202,49 @@ ${req.context}
1079
1202
  };
1080
1203
  }
1081
1204
  buildReviewTestSystemPrompt(_req) {
1082
- return `\u4F60\u662F\u4E00\u4F4D\u4E25\u8C28\u7684\u6D4B\u8BD5\u5BA1\u8BA1\u4E13\u5BB6\u3002\u4F60\u7684\u804C\u8D23\u662F\u5BA1\u67E5 AI \u751F\u6210\u7684\u6D4B\u8BD5\u7528\u4F8B\u662F\u5426\u4E0E\u6E90\u7801\u8D34\u5207\u4E14\u51C6\u786E\u3002
1083
-
1084
- \u5BA1\u67E5\u6807\u51C6\uFF1A
1085
- 1. **\u6D4B\u8BD5\u7C7B\u578B\u5339\u914D**\uFF1A\u6D4B\u8BD5\u7C7B\u578B\u662F\u5426\u4E0E\u6E90\u7801\u6587\u4EF6\u6027\u8D28\u5339\u914D\uFF08\u5982 .vue \u5E94\u4E3A\u7EC4\u4EF6\u6D4B\u8BD5\uFF0Cutils \u5E94\u4E3A\u5355\u5143\u6D4B\u8BD5\uFF09
1086
- 2. **\u8986\u76D6\u5B8C\u6574\u6027**\uFF1A\u662F\u5426\u8986\u76D6\u4E86\u6E90\u7801\u4E2D\u7684\u6838\u5FC3\u5BFC\u51FA\u9879\uFF08\u51FD\u6570\u3001\u7EC4\u4EF6\u7684 props/emits/methods\uFF09
1087
- 3. **\u65AD\u8A00\u6709\u6548\u6027**\uFF1A\u65AD\u8A00\u662F\u5426\u771F\u5B9E\u68C0\u9A8C\u4E86\u88AB\u6D4B\u884C\u4E3A\uFF0C\u800C\u975E\u7A7A\u65AD\u8A00\u6216\u6C38\u771F\u65AD\u8A00
1088
- 4. **\u5BFC\u5165\u6B63\u786E\u6027**\uFF1Aimport \u8DEF\u5F84\u548C\u6A21\u5757\u662F\u5426\u6B63\u786E
1089
- 5. **\u4EE3\u7801\u53EF\u8FD0\u884C\u6027**\uFF1A\u6D4B\u8BD5\u4EE3\u7801\u662F\u5426\u53EF\u76F4\u63A5\u8FD0\u884C\uFF0C\u65E0\u8BED\u6CD5\u9519\u8BEF
1090
-
1091
- \u8F93\u51FA\u683C\u5F0F\uFF08\u4E25\u683C\u9075\u5B88\uFF09\uFF1A
1092
- APPROVED: true \u6216 false
1093
- SCORE: 0.0 \u5230 1.0 \u4E4B\u95F4\u7684\u8BC4\u5206
1094
- FEEDBACK: \u4E00\u53E5\u8BDD\u5BA1\u8BA1\u610F\u89C1
1095
- ISSUES: \u95EE\u9898\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF0C\u683C\u5F0F "- \u95EE\u9898\u63CF\u8FF0"\uFF09
1096
- SUGGESTIONS: \u6539\u8FDB\u5EFA\u8BAE\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF0C\u683C\u5F0F "- \u5EFA\u8BAE\u63CF\u8FF0"\uFF09`;
1205
+ return `\u4F60\u662F\u6D4B\u8BD5\u5BA1\u8BA1\u4E13\u5BB6\u3002\u5BA1\u67E5\u6D4B\u8BD5\u4EE3\u7801\u662F\u5426\u51C6\u786E\u3002
1206
+ \u6807\u51C6:1.\u7C7B\u578B\u5339\u914D 2.\u8986\u76D6\u6838\u5FC3\u5BFC\u51FA/props/emits 3.\u65AD\u8A00\u6709\u6548(\u975E\u6C38\u771F) 4.import\u6B63\u786E 5.\u53EF\u8FD0\u884C
1207
+ \u8F93\u51FA:
1208
+ APPROVED:true\u6216false
1209
+ SCORE:0.0-1.0
1210
+ FEEDBACK:\u4E00\u53E5\u8BDD
1211
+ ISSUES:- \u95EE\u9898(\u6BCF\u884C\u4E00\u4E2A)
1212
+ SUGGESTIONS:- \u5EFA\u8BAE(\u6BCF\u884C\u4E00\u4E2A)`;
1097
1213
  }
1098
1214
  buildReviewTestUserPrompt(req) {
1099
- let prompt = `\u8BF7\u5BA1\u67E5\u4EE5\u4E0B\u6D4B\u8BD5\u7528\u4F8B\u662F\u5426\u4E0E\u6E90\u7801\u8D34\u5207\u4E14\u51C6\u786E\u3002
1100
-
1101
- \u88AB\u6D4B\u6587\u4EF6: ${req.target}
1102
- \u6D4B\u8BD5\u7C7B\u578B: ${req.testType}
1103
-
1104
- --- \u6E90\u7801\u5185\u5BB9 ---
1105
- \`\`\`typescript
1106
- ${req.sourceCode}
1215
+ const importPath = this.computeTestImportPath(req.testType, req.target);
1216
+ let prompt = `\u5BA1\u67E5\u6D4B\u8BD5\u4EE3\u7801\u3002\u88AB\u6D4B:${req.target} \u7C7B\u578B:${req.testType} import\u8DEF\u5F84:${importPath}
1217
+ `;
1218
+ prompt += `
1219
+ \u6E90\u7801:
1220
+ \`\`\`
1221
+ ${this.compressSourceCode(req.sourceCode, 2e3)}
1222
+ \`\`\`
1223
+ `;
1224
+ prompt += `
1225
+ \u6D4B\u8BD5\u4EE3\u7801:
1107
1226
  \`\`\`
1108
-
1109
- --- \u751F\u6210\u7684\u6D4B\u8BD5\u4EE3\u7801 ---
1110
- \`\`\`typescript
1111
1227
  ${req.testCode}
1112
1228
  \`\`\``;
1113
1229
  if (req.analysis) {
1114
- prompt += "\n\n--- \u6E90\u7801\u5206\u6790 ---";
1230
+ const parts = [];
1115
1231
  if (req.analysis.exports?.length > 0) {
1116
- prompt += `
1117
- \u5BFC\u51FA\u9879:
1118
- ${req.analysis.exports.map((e) => {
1119
- const params = e.params?.length ? `(${e.params.join(", ")})` : "";
1120
- const asyncFlag = e.isAsync ? "async " : "";
1121
- return ` - ${asyncFlag}${e.name}${params} [${e.kind}]`;
1122
- }).join("\n")}`;
1232
+ parts.push(`\u5BFC\u51FA:${req.analysis.exports.map((e) => `${e.isAsync ? "async " : ""}${e.name}(${e.params?.join(",") || ""})[${e.kind}]`).join(",")}`);
1123
1233
  }
1124
1234
  if (req.analysis.props?.length) {
1125
- prompt += `
1126
- Props:
1127
- ${req.analysis.props.map(
1128
- (p) => ` - ${p.name}: ${p.type}${p.required ? " (\u5FC5\u586B)" : " (\u53EF\u9009)"}`
1129
- ).join("\n")}`;
1235
+ parts.push(`Props:${req.analysis.props.map((p) => `${p.name}:${p.type}${p.required ? "!" : "?"}`).join(",")}`);
1130
1236
  }
1131
1237
  if (req.analysis.emits?.length) {
1238
+ parts.push(`Emits:${req.analysis.emits.map((e) => `${e.name}(${e.params?.join(",") || ""})`).join(",")}`);
1239
+ }
1240
+ if (parts.length > 0) {
1132
1241
  prompt += `
1133
- Emits:
1134
- ${req.analysis.emits.map(
1135
- (e) => ` - ${e.name}${e.params?.length ? `(${e.params.join(", ")})` : ""}`
1136
- ).join("\n")}`;
1242
+ \u5206\u6790:${parts.join("|")}`;
1137
1243
  }
1138
1244
  }
1139
1245
  if (req.generationDescription) {
1140
1246
  prompt += `
1141
-
1142
- \u751F\u6210\u8005\u8BF4\u660E: ${req.generationDescription}`;
1247
+ \u8BF4\u660E:${req.generationDescription}`;
1143
1248
  }
1144
1249
  return prompt;
1145
1250
  }
@@ -1199,6 +1304,61 @@ ${req.analysis.emits.map(
1199
1304
  return urlMap[provider] || "https://api.openai.com/v1";
1200
1305
  }
1201
1306
  };
1307
+ function compressFunctionBodies(code, maxLength) {
1308
+ const lines = code.split("\n");
1309
+ const result = [];
1310
+ let depth = 0;
1311
+ let fnDepth = 0;
1312
+ let inFunction = false;
1313
+ let braceBalance = 0;
1314
+ let capturedLines = 0;
1315
+ for (const line of lines) {
1316
+ const trimmed = line.trim();
1317
+ for (const ch of trimmed) {
1318
+ if (ch === "{") {
1319
+ braceBalance++;
1320
+ depth++;
1321
+ }
1322
+ if (ch === "}") {
1323
+ braceBalance--;
1324
+ depth = Math.max(0, depth - 1);
1325
+ }
1326
+ }
1327
+ const isFnSignature = /^(export\s+)?(async\s+)?function\s|=>\s*\{|=>\s*$/m.test(trimmed) || /^(const|let|var)\s+\w+\s*=\s*(async\s+)?(\([^)]*\)|[^=])\s*=>/.test(trimmed);
1328
+ if (isFnSignature && !inFunction) {
1329
+ inFunction = true;
1330
+ fnDepth = depth;
1331
+ result.push(line);
1332
+ capturedLines++;
1333
+ continue;
1334
+ }
1335
+ if (inFunction) {
1336
+ const isReturn = trimmed.startsWith("return ");
1337
+ const isBranch = /^(if|else|switch|case|try|catch|finally|for|while)/.test(trimmed);
1338
+ const isClosing = trimmed === "}" && depth <= fnDepth - 1;
1339
+ if (isClosing) {
1340
+ result.push(line);
1341
+ inFunction = false;
1342
+ capturedLines++;
1343
+ } else if (isReturn || isBranch) {
1344
+ result.push(trimmed.length > 120 ? `${trimmed.slice(0, 120)}...` : line);
1345
+ capturedLines++;
1346
+ } else if (trimmed.startsWith("//") || trimmed === "") {
1347
+ } else if (capturedLines < maxLength / 30) {
1348
+ result.push(trimmed.length > 100 ? `${trimmed.slice(0, 100)}...` : line);
1349
+ capturedLines++;
1350
+ }
1351
+ } else {
1352
+ result.push(line);
1353
+ capturedLines++;
1354
+ }
1355
+ if (result.join("\n").length > maxLength) {
1356
+ result.push("// ... (truncated)");
1357
+ break;
1358
+ }
1359
+ }
1360
+ return result.join("\n");
1361
+ }
1202
1362
 
1203
1363
  // src/ai/provider.ts
1204
1364
  var providerRegistry = /* @__PURE__ */ new Map();
@@ -1747,7 +1907,7 @@ function registerInitCommand(program2) {
1747
1907
  try {
1748
1908
  await executeInit(options);
1749
1909
  } catch (error) {
1750
- console.error(chalk2.red(`
1910
+ console.error(chalk3.red(`
1751
1911
  \u2717 ${error instanceof Error ? error.message : String(error)}
1752
1912
  `));
1753
1913
  process.exit(1);
@@ -1769,19 +1929,19 @@ async function executeInit(options) {
1769
1929
  }
1770
1930
  ]);
1771
1931
  if (!proceed) {
1772
- console.log(chalk2.gray("\n \u5DF2\u53D6\u6D88\u521D\u59CB\u5316\n"));
1932
+ console.log(chalk3.gray("\n \u5DF2\u53D6\u6D88\u521D\u59CB\u5316\n"));
1773
1933
  return;
1774
1934
  }
1775
1935
  }
1776
1936
  let globalAI = loadGlobalAIConfig();
1777
1937
  if (!globalAI) {
1778
- console.log(chalk2.cyan(" AI \u6A21\u578B\u914D\u7F6E (\u9996\u6B21\u4F7F\u7528\u9700\u914D\u7F6E\uFF0C\u4E4B\u540E\u53EF\u901A\u8FC7 qat change \u4FEE\u6539)\n"));
1938
+ console.log(chalk3.cyan(" AI \u6A21\u578B\u914D\u7F6E (\u9996\u6B21\u4F7F\u7528\u9700\u914D\u7F6E\uFF0C\u4E4B\u540E\u53EF\u901A\u8FC7 qat change \u4FEE\u6539)\n"));
1779
1939
  globalAI = await promptAIConfig();
1780
1940
  saveGlobalAIConfig(globalAI);
1781
- console.log(chalk2.gray(` \u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3 ${getAIConfigPath()}
1941
+ console.log(chalk3.gray(` \u914D\u7F6E\u5DF2\u4FDD\u5B58\u81F3 ${getAIConfigPath()}
1782
1942
  `));
1783
1943
  } else {
1784
- console.log(chalk2.green(` \u2713 \u5F53\u524D AI \u6A21\u578B: ${chalk2.white(globalAI.model)} @ ${chalk2.gray(globalAI.baseUrl)} (${maskApiKey(globalAI.apiKey)})
1944
+ console.log(chalk3.green(` \u2713 \u5F53\u524D AI \u6A21\u578B: ${chalk3.white(globalAI.model)} @ ${chalk3.gray(globalAI.baseUrl)} (${maskApiKey(globalAI.apiKey)})
1785
1945
  `));
1786
1946
  }
1787
1947
  const aiConfig = toAIConfig(globalAI);
@@ -1790,10 +1950,10 @@ async function executeInit(options) {
1790
1950
  try {
1791
1951
  const result = await testAIConnection(aiConfig);
1792
1952
  if (result.ok) {
1793
- testSpinner.succeed(`AI \u8FDE\u901A\u6B63\u5E38 ${chalk2.gray(`${globalAI.model} (${result.latencyMs}ms)`)}`);
1953
+ testSpinner.succeed(`AI \u8FDE\u901A\u6B63\u5E38 ${chalk3.gray(`${globalAI.model} (${result.latencyMs}ms)`)}`);
1794
1954
  } else {
1795
1955
  testSpinner.fail(`AI \u8FDE\u901A\u5F02\u5E38: ${result.message}`);
1796
- console.log(chalk2.yellow(" \u53EF\u8FD0\u884C qat change \u4FEE\u6539 AI \u914D\u7F6E\u3002"));
1956
+ console.log(chalk3.yellow(" \u53EF\u8FD0\u884C qat change \u4FEE\u6539 AI \u914D\u7F6E\u3002"));
1797
1957
  }
1798
1958
  } catch (error) {
1799
1959
  testSpinner.fail(`AI \u8FDE\u901A\u6D4B\u8BD5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
@@ -1814,7 +1974,7 @@ async function executeInit(options) {
1814
1974
  }
1815
1975
  ]);
1816
1976
  if (!overwrite) {
1817
- console.log(chalk2.gray(" \u4FDD\u7559\u73B0\u6709\u914D\u7F6E\u6587\u4EF6\uFF0C\u7EE7\u7EED\u540E\u7EED\u6B65\u9AA4..."));
1977
+ console.log(chalk3.gray(" \u4FDD\u7559\u73B0\u6709\u914D\u7F6E\u6587\u4EF6\uFF0C\u7EE7\u7EED\u540E\u7EED\u6B65\u9AA4..."));
1818
1978
  configPath = existingConfigPath;
1819
1979
  } else {
1820
1980
  const fileSpinner = ora("\u6B63\u5728\u8986\u76D6\u914D\u7F6E\u6587\u4EF6...").start();
@@ -1849,10 +2009,10 @@ async function executeInit(options) {
1849
2009
  const mockFilePath = path6.join(process.cwd(), mockDir, "auto-generated.json");
1850
2010
  if (!fs6.existsSync(mockFilePath)) {
1851
2011
  fs6.writeFileSync(mockFilePath, JSON.stringify(mockRoutes, null, 2), "utf-8");
1852
- console.log(chalk2.green(` \u81EA\u52A8\u53D1\u73B0 ${apiCalls.length} \u4E2A API \u63A5\u53E3\uFF0C\u5DF2\u751F\u6210 Mock \u8DEF\u7531`));
2012
+ console.log(chalk3.green(` \u81EA\u52A8\u53D1\u73B0 ${apiCalls.length} \u4E2A API \u63A5\u53E3\uFF0C\u5DF2\u751F\u6210 Mock \u8DEF\u7531`));
1853
2013
  }
1854
2014
  } else {
1855
- console.log(chalk2.gray(" \u672A\u53D1\u73B0 API \u8C03\u7528\uFF0C\u5DF2\u751F\u6210\u793A\u4F8B Mock \u8DEF\u7531"));
2015
+ console.log(chalk3.gray(" \u672A\u53D1\u73B0 API \u8C03\u7528\uFF0C\u5DF2\u751F\u6210\u793A\u4F8B Mock \u8DEF\u7531"));
1856
2016
  }
1857
2017
  }
1858
2018
  const srcDir = config.project?.srcDir || "src";
@@ -1860,7 +2020,7 @@ async function executeInit(options) {
1860
2020
  const utilities = discoverUtilityFiles(process.cwd(), srcDir);
1861
2021
  const totalFiles = components.length + utilities.length;
1862
2022
  if (totalFiles > 0) {
1863
- console.log(chalk2.cyan(`
2023
+ console.log(chalk3.cyan(`
1864
2024
  \u53D1\u73B0 ${totalFiles} \u4E2A\u53EF\u6D4B\u8BD5\u6587\u4EF6 (${components.length} \u7EC4\u4EF6, ${utilities.length} \u5DE5\u5177/\u670D\u52A1)`));
1865
2025
  }
1866
2026
  displayResult(configPath, createdDirs, totalFiles, projectInfo);
@@ -1947,8 +2107,8 @@ function buildProjectConfig(projectInfo) {
1947
2107
  };
1948
2108
  }
1949
2109
  function displayProjectInfo(info) {
1950
- console.log(chalk2.cyan("\n \u9879\u76EE\u68C0\u6D4B\u7ED3\u679C:"));
1951
- console.log(chalk2.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2110
+ console.log(chalk3.cyan("\n \u9879\u76EE\u68C0\u6D4B\u7ED3\u679C:"));
2111
+ console.log(chalk3.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1952
2112
  const items = [
1953
2113
  ["\u9879\u76EE\u540D\u79F0", info.name],
1954
2114
  ["\u6846\u67B6", info.frameworkConfidence > 0.5 ? `${info.frameworkDisplayName} (\u7F6E\u4FE1\u5EA6 ${Math.round(info.frameworkConfidence * 100)}%)` : info.frameworkDisplayName],
@@ -1970,8 +2130,8 @@ function displayProjectInfo(info) {
1970
2130
  items.push(["\u7EC4\u4EF6\u76EE\u5F55", info.componentDirs.join(", ")]);
1971
2131
  }
1972
2132
  for (const [label, value] of items) {
1973
- const displayValue = value === true ? chalk2.green("\u2713") : value === false ? chalk2.red("\u2717") : String(value);
1974
- console.log(` ${chalk2.white(label.padEnd(12))} ${displayValue}`);
2133
+ const displayValue = value === true ? chalk3.green("\u2713") : value === false ? chalk3.red("\u2717") : String(value);
2134
+ console.log(` ${chalk3.white(label.padEnd(12))} ${displayValue}`);
1975
2135
  }
1976
2136
  console.log();
1977
2137
  }
@@ -2002,34 +2162,34 @@ function createTestDirectories(config) {
2002
2162
  }
2003
2163
  function displayResult(configPath, createdDirs, totalTestableFiles, projectInfo) {
2004
2164
  const relativeConfig = path6.relative(process.cwd(), configPath);
2005
- console.log(chalk2.green("\n \u2713 \u9879\u76EE\u521D\u59CB\u5316\u5B8C\u6210!\n"));
2006
- console.log(chalk2.white(" \u5DF2\u751F\u6210\u914D\u7F6E:"));
2007
- console.log(chalk2.gray(` ${relativeConfig}`));
2165
+ console.log(chalk3.green("\n \u2713 \u9879\u76EE\u521D\u59CB\u5316\u5B8C\u6210!\n"));
2166
+ console.log(chalk3.white(" \u5DF2\u751F\u6210\u914D\u7F6E:"));
2167
+ console.log(chalk3.gray(` ${relativeConfig}`));
2008
2168
  console.log();
2009
2169
  if (createdDirs.length > 0) {
2010
- console.log(chalk2.white(" \u5DF2\u521B\u5EFA\u76EE\u5F55:"));
2170
+ console.log(chalk3.white(" \u5DF2\u521B\u5EFA\u76EE\u5F55:"));
2011
2171
  for (const dir of createdDirs) {
2012
- console.log(chalk2.gray(` ${dir}/`));
2172
+ console.log(chalk3.gray(` ${dir}/`));
2013
2173
  }
2014
2174
  console.log();
2015
2175
  }
2016
- console.log(chalk2.cyan(" \u4E0B\u4E00\u6B65:"));
2176
+ console.log(chalk3.cyan(" \u4E0B\u4E00\u6B65:"));
2017
2177
  if (totalTestableFiles > 0) {
2018
- console.log(chalk2.gray(` 1. qat create \u9009\u62E9\u6587\u4EF6\u5E76\u751F\u6210\u6D4B\u8BD5\u7528\u4F8B (\u53D1\u73B0 ${totalTestableFiles} \u4E2A\u53EF\u6D4B\u8BD5\u6587\u4EF6)`));
2178
+ console.log(chalk3.gray(` 1. qat create \u9009\u62E9\u6587\u4EF6\u5E76\u751F\u6210\u6D4B\u8BD5\u7528\u4F8B (\u53D1\u73B0 ${totalTestableFiles} \u4E2A\u53EF\u6D4B\u8BD5\u6587\u4EF6)`));
2019
2179
  } else {
2020
- console.log(chalk2.gray(" 1. qat create \u521B\u5EFA\u6D4B\u8BD5\u7528\u4F8B"));
2180
+ console.log(chalk3.gray(" 1. qat create \u521B\u5EFA\u6D4B\u8BD5\u7528\u4F8B"));
2021
2181
  }
2022
- console.log(chalk2.gray(" 2. qat run \u6267\u884C\u6D4B\u8BD5"));
2023
- console.log(chalk2.gray(" 3. qat status \u67E5\u770B AI \u6A21\u578B\u72B6\u6001"));
2182
+ console.log(chalk3.gray(" 2. qat run \u6267\u884C\u6D4B\u8BD5"));
2183
+ console.log(chalk3.gray(" 3. qat status \u67E5\u770B AI \u6A21\u578B\u72B6\u6001"));
2024
2184
  if (projectInfo.testFrameworks.length === 0) {
2025
2185
  console.log();
2026
- console.log(chalk2.yellow(" \u26A0 \u672A\u68C0\u6D4B\u5230\u6D4B\u8BD5\u6846\u67B6\u4F9D\u8D56\uFF0C\u8FD0\u884C qat run \u65F6\u4F1A\u63D0\u793A\u5B89\u88C5"));
2186
+ console.log(chalk3.yellow(" \u26A0 \u672A\u68C0\u6D4B\u5230\u6D4B\u8BD5\u6846\u67B6\u4F9D\u8D56\uFF0C\u8FD0\u884C qat run \u65F6\u4F1A\u63D0\u793A\u5B89\u88C5"));
2027
2187
  }
2028
2188
  console.log();
2029
2189
  }
2030
2190
 
2031
2191
  // src/commands/create.ts
2032
- import chalk4 from "chalk";
2192
+ import chalk5 from "chalk";
2033
2193
  import inquirer2 from "inquirer";
2034
2194
  import ora3 from "ora";
2035
2195
  import fs8 from "fs";
@@ -2082,9 +2242,33 @@ Handlebars.registerHelper("propTestValue", (prop) => {
2082
2242
  };
2083
2243
  return map[prop.type] || "'test-value'";
2084
2244
  });
2245
+ function resolveImportPath(testType, targetPath) {
2246
+ if (!targetPath) return targetPath;
2247
+ const testDirMap = {
2248
+ unit: "tests/unit",
2249
+ component: "tests/component",
2250
+ e2e: "tests/e2e",
2251
+ api: "tests/api",
2252
+ visual: "tests/visual",
2253
+ performance: "tests/e2e"
2254
+ };
2255
+ const testDir = testDirMap[testType];
2256
+ if (!testDir) return targetPath;
2257
+ if (targetPath.startsWith("../") || targetPath.startsWith("./../")) {
2258
+ return targetPath;
2259
+ }
2260
+ const depth = testDir.split("/").length;
2261
+ const prefix = "../".repeat(depth);
2262
+ let cleanPath = targetPath.replace(/^\.\//, "");
2263
+ if (!cleanPath.endsWith(".vue")) {
2264
+ cleanPath = cleanPath.replace(/\.(ts|js|tsx|jsx)$/, "");
2265
+ }
2266
+ return `${prefix}${cleanPath}`;
2267
+ }
2085
2268
  function renderTemplate(type, context) {
2086
2269
  const templateContent = loadTemplate(type);
2087
2270
  const template = Handlebars.compile(templateContent);
2271
+ const resolvedTarget = resolveImportPath(type, context.target);
2088
2272
  const fullContext = {
2089
2273
  vueVersion: 3,
2090
2274
  typescript: true,
@@ -2105,6 +2289,8 @@ function renderTemplate(type, context) {
2105
2289
  requiredProps: [],
2106
2290
  optionalProps: [],
2107
2291
  ...context,
2292
+ // 使用计算后的正确路径
2293
+ target: resolvedTarget,
2108
2294
  framework: context.framework || "vue",
2109
2295
  camelName: context.camelName || toCamelCase(context.name),
2110
2296
  pascalName: context.pascalName || toPascalCase(context.name)
@@ -2464,7 +2650,7 @@ function toPascalCase(str) {
2464
2650
  }
2465
2651
 
2466
2652
  // src/services/test-reviewer.ts
2467
- import chalk3 from "chalk";
2653
+ import chalk4 from "chalk";
2468
2654
  import ora2 from "ora";
2469
2655
  var MAX_RETRIES = 3;
2470
2656
  var REVIEW_THRESHOLD = 0.6;
@@ -2484,6 +2670,9 @@ async function generateWithReview(params) {
2484
2670
  for (let i = 0; i < MAX_RETRIES; i++) {
2485
2671
  attempts = i + 1;
2486
2672
  onAttempt?.(attempts, MAX_RETRIES);
2673
+ if (process.env.QAT_DEBUG === "true") {
2674
+ console.error(chalk4.gray(`[DEBUG] \u2500\u2500\u2500 \u751F\u6210\u8005 AI \u7B2C${attempts}\u6B21\u5C1D\u8BD5 \u2500\u2500\u2500`));
2675
+ }
2487
2676
  const generationPrompt = i === 0 ? void 0 : `\u4E0A\u6B21\u751F\u6210\u7684\u6D4B\u8BD5\u672A\u901A\u8FC7\u5BA1\u8BA1\uFF0C\u8BF7\u6839\u636E\u4EE5\u4E0B\u53CD\u9988\u91CD\u65B0\u751F\u6210\uFF1A
2488
2677
  \u5BA1\u8BA1\u8BC4\u5206: ${(lastReview.score * 100).toFixed(0)}%
2489
2678
  \u5BA1\u8BA1\u610F\u89C1: ${lastReview.feedback}
@@ -2496,16 +2685,17 @@ ${lastReview.suggestions.map((s) => `- ${s}`).join("\n")}
2496
2685
  const generateResponse = await generatorProvider.generateTest({
2497
2686
  type: testType,
2498
2687
  target: targetPath,
2499
- context: i === 0 ? sourceCode : `${sourceCode}
2500
-
2501
- --- \u5BA1\u8BA1\u53CD\u9988 ---
2502
- ${generationPrompt}`,
2688
+ // 重试时:源码已压缩在分析摘要中,context只传审计反馈以减少token
2689
+ context: i === 0 ? sourceCode : generationPrompt,
2503
2690
  framework: framework || void 0,
2504
2691
  analysis
2505
2692
  });
2506
2693
  currentCode = generateResponse.code;
2507
2694
  currentDescription = generateResponse.description;
2508
2695
  currentConfidence = generateResponse.confidence;
2696
+ if (process.env.QAT_DEBUG === "true") {
2697
+ console.error(chalk4.gray(`[DEBUG] \u2500\u2500\u2500 \u5BA1\u8BA1\u5458 AI \u5BA1\u67E5 \u2500\u2500\u2500`));
2698
+ }
2509
2699
  const reviewRequest = {
2510
2700
  target: targetPath,
2511
2701
  sourceCode,
@@ -2537,20 +2727,20 @@ function printReviewReport(report) {
2537
2727
  const approved = report.filter((r) => r.approved);
2538
2728
  const failed = report.filter((r) => !r.approved);
2539
2729
  console.log();
2540
- console.log(chalk3.cyan(" \u5BA1\u8BA1\u62A5\u544A:"));
2541
- console.log(chalk3.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2730
+ console.log(chalk4.cyan(" \u5BA1\u8BA1\u62A5\u544A:"));
2731
+ console.log(chalk4.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2542
2732
  for (const entry of approved) {
2543
- console.log(` ${chalk3.green("\u2713")} ${chalk3.gray(entry.target)} ${chalk3.green(`(${(entry.score * 100).toFixed(0)}%`)}${entry.attempts > 1 ? chalk3.yellow(` ${entry.attempts}\u6B21\u5C1D\u8BD5`) : ""})`);
2733
+ console.log(` ${chalk4.green("\u2713")} ${chalk4.gray(entry.target)} ${chalk4.green(`(${(entry.score * 100).toFixed(0)}%`)}${entry.attempts > 1 ? chalk4.yellow(` ${entry.attempts}\u6B21\u5C1D\u8BD5`) : ""})`);
2544
2734
  }
2545
2735
  for (const entry of failed) {
2546
- console.log(` ${chalk3.red("\u2717")} ${chalk3.gray(entry.target)} ${chalk3.red(`(${(entry.score * 100).toFixed(0)}%)`)}`);
2736
+ console.log(` ${chalk4.red("\u2717")} ${chalk4.gray(entry.target)} ${chalk4.red(`(${(entry.score * 100).toFixed(0)}%)`)}`);
2547
2737
  if (entry.issues.length > 0) {
2548
2738
  for (const issue of entry.issues.slice(0, 3)) {
2549
- console.log(chalk3.gray(` - ${issue}`));
2739
+ console.log(chalk4.gray(` - ${issue}`));
2550
2740
  }
2551
2741
  }
2552
2742
  if (entry.feedback) {
2553
- console.log(chalk3.gray(` \u53CD\u9988: ${entry.feedback}`));
2743
+ console.log(chalk4.gray(` \u53CD\u9988: ${entry.feedback}`));
2554
2744
  }
2555
2745
  }
2556
2746
  console.log();
@@ -2578,7 +2768,7 @@ function registerCreateCommand(program2) {
2578
2768
  try {
2579
2769
  await executeCreate(options);
2580
2770
  } catch (error) {
2581
- console.error(chalk4.red(`
2771
+ console.error(chalk5.red(`
2582
2772
  \u2717 ${error instanceof Error ? error.message : String(error)}
2583
2773
  `));
2584
2774
  process.exit(1);
@@ -2603,7 +2793,7 @@ async function executeCreate(options) {
2603
2793
  name: "types",
2604
2794
  message: "\u9009\u62E9\u6D4B\u8BD5\u7C7B\u578B (\u7A7A\u683C\u9009\u62E9/\u53D6\u6D88\uFF0C\u56DE\u8F66\u786E\u8BA4):",
2605
2795
  choices: Object.entries(TEST_TYPE_LABELS).map(([value, label]) => ({
2606
- name: `${label} - ${chalk4.gray(TEST_TYPE_DESCRIPTIONS[value])}`,
2796
+ name: `${label} - ${chalk5.gray(TEST_TYPE_DESCRIPTIONS[value])}`,
2607
2797
  value,
2608
2798
  short: label,
2609
2799
  checked: value === "unit" || value === "component"
@@ -2720,7 +2910,7 @@ async function executeCreate(options) {
2720
2910
  createdFiles.push({ type: testType, filePath });
2721
2911
  } catch (error) {
2722
2912
  spinner.fail(`${TEST_TYPE_LABELS[testType]} - ${path8.basename(testTarget)} \u521B\u5EFA\u5931\u8D25`);
2723
- console.log(chalk4.gray(` ${error instanceof Error ? error.message : String(error)}`));
2913
+ console.log(chalk5.gray(` ${error instanceof Error ? error.message : String(error)}`));
2724
2914
  }
2725
2915
  }
2726
2916
  }
@@ -2734,13 +2924,13 @@ async function selectTargets(types, projectInfo, srcDir) {
2734
2924
  if (types.includes("unit")) {
2735
2925
  const utils = discoverUtilityFiles(process.cwd(), srcDir);
2736
2926
  for (const f of utils.slice(0, 30)) {
2737
- allTargets.push({ name: `${chalk4.gray("[unit]")} ${f}`, value: f });
2927
+ allTargets.push({ name: `${chalk5.gray("[unit]")} ${f}`, value: f });
2738
2928
  }
2739
2929
  }
2740
2930
  if (types.includes("component")) {
2741
2931
  const components = discoverVueComponents(process.cwd(), srcDir);
2742
2932
  for (const f of components.slice(0, 30)) {
2743
- allTargets.push({ name: `${chalk4.gray("[comp]")} ${f}`, value: f });
2933
+ allTargets.push({ name: `${chalk5.gray("[comp]")} ${f}`, value: f });
2744
2934
  }
2745
2935
  }
2746
2936
  if (allTargets.length === 0) {
@@ -2761,7 +2951,7 @@ async function selectTargets(types, projectInfo, srcDir) {
2761
2951
  message: "\u9009\u62E9\u88AB\u6D4B\u76EE\u6807 (\u7A7A\u683C\u9009\u62E9/\u53D6\u6D88\uFF0C\u56DE\u8F66\u786E\u8BA4):",
2762
2952
  choices: [
2763
2953
  ...allTargets,
2764
- { name: chalk4.gray("\u624B\u52A8\u8F93\u5165\u8DEF\u5F84"), value: "__manual__" }
2954
+ { name: chalk5.gray("\u624B\u52A8\u8F93\u5165\u8DEF\u5F84"), value: "__manual__" }
2765
2955
  ],
2766
2956
  validate: (input) => {
2767
2957
  if (input.length === 0) return "\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u76EE\u6807";
@@ -2860,38 +3050,38 @@ function getTestOutputDir(type) {
2860
3050
  }
2861
3051
  function displayCreateResult(createdFiles, skippedCount, usedAI) {
2862
3052
  if (createdFiles.length === 0 && skippedCount === 0) {
2863
- console.log(chalk4.yellow("\n \u6CA1\u6709\u521B\u5EFA\u4EFB\u4F55\u6D4B\u8BD5\u6587\u4EF6\n"));
3053
+ console.log(chalk5.yellow("\n \u6CA1\u6709\u521B\u5EFA\u4EFB\u4F55\u6D4B\u8BD5\u6587\u4EF6\n"));
2864
3054
  return;
2865
3055
  }
2866
- console.log(chalk4.green(`
3056
+ console.log(chalk5.green(`
2867
3057
  \u2713 \u5DF2\u521B\u5EFA ${createdFiles.length} \u4E2A\u6D4B\u8BD5\u6587\u4EF6`));
2868
3058
  if (skippedCount > 0) {
2869
- console.log(chalk4.yellow(` \u26A0 \u8DF3\u8FC7 ${skippedCount} \u4E2A\u5DF2\u5B58\u5728\u7684\u6587\u4EF6`));
3059
+ console.log(chalk5.yellow(` \u26A0 \u8DF3\u8FC7 ${skippedCount} \u4E2A\u5DF2\u5B58\u5728\u7684\u6587\u4EF6`));
2870
3060
  }
2871
3061
  console.log();
2872
3062
  for (const { type, filePath } of createdFiles) {
2873
3063
  const relativePath = path8.relative(process.cwd(), filePath);
2874
- console.log(chalk4.white(` ${chalk4.cyan(TEST_TYPE_LABELS[type])} ${chalk4.gray(relativePath)}`));
3064
+ console.log(chalk5.white(` ${chalk5.cyan(TEST_TYPE_LABELS[type])} ${chalk5.gray(relativePath)}`));
2875
3065
  }
2876
3066
  if (usedAI) {
2877
3067
  console.log();
2878
- console.log(chalk4.magenta(" \u751F\u6210\u65B9\u5F0F: AI \u8F85\u52A9"));
3068
+ console.log(chalk5.magenta(" \u751F\u6210\u65B9\u5F0F: AI \u8F85\u52A9"));
2879
3069
  }
2880
3070
  console.log();
2881
- console.log(chalk4.gray(" \u8FD0\u884C\u6D4B\u8BD5:"));
3071
+ console.log(chalk5.gray(" \u8FD0\u884C\u6D4B\u8BD5:"));
2882
3072
  const uniqueTypes = [...new Set(createdFiles.map((f) => f.type))];
2883
3073
  if (uniqueTypes.length === 1) {
2884
- console.log(chalk4.cyan(` qat run -t ${uniqueTypes[0]}`));
3074
+ console.log(chalk5.cyan(` qat run -t ${uniqueTypes[0]}`));
2885
3075
  } else {
2886
- console.log(chalk4.cyan(` qat run -t ${uniqueTypes.join(" -t ")}`));
2887
- console.log(chalk4.gray(" # \u6216\u8FD0\u884C\u5168\u90E8"));
2888
- console.log(chalk4.cyan(" qat run"));
3076
+ console.log(chalk5.cyan(` qat run -t ${uniqueTypes.join(" -t ")}`));
3077
+ console.log(chalk5.gray(" # \u6216\u8FD0\u884C\u5168\u90E8"));
3078
+ console.log(chalk5.cyan(" qat run"));
2889
3079
  }
2890
3080
  console.log();
2891
3081
  }
2892
3082
 
2893
3083
  // src/commands/run.ts
2894
- import chalk5 from "chalk";
3084
+ import chalk6 from "chalk";
2895
3085
  import inquirer3 from "inquirer";
2896
3086
  import ora4 from "ora";
2897
3087
  import fs11 from "fs";
@@ -2959,14 +3149,14 @@ function buildVitestArgs(options) {
2959
3149
  if (options.files && options.files.length > 0) {
2960
3150
  args.push(...options.files);
2961
3151
  } else {
2962
- const includeMap = {
2963
- unit: ["tests/unit"],
2964
- component: ["tests/component"],
2965
- api: ["tests/api"]
3152
+ const pathMap = {
3153
+ unit: "tests/unit/**/*.test.ts",
3154
+ component: "tests/component/**/*.test.ts",
3155
+ api: "tests/api/**/*.test.ts"
2966
3156
  };
2967
- const includes = includeMap[options.type];
2968
- if (includes) {
2969
- args.push("--include", includes.map((d) => `${d}/**/*.test.ts`).join(","));
3157
+ const testPattern = pathMap[options.type];
3158
+ if (testPattern) {
3159
+ args.push(testPattern);
2970
3160
  }
2971
3161
  }
2972
3162
  if (options.coverage) {
@@ -3982,7 +4172,7 @@ function registerRunCommand(program2) {
3982
4172
  try {
3983
4173
  await executeRun(options);
3984
4174
  } catch (error) {
3985
- console.error(chalk5.red(`
4175
+ console.error(chalk6.red(`
3986
4176
  \u2717 ${error instanceof Error ? error.message : String(error)}
3987
4177
  `));
3988
4178
  process.exit(1);
@@ -3990,7 +4180,7 @@ function registerRunCommand(program2) {
3990
4180
  });
3991
4181
  }
3992
4182
  async function executeRun(options) {
3993
- const { type, file, tag, watch, parallel, browser } = options;
4183
+ const { type, file, watch, parallel } = options;
3994
4184
  const config = await loadConfig(options.config);
3995
4185
  const globalAI = loadGlobalAIConfig();
3996
4186
  if (globalAI) {
@@ -4002,15 +4192,15 @@ async function executeRun(options) {
4002
4192
  }
4003
4193
  let typesToRun = await determineTypesToRun(type, file, config);
4004
4194
  if (typesToRun.length === 0) {
4005
- console.log(chalk5.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\uFF08\u8BF7\u5728 qat.config.ts \u4E2D\u542F\u7528\uFF09\n"));
4195
+ console.log(chalk6.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\uFF08\u8BF7\u5728 qat.config.ts \u4E2D\u542F\u7528\uFF09\n"));
4006
4196
  return;
4007
4197
  }
4008
4198
  const missingDeps = checkTestDependencies(typesToRun);
4009
4199
  if (missingDeps.length > 0) {
4010
- console.log(chalk5.yellow("\n \u26A0 \u4EE5\u4E0B\u6D4B\u8BD5\u6846\u67B6\u4F9D\u8D56\u672A\u5B89\u88C5:\n"));
4200
+ console.log(chalk6.yellow("\n \u26A0 \u4EE5\u4E0B\u6D4B\u8BD5\u6846\u67B6\u4F9D\u8D56\u672A\u5B89\u88C5:\n"));
4011
4201
  for (const dep of missingDeps) {
4012
- console.log(chalk5.white(` ${dep.runner} (${dep.pkg})`));
4013
- console.log(chalk5.gray(` \u5B89\u88C5\u547D\u4EE4: ${chalk5.cyan(dep.installCmd)}`));
4202
+ console.log(chalk6.white(` ${dep.runner} (${dep.pkg})`));
4203
+ console.log(chalk6.gray(` \u5B89\u88C5\u547D\u4EE4: ${chalk6.cyan(dep.installCmd)}`));
4014
4204
  }
4015
4205
  console.log();
4016
4206
  const { action } = await inquirer3.prompt([
@@ -4027,13 +4217,13 @@ async function executeRun(options) {
4027
4217
  }
4028
4218
  ]);
4029
4219
  if (action === "cancel") {
4030
- console.log(chalk5.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4220
+ console.log(chalk6.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4031
4221
  return;
4032
4222
  }
4033
4223
  if (action === "install") {
4034
4224
  const installed = await installTestDependencies(missingDeps);
4035
4225
  if (!installed) {
4036
- console.log(chalk5.yellow(" \u90E8\u5206\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF0C\u5C06\u8DF3\u8FC7\u5BF9\u5E94\u7684\u6D4B\u8BD5\u7C7B\u578B"));
4226
+ console.log(chalk6.yellow(" \u90E8\u5206\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF0C\u5C06\u8DF3\u8FC7\u5BF9\u5E94\u7684\u6D4B\u8BD5\u7C7B\u578B"));
4037
4227
  }
4038
4228
  const stillMissing = checkTestDependencies(typesToRun);
4039
4229
  if (stillMissing.length > 0) {
@@ -4043,7 +4233,7 @@ async function executeRun(options) {
4043
4233
  return !dep || !missingRunners.has(dep.pkg);
4044
4234
  });
4045
4235
  if (typesToRun.length === 0) {
4046
- console.log(chalk5.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\uFF08\u4F9D\u8D56\u672A\u5B89\u88C5\uFF09\n"));
4236
+ console.log(chalk6.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\uFF08\u4F9D\u8D56\u672A\u5B89\u88C5\uFF09\n"));
4047
4237
  return;
4048
4238
  }
4049
4239
  }
@@ -4055,7 +4245,7 @@ async function executeRun(options) {
4055
4245
  return !dep || !missingRunners.has(dep.pkg);
4056
4246
  });
4057
4247
  if (typesToRun.length === 0) {
4058
- console.log(chalk5.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4248
+ console.log(chalk6.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4059
4249
  return;
4060
4250
  }
4061
4251
  }
@@ -4078,13 +4268,13 @@ async function executeRun(options) {
4078
4268
  }
4079
4269
  ]);
4080
4270
  if (action === "cancel") {
4081
- console.log(chalk5.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4271
+ console.log(chalk6.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4082
4272
  return;
4083
4273
  }
4084
4274
  if (action === "skip") {
4085
4275
  typesToRun = typesToRun.filter((t) => !SERVER_REQUIRED_TYPES.includes(t));
4086
4276
  if (typesToRun.length === 0) {
4087
- console.log(chalk5.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4277
+ console.log(chalk6.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4088
4278
  return;
4089
4279
  }
4090
4280
  }
@@ -4104,12 +4294,12 @@ async function executeRun(options) {
4104
4294
  }
4105
4295
  ]);
4106
4296
  if (fallback === "cancel") {
4107
- console.log(chalk5.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4297
+ console.log(chalk6.gray("\n \u5DF2\u53D6\u6D88\u8FD0\u884C\n"));
4108
4298
  return;
4109
4299
  }
4110
4300
  typesToRun = typesToRun.filter((t) => !SERVER_REQUIRED_TYPES.includes(t));
4111
4301
  if (typesToRun.length === 0) {
4112
- console.log(chalk5.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4302
+ console.log(chalk6.yellow("\n \u6CA1\u6709\u53EF\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B\n"));
4113
4303
  return;
4114
4304
  }
4115
4305
  }
@@ -4167,8 +4357,8 @@ async function executeRun(options) {
4167
4357
  const outputDir = config.report.outputDir || "qat-report";
4168
4358
  const reportPath = writeReportToDisk(reportData, outputDir);
4169
4359
  const relativePath = path12.relative(process.cwd(), reportPath);
4170
- console.log(chalk5.gray(`
4171
- \u62A5\u544A\u5DF2\u751F\u6210: ${chalk5.cyan(relativePath)}`));
4360
+ console.log(chalk6.gray(`
4361
+ \u62A5\u544A\u5DF2\u751F\u6210: ${chalk6.cyan(relativePath)}`));
4172
4362
  console.log();
4173
4363
  const hasFailures = results.some((r) => r.status === "failed");
4174
4364
  if (hasFailures && isAIAvailable(config.ai)) {
@@ -4177,7 +4367,7 @@ async function executeRun(options) {
4177
4367
  }
4178
4368
  function printDryRunCommands(types, options, config) {
4179
4369
  console.log();
4180
- console.log(chalk5.cyan(" \u53EF\u6267\u884C\u7684\u6D4B\u8BD5\u547D\u4EE4:\n"));
4370
+ console.log(chalk6.cyan(" \u53EF\u6267\u884C\u7684\u6D4B\u8BD5\u547D\u4EE4:\n"));
4181
4371
  for (const testType of types) {
4182
4372
  const label = TYPE_LABELS2[testType];
4183
4373
  const runner = TYPE_RUNNERS[testType];
@@ -4192,7 +4382,7 @@ function printDryRunCommands(types, options, config) {
4192
4382
  api: "tests/api"
4193
4383
  };
4194
4384
  const dir = dirMap[testType];
4195
- if (dir) cmd += ` --include '${dir}/**/*.test.ts'`;
4385
+ if (dir) cmd += ` '${dir}/**/*.test.ts'`;
4196
4386
  if (config.vitest.coverage) cmd += " --coverage";
4197
4387
  }
4198
4388
  break;
@@ -4214,17 +4404,17 @@ function printDryRunCommands(types, options, config) {
4214
4404
  default:
4215
4405
  cmd = `# ${label}: \u672A\u77E5\u8FD0\u884C\u5668`;
4216
4406
  }
4217
- console.log(chalk5.white(` ${label}:`));
4218
- console.log(chalk5.cyan(` ${cmd}`));
4407
+ console.log(chalk6.white(` ${label}:`));
4408
+ console.log(chalk6.cyan(` ${cmd}`));
4219
4409
  console.log();
4220
4410
  }
4221
- console.log(chalk5.gray(" \u6216\u4F7F\u7528 QAT \u7EDF\u4E00\u8FD0\u884C:"));
4411
+ console.log(chalk6.gray(" \u6216\u4F7F\u7528 QAT \u7EDF\u4E00\u8FD0\u884C:"));
4222
4412
  if (types.length === 1) {
4223
- console.log(chalk5.cyan(` qat run -t ${types[0]}`));
4413
+ console.log(chalk6.cyan(` qat run -t ${types[0]}`));
4224
4414
  } else {
4225
- console.log(chalk5.cyan(` qat run -t ${types.join(" -t ")}`));
4226
- console.log(chalk5.gray(" # \u5E76\u884C\u8FD0\u884C"));
4227
- console.log(chalk5.cyan(" qat run -p"));
4415
+ console.log(chalk6.cyan(` qat run -t ${types.join(" -t ")}`));
4416
+ console.log(chalk6.gray(" # \u5E76\u884C\u8FD0\u884C"));
4417
+ console.log(chalk6.cyan(" qat run -p"));
4228
4418
  }
4229
4419
  console.log();
4230
4420
  }
@@ -4247,7 +4437,7 @@ async function determineTypesToRun(type, file, config) {
4247
4437
  name: "selectedTypes",
4248
4438
  message: "\u9009\u62E9\u8981\u8FD0\u884C\u7684\u6D4B\u8BD5\u7C7B\u578B (\u7A7A\u683C\u9009\u62E9/\u53D6\u6D88\uFF0C\u56DE\u8F66\u786E\u8BA4):",
4249
4439
  choices: enabledTypes.map((t) => ({
4250
- name: `${TYPE_LABELS2[t]} (${chalk5.gray(TYPE_RUNNERS[t])})`,
4440
+ name: `${TYPE_LABELS2[t]} (${chalk6.gray(TYPE_RUNNERS[t])})`,
4251
4441
  value: t,
4252
4442
  checked: true
4253
4443
  })),
@@ -4306,8 +4496,8 @@ async function runTestType(testType, config, options) {
4306
4496
  throw new Error(`\u672A\u77E5\u7684\u8FD0\u884C\u5668: ${runner}`);
4307
4497
  }
4308
4498
  }
4309
- async function runWatchMode(config, options) {
4310
- console.log(chalk5.cyan(" \u76D1\u542C\u6A21\u5F0F\u5DF2\u542F\u52A8 (Ctrl+C \u9000\u51FA)\n"));
4499
+ async function runWatchMode(_config, options) {
4500
+ console.log(chalk6.cyan(" \u76D1\u542C\u6A21\u5F0F\u5DF2\u542F\u52A8 (Ctrl+C \u9000\u51FA)\n"));
4311
4501
  const { spawn } = await import("child_process");
4312
4502
  const args = ["vitest", "--watch"];
4313
4503
  if (options.file) {
@@ -4322,7 +4512,7 @@ async function runWatchMode(config, options) {
4322
4512
  };
4323
4513
  const dirs = types.map((t) => dirMap[t]).filter(Boolean);
4324
4514
  if (dirs.length > 0) {
4325
- args.push("--include", dirs.map((d) => `${d}/**/*.test.ts`).join(","));
4515
+ args.push(...dirs.map((d) => `${d}/**/*.test.ts`));
4326
4516
  }
4327
4517
  }
4328
4518
  const child = spawn("npx", args, {
@@ -4331,7 +4521,7 @@ async function runWatchMode(config, options) {
4331
4521
  shell: true
4332
4522
  });
4333
4523
  child.on("error", (err) => {
4334
- console.error(chalk5.red(`
4524
+ console.error(chalk6.red(`
4335
4525
  Vitest \u542F\u52A8\u5931\u8D25: ${err.message}
4336
4526
  `));
4337
4527
  });
@@ -4386,17 +4576,17 @@ function displayJestStyleResults(results) {
4386
4576
  for (const result of results) {
4387
4577
  const typeLabel = TYPE_LABELS2[result.type] || result.type;
4388
4578
  if (result.suites.length === 0) {
4389
- console.log(chalk5.gray(` ${typeLabel}: \u65E0\u6D4B\u8BD5\u7ED3\u679C`));
4579
+ console.log(chalk6.gray(` ${typeLabel}: \u65E0\u6D4B\u8BD5\u7ED3\u679C`));
4390
4580
  continue;
4391
4581
  }
4392
4582
  for (const suite of result.suites) {
4393
4583
  if (suite.tests.length === 0) continue;
4394
- const suiteIcon = suite.status === "passed" ? chalk5.green("PASS") : chalk5.red("FAIL");
4395
- console.log(` ${suiteIcon} ${chalk5.white(suite.name)} ${chalk5.gray(`(${formatDuration2(suite.duration)})`)}`);
4584
+ const suiteIcon = suite.status === "passed" ? chalk6.green("PASS") : chalk6.red("FAIL");
4585
+ console.log(` ${suiteIcon} ${chalk6.white(suite.name)} ${chalk6.gray(`(${formatDuration2(suite.duration)})`)}`);
4396
4586
  for (const test of suite.tests) {
4397
- const icon = test.status === "passed" ? chalk5.green(" \u2713") : test.status === "failed" ? chalk5.red(" \u2715") : chalk5.yellow(" \u25CB");
4398
- const name = test.status === "failed" ? chalk5.red(test.name) : test.name;
4399
- console.log(` ${icon} ${name} ${chalk5.gray(formatDuration2(test.duration))}`);
4587
+ const icon = test.status === "passed" ? chalk6.green(" \u2713") : test.status === "failed" ? chalk6.red(" \u2715") : chalk6.yellow(" \u25CB");
4588
+ const name = test.status === "failed" ? chalk6.red(test.name) : test.name;
4589
+ console.log(` ${icon} ${name} ${chalk6.gray(formatDuration2(test.duration))}`);
4400
4590
  }
4401
4591
  }
4402
4592
  console.log();
@@ -4428,28 +4618,28 @@ function displayJestStyleResults(results) {
4428
4618
  }
4429
4619
  }
4430
4620
  const total = totalPassed + totalFailed + totalSkipped;
4431
- console.log(chalk5.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4432
- console.log(chalk5.white(" \u6D4B\u8BD5\u7ED3\u679C\u6C47\u603B"));
4433
- console.log(chalk5.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4621
+ console.log(chalk6.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4622
+ console.log(chalk6.white(" \u6D4B\u8BD5\u7ED3\u679C\u6C47\u603B"));
4623
+ console.log(chalk6.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
4434
4624
  console.log();
4435
- console.log(` ${chalk5.white("\u7C7B\u578B".padEnd(14))} ${chalk5.white("\u901A\u8FC7".padStart(6))} ${chalk5.white("\u5931\u8D25".padStart(6))} ${chalk5.white("\u8DF3\u8FC7".padStart(6))} ${chalk5.white("\u603B\u8BA1".padStart(6))} ${chalk5.white("\u901A\u8FC7\u7387".padStart(8))} ${chalk5.white("\u8017\u65F6".padStart(8))}`);
4625
+ console.log(` ${chalk6.white("\u7C7B\u578B".padEnd(14))} ${chalk6.white("\u901A\u8FC7".padStart(6))} ${chalk6.white("\u5931\u8D25".padStart(6))} ${chalk6.white("\u8DF3\u8FC7".padStart(6))} ${chalk6.white("\u603B\u8BA1".padStart(6))} ${chalk6.white("\u901A\u8FC7\u7387".padStart(8))} ${chalk6.white("\u8017\u65F6".padStart(8))}`);
4436
4626
  console.log(` ${"\u2500".repeat(14)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(8)} ${"\u2500".repeat(8)}`);
4437
4627
  for (const [type, stats] of Object.entries(typeStats)) {
4438
4628
  const label = (TYPE_LABELS2[type] || type).padEnd(14);
4439
4629
  const typeTotal = stats.passed + stats.failed + stats.skipped;
4440
4630
  const rate = typeTotal > 0 ? (stats.passed / typeTotal * 100).toFixed(0) + "%" : "-";
4441
- const rateColored = typeTotal > 0 && stats.passed === typeTotal ? chalk5.green(rate.padStart(8)) : stats.failed > 0 ? chalk5.red(rate.padStart(8)) : rate.padStart(8);
4631
+ const rateColored = typeTotal > 0 && stats.passed === typeTotal ? chalk6.green(rate.padStart(8)) : stats.failed > 0 ? chalk6.red(rate.padStart(8)) : rate.padStart(8);
4442
4632
  console.log(` ${label} ${String(stats.passed).padStart(6)} ${String(stats.failed).padStart(6)} ${String(stats.skipped).padStart(6)} ${String(typeTotal).padStart(6)} ${rateColored} ${formatDuration2(stats.duration).padStart(8)}`);
4443
4633
  }
4444
4634
  console.log(` ${"\u2500".repeat(14)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(8)} ${"\u2500".repeat(8)}`);
4445
4635
  const totalRate = total > 0 ? (totalPassed / total * 100).toFixed(0) + "%" : "-";
4446
- const totalRateColored = total > 0 && totalFailed === 0 ? chalk5.green(totalRate.padStart(8)) : totalFailed > 0 ? chalk5.red(totalRate.padStart(8)) : totalRate.padStart(8);
4636
+ const totalRateColored = total > 0 && totalFailed === 0 ? chalk6.green(totalRate.padStart(8)) : totalFailed > 0 ? chalk6.red(totalRate.padStart(8)) : totalRate.padStart(8);
4447
4637
  console.log(` ${"\u603B\u8BA1".padEnd(14)} ${String(totalPassed).padStart(6)} ${String(totalFailed).padStart(6)} ${String(totalSkipped).padStart(6)} ${String(total).padStart(6)} ${totalRateColored} ${formatDuration2(totalDuration).padStart(8)}`);
4448
4638
  console.log();
4449
4639
  for (const result of results) {
4450
4640
  if (result.coverage) {
4451
4641
  const c = result.coverage;
4452
- console.log(chalk5.cyan(" \u8986\u76D6\u7387:"));
4642
+ console.log(chalk6.cyan(" \u8986\u76D6\u7387:"));
4453
4643
  console.log(` \u8BED\u53E5: ${coverageColor(c.statements)} \u5206\u652F: ${coverageColor(c.branches)} \u51FD\u6570: ${coverageColor(c.functions)} \u884C: ${coverageColor(c.lines)}`);
4454
4644
  console.log();
4455
4645
  }
@@ -4457,7 +4647,7 @@ function displayJestStyleResults(results) {
4457
4647
  for (const result of results) {
4458
4648
  if (result.type === "performance" && result.performance) {
4459
4649
  const p = result.performance;
4460
- console.log(chalk5.cyan(" \u6027\u80FD\u6307\u6807:"));
4650
+ console.log(chalk6.cyan(" \u6027\u80FD\u6307\u6807:"));
4461
4651
  console.log(` Performance: ${scoreColor(p.performance)} ${p.performance}/100`);
4462
4652
  console.log(` Accessibility: ${scoreColor(p.accessibility)} ${p.accessibility}/100`);
4463
4653
  console.log(` Best Practices: ${scoreColor(p.bestPractices)} ${p.bestPractices}/100`);
@@ -4474,31 +4664,31 @@ function displayJestStyleResults(results) {
4474
4664
  )
4475
4665
  );
4476
4666
  if (failedTests.length > 0) {
4477
- console.log(chalk5.red(" \u5931\u8D25\u8BE6\u60C5:"));
4667
+ console.log(chalk6.red(" \u5931\u8D25\u8BE6\u60C5:"));
4478
4668
  for (const { suite, test } of failedTests) {
4479
- console.log(chalk5.red(` \u2715 ${suite.name} > ${test.name}`));
4669
+ console.log(chalk6.red(` \u2715 ${suite.name} > ${test.name}`));
4480
4670
  if (test.error?.message) {
4481
- console.log(chalk5.gray(` ${test.error.message.split("\n")[0]}`));
4671
+ console.log(chalk6.gray(` ${test.error.message.split("\n")[0]}`));
4482
4672
  }
4483
4673
  }
4484
4674
  console.log();
4485
4675
  }
4486
4676
  if (totalFailed > 0) {
4487
- console.log(chalk5.red(` Tests: ${totalFailed} failed, ${totalPassed} passed, ${total} total`));
4677
+ console.log(chalk6.red(` Tests: ${totalFailed} failed, ${totalPassed} passed, ${total} total`));
4488
4678
  process.exitCode = 1;
4489
4679
  } else if (total === 0) {
4490
- console.log(chalk5.yellow(" \u6CA1\u6709\u53D1\u73B0\u6D4B\u8BD5\u7528\u4F8B"));
4680
+ console.log(chalk6.yellow(" \u6CA1\u6709\u53D1\u73B0\u6D4B\u8BD5\u7528\u4F8B"));
4491
4681
  } else {
4492
- console.log(chalk5.green(` Tests: ${totalPassed} passed, ${total} total`));
4682
+ console.log(chalk6.green(` Tests: ${totalPassed} passed, ${total} total`));
4493
4683
  }
4494
- console.log(chalk5.gray(` Time: ${formatDuration2(totalDuration)}`));
4684
+ console.log(chalk6.gray(` Time: ${formatDuration2(totalDuration)}`));
4495
4685
  console.log();
4496
4686
  }
4497
4687
  function coverageColor(value) {
4498
4688
  const pct3 = `${(value * 100).toFixed(1)}%`;
4499
- if (value >= 0.8) return chalk5.green(pct3);
4500
- if (value >= 0.5) return chalk5.yellow(pct3);
4501
- return chalk5.red(pct3);
4689
+ if (value >= 0.8) return chalk6.green(pct3);
4690
+ if (value >= 0.5) return chalk6.yellow(pct3);
4691
+ return chalk6.red(pct3);
4502
4692
  }
4503
4693
  async function aiAnalyzeFailures(results, aiConfig) {
4504
4694
  const failedTests = results.flatMap(
@@ -4507,23 +4697,23 @@ async function aiAnalyzeFailures(results, aiConfig) {
4507
4697
  )
4508
4698
  );
4509
4699
  if (failedTests.length === 0) return;
4510
- console.log(chalk5.magenta(" \u{1F916} AI \u5206\u6790\u5931\u8D25\u539F\u56E0..."));
4700
+ console.log(chalk6.magenta(" \u{1F916} AI \u5206\u6790\u5931\u8D25\u539F\u56E0..."));
4511
4701
  console.log();
4512
4702
  const provider = getAIProvider(aiConfig);
4513
4703
  if (!provider.capabilities.suggestFix) return;
4514
4704
  for (const { suite, test } of failedTests.slice(0, 5)) {
4515
4705
  try {
4516
4706
  const suggestions = await provider.suggestFix(test.error);
4517
- console.log(chalk5.white(` ${suite.name} > ${test.name}`));
4707
+ console.log(chalk6.white(` ${suite.name} > ${test.name}`));
4518
4708
  if (test.error?.message) {
4519
- console.log(chalk5.gray(` \u9519\u8BEF: ${test.error.message.split("\n")[0]}`));
4709
+ console.log(chalk6.gray(` \u9519\u8BEF: ${test.error.message.split("\n")[0]}`));
4520
4710
  }
4521
4711
  for (const suggestion of suggestions.slice(0, 3)) {
4522
- console.log(chalk5.cyan(` \u2192 ${suggestion}`));
4712
+ console.log(chalk6.cyan(` \u2192 ${suggestion}`));
4523
4713
  }
4524
4714
  console.log();
4525
4715
  } catch (error) {
4526
- console.log(chalk5.gray(` AI \u5206\u6790\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
4716
+ console.log(chalk6.gray(` AI \u5206\u6790\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
4527
4717
  }
4528
4718
  }
4529
4719
  }
@@ -4535,9 +4725,9 @@ function formatDuration2(ms) {
4535
4725
  return `${min}m ${sec}s`;
4536
4726
  }
4537
4727
  function scoreColor(score) {
4538
- if (score >= 90) return chalk5.green("\u25CF");
4539
- if (score >= 50) return chalk5.yellow("\u25CF");
4540
- return chalk5.red("\u25CF");
4728
+ if (score >= 90) return chalk6.green("\u25CF");
4729
+ if (score >= 50) return chalk6.yellow("\u25CF");
4730
+ return chalk6.red("\u25CF");
4541
4731
  }
4542
4732
  async function checkDevServer(config) {
4543
4733
  const baseUrl = config.playwright.baseURL || "http://localhost:5173";
@@ -4556,7 +4746,7 @@ async function startDevServer(config) {
4556
4746
  const hasPnpm = fs11.existsSync(path12.join(process.cwd(), "pnpm-lock.yaml"));
4557
4747
  const hasYarn = fs11.existsSync(path12.join(process.cwd(), "yarn.lock"));
4558
4748
  const pkgCmd = hasPnpm ? "pnpm" : hasYarn ? "yarn" : "npm";
4559
- console.log(chalk5.cyan(` \u6B63\u5728\u542F\u52A8 dev server (${pkgCmd} run dev) ...`));
4749
+ console.log(chalk6.cyan(` \u6B63\u5728\u542F\u52A8 dev server (${pkgCmd} run dev) ...`));
4560
4750
  const child = spawn(pkgCmd, ["run", "dev"], {
4561
4751
  cwd: process.cwd(),
4562
4752
  stdio: "pipe",
@@ -4572,13 +4762,13 @@ async function startDevServer(config) {
4572
4762
  waited += interval;
4573
4763
  const isUp = await checkDevServer(config);
4574
4764
  if (isUp) {
4575
- console.log(chalk5.green(` \u2713 dev server \u5DF2\u542F\u52A8 (${baseUrl})`));
4765
+ console.log(chalk6.green(` \u2713 dev server \u5DF2\u542F\u52A8 (${baseUrl})`));
4576
4766
  child.unref();
4577
4767
  return true;
4578
4768
  }
4579
4769
  }
4580
4770
  child.kill();
4581
- console.log(chalk5.red(" \u2717 dev server \u542F\u52A8\u8D85\u65F6"));
4771
+ console.log(chalk6.red(" \u2717 dev server \u542F\u52A8\u8D85\u65F6"));
4582
4772
  return false;
4583
4773
  }
4584
4774
  function saveRunResults(results) {
@@ -4670,7 +4860,7 @@ async function installTestDependencies(missingDeps) {
4670
4860
  spinner.succeed(`${dep.pkg} \u5B89\u88C5\u6210\u529F`);
4671
4861
  } catch (error) {
4672
4862
  spinner.fail(`${dep.pkg} \u5B89\u88C5\u5931\u8D25`);
4673
- console.log(chalk5.gray(` \u53EF\u624B\u52A8\u5B89\u88C5: ${chalk5.cyan(dep.installCmd)}`));
4863
+ console.log(chalk6.gray(` \u53EF\u624B\u52A8\u5B89\u88C5: ${chalk6.cyan(dep.installCmd)}`));
4674
4864
  allSuccess = false;
4675
4865
  }
4676
4866
  }
@@ -4678,7 +4868,7 @@ async function installTestDependencies(missingDeps) {
4678
4868
  }
4679
4869
 
4680
4870
  // src/commands/mock.ts
4681
- import chalk6 from "chalk";
4871
+ import chalk7 from "chalk";
4682
4872
  import ora5 from "ora";
4683
4873
  function registerMockCommand(program2) {
4684
4874
  program2.command("mock").description("Mock\u670D\u52A1\u7BA1\u7406 - \u542F\u52A8/\u505C\u6B62Mock API\u670D\u52A1\u5668").argument("<action>", "\u64CD\u4F5C\u7C7B\u578B (start|stop|status)").option("-p, --port <port>", "\u6307\u5B9A\u7AEF\u53E3\u53F7", "3456").action(async (action, options) => {
@@ -4689,7 +4879,7 @@ function registerMockCommand(program2) {
4689
4879
  config: options.config
4690
4880
  });
4691
4881
  } catch (error) {
4692
- console.error(chalk6.red(`
4882
+ console.error(chalk7.red(`
4693
4883
  \u2717 ${error instanceof Error ? error.message : String(error)}
4694
4884
  `));
4695
4885
  process.exit(1);
@@ -4713,9 +4903,9 @@ async function executeMock(options) {
4713
4903
  break;
4714
4904
  }
4715
4905
  default: {
4716
- console.error(chalk6.red(`
4906
+ console.error(chalk7.red(`
4717
4907
  \u672A\u77E5\u64CD\u4F5C: ${options.action}`));
4718
- console.log(chalk6.gray(" \u53EF\u7528\u64CD\u4F5C: start, stop, status\n"));
4908
+ console.log(chalk7.gray(" \u53EF\u7528\u64CD\u4F5C: start, stop, status\n"));
4719
4909
  process.exit(1);
4720
4910
  }
4721
4911
  }
@@ -4723,7 +4913,7 @@ async function executeMock(options) {
4723
4913
  async function startMock(port, routesDir) {
4724
4914
  const state = getMockServerState();
4725
4915
  if (state.running) {
4726
- console.log(chalk6.yellow(`
4916
+ console.log(chalk7.yellow(`
4727
4917
  Mock\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C (\u7AEF\u53E3: ${state.port})
4728
4918
  `));
4729
4919
  return;
@@ -4737,22 +4927,22 @@ async function startMock(port, routesDir) {
4737
4927
  await startMockServer(port, routes);
4738
4928
  spinner.succeed(`Mock\u670D\u52A1\u5668\u5DF2\u542F\u52A8`);
4739
4929
  console.log();
4740
- console.log(chalk6.white(" \u5730\u5740:"), chalk6.cyan(`http://localhost:${port}`));
4741
- console.log(chalk6.white(" \u8DEF\u7531:"), routes.length > 0 ? `${routes.length} \u4E2A` : chalk6.gray("\u4F7F\u7528\u9ED8\u8BA4\u8DEF\u7531"));
4742
- console.log(chalk6.white(" \u5065\u5EB7\u68C0\u67E5:"), chalk6.cyan(`http://localhost:${port}/api/health`));
4930
+ console.log(chalk7.white(" \u5730\u5740:"), chalk7.cyan(`http://localhost:${port}`));
4931
+ console.log(chalk7.white(" \u8DEF\u7531:"), routes.length > 0 ? `${routes.length} \u4E2A` : chalk7.gray("\u4F7F\u7528\u9ED8\u8BA4\u8DEF\u7531"));
4932
+ console.log(chalk7.white(" \u5065\u5EB7\u68C0\u67E5:"), chalk7.cyan(`http://localhost:${port}/api/health`));
4743
4933
  if (routes.length > 0) {
4744
4934
  console.log();
4745
- console.log(chalk6.white(" \u5DF2\u6CE8\u518C\u8DEF\u7531:"));
4935
+ console.log(chalk7.white(" \u5DF2\u6CE8\u518C\u8DEF\u7531:"));
4746
4936
  for (const route of routes.slice(0, 10)) {
4747
- const method = chalk6.gray(route.method.padEnd(6));
4937
+ const method = chalk7.gray(route.method.padEnd(6));
4748
4938
  console.log(` ${method} ${route.path}`);
4749
4939
  }
4750
4940
  if (routes.length > 10) {
4751
- console.log(chalk6.gray(` ... \u8FD8\u6709 ${routes.length - 10} \u4E2A\u8DEF\u7531`));
4941
+ console.log(chalk7.gray(` ... \u8FD8\u6709 ${routes.length - 10} \u4E2A\u8DEF\u7531`));
4752
4942
  }
4753
4943
  }
4754
4944
  console.log();
4755
- console.log(chalk6.gray(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668"));
4945
+ console.log(chalk7.gray(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668"));
4756
4946
  process.on("SIGINT", async () => {
4757
4947
  const stopSpinner = ora5("\u6B63\u5728\u505C\u6B62Mock\u670D\u52A1\u5668...").start();
4758
4948
  await stopMockServer();
@@ -4769,7 +4959,7 @@ async function startMock(port, routesDir) {
4769
4959
  async function stopMock() {
4770
4960
  const state = getMockServerState();
4771
4961
  if (!state.running) {
4772
- console.log(chalk6.yellow("\n Mock\u670D\u52A1\u5668\u672A\u5728\u8FD0\u884C\n"));
4962
+ console.log(chalk7.yellow("\n Mock\u670D\u52A1\u5668\u672A\u5728\u8FD0\u884C\n"));
4773
4963
  return;
4774
4964
  }
4775
4965
  const spinner = ora5("\u6B63\u5728\u505C\u6B62Mock\u670D\u52A1\u5668...").start();
@@ -4786,18 +4976,18 @@ function showStatus() {
4786
4976
  const state = getMockServerState();
4787
4977
  console.log();
4788
4978
  if (state.running) {
4789
- console.log(chalk6.green(" \u25CF Mock\u670D\u52A1\u5668\u8FD0\u884C\u4E2D"));
4790
- console.log(chalk6.white(" \u7AEF\u53E3:"), state.port);
4791
- console.log(chalk6.white(" \u8DEF\u7531:"), state.routes.length);
4979
+ console.log(chalk7.green(" \u25CF Mock\u670D\u52A1\u5668\u8FD0\u884C\u4E2D"));
4980
+ console.log(chalk7.white(" \u7AEF\u53E3:"), state.port);
4981
+ console.log(chalk7.white(" \u8DEF\u7531:"), state.routes.length);
4792
4982
  } else {
4793
- console.log(chalk6.gray(" \u25CB Mock\u670D\u52A1\u5668\u672A\u8FD0\u884C"));
4794
- console.log(chalk6.gray(" \u4F7F\u7528 qat mock start \u542F\u52A8"));
4983
+ console.log(chalk7.gray(" \u25CB Mock\u670D\u52A1\u5668\u672A\u8FD0\u884C"));
4984
+ console.log(chalk7.gray(" \u4F7F\u7528 qat mock start \u542F\u52A8"));
4795
4985
  }
4796
4986
  console.log();
4797
4987
  }
4798
4988
 
4799
4989
  // src/commands/report.ts
4800
- import chalk7 from "chalk";
4990
+ import chalk8 from "chalk";
4801
4991
  import ora6 from "ora";
4802
4992
  import fs12 from "fs";
4803
4993
  import path13 from "path";
@@ -4807,7 +4997,7 @@ function registerReportCommand(program2) {
4807
4997
  try {
4808
4998
  await executeReport(options);
4809
4999
  } catch (error) {
4810
- console.error(chalk7.red(`
5000
+ console.error(chalk8.red(`
4811
5001
  \u2717 ${error instanceof Error ? error.message : String(error)}
4812
5002
  `));
4813
5003
  process.exit(1);
@@ -4821,7 +5011,7 @@ async function executeReport(options) {
4821
5011
  const results = collectResults();
4822
5012
  if (results.length === 0) {
4823
5013
  spinner.info("\u6CA1\u6709\u627E\u5230\u6D4B\u8BD5\u7ED3\u679C");
4824
- console.log(chalk7.gray("\n \u63D0\u793A: \u5148\u8FD0\u884C qat run \u751F\u6210\u6D4B\u8BD5\u7ED3\u679C\n"));
5014
+ console.log(chalk8.gray("\n \u63D0\u793A: \u5148\u8FD0\u884C qat run \u751F\u6210\u6D4B\u8BD5\u7ED3\u679C\n"));
4825
5015
  return;
4826
5016
  }
4827
5017
  spinner.text = "\u6B63\u5728\u751F\u6210\u6D4B\u8BD5\u62A5\u544A...";
@@ -4874,31 +5064,31 @@ function displayReportResult(reportPath, data) {
4874
5064
  const relativePath = path13.relative(process.cwd(), reportPath);
4875
5065
  const passRate = data.summary.total > 0 ? (data.summary.passed / data.summary.total * 100).toFixed(1) : "0";
4876
5066
  console.log();
4877
- console.log(chalk7.green(" \u2713 \u6D4B\u8BD5\u62A5\u544A\u5DF2\u751F\u6210"));
5067
+ console.log(chalk8.green(" \u2713 \u6D4B\u8BD5\u62A5\u544A\u5DF2\u751F\u6210"));
4878
5068
  console.log();
4879
- console.log(chalk7.white(" \u62A5\u544A\u8DEF\u5F84:"), chalk7.cyan(relativePath));
4880
- console.log(chalk7.white(" \u901A\u8FC7\u7387: "), parseFloat(passRate) >= 80 ? chalk7.green(`${passRate}%`) : parseFloat(passRate) >= 50 ? chalk7.yellow(`${passRate}%`) : chalk7.red(`${passRate}%`));
4881
- console.log(chalk7.white(" \u6D4B\u8BD5\u7528\u4F8B:"), `${data.summary.total} total`);
4882
- console.log(chalk7.white(" \u2705 \u901A\u8FC7: "), chalk7.green(String(data.summary.passed)));
5069
+ console.log(chalk8.white(" \u62A5\u544A\u8DEF\u5F84:"), chalk8.cyan(relativePath));
5070
+ console.log(chalk8.white(" \u901A\u8FC7\u7387: "), parseFloat(passRate) >= 80 ? chalk8.green(`${passRate}%`) : parseFloat(passRate) >= 50 ? chalk8.yellow(`${passRate}%`) : chalk8.red(`${passRate}%`));
5071
+ console.log(chalk8.white(" \u6D4B\u8BD5\u7528\u4F8B:"), `${data.summary.total} total`);
5072
+ console.log(chalk8.white(" \u2705 \u901A\u8FC7: "), chalk8.green(String(data.summary.passed)));
4883
5073
  if (data.summary.failed > 0) {
4884
- console.log(chalk7.white(" \u274C \u5931\u8D25: "), chalk7.red(String(data.summary.failed)));
5074
+ console.log(chalk8.white(" \u274C \u5931\u8D25: "), chalk8.red(String(data.summary.failed)));
4885
5075
  }
4886
5076
  if (data.summary.skipped > 0) {
4887
- console.log(chalk7.white(" \u23ED\uFE0F \u8DF3\u8FC7: "), chalk7.yellow(String(data.summary.skipped)));
5077
+ console.log(chalk8.white(" \u23ED\uFE0F \u8DF3\u8FC7: "), chalk8.yellow(String(data.summary.skipped)));
4888
5078
  }
4889
5079
  if (Object.keys(data.byType).length > 0) {
4890
5080
  console.log();
4891
- console.log(chalk7.white(" \u6309\u7C7B\u578B:"));
5081
+ console.log(chalk8.white(" \u6309\u7C7B\u578B:"));
4892
5082
  for (const [type, stats] of Object.entries(data.byType)) {
4893
5083
  const rate = stats.total > 0 ? (stats.passed / stats.total * 100).toFixed(0) : "0";
4894
- const icon = stats.failed > 0 ? chalk7.red("\u274C") : chalk7.green("\u2705");
5084
+ const icon = stats.failed > 0 ? chalk8.red("\u274C") : chalk8.green("\u2705");
4895
5085
  console.log(` ${icon} ${type}: ${stats.passed}/${stats.total} (${rate}%)`);
4896
5086
  }
4897
5087
  }
4898
5088
  if (data.coverage) {
4899
5089
  console.log();
4900
- console.log(chalk7.white(" \u8986\u76D6\u7387:"));
4901
- console.log(` \u8BED\u53E5: ${chalk7.cyan(pct2(data.coverage.statements))} \u5206\u652F: ${chalk7.cyan(pct2(data.coverage.branches))} \u51FD\u6570: ${chalk7.cyan(pct2(data.coverage.functions))} \u884C: ${chalk7.cyan(pct2(data.coverage.lines))}`);
5090
+ console.log(chalk8.white(" \u8986\u76D6\u7387:"));
5091
+ console.log(` \u8BED\u53E5: ${chalk8.cyan(pct2(data.coverage.statements))} \u5206\u652F: ${chalk8.cyan(pct2(data.coverage.branches))} \u51FD\u6570: ${chalk8.cyan(pct2(data.coverage.functions))} \u884C: ${chalk8.cyan(pct2(data.coverage.lines))}`);
4902
5092
  }
4903
5093
  console.log();
4904
5094
  }
@@ -4918,13 +5108,13 @@ async function openReport(reportPath) {
4918
5108
  }
4919
5109
  exec(command, { shell: true }, (error) => {
4920
5110
  if (error) {
4921
- console.log(chalk7.gray(" \u63D0\u793A: \u624B\u52A8\u6253\u5F00\u62A5\u544A\u67E5\u770B"));
5111
+ console.log(chalk8.gray(" \u63D0\u793A: \u624B\u52A8\u6253\u5F00\u62A5\u544A\u67E5\u770B"));
4922
5112
  }
4923
5113
  });
4924
5114
  }
4925
5115
 
4926
5116
  // src/commands/visual.ts
4927
- import chalk8 from "chalk";
5117
+ import chalk9 from "chalk";
4928
5118
  import ora7 from "ora";
4929
5119
 
4930
5120
  // src/services/visual.ts
@@ -5091,7 +5281,7 @@ function registerVisualCommand(program2) {
5091
5281
  config: options.config
5092
5282
  });
5093
5283
  } catch (error) {
5094
- console.error(chalk8.red(`
5284
+ console.error(chalk9.red(`
5095
5285
  \u2717 ${error instanceof Error ? error.message : String(error)}
5096
5286
  `));
5097
5287
  process.exit(1);
@@ -5117,9 +5307,9 @@ async function executeVisual(options) {
5117
5307
  break;
5118
5308
  }
5119
5309
  default: {
5120
- console.error(chalk8.red(`
5310
+ console.error(chalk9.red(`
5121
5311
  \u672A\u77E5\u64CD\u4F5C: ${options.action}`));
5122
- console.log(chalk8.gray(" \u53EF\u7528\u64CD\u4F5C: test, approve, clean\n"));
5312
+ console.log(chalk9.gray(" \u53EF\u7528\u64CD\u4F5C: test, approve, clean\n"));
5123
5313
  process.exit(1);
5124
5314
  }
5125
5315
  }
@@ -5143,7 +5333,7 @@ async function runVisualTest(threshold, baselineDir, diffDir, config) {
5143
5333
  const currentDir = findCurrentScreenshotsDir(baselineDir);
5144
5334
  if (!currentDir) {
5145
5335
  compareSpinner.info("\u6CA1\u6709\u627E\u5230\u622A\u56FE\u6587\u4EF6");
5146
- console.log(chalk8.gray("\n \u63D0\u793A: \u5148\u8FD0\u884C qat run -t visual \u751F\u6210\u622A\u56FE\n"));
5336
+ console.log(chalk9.gray("\n \u63D0\u793A: \u5148\u8FD0\u884C qat run -t visual \u751F\u6210\u622A\u56FE\n"));
5147
5337
  return;
5148
5338
  }
5149
5339
  const results = compareDirectories(baselineDir, currentDir, diffDir, threshold);
@@ -5189,48 +5379,48 @@ function displayVisualResults(results, threshold) {
5189
5379
  const passed = results.filter((r) => r.passed);
5190
5380
  const failed = results.filter((r) => !r.passed);
5191
5381
  console.log();
5192
- console.log(chalk8.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5382
+ console.log(chalk9.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5193
5383
  if (failed.length === 0) {
5194
- console.log(chalk8.green(` \u2713 \u5168\u90E8\u901A\u8FC7 (${results.length} \u4E2A\u622A\u56FE\u6BD4\u5BF9)`));
5384
+ console.log(chalk9.green(` \u2713 \u5168\u90E8\u901A\u8FC7 (${results.length} \u4E2A\u622A\u56FE\u6BD4\u5BF9)`));
5195
5385
  } else {
5196
- console.log(chalk8.red(` \u2717 ${failed.length} \u4E2A\u622A\u56FE\u5B58\u5728\u5DEE\u5F02`));
5386
+ console.log(chalk9.red(` \u2717 ${failed.length} \u4E2A\u622A\u56FE\u5B58\u5728\u5DEE\u5F02`));
5197
5387
  }
5198
5388
  console.log();
5199
- console.log(` ${chalk8.white("\u9608\u503C:")} ${(threshold * 100).toFixed(0)}%`);
5200
- console.log(` ${chalk8.green("\u901A\u8FC7:")} ${passed.length}`);
5201
- console.log(` ${chalk8.red("\u5931\u8D25:")} ${failed.length}`);
5389
+ console.log(` ${chalk9.white("\u9608\u503C:")} ${(threshold * 100).toFixed(0)}%`);
5390
+ console.log(` ${chalk9.green("\u901A\u8FC7:")} ${passed.length}`);
5391
+ console.log(` ${chalk9.red("\u5931\u8D25:")} ${failed.length}`);
5202
5392
  if (passed.length > 0) {
5203
5393
  console.log();
5204
- console.log(chalk8.green(" \u901A\u8FC7\u7684\u622A\u56FE:"));
5394
+ console.log(chalk9.green(" \u901A\u8FC7\u7684\u622A\u56FE:"));
5205
5395
  for (const result of passed) {
5206
5396
  const name = path15.basename(result.baselinePath);
5207
5397
  if (result.totalPixels > 0) {
5208
5398
  const diffPct = (result.diffRatio * 100).toFixed(2);
5209
- console.log(chalk8.green(` \u2713 ${name} (\u5DEE\u5F02: ${diffPct}%)`));
5399
+ console.log(chalk9.green(` \u2713 ${name} (\u5DEE\u5F02: ${diffPct}%)`));
5210
5400
  } else {
5211
- console.log(chalk8.green(` \u2713 ${name} (\u65B0\u5EFA\u57FA\u7EBF)`));
5401
+ console.log(chalk9.green(` \u2713 ${name} (\u65B0\u5EFA\u57FA\u7EBF)`));
5212
5402
  }
5213
5403
  }
5214
5404
  }
5215
5405
  if (failed.length > 0) {
5216
5406
  console.log();
5217
- console.log(chalk8.red(" \u5931\u8D25\u7684\u622A\u56FE:"));
5407
+ console.log(chalk9.red(" \u5931\u8D25\u7684\u622A\u56FE:"));
5218
5408
  for (const result of failed) {
5219
5409
  const name = path15.basename(result.baselinePath);
5220
5410
  if (result.diffPixels === -1) {
5221
- console.log(chalk8.red(` \u2717 ${name} (\u5C3A\u5BF8\u4E0D\u5339\u914D)`));
5411
+ console.log(chalk9.red(` \u2717 ${name} (\u5C3A\u5BF8\u4E0D\u5339\u914D)`));
5222
5412
  } else {
5223
5413
  const diffPct = (result.diffRatio * 100).toFixed(2);
5224
- console.log(chalk8.red(` \u2717 ${name} (\u5DEE\u5F02: ${diffPct}%)`));
5414
+ console.log(chalk9.red(` \u2717 ${name} (\u5DEE\u5F02: ${diffPct}%)`));
5225
5415
  }
5226
5416
  if (result.diffPath) {
5227
- console.log(chalk8.gray(` \u5DEE\u5F02\u56FE: ${path15.relative(process.cwd(), result.diffPath)}`));
5417
+ console.log(chalk9.gray(` \u5DEE\u5F02\u56FE: ${path15.relative(process.cwd(), result.diffPath)}`));
5228
5418
  }
5229
5419
  }
5230
5420
  console.log();
5231
- console.log(chalk8.yellow(" \u63D0\u793A: \u8FD0\u884C qat visual approve \u66F4\u65B0\u57FA\u7EBF"));
5421
+ console.log(chalk9.yellow(" \u63D0\u793A: \u8FD0\u884C qat visual approve \u66F4\u65B0\u57FA\u7EBF"));
5232
5422
  }
5233
- console.log(chalk8.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5423
+ console.log(chalk9.cyan(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5234
5424
  console.log();
5235
5425
  }
5236
5426
  async function approveBaselines(baselineDir, diffDir) {
@@ -5249,7 +5439,7 @@ async function approveBaselines(baselineDir, diffDir) {
5249
5439
  spinner.succeed(`\u5DF2\u66F4\u65B0 ${updated.length} \u4E2A\u57FA\u7EBF\u5FEB\u7167`);
5250
5440
  console.log();
5251
5441
  for (const file of updated) {
5252
- console.log(chalk8.green(` \u2713 ${file}`));
5442
+ console.log(chalk9.green(` \u2713 ${file}`));
5253
5443
  }
5254
5444
  console.log();
5255
5445
  }
@@ -5259,14 +5449,14 @@ async function cleanAll(baselineDir, diffDir) {
5259
5449
  const diffs = cleanDiffs(diffDir);
5260
5450
  spinner.succeed("\u6E05\u7406\u5B8C\u6210");
5261
5451
  console.log();
5262
- console.log(chalk8.white(" \u5DF2\u5220\u9664:"));
5452
+ console.log(chalk9.white(" \u5DF2\u5220\u9664:"));
5263
5453
  console.log(` \u57FA\u7EBF: ${baselines} \u4E2A`);
5264
5454
  console.log(` \u5DEE\u5F02: ${diffs} \u4E2A`);
5265
5455
  console.log();
5266
5456
  }
5267
5457
 
5268
5458
  // src/commands/setup.ts
5269
- import chalk9 from "chalk";
5459
+ import chalk10 from "chalk";
5270
5460
  import inquirer4 from "inquirer";
5271
5461
  import ora8 from "ora";
5272
5462
  import { execFile as execFile4 } from "child_process";
@@ -5295,7 +5485,7 @@ function registerSetupCommand(program2) {
5295
5485
  try {
5296
5486
  await executeSetup(options);
5297
5487
  } catch (error) {
5298
- console.error(chalk9.red(`
5488
+ console.error(chalk10.red(`
5299
5489
  \u2717 ${error instanceof Error ? error.message : String(error)}
5300
5490
  `));
5301
5491
  process.exit(1);
@@ -5303,20 +5493,20 @@ function registerSetupCommand(program2) {
5303
5493
  });
5304
5494
  }
5305
5495
  async function executeSetup(options) {
5306
- console.log(chalk9.cyan("\n QAT \u4F9D\u8D56\u5B89\u88C5\u5668\n"));
5496
+ console.log(chalk10.cyan("\n QAT \u4F9D\u8D56\u5B89\u88C5\u5668\n"));
5307
5497
  const projectInfo = detectProject();
5308
5498
  if (!fs15.existsSync(path16.join(process.cwd(), "package.json"))) {
5309
5499
  throw new Error("\u672A\u627E\u5230 package.json\uFF0C\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u6267\u884C\u6B64\u547D\u4EE4");
5310
5500
  }
5311
5501
  if (projectInfo.frameworkConfidence > 0) {
5312
- console.log(chalk9.white(` \u68C0\u6D4B\u5230\u6846\u67B6: ${chalk9.cyan(projectInfo.frameworkDisplayName)}`));
5502
+ console.log(chalk10.white(` \u68C0\u6D4B\u5230\u6846\u67B6: ${chalk10.cyan(projectInfo.frameworkDisplayName)}`));
5313
5503
  if (projectInfo.uiLibrary !== "none") {
5314
- console.log(chalk9.white(` UI \u7EC4\u4EF6\u5E93: ${chalk9.cyan(projectInfo.uiLibrary)}`));
5504
+ console.log(chalk10.white(` UI \u7EC4\u4EF6\u5E93: ${chalk10.cyan(projectInfo.uiLibrary)}`));
5315
5505
  }
5316
5506
  if (projectInfo.monorepo !== "none") {
5317
- console.log(chalk9.white(` Monorepo: ${chalk9.cyan(projectInfo.monorepo)}`));
5507
+ console.log(chalk10.white(` Monorepo: ${chalk10.cyan(projectInfo.monorepo)}`));
5318
5508
  if (projectInfo.appDirs.length > 0) {
5319
- console.log(chalk9.white(` \u5B50\u9879\u76EE: ${chalk9.gray(projectInfo.appDirs.join(", "))}`));
5509
+ console.log(chalk10.white(` \u5B50\u9879\u76EE: ${chalk10.gray(projectInfo.appDirs.join(", "))}`));
5320
5510
  }
5321
5511
  }
5322
5512
  console.log();
@@ -5352,12 +5542,12 @@ async function executeSetup(options) {
5352
5542
  }
5353
5543
  const groupsToInstall = determineGroups(config, projectInfo, options.force);
5354
5544
  if (groupsToInstall.length === 0) {
5355
- console.log(chalk9.green(" \u2713 \u6240\u6709\u4F9D\u8D56\u5DF2\u5B89\u88C5\uFF0C\u65E0\u9700\u989D\u5916\u64CD\u4F5C\n"));
5545
+ console.log(chalk10.green(" \u2713 \u6240\u6709\u4F9D\u8D56\u5DF2\u5B89\u88C5\uFF0C\u65E0\u9700\u989D\u5916\u64CD\u4F5C\n"));
5356
5546
  return;
5357
5547
  }
5358
5548
  const selectedGroups = await selectGroups(groupsToInstall, options.dryRun);
5359
5549
  if (selectedGroups.length === 0) {
5360
- console.log(chalk9.gray("\n \u5DF2\u53D6\u6D88\u5B89\u88C5\n"));
5550
+ console.log(chalk10.gray("\n \u5DF2\u53D6\u6D88\u5B89\u88C5\n"));
5361
5551
  return;
5362
5552
  }
5363
5553
  const allPackages = selectedGroups.flatMap((g) => g.packages);
@@ -5371,19 +5561,19 @@ ${allPackages.map((p) => ` - ${p}`).join("\n")}`,
5371
5561
  }
5372
5562
  ]);
5373
5563
  if (!confirmed) {
5374
- console.log(chalk9.gray("\n \u5DF2\u53D6\u6D88\u5B89\u88C5\n"));
5564
+ console.log(chalk10.gray("\n \u5DF2\u53D6\u6D88\u5B89\u88C5\n"));
5375
5565
  return;
5376
5566
  }
5377
5567
  if (options.dryRun) {
5378
- console.log(chalk9.yellow("\n [Dry Run] \u4EE5\u4E0B\u547D\u4EE4\u5C06\u88AB\u6267\u884C:\n"));
5568
+ console.log(chalk10.yellow("\n [Dry Run] \u4EE5\u4E0B\u547D\u4EE4\u5C06\u88AB\u6267\u884C:\n"));
5379
5569
  const pm = getPackageManager(projectInfo.packageManager);
5380
5570
  const installCmd = pm === "npm" ? "npm install -D" : pm === "yarn" ? "yarn add -D" : pm === "pnpm" ? "pnpm add -D" : "bun add -D";
5381
5571
  for (const group of selectedGroups) {
5382
5572
  const dirHint = installDir !== process.cwd() ? ` (\u5728 ${path16.relative(process.cwd(), installDir) || installDir})` : "";
5383
- console.log(chalk9.white(` ${installCmd} ${group.packages.join(" ")}${dirHint}`));
5573
+ console.log(chalk10.white(` ${installCmd} ${group.packages.join(" ")}${dirHint}`));
5384
5574
  if (group.postInstall) {
5385
5575
  for (const cmd of group.postInstall) {
5386
- console.log(chalk9.white(` ${cmd}`));
5576
+ console.log(chalk10.white(` ${cmd}`));
5387
5577
  }
5388
5578
  }
5389
5579
  }
@@ -5496,36 +5686,36 @@ ${stderr}` : "")));
5496
5686
  });
5497
5687
  }
5498
5688
  function displaySetupResult(groups) {
5499
- console.log(chalk9.green("\n \u2713 \u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210!\n"));
5500
- console.log(chalk9.white(" \u5DF2\u5B89\u88C5:"));
5689
+ console.log(chalk10.green("\n \u2713 \u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210!\n"));
5690
+ console.log(chalk10.white(" \u5DF2\u5B89\u88C5:"));
5501
5691
  for (const group of groups) {
5502
- console.log(chalk9.cyan(`
5692
+ console.log(chalk10.cyan(`
5503
5693
  ${group.name}`));
5504
5694
  for (const pkg of group.packages) {
5505
- console.log(chalk9.gray(` \u2713 ${pkg}`));
5695
+ console.log(chalk10.gray(` \u2713 ${pkg}`));
5506
5696
  }
5507
5697
  if (group.postInstall) {
5508
5698
  for (const cmd of group.postInstall) {
5509
- console.log(chalk9.gray(` \u2713 ${cmd}`));
5699
+ console.log(chalk10.gray(` \u2713 ${cmd}`));
5510
5700
  }
5511
5701
  }
5512
5702
  }
5513
5703
  console.log();
5514
- console.log(chalk9.cyan(" \u4E0B\u4E00\u6B65:"));
5515
- console.log(chalk9.gray(" 1. \u8FD0\u884C qat create \u521B\u5EFA\u6D4B\u8BD5\u7528\u4F8B"));
5516
- console.log(chalk9.gray(" 2. \u8FD0\u884C qat run \u6267\u884C\u6D4B\u8BD5"));
5704
+ console.log(chalk10.cyan(" \u4E0B\u4E00\u6B65:"));
5705
+ console.log(chalk10.gray(" 1. \u8FD0\u884C qat create \u521B\u5EFA\u6D4B\u8BD5\u7528\u4F8B"));
5706
+ console.log(chalk10.gray(" 2. \u8FD0\u884C qat run \u6267\u884C\u6D4B\u8BD5"));
5517
5707
  console.log();
5518
5708
  }
5519
5709
 
5520
5710
  // src/commands/status.ts
5521
- import chalk10 from "chalk";
5711
+ import chalk11 from "chalk";
5522
5712
  import ora9 from "ora";
5523
5713
  function registerStatusCommand(program2) {
5524
5714
  program2.command("status").description("\u67E5\u770B QAT \u72B6\u6001 - AI \u6A21\u578B\u4FE1\u606F\u3001\u9879\u76EE\u914D\u7F6E").action(async (options) => {
5525
5715
  try {
5526
5716
  await executeStatus(options);
5527
5717
  } catch (error) {
5528
- console.error(chalk10.red(`
5718
+ console.error(chalk11.red(`
5529
5719
  \u2717 ${error instanceof Error ? error.message : String(error)}
5530
5720
  `));
5531
5721
  process.exit(1);
@@ -5533,24 +5723,24 @@ function registerStatusCommand(program2) {
5533
5723
  });
5534
5724
  }
5535
5725
  async function executeStatus(_options) {
5536
- console.log(chalk10.cyan("\n AI \u6A21\u578B\u72B6\u6001"));
5537
- console.log(chalk10.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5726
+ console.log(chalk11.cyan("\n AI \u6A21\u578B\u72B6\u6001"));
5727
+ console.log(chalk11.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5538
5728
  const globalAI = loadGlobalAIConfig();
5539
5729
  if (!globalAI) {
5540
- console.log(chalk10.yellow(" \u2717 \u672A\u914D\u7F6E AI \u6A21\u578B"));
5541
- console.log(chalk10.gray(" \u8FD0\u884C qat change \u914D\u7F6E AI \u6A21\u578B"));
5730
+ console.log(chalk11.yellow(" \u2717 \u672A\u914D\u7F6E AI \u6A21\u578B"));
5731
+ console.log(chalk11.gray(" \u8FD0\u884C qat change \u914D\u7F6E AI \u6A21\u578B"));
5542
5732
  } else {
5543
- console.log(` ${chalk10.white("\u6A21\u578B:")} ${chalk10.green(globalAI.model)}`);
5544
- console.log(` ${chalk10.white("API URL:")} ${chalk10.gray(globalAI.baseUrl)}`);
5545
- console.log(` ${chalk10.white("API Key:")} ${chalk10.gray(maskApiKey(globalAI.apiKey))}`);
5546
- console.log(` ${chalk10.white("Provider:")} ${chalk10.gray(globalAI.provider)}`);
5547
- console.log(` ${chalk10.white("\u914D\u7F6E\u6587\u4EF6:")} ${chalk10.gray(getAIConfigPath())}`);
5733
+ console.log(` ${chalk11.white("\u6A21\u578B:")} ${chalk11.green(globalAI.model)}`);
5734
+ console.log(` ${chalk11.white("API URL:")} ${chalk11.gray(globalAI.baseUrl)}`);
5735
+ console.log(` ${chalk11.white("API Key:")} ${chalk11.gray(maskApiKey(globalAI.apiKey))}`);
5736
+ console.log(` ${chalk11.white("Provider:")} ${chalk11.gray(globalAI.provider)}`);
5737
+ console.log(` ${chalk11.white("\u914D\u7F6E\u6587\u4EF6:")} ${chalk11.gray(getAIConfigPath())}`);
5548
5738
  const testSpinner = ora9(" \u6B63\u5728\u6D4B\u8BD5\u8FDE\u901A\u6027...").start();
5549
5739
  try {
5550
5740
  const aiConfig = toAIConfig(globalAI);
5551
5741
  const result = await testAIConnection(aiConfig);
5552
5742
  if (result.ok) {
5553
- testSpinner.succeed(` \u8FDE\u901A\u6B63\u5E38 ${chalk10.gray(`(${result.latencyMs}ms)`)}`);
5743
+ testSpinner.succeed(` \u8FDE\u901A\u6B63\u5E38 ${chalk11.gray(`(${result.latencyMs}ms)`)}`);
5554
5744
  } else {
5555
5745
  testSpinner.fail(` \u8FDE\u901A\u5F02\u5E38: ${result.message}`);
5556
5746
  }
@@ -5559,26 +5749,26 @@ async function executeStatus(_options) {
5559
5749
  }
5560
5750
  }
5561
5751
  console.log();
5562
- console.log(chalk10.cyan(" \u9879\u76EE\u914D\u7F6E"));
5563
- console.log(chalk10.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5752
+ console.log(chalk11.cyan(" \u9879\u76EE\u914D\u7F6E"));
5753
+ console.log(chalk11.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
5564
5754
  try {
5565
5755
  const config = await loadConfig();
5566
5756
  const projectInfo = detectProject();
5567
- console.log(` ${chalk10.white("\u6846\u67B6:")} ${projectInfo.frameworkDisplayName}`);
5568
- console.log(` ${chalk10.white("\u6E90\u7801\u76EE\u5F55:")} ${config.project.srcDir}`);
5569
- console.log(` ${chalk10.white("Vitest:")} ${config.vitest.enabled ? chalk10.green("\u2713") : chalk10.red("\u2717")} (${config.vitest.environment})`);
5570
- console.log(` ${chalk10.white("Playwright:")} ${config.playwright.enabled ? chalk10.green("\u2713") : chalk10.red("\u2717")} (${config.playwright.browsers.join(", ")})`);
5571
- console.log(` ${chalk10.white("Mock:")} ${config.mock.enabled ? chalk10.green("\u2713") : chalk10.red("\u2717")} (port ${config.mock.port})`);
5572
- console.log(` ${chalk10.white("Visual:")} ${config.visual.enabled ? chalk10.green("\u2713") : chalk10.red("\u2717")}`);
5573
- console.log(` ${chalk10.white("Lighthouse:")} ${config.lighthouse.enabled ? chalk10.green("\u2713") : chalk10.red("\u2717")}`);
5757
+ console.log(` ${chalk11.white("\u6846\u67B6:")} ${projectInfo.frameworkDisplayName}`);
5758
+ console.log(` ${chalk11.white("\u6E90\u7801\u76EE\u5F55:")} ${config.project.srcDir}`);
5759
+ console.log(` ${chalk11.white("Vitest:")} ${config.vitest.enabled ? chalk11.green("\u2713") : chalk11.red("\u2717")} (${config.vitest.environment})`);
5760
+ console.log(` ${chalk11.white("Playwright:")} ${config.playwright.enabled ? chalk11.green("\u2713") : chalk11.red("\u2717")} (${config.playwright.browsers.join(", ")})`);
5761
+ console.log(` ${chalk11.white("Mock:")} ${config.mock.enabled ? chalk11.green("\u2713") : chalk11.red("\u2717")} (port ${config.mock.port})`);
5762
+ console.log(` ${chalk11.white("Visual:")} ${config.visual.enabled ? chalk11.green("\u2713") : chalk11.red("\u2717")}`);
5763
+ console.log(` ${chalk11.white("Lighthouse:")} ${config.lighthouse.enabled ? chalk11.green("\u2713") : chalk11.red("\u2717")}`);
5574
5764
  } catch {
5575
- console.log(chalk10.yellow(" \u2717 \u672A\u627E\u5230\u9879\u76EE\u914D\u7F6E (\u8FD0\u884C qat init \u521D\u59CB\u5316)"));
5765
+ console.log(chalk11.yellow(" \u2717 \u672A\u627E\u5230\u9879\u76EE\u914D\u7F6E (\u8FD0\u884C qat init \u521D\u59CB\u5316)"));
5576
5766
  }
5577
5767
  console.log();
5578
5768
  }
5579
5769
 
5580
5770
  // src/commands/change.ts
5581
- import chalk11 from "chalk";
5771
+ import chalk12 from "chalk";
5582
5772
  import inquirer5 from "inquirer";
5583
5773
  import ora10 from "ora";
5584
5774
  function registerChangeCommand(program2) {
@@ -5586,7 +5776,7 @@ function registerChangeCommand(program2) {
5586
5776
  try {
5587
5777
  await executeChange(options);
5588
5778
  } catch (error) {
5589
- console.error(chalk11.red(`
5779
+ console.error(chalk12.red(`
5590
5780
  \u2717 ${error instanceof Error ? error.message : String(error)}
5591
5781
  `));
5592
5782
  process.exit(1);
@@ -5596,13 +5786,13 @@ function registerChangeCommand(program2) {
5596
5786
  async function executeChange(_options) {
5597
5787
  const current = loadGlobalAIConfig();
5598
5788
  if (current) {
5599
- console.log(chalk11.cyan("\n \u5F53\u524D AI \u914D\u7F6E:"));
5600
- console.log(` ${chalk11.white("\u6A21\u578B:")} ${chalk11.green(current.model)}`);
5601
- console.log(` ${chalk11.white("API URL:")} ${chalk11.gray(current.baseUrl)}`);
5602
- console.log(` ${chalk11.white("API Key:")} ${chalk11.gray(maskApiKey(current.apiKey))}`);
5789
+ console.log(chalk12.cyan("\n \u5F53\u524D AI \u914D\u7F6E:"));
5790
+ console.log(` ${chalk12.white("\u6A21\u578B:")} ${chalk12.green(current.model)}`);
5791
+ console.log(` ${chalk12.white("API URL:")} ${chalk12.gray(current.baseUrl)}`);
5792
+ console.log(` ${chalk12.white("API Key:")} ${chalk12.gray(maskApiKey(current.apiKey))}`);
5603
5793
  console.log();
5604
5794
  } else {
5605
- console.log(chalk11.yellow("\n \u5F53\u524D\u672A\u914D\u7F6E AI \u6A21\u578B\uFF0C\u8BF7\u914D\u7F6E:\n"));
5795
+ console.log(chalk12.yellow("\n \u5F53\u524D\u672A\u914D\u7F6E AI \u6A21\u578B\uFF0C\u8BF7\u914D\u7F6E:\n"));
5606
5796
  }
5607
5797
  const answers = await inquirer5.prompt([
5608
5798
  {
@@ -5640,16 +5830,16 @@ async function executeChange(_options) {
5640
5830
  model: answers.model?.trim() || "deepseek-chat"
5641
5831
  };
5642
5832
  saveGlobalAIConfig(newConfig);
5643
- console.log(chalk11.green(`
5833
+ console.log(chalk12.green(`
5644
5834
  \u2713 AI \u914D\u7F6E\u5DF2\u4FDD\u5B58`));
5645
- console.log(chalk11.gray(` ${getAIConfigPath()}`));
5646
- console.log(` ${chalk11.white("\u6A21\u578B:")} ${chalk11.green(newConfig.model)} @ ${chalk11.gray(newConfig.baseUrl)}`);
5835
+ console.log(chalk12.gray(` ${getAIConfigPath()}`));
5836
+ console.log(` ${chalk12.white("\u6A21\u578B:")} ${chalk12.green(newConfig.model)} @ ${chalk12.gray(newConfig.baseUrl)}`);
5647
5837
  const testSpinner = ora10(" \u6B63\u5728\u6D4B\u8BD5\u8FDE\u901A\u6027...").start();
5648
5838
  try {
5649
5839
  const aiConfig = toAIConfig(newConfig);
5650
5840
  const result = await testAIConnection(aiConfig);
5651
5841
  if (result.ok) {
5652
- testSpinner.succeed(` AI \u8FDE\u901A\u6B63\u5E38 ${chalk11.gray(`(${newConfig.model}, ${result.latencyMs}ms)`)}`);
5842
+ testSpinner.succeed(` AI \u8FDE\u901A\u6B63\u5E38 ${chalk12.gray(`(${newConfig.model}, ${result.latencyMs}ms)`)}`);
5653
5843
  } else {
5654
5844
  testSpinner.fail(` AI \u8FDE\u901A\u5F02\u5E38: ${result.message}`);
5655
5845
  }
@@ -5660,37 +5850,40 @@ async function executeChange(_options) {
5660
5850
  }
5661
5851
 
5662
5852
  // src/cli.ts
5663
- var VERSION = "0.3.02";
5853
+ var VERSION = "0.3.04";
5664
5854
  function printLogo() {
5665
5855
  const logo = `
5666
- ${chalk12.bold.cyan(" ___ _ _ _ _ _____ _ _ ")}
5667
- ${chalk12.bold.cyan(" / _ \\ _ _ (_) ___ | | __ / \\ _ _ | |_ ___ |_ _| ___ ___ | |_ (_) _ __ __ _ ")}
5668
- ${chalk12.bold.cyan(" | | | | | | | | | | / __| | |/ / / _ \\ | | | | | __| / _ \\ | | / _ \\ / __| | __| | | | '_ \\ / _` |")}
5669
- ${chalk12.bold.cyan(" | |_| | | |_| | | | | (__ | < / ___ \\ | |_| | | |_ | (_) | | | | __/ \\__ \\ | |_ | | | | | | | (_| |")}
5670
- ${chalk12.bold.cyan(" \\__\\_\\ \\__,_| |_| \\___| |_|\\_\\ /_/ \\_\\ \\__,_| \\__| \\___/ |_| \\___| |___/ \\__| |_| |_| |_| \\__, |")}
5671
- ${chalk12.bold.cyan(" |___/ ")}
5672
- ${chalk12.gray(" CLI\u81EA\u52A8\u5316\u6D4B\u8BD5\u5DE5\u5177 v")}${chalk12.green(VERSION)}
5856
+ ${chalk13.bold.cyan(" ___ _ _ _ _ _____ _ _ ")}
5857
+ ${chalk13.bold.cyan(" / _ \\ _ _ (_) ___ | | __ / \\ _ _ | |_ ___ |_ _| ___ ___ | |_ (_) _ __ __ _ ")}
5858
+ ${chalk13.bold.cyan(" | | | | | | | | | | / __| | |/ / / _ \\ | | | | | __| / _ \\ | | / _ \\ / __| | __| | | | '_ \\ / _` |")}
5859
+ ${chalk13.bold.cyan(" | |_| | | |_| | | | | (__ | < / ___ \\ | |_| | | |_ | (_) | | | | __/ \\__ \\ | |_ | | | | | | | (_| |")}
5860
+ ${chalk13.bold.cyan(" \\__\\_\\ \\__,_| |_| \\___| |_|\\_\\ /_/ \\_\\ \\__,_| \\__| \\___/ |_| \\___| |___/ \\__| |_| |_| |_| \\__, |")}
5861
+ ${chalk13.bold.cyan(" |___/ ")}
5862
+ ${chalk13.gray(" CLI\u81EA\u52A8\u5316\u6D4B\u8BD5\u5DE5\u5177 v")}${chalk13.green(VERSION)}
5673
5863
  `;
5674
5864
  console.log(logo);
5675
5865
  }
5676
5866
  var program = new Command();
5677
- program.name("qat").description("CLI\u81EA\u52A8\u5316\u6D4B\u8BD5\u5DE5\u5177 - \u9762\u5411Vue\u9879\u76EE\uFF0C\u96C6\u6210Vitest\u3001Playwright\uFF0C\u8986\u76D6\u6D4B\u8BD5\u5168\u6D41\u7A0B").version(VERSION).option("-c, --config <path>", "\u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").option("-v, --verbose", "\u663E\u793A\u8BE6\u7EC6\u8F93\u51FA").hook("preAction", async (thisCommand) => {
5867
+ program.name("qat").description("CLI\u81EA\u52A8\u5316\u6D4B\u8BD5\u5DE5\u5177 - \u9762\u5411Vue\u9879\u76EE\uFF0C\u96C6\u6210Vitest\u3001Playwright\uFF0C\u8986\u76D6\u6D4B\u8BD5\u5168\u6D41\u7A0B").version(VERSION).option("-c, --config <path>", "\u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").option("-v, --verbose", "\u663E\u793A\u8BE6\u7EC6\u8F93\u51FA").option("-d, --debug", "\u8C03\u8BD5\u6A21\u5F0F\uFF1A\u663E\u793AAI\u8BF7\u6C42/\u54CD\u5E94\u8BE6\u60C5").hook("preAction", async (thisCommand) => {
5678
5868
  printLogo();
5679
5869
  const opts = thisCommand.opts();
5680
5870
  if (opts.verbose) {
5681
5871
  process.env.QAT_VERBOSE = "true";
5682
5872
  }
5873
+ if (opts.debug) {
5874
+ process.env.QAT_DEBUG = "true";
5875
+ }
5683
5876
  if (opts.config) {
5684
5877
  process.env.QAT_CONFIG_PATH = opts.config;
5685
5878
  }
5686
5879
  const { loadExternalFrameworks } = await import("./framework-registry-YGZ63RDX.js");
5687
5880
  const loadResult = await loadExternalFrameworks(process.cwd());
5688
5881
  if (loadResult.loaded > 0 && opts.verbose) {
5689
- console.log(chalk12.gray(` [ext] \u5DF2\u52A0\u8F7D ${loadResult.loaded} \u4E2A\u5916\u90E8\u6269\u5C55\u6587\u4EF6: ${loadResult.files.join(", ")}`));
5882
+ console.log(chalk13.gray(` [ext] \u5DF2\u52A0\u8F7D ${loadResult.loaded} \u4E2A\u5916\u90E8\u6269\u5C55\u6587\u4EF6: ${loadResult.files.join(", ")}`));
5690
5883
  }
5691
5884
  if (loadResult.errors.length > 0) {
5692
5885
  for (const err of loadResult.errors) {
5693
- console.log(chalk12.yellow(` [ext] \u8B66\u544A: ${err.file} - ${err.error}`));
5886
+ console.log(chalk13.yellow(` [ext] \u8B66\u544A: ${err.file} - ${err.error}`));
5694
5887
  }
5695
5888
  }
5696
5889
  });
@@ -5704,9 +5897,9 @@ registerSetupCommand(program);
5704
5897
  registerStatusCommand(program);
5705
5898
  registerChangeCommand(program);
5706
5899
  program.on("command:*", (operands) => {
5707
- console.error(chalk12.red(`
5900
+ console.error(chalk13.red(`
5708
5901
  \u672A\u77E5\u547D\u4EE4: ${operands[0]}`));
5709
- console.log(chalk12.gray(` \u4F7F\u7528 qat --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4
5902
+ console.log(chalk13.gray(` \u4F7F\u7528 qat --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4
5710
5903
  `));
5711
5904
  process.exit(1);
5712
5905
  });