@nick848/sf-cli 1.0.20 → 1.0.22
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/index.js +389 -122
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +387 -120
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +387 -120
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -129,7 +129,10 @@ async function executeWorkflow(ctx) {
|
|
|
129
129
|
if (activeSession.phase === "context") {
|
|
130
130
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/9: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
|
|
131
131
|
lines.push("");
|
|
132
|
+
const loader = new LoadingIndicator2("\u8BFB\u53D6\u9879\u76EE\u914D\u7F6E");
|
|
133
|
+
loader.start();
|
|
132
134
|
activeSession.context = await readProjectContext(ctx.options.workingDirectory);
|
|
135
|
+
loader.stop();
|
|
133
136
|
lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
|
|
134
137
|
lines.push(chalk9__default.default.gray(` \u7C7B\u578B: ${activeSession.context.type}`));
|
|
135
138
|
lines.push(chalk9__default.default.gray(` \u6846\u67B6: ${activeSession.context.framework || "\u672A\u8BC6\u522B"}`));
|
|
@@ -219,7 +222,7 @@ ${resource.analysis}`;
|
|
|
219
222
|
lines.push("");
|
|
220
223
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/9: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
|
|
221
224
|
lines.push("");
|
|
222
|
-
const loader = new
|
|
225
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u751F\u6210 BDD \u573A\u666F");
|
|
223
226
|
loader.start();
|
|
224
227
|
try {
|
|
225
228
|
activeSession.bddScenarios = await generateBDDScenariosWithAI(
|
|
@@ -254,7 +257,7 @@ ${resource.analysis}`;
|
|
|
254
257
|
lines.push("");
|
|
255
258
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
|
|
256
259
|
lines.push("");
|
|
257
|
-
const loader = new
|
|
260
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
258
261
|
loader.start();
|
|
259
262
|
try {
|
|
260
263
|
activeSession.specItems = await generateSpecItemsWithAI(
|
|
@@ -423,31 +426,85 @@ async function handleWorkflowInput(input, ctx) {
|
|
|
423
426
|
activeSession.phase = "analysis";
|
|
424
427
|
return executeWorkflow(ctx);
|
|
425
428
|
}
|
|
426
|
-
if (activeSession.phase === "spec") {
|
|
429
|
+
if (activeSession.phase === "spec" || activeSession.specFeedbackState === "waiting_confirm") {
|
|
427
430
|
if (trimmed === "y" || trimmed === "yes" || trimmed === "\u786E\u8BA4") {
|
|
431
|
+
activeSession.specFeedbackState = void 0;
|
|
428
432
|
activeSession.phase = "tdd";
|
|
429
433
|
return executeWorkflow(ctx);
|
|
430
434
|
}
|
|
431
|
-
if (trimmed === "n" || trimmed === "no" || trimmed === "\u91CD\u65B0") {
|
|
432
|
-
activeSession.
|
|
433
|
-
|
|
434
|
-
activeSession.
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
435
|
+
if (trimmed === "n" || trimmed === "no" || trimmed === "\u4E0D\u6EE1\u610F" || trimmed === "\u91CD\u65B0") {
|
|
436
|
+
activeSession.specFeedbackState = "collecting_feedback";
|
|
437
|
+
if (!activeSession.specFeedbacks) {
|
|
438
|
+
activeSession.specFeedbacks = [];
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
output: chalk9__default.default.yellow("\n\u{1F4DD} \u8BF7\u8F93\u5165\u60A8\u5BF9\u89C4\u683C\u4E0D\u6EE1\u610F\u7684\u5730\u65B9:") + chalk9__default.default.gray("\n - \u9057\u6F0F\u7684\u529F\u80FD\u70B9") + chalk9__default.default.gray("\n - \u4E0D\u5408\u7406\u7684\u62C6\u5206") + chalk9__default.default.gray("\n - \u9700\u8981\u8865\u5145\u7684\u7EC6\u8282") + chalk9__default.default.gray("\n - \u5176\u4ED6\u6539\u8FDB\u5EFA\u8BAE") + chalk9__default.default.cyan('\n\n\u8F93\u5165\u5B8C\u6210\u540E\uFF0C\u8F93\u5165\u7A7A\u884C\u6216 "done" \u7ED3\u675F\u8F93\u5165')
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (activeSession.specFeedbackState === "collecting_feedback") {
|
|
446
|
+
if (trimmed === "" || trimmed === "done" || trimmed === "\u5B8C\u6210") {
|
|
447
|
+
if (!activeSession.specFeedbacks || activeSession.specFeedbacks.length === 0) {
|
|
448
|
+
return {
|
|
449
|
+
output: chalk9__default.default.yellow('\u26A0\uFE0F \u8BF7\u81F3\u5C11\u8F93\u5165\u4E00\u6761\u53CD\u9988\u610F\u89C1\uFF0C\u6216\u8F93\u5165 "cancel" \u53D6\u6D88')
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
activeSession.specFeedbackState = "feedback_received";
|
|
453
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u6839\u636E\u53CD\u9988\u91CD\u65B0\u751F\u6210\u89C4\u683C");
|
|
454
|
+
loader.start();
|
|
455
|
+
try {
|
|
456
|
+
activeSession.specItems = await generateSpecItemsWithFeedback(
|
|
457
|
+
activeSession.refinedRequirement,
|
|
458
|
+
activeSession.context,
|
|
459
|
+
activeSession.bddScenarios,
|
|
460
|
+
activeSession.clarificationQuestions,
|
|
461
|
+
activeSession.referenceResources,
|
|
462
|
+
activeSession.specFeedbacks,
|
|
463
|
+
ctx
|
|
464
|
+
);
|
|
465
|
+
loader.stop(chalk9__default.default.green(" \u2713 \u89C4\u683C\u5DF2\u6839\u636E\u53CD\u9988\u91CD\u65B0\u751F\u6210"));
|
|
466
|
+
} catch (error) {
|
|
467
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u4F7F\u7528\u57FA\u7840\u65B9\u6CD5\u91CD\u65B0\u751F\u6210"));
|
|
468
|
+
activeSession.specItems = generateSpecItems(
|
|
469
|
+
activeSession.refinedRequirement,
|
|
470
|
+
activeSession.context,
|
|
471
|
+
activeSession.bddScenarios,
|
|
472
|
+
activeSession.clarificationQuestions,
|
|
473
|
+
activeSession.referenceResources
|
|
474
|
+
);
|
|
475
|
+
}
|
|
445
476
|
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
477
|
+
activeSession.specFeedbackState = "waiting_confirm";
|
|
478
|
+
const lines = [];
|
|
479
|
+
lines.push(chalk9__default.default.cyan("\n\u2501\u2501\u2501 \u66F4\u65B0\u540E\u7684\u4EFB\u52A1\u6982\u89C8 \u2501\u2501\u2501"));
|
|
480
|
+
for (const item of activeSession.specItems.slice(0, 8)) {
|
|
481
|
+
const icon = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
482
|
+
lines.push(chalk9__default.default.gray(` ${icon} [${item.id}] ${item.title}`));
|
|
483
|
+
}
|
|
484
|
+
if (activeSession.specItems.length > 8) {
|
|
485
|
+
lines.push(chalk9__default.default.gray(` ... \u5171 ${activeSession.specItems.length} \u4E2A\u4EFB\u52A1`));
|
|
486
|
+
}
|
|
446
487
|
return {
|
|
447
|
-
output:
|
|
448
|
-
|
|
488
|
+
output: lines.join("\n") + chalk9__default.default.green(`
|
|
489
|
+
|
|
490
|
+
\u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u66F4\u65B0`) + chalk9__default.default.gray(`
|
|
491
|
+
\u8DEF\u5F84: ${specPath}`) + chalk9__default.default.yellow("\n\n\u8BF7\u786E\u8BA4:") + chalk9__default.default.green("\n y - \u786E\u8BA4\u89C4\u683C") + chalk9__default.default.red("\n n - \u4ECD\u6709\u95EE\u9898\uFF0C\u7EE7\u7EED\u53CD\u9988")
|
|
449
492
|
};
|
|
450
493
|
}
|
|
494
|
+
if (trimmed === "cancel" || trimmed === "\u53D6\u6D88") {
|
|
495
|
+
activeSession.specFeedbackState = "waiting_confirm";
|
|
496
|
+
activeSession.specFeedbacks = [];
|
|
497
|
+
return {
|
|
498
|
+
output: chalk9__default.default.gray("\u5DF2\u53D6\u6D88\u53CD\u9988\uFF0C\u8FD4\u56DE\u89C4\u683C\u786E\u8BA4") + chalk9__default.default.yellow("\n\n\u8BF7\u786E\u8BA4:") + chalk9__default.default.green("\n y - \u786E\u8BA4\u89C4\u683C") + chalk9__default.default.red("\n n - \u4E0D\u6EE1\u610F\uFF0C\u91CD\u65B0\u751F\u6210")
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
if (!activeSession.specFeedbacks) {
|
|
502
|
+
activeSession.specFeedbacks = [];
|
|
503
|
+
}
|
|
504
|
+
activeSession.specFeedbacks.push(trimmed);
|
|
505
|
+
return {
|
|
506
|
+
output: chalk9__default.default.gray(`\u5DF2\u8BB0\u5F55\u53CD\u9988 #${activeSession.specFeedbacks.length}: `) + chalk9__default.default.white(trimmed.slice(0, 50)) + chalk9__default.default.gray('\n\u7EE7\u7EED\u8F93\u5165\uFF0C\u6216\u8F93\u5165 "done" \u5B8C\u6210\u53CD\u9988')
|
|
507
|
+
};
|
|
451
508
|
}
|
|
452
509
|
if (activeSession.phase === "develop") {
|
|
453
510
|
if (trimmed === "continue" || trimmed === "\u7EE7\u7EED" || trimmed === "done" || trimmed === "\u5B8C\u6210") {
|
|
@@ -599,107 +656,115 @@ function getCategoryLabel(category) {
|
|
|
599
656
|
async function executeDevelopment(ctx, session) {
|
|
600
657
|
const workingDir = ctx.options.workingDirectory;
|
|
601
658
|
const files = [];
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
659
|
+
console.log("");
|
|
660
|
+
for (let i = 0; i < session.specItems.length; i++) {
|
|
661
|
+
const item = session.specItems[i];
|
|
662
|
+
const prefix = `[${i + 1}/${session.specItems.length}]`;
|
|
663
|
+
if (item.title.includes("\u6D4B\u8BD5") || item.title.includes("test")) {
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
const loader = new LoadingIndicator2(`${prefix} \u751F\u6210: ${item.title.slice(0, 20)}...`);
|
|
667
|
+
loader.start();
|
|
668
|
+
try {
|
|
669
|
+
const taskPrompt = buildTaskPrompt(session, item, i);
|
|
670
|
+
const messages = [
|
|
671
|
+
{
|
|
672
|
+
role: "system",
|
|
673
|
+
content: `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u524D\u7AEF\u5F00\u53D1\u5DE5\u7A0B\u5E08\u3002\u8BF7\u6839\u636E\u4EFB\u52A1\u63CF\u8FF0\u751F\u6210\u4EE3\u7801\u5B9E\u73B0\u3002
|
|
610
674
|
|
|
611
675
|
\u26A0\uFE0F \u91CD\u8981\u89C4\u5219\uFF1A
|
|
612
|
-
1. \
|
|
613
|
-
2. \
|
|
614
|
-
3. \
|
|
615
|
-
|
|
616
|
-
\u4EE3\u7801\u8981\u6C42\uFF1A
|
|
617
|
-
1. \u751F\u6210\u5B8C\u6574\u3001\u53EF\u8FD0\u884C\u7684\u4EE3\u7801
|
|
618
|
-
2. \u9075\u5FAA\u9879\u76EE\u73B0\u6709\u7684\u4EE3\u7801\u98CE\u683C\u548C\u89C4\u8303
|
|
619
|
-
3. \u4F7F\u7528\u9879\u76EE\u6307\u5B9A\u7684\u6280\u672F\u6808
|
|
620
|
-
4. \u4EE3\u7801\u8981\u6709\u9002\u5F53\u7684\u6CE8\u91CA
|
|
621
|
-
5. \u8FD4\u56DE\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u6587\u4EF6\u7528 \`\`\`filename \u4EE3\u7801 \`\`\` \u5305\u88F9
|
|
676
|
+
1. \u53EA\u751F\u6210\u5F53\u524D\u4EFB\u52A1\u76F8\u5173\u7684\u4EE3\u7801\uFF0C\u4E0D\u8981\u751F\u6210\u5176\u4ED6\u4EFB\u52A1\u7684\u4EE3\u7801
|
|
677
|
+
2. \u6280\u672F\u5B9E\u73B0\u5FC5\u987B\u4E25\u683C\u9075\u5FAA\u9879\u76EE\u73B0\u6709\u7684\u5F00\u53D1\u89C4\u8303
|
|
678
|
+
3. \u751F\u6210\u5B8C\u6574\u3001\u53EF\u8FD0\u884C\u7684\u4EE3\u7801
|
|
679
|
+
4. \u8FD4\u56DE\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u6587\u4EF6\u7528 \`\`\`filename \u4EE3\u7801 \`\`\` \u5305\u88F9
|
|
622
680
|
|
|
623
681
|
\u9879\u76EE\u4FE1\u606F\uFF1A
|
|
624
682
|
- \u540D\u79F0: ${session.context?.name}
|
|
625
683
|
- \u6846\u67B6: ${session.context?.framework || "\u672A\u6307\u5B9A"}
|
|
626
684
|
- \u6280\u672F\u6808: ${session.context?.techStack.join(", ") || "\u672A\u6307\u5B9A"}
|
|
627
685
|
|
|
628
|
-
${session.context?.devStandards ? `\u3010\
|
|
629
|
-
${session.context.devStandards.slice(0,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
686
|
+
${session.context?.devStandards ? `\u3010\u5F00\u53D1\u89C4\u8303\u3011
|
|
687
|
+
${session.context.devStandards.slice(0, 2e3)}` : ""}`
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
role: "user",
|
|
691
|
+
content: taskPrompt
|
|
692
|
+
}
|
|
693
|
+
];
|
|
694
|
+
const response = await ctx.modelService.sendMessage(messages, {
|
|
695
|
+
temperature: 0.3,
|
|
696
|
+
maxTokens: 4e3,
|
|
697
|
+
// 单个任务减少 token
|
|
698
|
+
agent: "frontend-dev",
|
|
699
|
+
timeout: 3e5
|
|
700
|
+
// 5分钟超时,确保复杂代码有足够时间
|
|
701
|
+
});
|
|
702
|
+
const codeBlocks = parseCodeBlocks(response.content);
|
|
703
|
+
if (codeBlocks.length > 0) {
|
|
704
|
+
for (const block of codeBlocks) {
|
|
705
|
+
const filePath = path4__namespace.join(workingDir, block.filename);
|
|
706
|
+
const dir = path4__namespace.dirname(filePath);
|
|
707
|
+
await fs4__namespace.mkdir(dir, { recursive: true });
|
|
708
|
+
await fs4__namespace.writeFile(filePath, block.code, "utf-8");
|
|
709
|
+
files.push(block.filename);
|
|
710
|
+
}
|
|
711
|
+
loader.stop(chalk9__default.default.green(`${prefix} \u2713 ${item.title.slice(0, 25)} (${codeBlocks.length} \u4E2A\u6587\u4EF6)`));
|
|
712
|
+
} else {
|
|
713
|
+
const implDir = path4__namespace.join(workingDir, "src");
|
|
714
|
+
await fs4__namespace.mkdir(implDir, { recursive: true });
|
|
715
|
+
const fileName = `${item.title.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_")}.ts`;
|
|
716
|
+
const filePath = path4__namespace.join(implDir, fileName);
|
|
717
|
+
await fs4__namespace.writeFile(filePath, `// TODO: ${item.title}
|
|
718
|
+
// ${item.description}
|
|
719
|
+
`, "utf-8");
|
|
720
|
+
files.push(`src/${fileName}`);
|
|
721
|
+
loader.stop(chalk9__default.default.yellow(`${prefix} \u26A0 \u751F\u6210\u57FA\u7840\u6A21\u677F: ${item.title.slice(0, 20)}`));
|
|
722
|
+
}
|
|
723
|
+
if (i < session.specItems.length - 1) {
|
|
724
|
+
await new Promise((resolve4) => setTimeout(resolve4, 500));
|
|
634
725
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
const response = await ctx.modelService.sendMessage(messages, {
|
|
638
|
-
temperature: 0.3,
|
|
639
|
-
maxTokens: 8e3,
|
|
640
|
-
agent: "frontend-dev",
|
|
641
|
-
timeout: 18e4
|
|
642
|
-
// 3 分钟超时
|
|
643
|
-
});
|
|
644
|
-
loader.update("\u6B63\u5728\u89E3\u6790\u4EE3\u7801");
|
|
645
|
-
const codeBlocks = parseCodeBlocks(response.content);
|
|
646
|
-
for (const block of codeBlocks) {
|
|
647
|
-
const filePath = path4__namespace.join(workingDir, block.filename);
|
|
648
|
-
const dir = path4__namespace.dirname(filePath);
|
|
649
|
-
await fs4__namespace.mkdir(dir, { recursive: true });
|
|
650
|
-
await fs4__namespace.writeFile(filePath, block.code, "utf-8");
|
|
651
|
-
files.push(block.filename);
|
|
652
|
-
}
|
|
653
|
-
if (files.length === 0) {
|
|
654
|
-
const implDir = path4__namespace.join(workingDir, "src", "features");
|
|
655
|
-
await fs4__namespace.mkdir(implDir, { recursive: true });
|
|
656
|
-
const featureName = session.specItems[0]?.title || "feature";
|
|
657
|
-
const fileName = `${featureName.replace(/[^a-zA-Z0-9]/g, "_")}.ts`;
|
|
658
|
-
const filePath = path4__namespace.join(implDir, fileName);
|
|
659
|
-
const stubCode = `/**
|
|
660
|
-
* ${session.requirement}
|
|
661
|
-
*
|
|
662
|
-
* TODO: \u6B64\u6587\u4EF6\u7531 AI \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u6839\u636E\u9700\u6C42\u5B8C\u5584\u5B9E\u73B0
|
|
663
|
-
*/
|
|
664
|
-
|
|
665
|
-
export function ${featureName.replace(/[^a-zA-Z0-9]/g, "")}() {
|
|
666
|
-
// TODO: \u5B9E\u73B0\u529F\u80FD
|
|
667
|
-
console.log('${featureName} - \u5F85\u5B9E\u73B0');
|
|
668
|
-
}
|
|
669
|
-
`;
|
|
670
|
-
await fs4__namespace.writeFile(filePath, stubCode, "utf-8");
|
|
671
|
-
files.push(`src/features/${fileName}`);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
loader.stop(chalk9__default.default.red(`${prefix} \u2717 \u5931\u8D25: ${error.message.slice(0, 40)}`));
|
|
672
728
|
}
|
|
673
|
-
|
|
729
|
+
}
|
|
730
|
+
if (files.length > 0) {
|
|
674
731
|
return { success: true, files };
|
|
675
|
-
}
|
|
676
|
-
loader.stop();
|
|
732
|
+
} else {
|
|
677
733
|
return {
|
|
678
734
|
success: false,
|
|
679
735
|
files: [],
|
|
680
|
-
error:
|
|
736
|
+
error: "\u6240\u6709\u4EFB\u52A1\u4EE3\u7801\u751F\u6210\u5931\u8D25"
|
|
681
737
|
};
|
|
682
738
|
}
|
|
683
739
|
}
|
|
684
|
-
function
|
|
740
|
+
function buildTaskPrompt(session, item, index) {
|
|
685
741
|
const lines = [];
|
|
686
|
-
lines.push(
|
|
687
|
-
lines.push(
|
|
688
|
-
lines.push(
|
|
689
|
-
lines.push(
|
|
690
|
-
|
|
691
|
-
lines.push(
|
|
692
|
-
for (const
|
|
693
|
-
lines.push(`- ${
|
|
742
|
+
lines.push(`## \u5F53\u524D\u4EFB\u52A1 (#${index + 1})`);
|
|
743
|
+
lines.push(`**\u6807\u9898**: ${item.title}`);
|
|
744
|
+
lines.push(`**\u63CF\u8FF0**: ${item.description}`);
|
|
745
|
+
lines.push(`**\u4F18\u5148\u7EA7**: ${item.priority}`);
|
|
746
|
+
if (item.tests && item.tests.length > 0) {
|
|
747
|
+
lines.push(`**\u9A8C\u6536\u6807\u51C6**:`);
|
|
748
|
+
for (const t of item.tests) {
|
|
749
|
+
lines.push(`- ${t}`);
|
|
694
750
|
}
|
|
695
751
|
}
|
|
696
752
|
lines.push("");
|
|
697
|
-
lines.push(
|
|
698
|
-
|
|
699
|
-
|
|
753
|
+
lines.push(`## \u6574\u4F53\u9700\u6C42\u80CC\u666F`);
|
|
754
|
+
lines.push(session.requirement);
|
|
755
|
+
const relatedScenario = session.bddScenarios.find(
|
|
756
|
+
(s) => item.title.includes(s.feature) || s.feature.includes(item.title)
|
|
757
|
+
);
|
|
758
|
+
if (relatedScenario) {
|
|
759
|
+
lines.push("");
|
|
760
|
+
lines.push(`## \u76F8\u5173 BDD \u573A\u666F`);
|
|
761
|
+
lines.push(`Feature: ${relatedScenario.feature}`);
|
|
762
|
+
for (const s of relatedScenario.scenarios.slice(0, 2)) {
|
|
763
|
+
lines.push(`- ${s.name}`);
|
|
764
|
+
}
|
|
700
765
|
}
|
|
701
766
|
lines.push("");
|
|
702
|
-
lines.push("\u8BF7\
|
|
767
|
+
lines.push("\u8BF7\u751F\u6210\u5B9E\u73B0\u6B64\u4EFB\u52A1\u7684\u4EE3\u7801\u3002\u53EA\u751F\u6210\u5F53\u524D\u4EFB\u52A1\u9700\u8981\u7684\u6587\u4EF6\u3002");
|
|
703
768
|
return lines.join("\n");
|
|
704
769
|
}
|
|
705
770
|
function parseCodeBlocks(content) {
|
|
@@ -720,6 +785,8 @@ async function executeReview(ctx, session) {
|
|
|
720
785
|
const workingDir = ctx.options.workingDirectory;
|
|
721
786
|
const issues = [];
|
|
722
787
|
const suggestions = [];
|
|
788
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u5BA1\u6838\u4EE3\u7801");
|
|
789
|
+
loader.start();
|
|
723
790
|
try {
|
|
724
791
|
const codeContents = [];
|
|
725
792
|
for (const file of session.implFiles) {
|
|
@@ -782,7 +849,9 @@ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
|
|
|
782
849
|
const response = await ctx.modelService.sendMessage(messages, {
|
|
783
850
|
temperature: 0.2,
|
|
784
851
|
maxTokens: 2e3,
|
|
785
|
-
agent: "code-reviewer"
|
|
852
|
+
agent: "code-reviewer",
|
|
853
|
+
timeout: 18e4
|
|
854
|
+
// 3分钟超时
|
|
786
855
|
});
|
|
787
856
|
const result = response.content;
|
|
788
857
|
const passed = result.includes("\u5BA1\u6838\u901A\u8FC7") || result.includes("\u901A\u8FC7") || !result.includes("\u4E0D\u901A\u8FC7");
|
|
@@ -804,8 +873,10 @@ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
|
|
|
804
873
|
const lines = result.split("\n").filter((l) => l.includes("\u5EFA\u8BAE") || l.includes("\u6539\u8FDB") || l.includes("\u4F18\u5316"));
|
|
805
874
|
suggestions.push(...lines.map((l) => l.replace(/^[-*]\s*/, "").trim()).filter((l) => l));
|
|
806
875
|
}
|
|
876
|
+
loader.stop(passed ? chalk9__default.default.green(" \u2713 \u5BA1\u6838\u901A\u8FC7") : chalk9__default.default.yellow(" \u26A0 \u53D1\u73B0\u95EE\u9898"));
|
|
807
877
|
return { passed, issues, suggestions };
|
|
808
878
|
} catch (error) {
|
|
879
|
+
loader.stop(chalk9__default.default.red(" \u2717 \u5BA1\u6838\u51FA\u9519"));
|
|
809
880
|
suggestions.push(`\u5BA1\u6838\u8FC7\u7A0B\u51FA\u9519: ${error.message}`);
|
|
810
881
|
return { passed: true, issues, suggestions };
|
|
811
882
|
}
|
|
@@ -1011,7 +1082,8 @@ ${r.analysis}`).join("\n\n") : "\u65E0"}
|
|
|
1011
1082
|
], {
|
|
1012
1083
|
temperature: 0.3,
|
|
1013
1084
|
maxTokens: 4e3,
|
|
1014
|
-
timeout:
|
|
1085
|
+
timeout: 3e5
|
|
1086
|
+
// 5分钟超时
|
|
1015
1087
|
});
|
|
1016
1088
|
try {
|
|
1017
1089
|
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
@@ -1219,7 +1291,7 @@ ${questions.filter((q) => q.answered).map((q) => `- ${q.question}: ${q.answer}`)
|
|
|
1219
1291
|
- \u96C6\u6210\u6D4B\u8BD5
|
|
1220
1292
|
|
|
1221
1293
|
\u8BF7\u76F4\u63A5\u8F93\u51FA JSON \u6570\u7EC4\u3002`;
|
|
1222
|
-
const loader = new
|
|
1294
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
1223
1295
|
loader.start();
|
|
1224
1296
|
try {
|
|
1225
1297
|
const response = await ctx.modelService.sendMessage([
|
|
@@ -1227,25 +1299,131 @@ ${questions.filter((q) => q.answered).map((q) => `- ${q.question}: ${q.answer}`)
|
|
|
1227
1299
|
], {
|
|
1228
1300
|
temperature: 0.3,
|
|
1229
1301
|
maxTokens: 4e3,
|
|
1230
|
-
timeout:
|
|
1302
|
+
timeout: 3e5
|
|
1303
|
+
// 5分钟超时
|
|
1231
1304
|
});
|
|
1232
1305
|
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
1233
1306
|
if (jsonMatch) {
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1307
|
+
try {
|
|
1308
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
1309
|
+
loader.stop(chalk9__default.default.green(` \u2713 \u5DF2\u62C6\u5206 ${parsed.length} \u4E2A\u4EFB\u52A1`));
|
|
1310
|
+
return parsed.map((item, index) => ({
|
|
1311
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
1312
|
+
title: item.title,
|
|
1313
|
+
description: item.description,
|
|
1314
|
+
priority: item.priority || "medium",
|
|
1315
|
+
files: [],
|
|
1316
|
+
tests: item.acceptanceCriteria || []
|
|
1317
|
+
}));
|
|
1318
|
+
} catch (parseError) {
|
|
1319
|
+
loader.stop(chalk9__default.default.yellow(` \u26A0 JSON \u89E3\u6790\u5931\u8D25: ${parseError.message.slice(0, 50)}`));
|
|
1320
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1321
|
+
}
|
|
1244
1322
|
}
|
|
1245
|
-
|
|
1323
|
+
try {
|
|
1324
|
+
const parsed = JSON.parse(response.content);
|
|
1325
|
+
if (Array.isArray(parsed)) {
|
|
1326
|
+
loader.stop(chalk9__default.default.green(` \u2713 \u5DF2\u62C6\u5206 ${parsed.length} \u4E2A\u4EFB\u52A1`));
|
|
1327
|
+
return parsed.map((item, index) => ({
|
|
1328
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
1329
|
+
title: item.title,
|
|
1330
|
+
description: item.description,
|
|
1331
|
+
priority: item.priority || "medium",
|
|
1332
|
+
files: [],
|
|
1333
|
+
tests: item.acceptanceCriteria || []
|
|
1334
|
+
}));
|
|
1335
|
+
}
|
|
1336
|
+
} catch {
|
|
1337
|
+
}
|
|
1338
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u672A\u80FD\u89E3\u6790 AI \u54CD\u5E94\uFF0C\u4F7F\u7528\u57FA\u7840\u62C6\u5206"));
|
|
1246
1339
|
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1247
1340
|
} catch (error) {
|
|
1248
|
-
|
|
1341
|
+
const errMsg = error.message.slice(0, 80);
|
|
1342
|
+
loader.stop(chalk9__default.default.yellow(` \u26A0 AI \u8C03\u7528\u5931\u8D25: ${errMsg}`));
|
|
1343
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
async function generateSpecItemsWithFeedback(requirement, context, bddScenarios, questions, references, feedbacks, ctx) {
|
|
1347
|
+
const prompt2 = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u9879\u76EE\u7ECF\u7406\u548C\u6280\u672F\u67B6\u6784\u5E08\u3002\u8BF7\u6839\u636E\u7528\u6237\u53CD\u9988\uFF0C\u91CD\u65B0\u62C6\u5206\u9700\u6C42\u4EFB\u52A1\u3002
|
|
1348
|
+
|
|
1349
|
+
## \u9700\u6C42\u63CF\u8FF0
|
|
1350
|
+
${requirement}
|
|
1351
|
+
|
|
1352
|
+
## \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
1353
|
+
- \u6280\u672F\u6808: ${context.techStack?.join(", ") || "TypeScript"}
|
|
1354
|
+
- \u6846\u67B6: ${context.framework || "\u672A\u6307\u5B9A"}
|
|
1355
|
+
${context.devStandards ? `
|
|
1356
|
+
## \u5F00\u53D1\u89C4\u8303\uFF08\u5FC5\u987B\u9075\u5FAA\uFF09
|
|
1357
|
+
${context.devStandards.slice(0, 2e3)}
|
|
1358
|
+
` : ""}
|
|
1359
|
+
|
|
1360
|
+
## \u4E4B\u524D\u7684 BDD \u573A\u666F
|
|
1361
|
+
${bddScenarios.map((s) => `- Feature: ${s.feature}`).join("\n")}
|
|
1362
|
+
|
|
1363
|
+
## \u7528\u6237\u53CD\u9988\uFF08\u5FC5\u987B\u89E3\u51B3\u8FD9\u4E9B\u95EE\u9898\uFF09
|
|
1364
|
+
${feedbacks.map((f, i) => `${i + 1}. ${f}`).join("\n")}
|
|
1365
|
+
|
|
1366
|
+
## \u8981\u6C42
|
|
1367
|
+
1. **\u5FC5\u987B\u89E3\u51B3\u7528\u6237\u53CD\u9988\u4E2D\u7684\u6240\u6709\u95EE\u9898**
|
|
1368
|
+
2. \u5982\u679C\u7528\u6237\u6307\u51FA\u9057\u6F0F\u7684\u529F\u80FD\u70B9\uFF0C\u8BF7\u8865\u5145\u76F8\u5173\u4EFB\u52A1
|
|
1369
|
+
3. \u5982\u679C\u7528\u6237\u6307\u51FA\u62C6\u5206\u4E0D\u5408\u7406\uFF0C\u8BF7\u91CD\u65B0\u8C03\u6574\u7C92\u5EA6
|
|
1370
|
+
4. \u5982\u679C\u7528\u6237\u9700\u8981\u66F4\u591A\u7EC6\u8282\uFF0C\u8BF7\u62C6\u5206\u5F97\u66F4\u7EC6\u81F4
|
|
1371
|
+
5. \u6BCF\u4E2A\u4EFB\u52A1\u5E94\u8BE5\u5355\u4E00\u804C\u8D23\u30012-4\u5C0F\u65F6\u53EF\u5B8C\u6210
|
|
1372
|
+
|
|
1373
|
+
## \u8F93\u51FA\u683C\u5F0F (JSON)
|
|
1374
|
+
\`\`\`json
|
|
1375
|
+
[
|
|
1376
|
+
{
|
|
1377
|
+
"id": "T001",
|
|
1378
|
+
"title": "\u4EFB\u52A1\u6807\u9898\uFF08\u7B80\u77ED\u660E\u786E\uFF09",
|
|
1379
|
+
"description": "\u8BE6\u7EC6\u63CF\u8FF0",
|
|
1380
|
+
"priority": "high",
|
|
1381
|
+
"acceptanceCriteria": ["\u9A8C\u6536\u6807\u51C61", "\u9A8C\u6536\u6807\u51C62"]
|
|
1382
|
+
}
|
|
1383
|
+
]
|
|
1384
|
+
\`\`\`
|
|
1385
|
+
|
|
1386
|
+
\u8BF7\u76F4\u63A5\u8F93\u51FA JSON \u6570\u7EC4\uFF0C\u786E\u4FDD\u89E3\u51B3\u4E86\u7528\u6237\u7684\u6240\u6709\u53CD\u9988\u3002`;
|
|
1387
|
+
try {
|
|
1388
|
+
const response = await ctx.modelService.sendMessage([
|
|
1389
|
+
{ role: "user", content: prompt2 }
|
|
1390
|
+
], {
|
|
1391
|
+
temperature: 0.3,
|
|
1392
|
+
maxTokens: 4e3,
|
|
1393
|
+
timeout: 3e5
|
|
1394
|
+
// 5分钟超时
|
|
1395
|
+
});
|
|
1396
|
+
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
1397
|
+
if (jsonMatch) {
|
|
1398
|
+
try {
|
|
1399
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
1400
|
+
return parsed.map((item, index) => ({
|
|
1401
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
1402
|
+
title: item.title,
|
|
1403
|
+
description: item.description,
|
|
1404
|
+
priority: item.priority || "medium",
|
|
1405
|
+
files: [],
|
|
1406
|
+
tests: item.acceptanceCriteria || []
|
|
1407
|
+
}));
|
|
1408
|
+
} catch {
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
try {
|
|
1412
|
+
const parsed = JSON.parse(response.content);
|
|
1413
|
+
if (Array.isArray(parsed)) {
|
|
1414
|
+
return parsed.map((item, index) => ({
|
|
1415
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
1416
|
+
title: item.title,
|
|
1417
|
+
description: item.description,
|
|
1418
|
+
priority: item.priority || "medium",
|
|
1419
|
+
files: [],
|
|
1420
|
+
tests: item.acceptanceCriteria || []
|
|
1421
|
+
}));
|
|
1422
|
+
}
|
|
1423
|
+
} catch {
|
|
1424
|
+
}
|
|
1425
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1426
|
+
} catch {
|
|
1249
1427
|
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1250
1428
|
}
|
|
1251
1429
|
}
|
|
@@ -1315,6 +1493,16 @@ function formatSpecFile(session) {
|
|
|
1315
1493
|
lines.push("");
|
|
1316
1494
|
}
|
|
1317
1495
|
}
|
|
1496
|
+
if (session.specFeedbacks && session.specFeedbacks.length > 0) {
|
|
1497
|
+
lines.push("## \u89C4\u683C\u8FED\u4EE3\u53CD\u9988");
|
|
1498
|
+
lines.push("");
|
|
1499
|
+
for (let i = 0; i < session.specFeedbacks.length; i++) {
|
|
1500
|
+
lines.push(`${i + 1}. ${session.specFeedbacks[i]}`);
|
|
1501
|
+
}
|
|
1502
|
+
lines.push("");
|
|
1503
|
+
lines.push("---");
|
|
1504
|
+
lines.push("");
|
|
1505
|
+
}
|
|
1318
1506
|
lines.push("## \u4EFB\u52A1\u5217\u8868");
|
|
1319
1507
|
lines.push("");
|
|
1320
1508
|
for (const item of session.specItems) {
|
|
@@ -1335,7 +1523,7 @@ async function generateTests(workingDir, session, ctx) {
|
|
|
1335
1523
|
for (const scenario of session.bddScenarios) {
|
|
1336
1524
|
const testName = scenario.feature.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_");
|
|
1337
1525
|
const testPath = path4__namespace.join(testDir, `${testName}.test.ts`);
|
|
1338
|
-
const loader = new
|
|
1526
|
+
const loader = new LoadingIndicator2(`\u751F\u6210\u6D4B\u8BD5: ${scenario.feature.slice(0, 20)}...`);
|
|
1339
1527
|
loader.start();
|
|
1340
1528
|
try {
|
|
1341
1529
|
const content = await generateTestFileWithAI(scenario, session, ctx);
|
|
@@ -1390,7 +1578,9 @@ ${scenario.scenarios.map((s) => `
|
|
|
1390
1578
|
{ role: "user", content: prompt2 }
|
|
1391
1579
|
], {
|
|
1392
1580
|
temperature: 0.3,
|
|
1393
|
-
maxTokens: 4e3
|
|
1581
|
+
maxTokens: 4e3,
|
|
1582
|
+
timeout: 18e4
|
|
1583
|
+
// 3分钟超时
|
|
1394
1584
|
});
|
|
1395
1585
|
const codeMatch = response.content.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);
|
|
1396
1586
|
if (codeMatch) {
|
|
@@ -1489,7 +1679,10 @@ async function fetchAndAnalyzeReference(url, ctx, projectContext) {
|
|
|
1489
1679
|
const type = detectResourceType(url);
|
|
1490
1680
|
let content = "";
|
|
1491
1681
|
let analysis = "";
|
|
1682
|
+
const loader = new LoadingIndicator2(`\u83B7\u53D6 ${url.slice(0, 40)}...`);
|
|
1683
|
+
loader.start();
|
|
1492
1684
|
try {
|
|
1685
|
+
loader.update("\u6B63\u5728\u83B7\u53D6\u7F51\u9875\u5185\u5BB9");
|
|
1493
1686
|
const response = await fetch(url, {
|
|
1494
1687
|
headers: {
|
|
1495
1688
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
@@ -1500,11 +1693,14 @@ async function fetchAndAnalyzeReference(url, ctx, projectContext) {
|
|
|
1500
1693
|
}
|
|
1501
1694
|
content = await response.text();
|
|
1502
1695
|
if (ctx.modelService.getCurrentModel()) {
|
|
1696
|
+
loader.update("\u6B63\u5728\u5206\u6790\u5185\u5BB9");
|
|
1503
1697
|
analysis = await analyzeReferenceContent(url, content, type, ctx, projectContext);
|
|
1504
1698
|
} else {
|
|
1505
1699
|
analysis = extractBasicInfo(content, type);
|
|
1506
1700
|
}
|
|
1701
|
+
loader.stop();
|
|
1507
1702
|
} catch (error) {
|
|
1703
|
+
loader.stop();
|
|
1508
1704
|
throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u53C2\u8003\u8D44\u6E90: ${error.message}`);
|
|
1509
1705
|
}
|
|
1510
1706
|
return { url, type, content: content.slice(0, 1e4), analysis };
|
|
@@ -1573,14 +1769,16 @@ ${content.slice(0, 8e3)}
|
|
|
1573
1769
|
\u6CE8\u610F\uFF1A\u8BF7\u4EE5 Markdown \u683C\u5F0F\u8F93\u51FA\uFF0C\u91CD\u70B9\u7A81\u51FA**\u4E1A\u52A1\u903B\u8F91**\u548C**\u529F\u80FD\u7279\u6027**\u3002
|
|
1574
1770
|
\u6280\u672F\u5B9E\u73B0\u65B9\u6848\u7531\u9879\u76EE\u89C4\u8303\u51B3\u5B9A\uFF0C\u6B64\u5904\u4E0D\u6D89\u53CA\u3002
|
|
1575
1771
|
`;
|
|
1576
|
-
const loader = new
|
|
1772
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u5206\u6790\u53C2\u8003\u8D44\u6E90");
|
|
1577
1773
|
loader.start();
|
|
1578
1774
|
try {
|
|
1579
1775
|
const response = await ctx.modelService.sendMessage([
|
|
1580
1776
|
{ role: "user", content: prompt2 }
|
|
1581
1777
|
], {
|
|
1582
1778
|
temperature: 0.3,
|
|
1583
|
-
maxTokens: 4e3
|
|
1779
|
+
maxTokens: 4e3,
|
|
1780
|
+
timeout: 18e4
|
|
1781
|
+
// 3分钟超时
|
|
1584
1782
|
});
|
|
1585
1783
|
loader.stop(chalk9__default.default.green(" \u2713 \u5206\u6790\u5B8C\u6210"));
|
|
1586
1784
|
return response.content;
|
|
@@ -1627,11 +1825,11 @@ function getActiveSession() {
|
|
|
1627
1825
|
function clearActiveSession() {
|
|
1628
1826
|
activeSession = null;
|
|
1629
1827
|
}
|
|
1630
|
-
var
|
|
1828
|
+
var LoadingIndicator2, MAX_FILE_SIZE2, COMPLEXITY_THRESHOLD, CLARITY_THRESHOLD, activeSession, new_default;
|
|
1631
1829
|
var init_new = __esm({
|
|
1632
1830
|
"src/commands/new.ts"() {
|
|
1633
1831
|
init_cjs_shims();
|
|
1634
|
-
|
|
1832
|
+
LoadingIndicator2 = class {
|
|
1635
1833
|
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1636
1834
|
frameIndex = 0;
|
|
1637
1835
|
interval = null;
|
|
@@ -1996,9 +2194,10 @@ var BaseAdapter = class {
|
|
|
1996
2194
|
}
|
|
1997
2195
|
/**
|
|
1998
2196
|
* 获取超时时间
|
|
2197
|
+
* 默认 5 分钟,对于复杂的代码生成任务足够
|
|
1999
2198
|
*/
|
|
2000
2199
|
getTimeout() {
|
|
2001
|
-
return this.config?.timeout ||
|
|
2200
|
+
return this.config?.timeout || 3e5;
|
|
2002
2201
|
}
|
|
2003
2202
|
/**
|
|
2004
2203
|
* 获取重试次数
|
|
@@ -8188,6 +8387,36 @@ ${chalk9__default.default.yellow("\u793A\u4F8B:")}
|
|
|
8188
8387
|
|
|
8189
8388
|
// src/commands/model.ts
|
|
8190
8389
|
init_cjs_shims();
|
|
8390
|
+
var LoadingIndicator = class {
|
|
8391
|
+
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8392
|
+
frameIndex = 0;
|
|
8393
|
+
interval = null;
|
|
8394
|
+
message;
|
|
8395
|
+
constructor(message) {
|
|
8396
|
+
this.message = message;
|
|
8397
|
+
}
|
|
8398
|
+
start() {
|
|
8399
|
+
process.stdout.write("\x1B[?25l");
|
|
8400
|
+
this.interval = setInterval(() => {
|
|
8401
|
+
const frame = this.frames[this.frameIndex];
|
|
8402
|
+
process.stdout.write(`\r${chalk9__default.default.cyan(frame)} ${this.message}...`);
|
|
8403
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
8404
|
+
}, 80);
|
|
8405
|
+
}
|
|
8406
|
+
stop(finalMessage) {
|
|
8407
|
+
if (this.interval) {
|
|
8408
|
+
clearInterval(this.interval);
|
|
8409
|
+
this.interval = null;
|
|
8410
|
+
}
|
|
8411
|
+
process.stdout.write("\x1B[?25h");
|
|
8412
|
+
if (finalMessage) {
|
|
8413
|
+
process.stdout.write(`\r${finalMessage}
|
|
8414
|
+
`);
|
|
8415
|
+
} else {
|
|
8416
|
+
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
8417
|
+
}
|
|
8418
|
+
}
|
|
8419
|
+
};
|
|
8191
8420
|
async function handleModel(args, ctx) {
|
|
8192
8421
|
const subCommand = args[0];
|
|
8193
8422
|
const configManager = ctx.configManager;
|
|
@@ -8287,9 +8516,12 @@ async function verifyCurrentModel(configManager, modelService) {
|
|
|
8287
8516
|
output: chalk9__default.default.red(`\u2717 \u672A\u77E5\u6A21\u578B: ${currentModel}`)
|
|
8288
8517
|
};
|
|
8289
8518
|
}
|
|
8519
|
+
const loader = new LoadingIndicator(`\u9A8C\u8BC1 ${modelInfo.name} API Key`);
|
|
8520
|
+
loader.start();
|
|
8290
8521
|
try {
|
|
8291
8522
|
const adapter = createAdapter(modelInfo.provider);
|
|
8292
8523
|
const isValid = await adapter.validateApiKey(apiKey);
|
|
8524
|
+
loader.stop();
|
|
8293
8525
|
if (isValid) {
|
|
8294
8526
|
return {
|
|
8295
8527
|
output: chalk9__default.default.green(`\u2713 API Key \u9A8C\u8BC1\u6210\u529F
|
|
@@ -8301,6 +8533,7 @@ async function verifyCurrentModel(configManager, modelService) {
|
|
|
8301
8533
|
};
|
|
8302
8534
|
}
|
|
8303
8535
|
} catch (error) {
|
|
8536
|
+
loader.stop();
|
|
8304
8537
|
return {
|
|
8305
8538
|
output: chalk9__default.default.red(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${error.message}`)
|
|
8306
8539
|
};
|
|
@@ -9512,6 +9745,36 @@ async function executeShell(command, ctx) {
|
|
|
9512
9745
|
// src/commands/natural.ts
|
|
9513
9746
|
init_cjs_shims();
|
|
9514
9747
|
init_new();
|
|
9748
|
+
var LoadingIndicator3 = class {
|
|
9749
|
+
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
9750
|
+
frameIndex = 0;
|
|
9751
|
+
interval = null;
|
|
9752
|
+
message;
|
|
9753
|
+
constructor(message) {
|
|
9754
|
+
this.message = message;
|
|
9755
|
+
}
|
|
9756
|
+
start() {
|
|
9757
|
+
process.stdout.write("\x1B[?25l");
|
|
9758
|
+
this.interval = setInterval(() => {
|
|
9759
|
+
const frame = this.frames[this.frameIndex];
|
|
9760
|
+
process.stdout.write(`\r${chalk9__default.default.cyan(frame)} ${this.message}...`);
|
|
9761
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
9762
|
+
}, 80);
|
|
9763
|
+
}
|
|
9764
|
+
stop(finalMessage) {
|
|
9765
|
+
if (this.interval) {
|
|
9766
|
+
clearInterval(this.interval);
|
|
9767
|
+
this.interval = null;
|
|
9768
|
+
}
|
|
9769
|
+
process.stdout.write("\x1B[?25h");
|
|
9770
|
+
if (finalMessage) {
|
|
9771
|
+
process.stdout.write(`\r${finalMessage}
|
|
9772
|
+
`);
|
|
9773
|
+
} else {
|
|
9774
|
+
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
9775
|
+
}
|
|
9776
|
+
}
|
|
9777
|
+
};
|
|
9515
9778
|
async function handleNaturalLanguage(input, ctx) {
|
|
9516
9779
|
const trimmedInput = input.trim();
|
|
9517
9780
|
const session = getActiveSession();
|
|
@@ -9531,6 +9794,8 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
9531
9794
|
contextUsed: 0
|
|
9532
9795
|
};
|
|
9533
9796
|
}
|
|
9797
|
+
const loader = new LoadingIndicator3("AI \u601D\u8003\u4E2D");
|
|
9798
|
+
loader.start();
|
|
9534
9799
|
try {
|
|
9535
9800
|
const response = await ctx.modelService.sendMessage(
|
|
9536
9801
|
[
|
|
@@ -9548,6 +9813,7 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
9548
9813
|
maxTokens: 2e3
|
|
9549
9814
|
}
|
|
9550
9815
|
);
|
|
9816
|
+
loader.stop();
|
|
9551
9817
|
ctx.contextManager.addMessage({
|
|
9552
9818
|
role: "user",
|
|
9553
9819
|
content: trimmedInput
|
|
@@ -9561,6 +9827,7 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
9561
9827
|
contextUsed: response.usage?.totalTokens || 0
|
|
9562
9828
|
};
|
|
9563
9829
|
} catch (error) {
|
|
9830
|
+
loader.stop();
|
|
9564
9831
|
const errorMessage = error.message;
|
|
9565
9832
|
if (errorMessage.includes("\u672A\u914D\u7F6E") || errorMessage.includes("\u672A\u521D\u59CB\u5316")) {
|
|
9566
9833
|
return {
|