@nick848/sf-cli 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -59,6 +59,7 @@ async function handleNew(args, ctx) {
59
59
  context: null,
60
60
  clarityScore: 0,
61
61
  clarificationQuestions: [],
62
+ referenceResources: [],
62
63
  complexity: 0,
63
64
  bddScenarios: [],
64
65
  specItems: [],
@@ -101,7 +102,7 @@ async function executeWorkflow(ctx) {
101
102
  const lines = [];
102
103
  try {
103
104
  if (activeSession.phase === "context") {
104
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/8: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
105
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/9: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
105
106
  lines.push("");
106
107
  activeSession.context = await readProjectContext(ctx.options.workingDirectory);
107
108
  lines.push(chalk9.gray(` \u9879\u76EE: ${activeSession.context.name}`));
@@ -115,7 +116,7 @@ async function executeWorkflow(ctx) {
115
116
  }
116
117
  if (activeSession.phase === "clarify") {
117
118
  lines.push("");
118
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/8: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
119
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/9: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
119
120
  lines.push("");
120
121
  const clarityResult = analyzeRequirementClarity(
121
122
  activeSession.requirement,
@@ -141,11 +142,40 @@ async function executeWorkflow(ctx) {
141
142
  return { output: lines.join("\n") };
142
143
  }
143
144
  lines.push(chalk9.green(" \u2713 \u9700\u6C42\u6E05\u6670\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u6B65"));
145
+ activeSession.phase = "reference";
146
+ }
147
+ if (activeSession.phase === "reference") {
148
+ lines.push("");
149
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/9: \u53C2\u8003\u8D44\u6E90\u5206\u6790 \u2501\u2501\u2501"));
150
+ lines.push("");
151
+ const urls = extractUrls(activeSession.refinedRequirement);
152
+ if (urls.length > 0) {
153
+ lines.push(chalk9.gray(` \u53D1\u73B0 ${urls.length} \u4E2A\u53C2\u8003\u94FE\u63A5`));
154
+ lines.push("");
155
+ for (const url of urls) {
156
+ lines.push(chalk9.gray(` \u{1F4CE} ${url}`));
157
+ try {
158
+ const resource = await fetchAndAnalyzeReference(url, ctx);
159
+ activeSession.referenceResources.push(resource);
160
+ lines.push(chalk9.green(` \u2713 \u5DF2\u5206\u6790`));
161
+ activeSession.refinedRequirement += `
162
+
163
+ \u3010\u53C2\u8003\u8D44\u6E90\u5206\u6790 - ${url}\u3011
164
+ ${resource.analysis}`;
165
+ } catch (error) {
166
+ lines.push(chalk9.yellow(` \u26A0 \u83B7\u53D6\u5931\u8D25: ${error.message}`));
167
+ }
168
+ }
169
+ lines.push("");
170
+ lines.push(chalk9.green(" \u2713 \u53C2\u8003\u8D44\u6E90\u5206\u6790\u5B8C\u6210"));
171
+ } else {
172
+ lines.push(chalk9.gray(" \u65E0\u5916\u90E8\u53C2\u8003\u94FE\u63A5"));
173
+ }
144
174
  activeSession.phase = "analysis";
145
175
  }
146
176
  if (activeSession.phase === "analysis") {
147
177
  lines.push("");
148
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/8: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
178
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/9: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
149
179
  lines.push("");
150
180
  activeSession.complexity = analyzeComplexity(
151
181
  activeSession.refinedRequirement,
@@ -162,12 +192,13 @@ async function executeWorkflow(ctx) {
162
192
  }
163
193
  if (activeSession.phase === "bdd") {
164
194
  lines.push("");
165
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/8: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
195
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/9: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
166
196
  lines.push("");
167
197
  activeSession.bddScenarios = generateBDDScenarios(
168
198
  activeSession.refinedRequirement,
169
199
  activeSession.context,
170
- activeSession.clarificationQuestions
200
+ activeSession.clarificationQuestions,
201
+ activeSession.referenceResources
171
202
  );
172
203
  for (const scenario of activeSession.bddScenarios) {
173
204
  lines.push(chalk9.white(` Feature: ${scenario.feature}`));
@@ -182,13 +213,14 @@ async function executeWorkflow(ctx) {
182
213
  }
183
214
  if (activeSession.phase === "spec") {
184
215
  lines.push("");
185
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/8: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
216
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
186
217
  lines.push("");
187
218
  activeSession.specItems = generateSpecItems(
188
219
  activeSession.refinedRequirement,
189
220
  activeSession.context,
190
221
  activeSession.bddScenarios,
191
- activeSession.clarificationQuestions
222
+ activeSession.clarificationQuestions,
223
+ activeSession.referenceResources
192
224
  );
193
225
  const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
194
226
  lines.push(chalk9.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
@@ -212,7 +244,7 @@ async function executeWorkflow(ctx) {
212
244
  }
213
245
  if (activeSession.phase === "tdd") {
214
246
  lines.push("");
215
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/8: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
247
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/9: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
216
248
  lines.push("");
217
249
  activeSession.testFiles = await generateTests(ctx.options.workingDirectory, activeSession);
218
250
  lines.push(chalk9.green(" \u2713 \u6D4B\u8BD5\u6587\u4EF6\u5DF2\u751F\u6210"));
@@ -223,7 +255,7 @@ async function executeWorkflow(ctx) {
223
255
  }
224
256
  if (activeSession.phase === "develop") {
225
257
  lines.push("");
226
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/8: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
258
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/9: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
227
259
  lines.push("");
228
260
  lines.push(chalk9.yellow(" \u{1F680} \u6B63\u5728\u8C03\u7528 AI \u751F\u6210\u4EE3\u7801..."));
229
261
  try {
@@ -248,7 +280,7 @@ async function executeWorkflow(ctx) {
248
280
  }
249
281
  if (activeSession.phase === "review") {
250
282
  lines.push("");
251
- lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/8: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
283
+ lines.push(chalk9.cyan("\u2501\u2501\u2501 \u9636\u6BB5 9/9: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
252
284
  lines.push("");
253
285
  lines.push(chalk9.yellow(" \u{1F50D} \u6B63\u5728\u8FDB\u884C\u4EE3\u7801\u5BA1\u6838..."));
254
286
  try {
@@ -790,13 +822,41 @@ function analyzeComplexity(requirement, context) {
790
822
  if (!context.framework) score += 0.5;
791
823
  return Math.max(1, Math.min(10, Math.round(score)));
792
824
  }
793
- function generateBDDScenarios(requirement, context, questions) {
825
+ function generateBDDScenarios(requirement, context, questions, references = []) {
794
826
  const scenarios = [];
795
827
  questions.find((q) => q.category === "ui" && q.answered)?.answer;
796
828
  const interactionAnswer = questions.find((q) => q.category === "interaction" && q.answered)?.answer;
797
829
  const edgeAnswer = questions.find((q) => q.category === "edge" && q.answered)?.answer;
830
+ if (references.length > 0) {
831
+ for (const ref of references) {
832
+ const refFeatures = extractFeaturesFromReference(ref);
833
+ for (const feature of refFeatures) {
834
+ const scenario = {
835
+ feature: feature.title,
836
+ description: feature.description,
837
+ scenarios: []
838
+ };
839
+ scenario.scenarios.push({
840
+ name: `\u6B63\u5E38\u6D41\u7A0B: ${feature.title}`,
841
+ given: [`\u7528\u6237\u8FDB\u5165\u76F8\u5173\u9875\u9762`],
842
+ when: [`\u7528\u6237\u6267\u884C "${feature.title}" \u64CD\u4F5C`],
843
+ then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5E76\u8FD4\u56DE\u9884\u671F\u7ED3\u679C`]
844
+ });
845
+ if (feature.hasInput) {
846
+ scenario.scenarios.push({
847
+ name: `\u8FB9\u754C\u60C5\u51B5: \u8F93\u5165\u9A8C\u8BC1`,
848
+ given: [`\u7528\u6237\u8FDB\u5165\u8F93\u5165\u754C\u9762`],
849
+ when: [`\u7528\u6237\u8F93\u5165\u8FB9\u754C\u503C\u6216\u7A7A\u503C`],
850
+ then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u8FB9\u754C\u60C5\u51B5`]
851
+ });
852
+ }
853
+ scenarios.push(scenario);
854
+ }
855
+ }
856
+ }
798
857
  const features = extractFeatures(requirement);
799
858
  for (const feature of features) {
859
+ if (scenarios.some((s) => s.feature === feature.title)) continue;
800
860
  const scenario = {
801
861
  feature: feature.title,
802
862
  description: feature.description,
@@ -828,6 +888,46 @@ function generateBDDScenarios(requirement, context, questions) {
828
888
  }
829
889
  return scenarios;
830
890
  }
891
+ function extractFeaturesFromReference(ref) {
892
+ const features = [];
893
+ const analysis = ref.analysis.toLowerCase();
894
+ if (analysis.includes("\u8F93\u5165") || analysis.includes("\u8868\u5355")) {
895
+ features.push({
896
+ title: "\u8F93\u5165\u8868\u5355",
897
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u8F93\u5165\u8868\u5355\u529F\u80FD",
898
+ hasInput: true
899
+ });
900
+ }
901
+ if (analysis.includes("\u6309\u94AE") || analysis.includes("\u64CD\u4F5C")) {
902
+ features.push({
903
+ title: "\u4EA4\u4E92\u6309\u94AE",
904
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6309\u94AE\u4EA4\u4E92",
905
+ hasInput: false
906
+ });
907
+ }
908
+ if (analysis.includes("\u8868\u683C") || analysis.includes("\u5217\u8868")) {
909
+ features.push({
910
+ title: "\u6570\u636E\u5217\u8868",
911
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6570\u636E\u5C55\u793A",
912
+ hasInput: false
913
+ });
914
+ }
915
+ if (analysis.includes("\u56FE\u8868") || analysis.includes("\u53EF\u89C6\u5316")) {
916
+ features.push({
917
+ title: "\u56FE\u8868\u5C55\u793A",
918
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u56FE\u8868\u53EF\u89C6\u5316",
919
+ hasInput: false
920
+ });
921
+ }
922
+ if (features.length === 0) {
923
+ features.push({
924
+ title: "\u53C2\u8003\u529F\u80FD\u5B9E\u73B0",
925
+ description: `\u57FA\u4E8E\u53C2\u8003\u8D44\u6E90 ${ref.url} \u5B9E\u73B0\u7684\u529F\u80FD`,
926
+ hasInput: true
927
+ });
928
+ }
929
+ return features;
930
+ }
831
931
  function extractFeatures(requirement) {
832
932
  const features = [];
833
933
  const urlMatch = requirement.match(/https?:\/\/[^\s]+/);
@@ -868,15 +968,26 @@ function extractFeatures(requirement) {
868
968
  }
869
969
  return features;
870
970
  }
871
- function generateSpecItems(requirement, context, bddScenarios, questions) {
971
+ function generateSpecItems(requirement, context, bddScenarios, questions, references = []) {
872
972
  const items = [];
873
973
  let id = 1;
974
+ for (const ref of references) {
975
+ items.push({
976
+ id: `T${id.toString().padStart(3, "0")}`,
977
+ title: `\u53C2\u8003\u5206\u6790: ${ref.type}`,
978
+ description: `\u5206\u6790\u53C2\u8003\u8D44\u6E90 ${ref.url}`,
979
+ priority: "high",
980
+ files: [],
981
+ tests: []
982
+ });
983
+ id++;
984
+ }
874
985
  for (const scenario of bddScenarios) {
875
986
  items.push({
876
987
  id: `T${id.toString().padStart(3, "0")}`,
877
988
  title: scenario.feature,
878
989
  description: scenario.description,
879
- priority: id <= 2 ? "high" : "medium",
990
+ priority: id <= 3 ? "high" : "medium",
880
991
  files: [],
881
992
  tests: []
882
993
  });
@@ -919,6 +1030,19 @@ function formatSpecFile(session) {
919
1030
  lines.push("---");
920
1031
  lines.push("");
921
1032
  }
1033
+ if (session.referenceResources.length > 0) {
1034
+ lines.push("## \u53C2\u8003\u8D44\u6E90");
1035
+ lines.push("");
1036
+ for (const ref of session.referenceResources) {
1037
+ lines.push(`### ${ref.url}`);
1038
+ lines.push(`> \u7C7B\u578B: ${ref.type}`);
1039
+ lines.push("");
1040
+ lines.push(ref.analysis);
1041
+ lines.push("");
1042
+ }
1043
+ lines.push("---");
1044
+ lines.push("");
1045
+ }
922
1046
  if (session.clarificationQuestions.some((q) => q.answered)) {
923
1047
  lines.push("## \u9700\u6C42\u6F84\u6E05");
924
1048
  lines.push("");
@@ -1024,6 +1148,96 @@ function generateSessionId() {
1024
1148
  const random = Math.random().toString(36).slice(2, 6);
1025
1149
  return `WF-${timestamp}-${random}`.toUpperCase();
1026
1150
  }
1151
+ function extractUrls(text) {
1152
+ const urlRegex = /https?:\/\/[^\s<>"{}|\\^`\[\]]+/gi;
1153
+ const matches = text.match(urlRegex);
1154
+ return matches ? [...new Set(matches)] : [];
1155
+ }
1156
+ async function fetchAndAnalyzeReference(url, ctx) {
1157
+ const type = detectResourceType(url);
1158
+ let content = "";
1159
+ let analysis = "";
1160
+ try {
1161
+ const response = await fetch(url, {
1162
+ headers: {
1163
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
1164
+ }
1165
+ });
1166
+ if (!response.ok) {
1167
+ throw new Error(`HTTP ${response.status}`);
1168
+ }
1169
+ content = await response.text();
1170
+ if (ctx.modelService.getCurrentModel()) {
1171
+ analysis = await analyzeReferenceContent(url, content, type, ctx);
1172
+ } else {
1173
+ analysis = extractBasicInfo(content, type);
1174
+ }
1175
+ } catch (error) {
1176
+ throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u53C2\u8003\u8D44\u6E90: ${error.message}`);
1177
+ }
1178
+ return { url, type, content: content.slice(0, 1e4), analysis };
1179
+ }
1180
+ function detectResourceType(url) {
1181
+ if (url.includes("figma.com") || url.includes("lanhuapp.com")) {
1182
+ return "design";
1183
+ }
1184
+ if (/\.(png|jpg|jpeg|gif|webp|svg)$/i.test(url)) {
1185
+ return "image";
1186
+ }
1187
+ if (/api\//i.test(url)) {
1188
+ return "api";
1189
+ }
1190
+ return "webpage";
1191
+ }
1192
+ async function analyzeReferenceContent(url, content, type, ctx) {
1193
+ const typePrompts = {
1194
+ webpage: "\u5206\u6790\u8FD9\u4E2A\u7F51\u9875\u7684\u529F\u80FD\u3001UI\u7EC4\u4EF6\u548C\u4EA4\u4E92\u65B9\u5F0F",
1195
+ design: "\u5206\u6790\u8FD9\u4E2A\u8BBE\u8BA1\u7A3F\u7684\u5E03\u5C40\u3001\u7EC4\u4EF6\u548C\u6837\u5F0F",
1196
+ image: "\u63CF\u8FF0\u8FD9\u4E2A\u56FE\u7247\u7684\u5185\u5BB9\u548C\u8BBE\u8BA1\u5143\u7D20",
1197
+ api: "\u5206\u6790\u8FD9\u4E2AAPI\u7684\u7ED3\u6784\u548C\u53C2\u6570"
1198
+ };
1199
+ const prompt2 = `
1200
+ \u8BF7\u5206\u6790\u4EE5\u4E0B\u53C2\u8003\u8D44\u6E90\u7684 URL\uFF0C\u63D0\u53D6\u5BF9\u5F00\u53D1\u6709\u7528\u7684\u4FE1\u606F\uFF1A
1201
+
1202
+ URL: ${url}
1203
+ \u7C7B\u578B: ${type}
1204
+
1205
+ \u5185\u5BB9\u6458\u8981:
1206
+ ${content.slice(0, 5e3)}
1207
+
1208
+ ${typePrompts[type]}
1209
+
1210
+ \u8BF7\u63D0\u53D6\uFF1A
1211
+ 1. \u4E3B\u8981\u529F\u80FD\u70B9
1212
+ 2. UI\u7EC4\u4EF6\u7ED3\u6784
1213
+ 3. \u4EA4\u4E92\u65B9\u5F0F
1214
+ 4. \u6570\u636E\u7ED3\u6784\uFF08\u5982\u679C\u6709\uFF09
1215
+ 5. \u6280\u672F\u5B9E\u73B0\u5EFA\u8BAE
1216
+
1217
+ \u4EE5\u7B80\u6D01\u7684\u8981\u70B9\u5F62\u5F0F\u8F93\u51FA\u3002
1218
+ `;
1219
+ try {
1220
+ const response = await ctx.modelService.sendMessage([
1221
+ { role: "user", content: prompt2 }
1222
+ ], { temperature: 0.3, maxTokens: 2e3 });
1223
+ return response.content;
1224
+ } catch {
1225
+ return extractBasicInfo(content, type);
1226
+ }
1227
+ }
1228
+ function extractBasicInfo(content, type) {
1229
+ const titleMatch = content.match(/<title[^>]*>([^<]+)<\/title>/i);
1230
+ const descMatch = content.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']+)["']/i);
1231
+ const parts = [];
1232
+ if (titleMatch) {
1233
+ parts.push(`\u6807\u9898: ${titleMatch[1]}`);
1234
+ }
1235
+ if (descMatch) {
1236
+ parts.push(`\u63CF\u8FF0: ${descMatch[1]}`);
1237
+ }
1238
+ parts.push(`\u8D44\u6E90\u7C7B\u578B: ${type}`);
1239
+ return parts.join("\n");
1240
+ }
1027
1241
  function generateComplexityBar(score) {
1028
1242
  const filled = Math.round(score / 2);
1029
1243
  const empty = 5 - filled;
@@ -1033,6 +1247,7 @@ function getPhaseLabel(phase) {
1033
1247
  const labels = {
1034
1248
  context: "\u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6",
1035
1249
  clarify: "\u9700\u6C42\u6F84\u6E05",
1250
+ reference: "\u53C2\u8003\u8D44\u6E90\u5206\u6790",
1036
1251
  analysis: "\u590D\u6742\u5EA6\u8BC4\u4F30",
1037
1252
  bdd: "BDD \u573A\u666F\u62C6\u89E3",
1038
1253
  spec: "OpenSpec \u89C4\u683C",
@@ -7576,25 +7791,21 @@ ${chalk9.yellow("\u793A\u4F8B:")}
7576
7791
 
7577
7792
  // src/commands/model.ts
7578
7793
  init_esm_shims();
7579
-
7580
- // src/services/index.ts
7581
- init_esm_shims();
7582
-
7583
- // src/commands/model.ts
7584
7794
  async function handleModel(args, ctx) {
7585
7795
  const subCommand = args[0];
7586
7796
  const configManager = ctx.configManager;
7797
+ const modelService = ctx.modelService;
7587
7798
  switch (subCommand) {
7588
7799
  case "list":
7589
7800
  return listModels();
7590
7801
  case "current":
7591
7802
  return showCurrentModel(configManager);
7592
7803
  case "set":
7593
- return setModelDirectly(args[1], configManager);
7804
+ return setModelDirectly(args[1], configManager, modelService);
7594
7805
  case "verify":
7595
7806
  return verifyCurrentModel(configManager);
7596
7807
  default:
7597
- return selectModel(configManager);
7808
+ return selectModel(configManager, modelService);
7598
7809
  }
7599
7810
  }
7600
7811
  async function listModels() {
@@ -7635,7 +7846,7 @@ async function showCurrentModel(configManager) {
7635
7846
  ];
7636
7847
  return { output: lines.join("\n") };
7637
7848
  }
7638
- async function setModelDirectly(modelId, configManager) {
7849
+ async function setModelDirectly(modelId, configManager, modelService) {
7639
7850
  if (!modelId) {
7640
7851
  return {
7641
7852
  output: chalk9.red("\u8BF7\u6307\u5B9A\u6A21\u578BID\uFF0C\u4F8B\u5982: /model set gpt-4o")
@@ -7650,11 +7861,22 @@ async function setModelDirectly(modelId, configManager) {
7650
7861
  }
7651
7862
  configManager.set("model", modelId);
7652
7863
  await configManager.save();
7864
+ const apiKey = configManager.get("apiKey");
7865
+ if (apiKey) {
7866
+ try {
7867
+ await modelService.configureModel({
7868
+ provider: modelInfo.provider,
7869
+ model: modelId,
7870
+ apiKey
7871
+ });
7872
+ } catch {
7873
+ }
7874
+ }
7653
7875
  return {
7654
7876
  output: chalk9.green(`\u2713 \u5DF2\u5207\u6362\u5230\u6A21\u578B: ${modelInfo.name} (${modelInfo.provider})`)
7655
7877
  };
7656
7878
  }
7657
- async function verifyCurrentModel(configManager) {
7879
+ async function verifyCurrentModel(configManager, modelService) {
7658
7880
  const currentModel = configManager.get("model");
7659
7881
  const apiKey = configManager.get("apiKey");
7660
7882
  if (!apiKey) {
@@ -7687,7 +7909,7 @@ async function verifyCurrentModel(configManager) {
7687
7909
  };
7688
7910
  }
7689
7911
  }
7690
- async function selectModel(configManager) {
7912
+ async function selectModel(configManager, modelService) {
7691
7913
  try {
7692
7914
  const currentModel = configManager.get("model");
7693
7915
  const currentApiKey = configManager.get("apiKey");
@@ -7751,6 +7973,11 @@ async function selectModel(configManager) {
7751
7973
  configManager.set("model", modelResponse.model);
7752
7974
  configManager.set("apiKey", apiKeyResponse.apiKey);
7753
7975
  await configManager.save();
7976
+ await modelService.configureModel({
7977
+ provider: selectedModel.provider,
7978
+ model: modelResponse.model,
7979
+ apiKey: apiKeyResponse.apiKey
7980
+ });
7754
7981
  return {
7755
7982
  output: chalk9.green(`
7756
7983
  \u2713 \u6A21\u578B\u914D\u7F6E\u5B8C\u6210