@nick848/sf-cli 1.0.19 → 1.0.20
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 +111 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +111 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -254,23 +254,38 @@ ${resource.analysis}`;
|
|
|
254
254
|
lines.push("");
|
|
255
255
|
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
|
|
256
256
|
lines.push("");
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
activeSession.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
257
|
+
const loader = new LoadingIndicator("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
258
|
+
loader.start();
|
|
259
|
+
try {
|
|
260
|
+
activeSession.specItems = await generateSpecItemsWithAI(
|
|
261
|
+
activeSession.refinedRequirement,
|
|
262
|
+
activeSession.context,
|
|
263
|
+
activeSession.bddScenarios,
|
|
264
|
+
activeSession.clarificationQuestions,
|
|
265
|
+
activeSession.referenceResources,
|
|
266
|
+
ctx
|
|
267
|
+
);
|
|
268
|
+
loader.stop();
|
|
269
|
+
} catch {
|
|
270
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u4F7F\u7528\u57FA\u7840\u89C4\u683C\u62C6\u5206"));
|
|
271
|
+
activeSession.specItems = generateSpecItems(
|
|
272
|
+
activeSession.refinedRequirement,
|
|
273
|
+
activeSession.context,
|
|
274
|
+
activeSession.bddScenarios,
|
|
275
|
+
activeSession.clarificationQuestions,
|
|
276
|
+
activeSession.referenceResources
|
|
277
|
+
);
|
|
278
|
+
}
|
|
264
279
|
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
265
280
|
lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
266
281
|
lines.push(chalk9__default.default.gray(` \u8DEF\u5F84: ${specPath}`));
|
|
267
282
|
lines.push("");
|
|
268
283
|
lines.push(chalk9__default.default.cyan(" \u4EFB\u52A1\u6982\u89C8:"));
|
|
269
|
-
for (const item of activeSession.specItems.slice(0,
|
|
284
|
+
for (const item of activeSession.specItems.slice(0, 8)) {
|
|
270
285
|
const icon = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
271
286
|
lines.push(chalk9__default.default.gray(` ${icon} [${item.id}] ${item.title}`));
|
|
272
287
|
}
|
|
273
|
-
if (activeSession.specItems.length >
|
|
288
|
+
if (activeSession.specItems.length > 8) {
|
|
274
289
|
lines.push(chalk9__default.default.gray(` ... \u5171 ${activeSession.specItems.length} \u4E2A\u4EFB\u52A1`));
|
|
275
290
|
}
|
|
276
291
|
lines.push("");
|
|
@@ -417,13 +432,15 @@ async function handleWorkflowInput(input, ctx) {
|
|
|
417
432
|
activeSession.bddScenarios = generateBDDScenarios(
|
|
418
433
|
activeSession.refinedRequirement,
|
|
419
434
|
activeSession.context,
|
|
420
|
-
activeSession.clarificationQuestions
|
|
435
|
+
activeSession.clarificationQuestions,
|
|
436
|
+
activeSession.referenceResources
|
|
421
437
|
);
|
|
422
438
|
activeSession.specItems = generateSpecItems(
|
|
423
439
|
activeSession.refinedRequirement,
|
|
424
440
|
activeSession.context,
|
|
425
441
|
activeSession.bddScenarios,
|
|
426
|
-
activeSession.clarificationQuestions
|
|
442
|
+
activeSession.clarificationQuestions,
|
|
443
|
+
activeSession.referenceResources
|
|
427
444
|
);
|
|
428
445
|
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
429
446
|
return {
|
|
@@ -1149,6 +1166,89 @@ function generateSpecItems(requirement, context, bddScenarios, questions, refere
|
|
|
1149
1166
|
});
|
|
1150
1167
|
return items;
|
|
1151
1168
|
}
|
|
1169
|
+
async function generateSpecItemsWithAI(requirement, context, bddScenarios, questions, references, ctx) {
|
|
1170
|
+
const prompt2 = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u9879\u76EE\u7ECF\u7406\u548C\u6280\u672F\u67B6\u6784\u5E08\u3002\u8BF7\u5C06\u4EE5\u4E0B\u9700\u6C42\u62C6\u5206\u4E3A\u7CBE\u7EC6\u5316\u7684\u5F00\u53D1\u4EFB\u52A1\u3002
|
|
1171
|
+
|
|
1172
|
+
## \u9700\u6C42\u63CF\u8FF0
|
|
1173
|
+
${requirement}
|
|
1174
|
+
|
|
1175
|
+
## \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
1176
|
+
- \u6280\u672F\u6808: ${context.techStack?.join(", ") || "TypeScript"}
|
|
1177
|
+
- \u6846\u67B6: ${context.framework || "\u672A\u6307\u5B9A"}
|
|
1178
|
+
${context.devStandards ? `
|
|
1179
|
+
## \u5F00\u53D1\u89C4\u8303\uFF08\u5FC5\u987B\u9075\u5FAA\uFF09
|
|
1180
|
+
${context.devStandards.slice(0, 2e3)}
|
|
1181
|
+
` : ""}
|
|
1182
|
+
|
|
1183
|
+
## BDD \u573A\u666F\u53C2\u8003
|
|
1184
|
+
${bddScenarios.map((s) => `- Feature: ${s.feature} (${s.scenarios.length} \u4E2A\u573A\u666F)`).join("\n")}
|
|
1185
|
+
|
|
1186
|
+
## \u6F84\u6E05\u4FE1\u606F
|
|
1187
|
+
${questions.filter((q) => q.answered).map((q) => `- ${q.question}: ${q.answer}`).join("\n") || "\u65E0"}
|
|
1188
|
+
|
|
1189
|
+
## \u62C6\u5206\u8981\u6C42
|
|
1190
|
+
|
|
1191
|
+
\u8BF7\u5C06\u9700\u6C42\u62C6\u5206\u4E3A **\u7EC6\u7C92\u5EA6\u7684\u5F00\u53D1\u4EFB\u52A1**\uFF0C\u6BCF\u4E2A\u4EFB\u52A1\u5E94\u8BE5\uFF1A
|
|
1192
|
+
1. **\u5355\u4E00\u804C\u8D23** - \u4E00\u4E2A\u4EFB\u52A1\u53EA\u505A\u4E00\u4EF6\u4E8B
|
|
1193
|
+
2. **\u53EF\u72EC\u7ACB\u6D4B\u8BD5** - \u6709\u660E\u786E\u7684\u9A8C\u6536\u6807\u51C6
|
|
1194
|
+
3. **2-4\u5C0F\u65F6\u53EF\u5B8C\u6210** - \u5982\u679C\u4EFB\u52A1\u592A\u5927\uFF0C\u7EE7\u7EED\u62C6\u5206
|
|
1195
|
+
4. **\u6709\u660E\u786E\u7684\u8F93\u5165\u8F93\u51FA** - \u6E05\u695A\u77E5\u9053\u9700\u8981\u4EC0\u4E48\u3001\u4EA7\u51FA\u4EC0\u4E48
|
|
1196
|
+
|
|
1197
|
+
## \u8F93\u51FA\u683C\u5F0F (JSON)
|
|
1198
|
+
\`\`\`json
|
|
1199
|
+
[
|
|
1200
|
+
{
|
|
1201
|
+
"id": "T001",
|
|
1202
|
+
"title": "\u4EFB\u52A1\u6807\u9898\uFF08\u7B80\u77ED\u660E\u786E\uFF09",
|
|
1203
|
+
"description": "\u8BE6\u7EC6\u63CF\u8FF0\uFF1A\u8981\u505A\u4EC0\u4E48\u3001\u5982\u4F55\u505A\u3001\u9A8C\u6536\u6807\u51C6",
|
|
1204
|
+
"priority": "high",
|
|
1205
|
+
"estimatedHours": 2,
|
|
1206
|
+
"dependencies": [],
|
|
1207
|
+
"acceptanceCriteria": ["\u9A8C\u6536\u6807\u51C61", "\u9A8C\u6536\u6807\u51C62"]
|
|
1208
|
+
}
|
|
1209
|
+
]
|
|
1210
|
+
\`\`\`
|
|
1211
|
+
|
|
1212
|
+
## \u62C6\u5206\u5EFA\u8BAE
|
|
1213
|
+
\u5BF9\u4E8E\u590D\u6742\u529F\u80FD\uFF08\u5982\u7B97\u6CD5\u7C7B\uFF09\uFF0C\u5E94\u8BE5\u62C6\u5206\u4E3A\uFF1A
|
|
1214
|
+
- \u6570\u636E\u7ED3\u6784/\u6A21\u578B\u5B9A\u4E49
|
|
1215
|
+
- \u6838\u5FC3\u7B97\u6CD5\u5206\u6B65\u5B9E\u73B0\uFF08\u6BCF\u4E2A\u8BA1\u7B97\u6B65\u9AA4\u4E00\u4E2A\u4EFB\u52A1\uFF09
|
|
1216
|
+
- \u8F93\u5165\u9A8C\u8BC1
|
|
1217
|
+
- \u7ED3\u679C\u683C\u5F0F\u5316
|
|
1218
|
+
- UI \u5C55\u793A\u7EC4\u4EF6
|
|
1219
|
+
- \u96C6\u6210\u6D4B\u8BD5
|
|
1220
|
+
|
|
1221
|
+
\u8BF7\u76F4\u63A5\u8F93\u51FA JSON \u6570\u7EC4\u3002`;
|
|
1222
|
+
const loader = new LoadingIndicator("AI \u6B63\u5728\u62C6\u5206\u89C4\u683C");
|
|
1223
|
+
loader.start();
|
|
1224
|
+
try {
|
|
1225
|
+
const response = await ctx.modelService.sendMessage([
|
|
1226
|
+
{ role: "user", content: prompt2 }
|
|
1227
|
+
], {
|
|
1228
|
+
temperature: 0.3,
|
|
1229
|
+
maxTokens: 4e3,
|
|
1230
|
+
timeout: 12e4
|
|
1231
|
+
});
|
|
1232
|
+
const jsonMatch = response.content.match(/```json\s*([\s\S]*?)```/);
|
|
1233
|
+
if (jsonMatch) {
|
|
1234
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
1235
|
+
loader.stop(chalk9__default.default.green(` \u2713 \u5DF2\u62C6\u5206 ${parsed.length} \u4E2A\u4EFB\u52A1`));
|
|
1236
|
+
return parsed.map((item) => ({
|
|
1237
|
+
id: item.id || `T${String(parsed.indexOf(item) + 1).padStart(3, "0")}`,
|
|
1238
|
+
title: item.title,
|
|
1239
|
+
description: item.description,
|
|
1240
|
+
priority: item.priority || "medium",
|
|
1241
|
+
files: [],
|
|
1242
|
+
tests: item.acceptanceCriteria || []
|
|
1243
|
+
}));
|
|
1244
|
+
}
|
|
1245
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 \u89E3\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u57FA\u7840\u62C6\u5206"));
|
|
1246
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
loader.stop(chalk9__default.default.yellow(" \u26A0 AI \u62C6\u5206\u5931\u8D25\uFF0C\u4F7F\u7528\u57FA\u7840\u62C6\u5206"));
|
|
1249
|
+
return generateSpecItems(requirement, context, bddScenarios, questions, references);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1152
1252
|
async function saveSpecFile(workingDir, session) {
|
|
1153
1253
|
const specDir = path4__namespace.join(workingDir, "openspec", "changes");
|
|
1154
1254
|
await fs4__namespace.mkdir(specDir, { recursive: true });
|