@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/cli/index.js
CHANGED
|
@@ -244,9 +244,10 @@ var init_base = __esm({
|
|
|
244
244
|
}
|
|
245
245
|
/**
|
|
246
246
|
* 获取超时时间
|
|
247
|
+
* 默认 5 分钟,对于复杂的代码生成任务足够
|
|
247
248
|
*/
|
|
248
249
|
getTimeout() {
|
|
249
|
-
return this.config?.timeout ||
|
|
250
|
+
return this.config?.timeout || 3e5;
|
|
250
251
|
}
|
|
251
252
|
/**
|
|
252
253
|
* 获取重试次数
|
|
@@ -1057,9 +1058,12 @@ async function verifyCurrentModel(configManager, modelService) {
|
|
|
1057
1058
|
output: chalk9__default.default.red(`\u2717 \u672A\u77E5\u6A21\u578B: ${currentModel}`)
|
|
1058
1059
|
};
|
|
1059
1060
|
}
|
|
1061
|
+
const loader = new LoadingIndicator(`\u9A8C\u8BC1 ${modelInfo.name} API Key`);
|
|
1062
|
+
loader.start();
|
|
1060
1063
|
try {
|
|
1061
1064
|
const adapter = createAdapter(modelInfo.provider);
|
|
1062
1065
|
const isValid = await adapter.validateApiKey(apiKey);
|
|
1066
|
+
loader.stop();
|
|
1063
1067
|
if (isValid) {
|
|
1064
1068
|
return {
|
|
1065
1069
|
output: chalk9__default.default.green(`\u2713 API Key \u9A8C\u8BC1\u6210\u529F
|
|
@@ -1071,6 +1075,7 @@ async function verifyCurrentModel(configManager, modelService) {
|
|
|
1071
1075
|
};
|
|
1072
1076
|
}
|
|
1073
1077
|
} catch (error) {
|
|
1078
|
+
loader.stop();
|
|
1074
1079
|
return {
|
|
1075
1080
|
output: chalk9__default.default.red(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${error.message}`)
|
|
1076
1081
|
};
|
|
@@ -1192,12 +1197,42 @@ function createSpinner(message) {
|
|
|
1192
1197
|
stop: () => process.stdout.write(" ".repeat(message.length + 10) + "\r")
|
|
1193
1198
|
};
|
|
1194
1199
|
}
|
|
1195
|
-
var model_default;
|
|
1200
|
+
var LoadingIndicator, model_default;
|
|
1196
1201
|
var init_model2 = __esm({
|
|
1197
1202
|
"src/commands/model.ts"() {
|
|
1198
1203
|
init_cjs_shims();
|
|
1199
1204
|
init_adapters();
|
|
1200
1205
|
init_model();
|
|
1206
|
+
LoadingIndicator = class {
|
|
1207
|
+
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1208
|
+
frameIndex = 0;
|
|
1209
|
+
interval = null;
|
|
1210
|
+
message;
|
|
1211
|
+
constructor(message) {
|
|
1212
|
+
this.message = message;
|
|
1213
|
+
}
|
|
1214
|
+
start() {
|
|
1215
|
+
process.stdout.write("\x1B[?25l");
|
|
1216
|
+
this.interval = setInterval(() => {
|
|
1217
|
+
const frame = this.frames[this.frameIndex];
|
|
1218
|
+
process.stdout.write(`\r${chalk9__default.default.cyan(frame)} ${this.message}...`);
|
|
1219
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
1220
|
+
}, 80);
|
|
1221
|
+
}
|
|
1222
|
+
stop(finalMessage) {
|
|
1223
|
+
if (this.interval) {
|
|
1224
|
+
clearInterval(this.interval);
|
|
1225
|
+
this.interval = null;
|
|
1226
|
+
}
|
|
1227
|
+
process.stdout.write("\x1B[?25h");
|
|
1228
|
+
if (finalMessage) {
|
|
1229
|
+
process.stdout.write(`\r${finalMessage}
|
|
1230
|
+
`);
|
|
1231
|
+
} else {
|
|
1232
|
+
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1201
1236
|
model_default = selectModel;
|
|
1202
1237
|
}
|
|
1203
1238
|
});
|
|
@@ -1459,7 +1494,10 @@ async function executeWorkflow(ctx) {
|
|
|
1459
1494
|
if (activeSession.phase === "context") {
|
|
1460
1495
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/9: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
|
|
1461
1496
|
lines.push("");
|
|
1497
|
+
const loader = new LoadingIndicator2("\u8BFB\u53D6\u9879\u76EE\u914D\u7F6E");
|
|
1498
|
+
loader.start();
|
|
1462
1499
|
activeSession.context = await readProjectContext(ctx.options.workingDirectory);
|
|
1500
|
+
loader.stop();
|
|
1463
1501
|
lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
|
|
1464
1502
|
lines.push(chalk9__default.default.gray(` \u7C7B\u578B: ${activeSession.context.type}`));
|
|
1465
1503
|
lines.push(chalk9__default.default.gray(` \u6846\u67B6: ${activeSession.context.framework || "\u672A\u8BC6\u522B"}`));
|
|
@@ -1549,7 +1587,7 @@ ${resource.analysis}`;
|
|
|
1549
1587
|
lines.push("");
|
|
1550
1588
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/9: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
|
|
1551
1589
|
lines.push("");
|
|
1552
|
-
const loader = new
|
|
1590
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u751F\u6210 BDD \u573A\u666F");
|
|
1553
1591
|
loader.start();
|
|
1554
1592
|
try {
|
|
1555
1593
|
activeSession.bddScenarios = await generateBDDScenariosWithAI(
|
|
@@ -1584,7 +1622,7 @@ ${resource.analysis}`;
|
|
|
1584
1622
|
lines.push("");
|
|
1585
1623
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
|
|
1586
1624
|
lines.push("");
|
|
1587
|
-
const loader = new
|
|
1625
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
1588
1626
|
loader.start();
|
|
1589
1627
|
try {
|
|
1590
1628
|
activeSession.specItems = await generateSpecItemsWithAI(
|
|
@@ -1753,31 +1791,85 @@ async function handleWorkflowInput(input, ctx) {
|
|
|
1753
1791
|
activeSession.phase = "analysis";
|
|
1754
1792
|
return executeWorkflow(ctx);
|
|
1755
1793
|
}
|
|
1756
|
-
if (activeSession.phase === "spec") {
|
|
1794
|
+
if (activeSession.phase === "spec" || activeSession.specFeedbackState === "waiting_confirm") {
|
|
1757
1795
|
if (trimmed === "y" || trimmed === "yes" || trimmed === "\u786E\u8BA4") {
|
|
1796
|
+
activeSession.specFeedbackState = void 0;
|
|
1758
1797
|
activeSession.phase = "tdd";
|
|
1759
1798
|
return executeWorkflow(ctx);
|
|
1760
1799
|
}
|
|
1761
|
-
if (trimmed === "n" || trimmed === "no" || trimmed === "\u91CD\u65B0") {
|
|
1762
|
-
activeSession.
|
|
1763
|
-
|
|
1764
|
-
activeSession.
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1800
|
+
if (trimmed === "n" || trimmed === "no" || trimmed === "\u4E0D\u6EE1\u610F" || trimmed === "\u91CD\u65B0") {
|
|
1801
|
+
activeSession.specFeedbackState = "collecting_feedback";
|
|
1802
|
+
if (!activeSession.specFeedbacks) {
|
|
1803
|
+
activeSession.specFeedbacks = [];
|
|
1804
|
+
}
|
|
1805
|
+
return {
|
|
1806
|
+
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')
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
if (activeSession.specFeedbackState === "collecting_feedback") {
|
|
1811
|
+
if (trimmed === "" || trimmed === "done" || trimmed === "\u5B8C\u6210") {
|
|
1812
|
+
if (!activeSession.specFeedbacks || activeSession.specFeedbacks.length === 0) {
|
|
1813
|
+
return {
|
|
1814
|
+
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')
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
activeSession.specFeedbackState = "feedback_received";
|
|
1818
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u6839\u636E\u53CD\u9988\u91CD\u65B0\u751F\u6210\u89C4\u683C");
|
|
1819
|
+
loader.start();
|
|
1820
|
+
try {
|
|
1821
|
+
activeSession.specItems = await generateSpecItemsWithFeedback(
|
|
1822
|
+
activeSession.refinedRequirement,
|
|
1823
|
+
activeSession.context,
|
|
1824
|
+
activeSession.bddScenarios,
|
|
1825
|
+
activeSession.clarificationQuestions,
|
|
1826
|
+
activeSession.referenceResources,
|
|
1827
|
+
activeSession.specFeedbacks,
|
|
1828
|
+
ctx
|
|
1829
|
+
);
|
|
1830
|
+
loader.stop(chalk9__default.default.green(" \u2713 \u89C4\u683C\u5DF2\u6839\u636E\u53CD\u9988\u91CD\u65B0\u751F\u6210"));
|
|
1831
|
+
} catch (error) {
|
|
1832
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u4F7F\u7528\u57FA\u7840\u65B9\u6CD5\u91CD\u65B0\u751F\u6210"));
|
|
1833
|
+
activeSession.specItems = generateSpecItems(
|
|
1834
|
+
activeSession.refinedRequirement,
|
|
1835
|
+
activeSession.context,
|
|
1836
|
+
activeSession.bddScenarios,
|
|
1837
|
+
activeSession.clarificationQuestions,
|
|
1838
|
+
activeSession.referenceResources
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1775
1841
|
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
1842
|
+
activeSession.specFeedbackState = "waiting_confirm";
|
|
1843
|
+
const lines = [];
|
|
1844
|
+
lines.push(chalk9__default.default.cyan("\n\u2501\u2501\u2501 \u66F4\u65B0\u540E\u7684\u4EFB\u52A1\u6982\u89C8 \u2501\u2501\u2501"));
|
|
1845
|
+
for (const item of activeSession.specItems.slice(0, 8)) {
|
|
1846
|
+
const icon = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
1847
|
+
lines.push(chalk9__default.default.gray(` ${icon} [${item.id}] ${item.title}`));
|
|
1848
|
+
}
|
|
1849
|
+
if (activeSession.specItems.length > 8) {
|
|
1850
|
+
lines.push(chalk9__default.default.gray(` ... \u5171 ${activeSession.specItems.length} \u4E2A\u4EFB\u52A1`));
|
|
1851
|
+
}
|
|
1776
1852
|
return {
|
|
1777
|
-
output:
|
|
1778
|
-
|
|
1853
|
+
output: lines.join("\n") + chalk9__default.default.green(`
|
|
1854
|
+
|
|
1855
|
+
\u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u66F4\u65B0`) + chalk9__default.default.gray(`
|
|
1856
|
+
\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")
|
|
1779
1857
|
};
|
|
1780
1858
|
}
|
|
1859
|
+
if (trimmed === "cancel" || trimmed === "\u53D6\u6D88") {
|
|
1860
|
+
activeSession.specFeedbackState = "waiting_confirm";
|
|
1861
|
+
activeSession.specFeedbacks = [];
|
|
1862
|
+
return {
|
|
1863
|
+
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")
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
if (!activeSession.specFeedbacks) {
|
|
1867
|
+
activeSession.specFeedbacks = [];
|
|
1868
|
+
}
|
|
1869
|
+
activeSession.specFeedbacks.push(trimmed);
|
|
1870
|
+
return {
|
|
1871
|
+
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')
|
|
1872
|
+
};
|
|
1781
1873
|
}
|
|
1782
1874
|
if (activeSession.phase === "develop") {
|
|
1783
1875
|
if (trimmed === "continue" || trimmed === "\u7EE7\u7EED" || trimmed === "done" || trimmed === "\u5B8C\u6210") {
|
|
@@ -1929,107 +2021,115 @@ function getCategoryLabel(category) {
|
|
|
1929
2021
|
async function executeDevelopment(ctx, session) {
|
|
1930
2022
|
const workingDir = ctx.options.workingDirectory;
|
|
1931
2023
|
const files = [];
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
const
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
2024
|
+
console.log("");
|
|
2025
|
+
for (let i = 0; i < session.specItems.length; i++) {
|
|
2026
|
+
const item = session.specItems[i];
|
|
2027
|
+
const prefix = `[${i + 1}/${session.specItems.length}]`;
|
|
2028
|
+
if (item.title.includes("\u6D4B\u8BD5") || item.title.includes("test")) {
|
|
2029
|
+
continue;
|
|
2030
|
+
}
|
|
2031
|
+
const loader = new LoadingIndicator2(`${prefix} \u751F\u6210: ${item.title.slice(0, 20)}...`);
|
|
2032
|
+
loader.start();
|
|
2033
|
+
try {
|
|
2034
|
+
const taskPrompt = buildTaskPrompt(session, item, i);
|
|
2035
|
+
const messages = [
|
|
2036
|
+
{
|
|
2037
|
+
role: "system",
|
|
2038
|
+
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
|
|
1940
2039
|
|
|
1941
2040
|
\u26A0\uFE0F \u91CD\u8981\u89C4\u5219\uFF1A
|
|
1942
|
-
1. \
|
|
1943
|
-
2. \
|
|
1944
|
-
3. \
|
|
1945
|
-
|
|
1946
|
-
\u4EE3\u7801\u8981\u6C42\uFF1A
|
|
1947
|
-
1. \u751F\u6210\u5B8C\u6574\u3001\u53EF\u8FD0\u884C\u7684\u4EE3\u7801
|
|
1948
|
-
2. \u9075\u5FAA\u9879\u76EE\u73B0\u6709\u7684\u4EE3\u7801\u98CE\u683C\u548C\u89C4\u8303
|
|
1949
|
-
3. \u4F7F\u7528\u9879\u76EE\u6307\u5B9A\u7684\u6280\u672F\u6808
|
|
1950
|
-
4. \u4EE3\u7801\u8981\u6709\u9002\u5F53\u7684\u6CE8\u91CA
|
|
1951
|
-
5. \u8FD4\u56DE\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u6587\u4EF6\u7528 \`\`\`filename \u4EE3\u7801 \`\`\` \u5305\u88F9
|
|
2041
|
+
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
|
|
2042
|
+
2. \u6280\u672F\u5B9E\u73B0\u5FC5\u987B\u4E25\u683C\u9075\u5FAA\u9879\u76EE\u73B0\u6709\u7684\u5F00\u53D1\u89C4\u8303
|
|
2043
|
+
3. \u751F\u6210\u5B8C\u6574\u3001\u53EF\u8FD0\u884C\u7684\u4EE3\u7801
|
|
2044
|
+
4. \u8FD4\u56DE\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u6587\u4EF6\u7528 \`\`\`filename \u4EE3\u7801 \`\`\` \u5305\u88F9
|
|
1952
2045
|
|
|
1953
2046
|
\u9879\u76EE\u4FE1\u606F\uFF1A
|
|
1954
2047
|
- \u540D\u79F0: ${session.context?.name}
|
|
1955
2048
|
- \u6846\u67B6: ${session.context?.framework || "\u672A\u6307\u5B9A"}
|
|
1956
2049
|
- \u6280\u672F\u6808: ${session.context?.techStack.join(", ") || "\u672A\u6307\u5B9A"}
|
|
1957
2050
|
|
|
1958
|
-
${session.context?.devStandards ? `\u3010\
|
|
1959
|
-
${session.context.devStandards.slice(0,
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2051
|
+
${session.context?.devStandards ? `\u3010\u5F00\u53D1\u89C4\u8303\u3011
|
|
2052
|
+
${session.context.devStandards.slice(0, 2e3)}` : ""}`
|
|
2053
|
+
},
|
|
2054
|
+
{
|
|
2055
|
+
role: "user",
|
|
2056
|
+
content: taskPrompt
|
|
2057
|
+
}
|
|
2058
|
+
];
|
|
2059
|
+
const response = await ctx.modelService.sendMessage(messages, {
|
|
2060
|
+
temperature: 0.3,
|
|
2061
|
+
maxTokens: 4e3,
|
|
2062
|
+
// 单个任务减少 token
|
|
2063
|
+
agent: "frontend-dev",
|
|
2064
|
+
timeout: 3e5
|
|
2065
|
+
// 5分钟超时,确保复杂代码有足够时间
|
|
2066
|
+
});
|
|
2067
|
+
const codeBlocks = parseCodeBlocks(response.content);
|
|
2068
|
+
if (codeBlocks.length > 0) {
|
|
2069
|
+
for (const block of codeBlocks) {
|
|
2070
|
+
const filePath = path5__namespace.join(workingDir, block.filename);
|
|
2071
|
+
const dir = path5__namespace.dirname(filePath);
|
|
2072
|
+
await fs5__namespace.mkdir(dir, { recursive: true });
|
|
2073
|
+
await fs5__namespace.writeFile(filePath, block.code, "utf-8");
|
|
2074
|
+
files.push(block.filename);
|
|
2075
|
+
}
|
|
2076
|
+
loader.stop(chalk9__default.default.green(`${prefix} \u2713 ${item.title.slice(0, 25)} (${codeBlocks.length} \u4E2A\u6587\u4EF6)`));
|
|
2077
|
+
} else {
|
|
2078
|
+
const implDir = path5__namespace.join(workingDir, "src");
|
|
2079
|
+
await fs5__namespace.mkdir(implDir, { recursive: true });
|
|
2080
|
+
const fileName = `${item.title.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_")}.ts`;
|
|
2081
|
+
const filePath = path5__namespace.join(implDir, fileName);
|
|
2082
|
+
await fs5__namespace.writeFile(filePath, `// TODO: ${item.title}
|
|
2083
|
+
// ${item.description}
|
|
2084
|
+
`, "utf-8");
|
|
2085
|
+
files.push(`src/${fileName}`);
|
|
2086
|
+
loader.stop(chalk9__default.default.yellow(`${prefix} \u26A0 \u751F\u6210\u57FA\u7840\u6A21\u677F: ${item.title.slice(0, 20)}`));
|
|
2087
|
+
}
|
|
2088
|
+
if (i < session.specItems.length - 1) {
|
|
2089
|
+
await new Promise((resolve5) => setTimeout(resolve5, 500));
|
|
1964
2090
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
const response = await ctx.modelService.sendMessage(messages, {
|
|
1968
|
-
temperature: 0.3,
|
|
1969
|
-
maxTokens: 8e3,
|
|
1970
|
-
agent: "frontend-dev",
|
|
1971
|
-
timeout: 18e4
|
|
1972
|
-
// 3 分钟超时
|
|
1973
|
-
});
|
|
1974
|
-
loader.update("\u6B63\u5728\u89E3\u6790\u4EE3\u7801");
|
|
1975
|
-
const codeBlocks = parseCodeBlocks(response.content);
|
|
1976
|
-
for (const block of codeBlocks) {
|
|
1977
|
-
const filePath = path5__namespace.join(workingDir, block.filename);
|
|
1978
|
-
const dir = path5__namespace.dirname(filePath);
|
|
1979
|
-
await fs5__namespace.mkdir(dir, { recursive: true });
|
|
1980
|
-
await fs5__namespace.writeFile(filePath, block.code, "utf-8");
|
|
1981
|
-
files.push(block.filename);
|
|
1982
|
-
}
|
|
1983
|
-
if (files.length === 0) {
|
|
1984
|
-
const implDir = path5__namespace.join(workingDir, "src", "features");
|
|
1985
|
-
await fs5__namespace.mkdir(implDir, { recursive: true });
|
|
1986
|
-
const featureName = session.specItems[0]?.title || "feature";
|
|
1987
|
-
const fileName = `${featureName.replace(/[^a-zA-Z0-9]/g, "_")}.ts`;
|
|
1988
|
-
const filePath = path5__namespace.join(implDir, fileName);
|
|
1989
|
-
const stubCode = `/**
|
|
1990
|
-
* ${session.requirement}
|
|
1991
|
-
*
|
|
1992
|
-
* TODO: \u6B64\u6587\u4EF6\u7531 AI \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u6839\u636E\u9700\u6C42\u5B8C\u5584\u5B9E\u73B0
|
|
1993
|
-
*/
|
|
1994
|
-
|
|
1995
|
-
export function ${featureName.replace(/[^a-zA-Z0-9]/g, "")}() {
|
|
1996
|
-
// TODO: \u5B9E\u73B0\u529F\u80FD
|
|
1997
|
-
console.log('${featureName} - \u5F85\u5B9E\u73B0');
|
|
1998
|
-
}
|
|
1999
|
-
`;
|
|
2000
|
-
await fs5__namespace.writeFile(filePath, stubCode, "utf-8");
|
|
2001
|
-
files.push(`src/features/${fileName}`);
|
|
2091
|
+
} catch (error) {
|
|
2092
|
+
loader.stop(chalk9__default.default.red(`${prefix} \u2717 \u5931\u8D25: ${error.message.slice(0, 40)}`));
|
|
2002
2093
|
}
|
|
2003
|
-
|
|
2094
|
+
}
|
|
2095
|
+
if (files.length > 0) {
|
|
2004
2096
|
return { success: true, files };
|
|
2005
|
-
}
|
|
2006
|
-
loader.stop();
|
|
2097
|
+
} else {
|
|
2007
2098
|
return {
|
|
2008
2099
|
success: false,
|
|
2009
2100
|
files: [],
|
|
2010
|
-
error:
|
|
2101
|
+
error: "\u6240\u6709\u4EFB\u52A1\u4EE3\u7801\u751F\u6210\u5931\u8D25"
|
|
2011
2102
|
};
|
|
2012
2103
|
}
|
|
2013
2104
|
}
|
|
2014
|
-
function
|
|
2105
|
+
function buildTaskPrompt(session, item, index) {
|
|
2015
2106
|
const lines = [];
|
|
2016
|
-
lines.push(
|
|
2017
|
-
lines.push(
|
|
2018
|
-
lines.push(
|
|
2019
|
-
lines.push(
|
|
2020
|
-
|
|
2021
|
-
lines.push(
|
|
2022
|
-
for (const
|
|
2023
|
-
lines.push(`- ${
|
|
2107
|
+
lines.push(`## \u5F53\u524D\u4EFB\u52A1 (#${index + 1})`);
|
|
2108
|
+
lines.push(`**\u6807\u9898**: ${item.title}`);
|
|
2109
|
+
lines.push(`**\u63CF\u8FF0**: ${item.description}`);
|
|
2110
|
+
lines.push(`**\u4F18\u5148\u7EA7**: ${item.priority}`);
|
|
2111
|
+
if (item.tests && item.tests.length > 0) {
|
|
2112
|
+
lines.push(`**\u9A8C\u6536\u6807\u51C6**:`);
|
|
2113
|
+
for (const t of item.tests) {
|
|
2114
|
+
lines.push(`- ${t}`);
|
|
2024
2115
|
}
|
|
2025
2116
|
}
|
|
2026
2117
|
lines.push("");
|
|
2027
|
-
lines.push(
|
|
2028
|
-
|
|
2029
|
-
|
|
2118
|
+
lines.push(`## \u6574\u4F53\u9700\u6C42\u80CC\u666F`);
|
|
2119
|
+
lines.push(session.requirement);
|
|
2120
|
+
const relatedScenario = session.bddScenarios.find(
|
|
2121
|
+
(s) => item.title.includes(s.feature) || s.feature.includes(item.title)
|
|
2122
|
+
);
|
|
2123
|
+
if (relatedScenario) {
|
|
2124
|
+
lines.push("");
|
|
2125
|
+
lines.push(`## \u76F8\u5173 BDD \u573A\u666F`);
|
|
2126
|
+
lines.push(`Feature: ${relatedScenario.feature}`);
|
|
2127
|
+
for (const s of relatedScenario.scenarios.slice(0, 2)) {
|
|
2128
|
+
lines.push(`- ${s.name}`);
|
|
2129
|
+
}
|
|
2030
2130
|
}
|
|
2031
2131
|
lines.push("");
|
|
2032
|
-
lines.push("\u8BF7\
|
|
2132
|
+
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");
|
|
2033
2133
|
return lines.join("\n");
|
|
2034
2134
|
}
|
|
2035
2135
|
function parseCodeBlocks(content) {
|
|
@@ -2050,6 +2150,8 @@ async function executeReview(ctx, session) {
|
|
|
2050
2150
|
const workingDir = ctx.options.workingDirectory;
|
|
2051
2151
|
const issues = [];
|
|
2052
2152
|
const suggestions = [];
|
|
2153
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u5BA1\u6838\u4EE3\u7801");
|
|
2154
|
+
loader.start();
|
|
2053
2155
|
try {
|
|
2054
2156
|
const codeContents = [];
|
|
2055
2157
|
for (const file of session.implFiles) {
|
|
@@ -2112,7 +2214,9 @@ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
|
|
|
2112
2214
|
const response = await ctx.modelService.sendMessage(messages, {
|
|
2113
2215
|
temperature: 0.2,
|
|
2114
2216
|
maxTokens: 2e3,
|
|
2115
|
-
agent: "code-reviewer"
|
|
2217
|
+
agent: "code-reviewer",
|
|
2218
|
+
timeout: 18e4
|
|
2219
|
+
// 3分钟超时
|
|
2116
2220
|
});
|
|
2117
2221
|
const result = response.content;
|
|
2118
2222
|
const passed = result.includes("\u5BA1\u6838\u901A\u8FC7") || result.includes("\u901A\u8FC7") || !result.includes("\u4E0D\u901A\u8FC7");
|
|
@@ -2134,8 +2238,10 @@ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
|
|
|
2134
2238
|
const lines = result.split("\n").filter((l) => l.includes("\u5EFA\u8BAE") || l.includes("\u6539\u8FDB") || l.includes("\u4F18\u5316"));
|
|
2135
2239
|
suggestions.push(...lines.map((l) => l.replace(/^[-*]\s*/, "").trim()).filter((l) => l));
|
|
2136
2240
|
}
|
|
2241
|
+
loader.stop(passed ? chalk9__default.default.green(" \u2713 \u5BA1\u6838\u901A\u8FC7") : chalk9__default.default.yellow(" \u26A0 \u53D1\u73B0\u95EE\u9898"));
|
|
2137
2242
|
return { passed, issues, suggestions };
|
|
2138
2243
|
} catch (error) {
|
|
2244
|
+
loader.stop(chalk9__default.default.red(" \u2717 \u5BA1\u6838\u51FA\u9519"));
|
|
2139
2245
|
suggestions.push(`\u5BA1\u6838\u8FC7\u7A0B\u51FA\u9519: ${error.message}`);
|
|
2140
2246
|
return { passed: true, issues, suggestions };
|
|
2141
2247
|
}
|
|
@@ -2341,7 +2447,8 @@ ${r.analysis}`).join("\n\n") : "\u65E0"}
|
|
|
2341
2447
|
], {
|
|
2342
2448
|
temperature: 0.3,
|
|
2343
2449
|
maxTokens: 4e3,
|
|
2344
|
-
timeout:
|
|
2450
|
+
timeout: 3e5
|
|
2451
|
+
// 5分钟超时
|
|
2345
2452
|
});
|
|
2346
2453
|
try {
|
|
2347
2454
|
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
@@ -2549,7 +2656,7 @@ ${questions.filter((q) => q.answered).map((q) => `- ${q.question}: ${q.answer}`)
|
|
|
2549
2656
|
- \u96C6\u6210\u6D4B\u8BD5
|
|
2550
2657
|
|
|
2551
2658
|
\u8BF7\u76F4\u63A5\u8F93\u51FA JSON \u6570\u7EC4\u3002`;
|
|
2552
|
-
const loader = new
|
|
2659
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
2553
2660
|
loader.start();
|
|
2554
2661
|
try {
|
|
2555
2662
|
const response = await ctx.modelService.sendMessage([
|
|
@@ -2557,25 +2664,131 @@ ${questions.filter((q) => q.answered).map((q) => `- ${q.question}: ${q.answer}`)
|
|
|
2557
2664
|
], {
|
|
2558
2665
|
temperature: 0.3,
|
|
2559
2666
|
maxTokens: 4e3,
|
|
2560
|
-
timeout:
|
|
2667
|
+
timeout: 3e5
|
|
2668
|
+
// 5分钟超时
|
|
2561
2669
|
});
|
|
2562
2670
|
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
2563
2671
|
if (jsonMatch) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2672
|
+
try {
|
|
2673
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
2674
|
+
loader.stop(chalk9__default.default.green(` \u2713 \u5DF2\u62C6\u5206 ${parsed.length} \u4E2A\u4EFB\u52A1`));
|
|
2675
|
+
return parsed.map((item, index) => ({
|
|
2676
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
2677
|
+
title: item.title,
|
|
2678
|
+
description: item.description,
|
|
2679
|
+
priority: item.priority || "medium",
|
|
2680
|
+
files: [],
|
|
2681
|
+
tests: item.acceptanceCriteria || []
|
|
2682
|
+
}));
|
|
2683
|
+
} catch (parseError) {
|
|
2684
|
+
loader.stop(chalk9__default.default.yellow(` \u26A0 JSON \u89E3\u6790\u5931\u8D25: ${parseError.message.slice(0, 50)}`));
|
|
2685
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
try {
|
|
2689
|
+
const parsed = JSON.parse(response.content);
|
|
2690
|
+
if (Array.isArray(parsed)) {
|
|
2691
|
+
loader.stop(chalk9__default.default.green(` \u2713 \u5DF2\u62C6\u5206 ${parsed.length} \u4E2A\u4EFB\u52A1`));
|
|
2692
|
+
return parsed.map((item, index) => ({
|
|
2693
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
2694
|
+
title: item.title,
|
|
2695
|
+
description: item.description,
|
|
2696
|
+
priority: item.priority || "medium",
|
|
2697
|
+
files: [],
|
|
2698
|
+
tests: item.acceptanceCriteria || []
|
|
2699
|
+
}));
|
|
2700
|
+
}
|
|
2701
|
+
} catch {
|
|
2702
|
+
}
|
|
2703
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u672A\u80FD\u89E3\u6790 AI \u54CD\u5E94\uFF0C\u4F7F\u7528\u57FA\u7840\u62C6\u5206"));
|
|
2576
2704
|
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
2577
2705
|
} catch (error) {
|
|
2578
|
-
|
|
2706
|
+
const errMsg = error.message.slice(0, 80);
|
|
2707
|
+
loader.stop(chalk9__default.default.yellow(` \u26A0 AI \u8C03\u7528\u5931\u8D25: ${errMsg}`));
|
|
2708
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
async function generateSpecItemsWithFeedback(requirement, context, bddScenarios, questions, references, feedbacks, ctx) {
|
|
2712
|
+
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
|
|
2713
|
+
|
|
2714
|
+
## \u9700\u6C42\u63CF\u8FF0
|
|
2715
|
+
${requirement}
|
|
2716
|
+
|
|
2717
|
+
## \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
2718
|
+
- \u6280\u672F\u6808: ${context.techStack?.join(", ") || "TypeScript"}
|
|
2719
|
+
- \u6846\u67B6: ${context.framework || "\u672A\u6307\u5B9A"}
|
|
2720
|
+
${context.devStandards ? `
|
|
2721
|
+
## \u5F00\u53D1\u89C4\u8303\uFF08\u5FC5\u987B\u9075\u5FAA\uFF09
|
|
2722
|
+
${context.devStandards.slice(0, 2e3)}
|
|
2723
|
+
` : ""}
|
|
2724
|
+
|
|
2725
|
+
## \u4E4B\u524D\u7684 BDD \u573A\u666F
|
|
2726
|
+
${bddScenarios.map((s) => `- Feature: ${s.feature}`).join("\n")}
|
|
2727
|
+
|
|
2728
|
+
## \u7528\u6237\u53CD\u9988\uFF08\u5FC5\u987B\u89E3\u51B3\u8FD9\u4E9B\u95EE\u9898\uFF09
|
|
2729
|
+
${feedbacks.map((f, i) => `${i + 1}. ${f}`).join("\n")}
|
|
2730
|
+
|
|
2731
|
+
## \u8981\u6C42
|
|
2732
|
+
1. **\u5FC5\u987B\u89E3\u51B3\u7528\u6237\u53CD\u9988\u4E2D\u7684\u6240\u6709\u95EE\u9898**
|
|
2733
|
+
2. \u5982\u679C\u7528\u6237\u6307\u51FA\u9057\u6F0F\u7684\u529F\u80FD\u70B9\uFF0C\u8BF7\u8865\u5145\u76F8\u5173\u4EFB\u52A1
|
|
2734
|
+
3. \u5982\u679C\u7528\u6237\u6307\u51FA\u62C6\u5206\u4E0D\u5408\u7406\uFF0C\u8BF7\u91CD\u65B0\u8C03\u6574\u7C92\u5EA6
|
|
2735
|
+
4. \u5982\u679C\u7528\u6237\u9700\u8981\u66F4\u591A\u7EC6\u8282\uFF0C\u8BF7\u62C6\u5206\u5F97\u66F4\u7EC6\u81F4
|
|
2736
|
+
5. \u6BCF\u4E2A\u4EFB\u52A1\u5E94\u8BE5\u5355\u4E00\u804C\u8D23\u30012-4\u5C0F\u65F6\u53EF\u5B8C\u6210
|
|
2737
|
+
|
|
2738
|
+
## \u8F93\u51FA\u683C\u5F0F (JSON)
|
|
2739
|
+
\`\`\`json
|
|
2740
|
+
[
|
|
2741
|
+
{
|
|
2742
|
+
"id": "T001",
|
|
2743
|
+
"title": "\u4EFB\u52A1\u6807\u9898\uFF08\u7B80\u77ED\u660E\u786E\uFF09",
|
|
2744
|
+
"description": "\u8BE6\u7EC6\u63CF\u8FF0",
|
|
2745
|
+
"priority": "high",
|
|
2746
|
+
"acceptanceCriteria": ["\u9A8C\u6536\u6807\u51C61", "\u9A8C\u6536\u6807\u51C62"]
|
|
2747
|
+
}
|
|
2748
|
+
]
|
|
2749
|
+
\`\`\`
|
|
2750
|
+
|
|
2751
|
+
\u8BF7\u76F4\u63A5\u8F93\u51FA JSON \u6570\u7EC4\uFF0C\u786E\u4FDD\u89E3\u51B3\u4E86\u7528\u6237\u7684\u6240\u6709\u53CD\u9988\u3002`;
|
|
2752
|
+
try {
|
|
2753
|
+
const response = await ctx.modelService.sendMessage([
|
|
2754
|
+
{ role: "user", content: prompt2 }
|
|
2755
|
+
], {
|
|
2756
|
+
temperature: 0.3,
|
|
2757
|
+
maxTokens: 4e3,
|
|
2758
|
+
timeout: 3e5
|
|
2759
|
+
// 5分钟超时
|
|
2760
|
+
});
|
|
2761
|
+
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
2762
|
+
if (jsonMatch) {
|
|
2763
|
+
try {
|
|
2764
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
2765
|
+
return parsed.map((item, index) => ({
|
|
2766
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
2767
|
+
title: item.title,
|
|
2768
|
+
description: item.description,
|
|
2769
|
+
priority: item.priority || "medium",
|
|
2770
|
+
files: [],
|
|
2771
|
+
tests: item.acceptanceCriteria || []
|
|
2772
|
+
}));
|
|
2773
|
+
} catch {
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
try {
|
|
2777
|
+
const parsed = JSON.parse(response.content);
|
|
2778
|
+
if (Array.isArray(parsed)) {
|
|
2779
|
+
return parsed.map((item, index) => ({
|
|
2780
|
+
id: item.id || `T${String(index + 1).padStart(3, "0")}`,
|
|
2781
|
+
title: item.title,
|
|
2782
|
+
description: item.description,
|
|
2783
|
+
priority: item.priority || "medium",
|
|
2784
|
+
files: [],
|
|
2785
|
+
tests: item.acceptanceCriteria || []
|
|
2786
|
+
}));
|
|
2787
|
+
}
|
|
2788
|
+
} catch {
|
|
2789
|
+
}
|
|
2790
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
2791
|
+
} catch {
|
|
2579
2792
|
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
2580
2793
|
}
|
|
2581
2794
|
}
|
|
@@ -2645,6 +2858,16 @@ function formatSpecFile(session) {
|
|
|
2645
2858
|
lines.push("");
|
|
2646
2859
|
}
|
|
2647
2860
|
}
|
|
2861
|
+
if (session.specFeedbacks && session.specFeedbacks.length > 0) {
|
|
2862
|
+
lines.push("## \u89C4\u683C\u8FED\u4EE3\u53CD\u9988");
|
|
2863
|
+
lines.push("");
|
|
2864
|
+
for (let i = 0; i < session.specFeedbacks.length; i++) {
|
|
2865
|
+
lines.push(`${i + 1}. ${session.specFeedbacks[i]}`);
|
|
2866
|
+
}
|
|
2867
|
+
lines.push("");
|
|
2868
|
+
lines.push("---");
|
|
2869
|
+
lines.push("");
|
|
2870
|
+
}
|
|
2648
2871
|
lines.push("## \u4EFB\u52A1\u5217\u8868");
|
|
2649
2872
|
lines.push("");
|
|
2650
2873
|
for (const item of session.specItems) {
|
|
@@ -2665,7 +2888,7 @@ async function generateTests(workingDir, session, ctx) {
|
|
|
2665
2888
|
for (const scenario of session.bddScenarios) {
|
|
2666
2889
|
const testName = scenario.feature.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_");
|
|
2667
2890
|
const testPath = path5__namespace.join(testDir, `${testName}.test.ts`);
|
|
2668
|
-
const loader = new
|
|
2891
|
+
const loader = new LoadingIndicator2(`\u751F\u6210\u6D4B\u8BD5: ${scenario.feature.slice(0, 20)}...`);
|
|
2669
2892
|
loader.start();
|
|
2670
2893
|
try {
|
|
2671
2894
|
const content = await generateTestFileWithAI(scenario, session, ctx);
|
|
@@ -2720,7 +2943,9 @@ ${scenario.scenarios.map((s) => `
|
|
|
2720
2943
|
{ role: "user", content: prompt2 }
|
|
2721
2944
|
], {
|
|
2722
2945
|
temperature: 0.3,
|
|
2723
|
-
maxTokens: 4e3
|
|
2946
|
+
maxTokens: 4e3,
|
|
2947
|
+
timeout: 18e4
|
|
2948
|
+
// 3分钟超时
|
|
2724
2949
|
});
|
|
2725
2950
|
const codeMatch = response.content.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);
|
|
2726
2951
|
if (codeMatch) {
|
|
@@ -2819,7 +3044,10 @@ async function fetchAndAnalyzeReference(url, ctx, projectContext) {
|
|
|
2819
3044
|
const type = detectResourceType(url);
|
|
2820
3045
|
let content = "";
|
|
2821
3046
|
let analysis = "";
|
|
3047
|
+
const loader = new LoadingIndicator2(`\u83B7\u53D6 ${url.slice(0, 40)}...`);
|
|
3048
|
+
loader.start();
|
|
2822
3049
|
try {
|
|
3050
|
+
loader.update("\u6B63\u5728\u83B7\u53D6\u7F51\u9875\u5185\u5BB9");
|
|
2823
3051
|
const response = await fetch(url, {
|
|
2824
3052
|
headers: {
|
|
2825
3053
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
@@ -2830,11 +3058,14 @@ async function fetchAndAnalyzeReference(url, ctx, projectContext) {
|
|
|
2830
3058
|
}
|
|
2831
3059
|
content = await response.text();
|
|
2832
3060
|
if (ctx.modelService.getCurrentModel()) {
|
|
3061
|
+
loader.update("\u6B63\u5728\u5206\u6790\u5185\u5BB9");
|
|
2833
3062
|
analysis = await analyzeReferenceContent(url, content, type, ctx, projectContext);
|
|
2834
3063
|
} else {
|
|
2835
3064
|
analysis = extractBasicInfo(content, type);
|
|
2836
3065
|
}
|
|
3066
|
+
loader.stop();
|
|
2837
3067
|
} catch (error) {
|
|
3068
|
+
loader.stop();
|
|
2838
3069
|
throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u53C2\u8003\u8D44\u6E90: ${error.message}`);
|
|
2839
3070
|
}
|
|
2840
3071
|
return { url, type, content: content.slice(0, 1e4), analysis };
|
|
@@ -2903,14 +3134,16 @@ ${content.slice(0, 8e3)}
|
|
|
2903
3134
|
\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
|
|
2904
3135
|
\u6280\u672F\u5B9E\u73B0\u65B9\u6848\u7531\u9879\u76EE\u89C4\u8303\u51B3\u5B9A\uFF0C\u6B64\u5904\u4E0D\u6D89\u53CA\u3002
|
|
2905
3136
|
`;
|
|
2906
|
-
const loader = new
|
|
3137
|
+
const loader = new LoadingIndicator2("AI \u6B63\u5728\u5206\u6790\u53C2\u8003\u8D44\u6E90");
|
|
2907
3138
|
loader.start();
|
|
2908
3139
|
try {
|
|
2909
3140
|
const response = await ctx.modelService.sendMessage([
|
|
2910
3141
|
{ role: "user", content: prompt2 }
|
|
2911
3142
|
], {
|
|
2912
3143
|
temperature: 0.3,
|
|
2913
|
-
maxTokens: 4e3
|
|
3144
|
+
maxTokens: 4e3,
|
|
3145
|
+
timeout: 18e4
|
|
3146
|
+
// 3分钟超时
|
|
2914
3147
|
});
|
|
2915
3148
|
loader.stop(chalk9__default.default.green(" \u2713 \u5206\u6790\u5B8C\u6210"));
|
|
2916
3149
|
return response.content;
|
|
@@ -2957,11 +3190,11 @@ function getActiveSession() {
|
|
|
2957
3190
|
function clearActiveSession() {
|
|
2958
3191
|
activeSession = null;
|
|
2959
3192
|
}
|
|
2960
|
-
var
|
|
3193
|
+
var LoadingIndicator2, MAX_FILE_SIZE2, COMPLEXITY_THRESHOLD, CLARITY_THRESHOLD, activeSession, new_default;
|
|
2961
3194
|
var init_new = __esm({
|
|
2962
3195
|
"src/commands/new.ts"() {
|
|
2963
3196
|
init_cjs_shims();
|
|
2964
|
-
|
|
3197
|
+
LoadingIndicator2 = class {
|
|
2965
3198
|
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2966
3199
|
frameIndex = 0;
|
|
2967
3200
|
interval = null;
|
|
@@ -7131,6 +7364,36 @@ async function executeShell(command, ctx) {
|
|
|
7131
7364
|
// src/commands/natural.ts
|
|
7132
7365
|
init_cjs_shims();
|
|
7133
7366
|
init_new();
|
|
7367
|
+
var LoadingIndicator3 = class {
|
|
7368
|
+
frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
7369
|
+
frameIndex = 0;
|
|
7370
|
+
interval = null;
|
|
7371
|
+
message;
|
|
7372
|
+
constructor(message) {
|
|
7373
|
+
this.message = message;
|
|
7374
|
+
}
|
|
7375
|
+
start() {
|
|
7376
|
+
process.stdout.write("\x1B[?25l");
|
|
7377
|
+
this.interval = setInterval(() => {
|
|
7378
|
+
const frame = this.frames[this.frameIndex];
|
|
7379
|
+
process.stdout.write(`\r${chalk9__default.default.cyan(frame)} ${this.message}...`);
|
|
7380
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
7381
|
+
}, 80);
|
|
7382
|
+
}
|
|
7383
|
+
stop(finalMessage) {
|
|
7384
|
+
if (this.interval) {
|
|
7385
|
+
clearInterval(this.interval);
|
|
7386
|
+
this.interval = null;
|
|
7387
|
+
}
|
|
7388
|
+
process.stdout.write("\x1B[?25h");
|
|
7389
|
+
if (finalMessage) {
|
|
7390
|
+
process.stdout.write(`\r${finalMessage}
|
|
7391
|
+
`);
|
|
7392
|
+
} else {
|
|
7393
|
+
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
7394
|
+
}
|
|
7395
|
+
}
|
|
7396
|
+
};
|
|
7134
7397
|
async function handleNaturalLanguage(input, ctx) {
|
|
7135
7398
|
const trimmedInput = input.trim();
|
|
7136
7399
|
const session = getActiveSession();
|
|
@@ -7150,6 +7413,8 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
7150
7413
|
contextUsed: 0
|
|
7151
7414
|
};
|
|
7152
7415
|
}
|
|
7416
|
+
const loader = new LoadingIndicator3("AI \u601D\u8003\u4E2D");
|
|
7417
|
+
loader.start();
|
|
7153
7418
|
try {
|
|
7154
7419
|
const response = await ctx.modelService.sendMessage(
|
|
7155
7420
|
[
|
|
@@ -7167,6 +7432,7 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
7167
7432
|
maxTokens: 2e3
|
|
7168
7433
|
}
|
|
7169
7434
|
);
|
|
7435
|
+
loader.stop();
|
|
7170
7436
|
ctx.contextManager.addMessage({
|
|
7171
7437
|
role: "user",
|
|
7172
7438
|
content: trimmedInput
|
|
@@ -7180,6 +7446,7 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
7180
7446
|
contextUsed: response.usage?.totalTokens || 0
|
|
7181
7447
|
};
|
|
7182
7448
|
} catch (error) {
|
|
7449
|
+
loader.stop();
|
|
7183
7450
|
const errorMessage = error.message;
|
|
7184
7451
|
if (errorMessage.includes("\u672A\u914D\u7F6E") || errorMessage.includes("\u672A\u521D\u59CB\u5316")) {
|
|
7185
7452
|
return {
|