@nick848/sf-cli 1.0.16 → 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/CHANGELOG.md +24 -0
- package/dist/cli/index.js +230 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +228 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +228 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -408,7 +408,7 @@ interface CLIConfig {
|
|
|
408
408
|
theme: 'light' | 'dark' | 'auto';
|
|
409
409
|
}
|
|
410
410
|
type WorkflowStep = 'explore' | 'new' | 'continue' | 'apply' | 'archive' | 'propose';
|
|
411
|
-
type WorkflowPhase = 'context' | 'clarify' | 'analysis' | 'bdd' | 'spec' | 'tdd' | 'develop' | 'review';
|
|
411
|
+
type WorkflowPhase = 'context' | 'clarify' | 'reference' | 'analysis' | 'bdd' | 'spec' | 'tdd' | 'develop' | 'review';
|
|
412
412
|
type WorkflowType = 'complex' | 'simple';
|
|
413
413
|
type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
414
414
|
interface WorkflowState {
|
package/dist/index.d.ts
CHANGED
|
@@ -408,7 +408,7 @@ interface CLIConfig {
|
|
|
408
408
|
theme: 'light' | 'dark' | 'auto';
|
|
409
409
|
}
|
|
410
410
|
type WorkflowStep = 'explore' | 'new' | 'continue' | 'apply' | 'archive' | 'propose';
|
|
411
|
-
type WorkflowPhase = 'context' | 'clarify' | 'analysis' | 'bdd' | 'spec' | 'tdd' | 'develop' | 'review';
|
|
411
|
+
type WorkflowPhase = 'context' | 'clarify' | 'reference' | 'analysis' | 'bdd' | 'spec' | 'tdd' | 'develop' | 'review';
|
|
412
412
|
type WorkflowType = 'complex' | 'simple';
|
|
413
413
|
type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
414
414
|
interface WorkflowState {
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,7 @@ async function handleNew(args, ctx) {
|
|
|
84
84
|
context: null,
|
|
85
85
|
clarityScore: 0,
|
|
86
86
|
clarificationQuestions: [],
|
|
87
|
+
referenceResources: [],
|
|
87
88
|
complexity: 0,
|
|
88
89
|
bddScenarios: [],
|
|
89
90
|
specItems: [],
|
|
@@ -126,7 +127,7 @@ async function executeWorkflow(ctx) {
|
|
|
126
127
|
const lines = [];
|
|
127
128
|
try {
|
|
128
129
|
if (activeSession.phase === "context") {
|
|
129
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/
|
|
130
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/9: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
|
|
130
131
|
lines.push("");
|
|
131
132
|
activeSession.context = await readProjectContext(ctx.options.workingDirectory);
|
|
132
133
|
lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
|
|
@@ -140,7 +141,7 @@ async function executeWorkflow(ctx) {
|
|
|
140
141
|
}
|
|
141
142
|
if (activeSession.phase === "clarify") {
|
|
142
143
|
lines.push("");
|
|
143
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/
|
|
144
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/9: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
|
|
144
145
|
lines.push("");
|
|
145
146
|
const clarityResult = analyzeRequirementClarity(
|
|
146
147
|
activeSession.requirement,
|
|
@@ -166,11 +167,40 @@ async function executeWorkflow(ctx) {
|
|
|
166
167
|
return { output: lines.join("\n") };
|
|
167
168
|
}
|
|
168
169
|
lines.push(chalk9__default.default.green(" \u2713 \u9700\u6C42\u6E05\u6670\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u6B65"));
|
|
170
|
+
activeSession.phase = "reference";
|
|
171
|
+
}
|
|
172
|
+
if (activeSession.phase === "reference") {
|
|
173
|
+
lines.push("");
|
|
174
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/9: \u53C2\u8003\u8D44\u6E90\u5206\u6790 \u2501\u2501\u2501"));
|
|
175
|
+
lines.push("");
|
|
176
|
+
const urls = extractUrls(activeSession.refinedRequirement);
|
|
177
|
+
if (urls.length > 0) {
|
|
178
|
+
lines.push(chalk9__default.default.gray(` \u53D1\u73B0 ${urls.length} \u4E2A\u53C2\u8003\u94FE\u63A5`));
|
|
179
|
+
lines.push("");
|
|
180
|
+
for (const url of urls) {
|
|
181
|
+
lines.push(chalk9__default.default.gray(` \u{1F4CE} ${url}`));
|
|
182
|
+
try {
|
|
183
|
+
const resource = await fetchAndAnalyzeReference(url, ctx);
|
|
184
|
+
activeSession.referenceResources.push(resource);
|
|
185
|
+
lines.push(chalk9__default.default.green(` \u2713 \u5DF2\u5206\u6790`));
|
|
186
|
+
activeSession.refinedRequirement += `
|
|
187
|
+
|
|
188
|
+
\u3010\u53C2\u8003\u8D44\u6E90\u5206\u6790 - ${url}\u3011
|
|
189
|
+
${resource.analysis}`;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
lines.push(chalk9__default.default.yellow(` \u26A0 \u83B7\u53D6\u5931\u8D25: ${error.message}`));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push(chalk9__default.default.green(" \u2713 \u53C2\u8003\u8D44\u6E90\u5206\u6790\u5B8C\u6210"));
|
|
196
|
+
} else {
|
|
197
|
+
lines.push(chalk9__default.default.gray(" \u65E0\u5916\u90E8\u53C2\u8003\u94FE\u63A5"));
|
|
198
|
+
}
|
|
169
199
|
activeSession.phase = "analysis";
|
|
170
200
|
}
|
|
171
201
|
if (activeSession.phase === "analysis") {
|
|
172
202
|
lines.push("");
|
|
173
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
203
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/9: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
|
|
174
204
|
lines.push("");
|
|
175
205
|
activeSession.complexity = analyzeComplexity(
|
|
176
206
|
activeSession.refinedRequirement,
|
|
@@ -187,12 +217,13 @@ async function executeWorkflow(ctx) {
|
|
|
187
217
|
}
|
|
188
218
|
if (activeSession.phase === "bdd") {
|
|
189
219
|
lines.push("");
|
|
190
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
220
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/9: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
|
|
191
221
|
lines.push("");
|
|
192
222
|
activeSession.bddScenarios = generateBDDScenarios(
|
|
193
223
|
activeSession.refinedRequirement,
|
|
194
224
|
activeSession.context,
|
|
195
|
-
activeSession.clarificationQuestions
|
|
225
|
+
activeSession.clarificationQuestions,
|
|
226
|
+
activeSession.referenceResources
|
|
196
227
|
);
|
|
197
228
|
for (const scenario of activeSession.bddScenarios) {
|
|
198
229
|
lines.push(chalk9__default.default.white(` Feature: ${scenario.feature}`));
|
|
@@ -207,13 +238,14 @@ async function executeWorkflow(ctx) {
|
|
|
207
238
|
}
|
|
208
239
|
if (activeSession.phase === "spec") {
|
|
209
240
|
lines.push("");
|
|
210
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
241
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
|
|
211
242
|
lines.push("");
|
|
212
243
|
activeSession.specItems = generateSpecItems(
|
|
213
244
|
activeSession.refinedRequirement,
|
|
214
245
|
activeSession.context,
|
|
215
246
|
activeSession.bddScenarios,
|
|
216
|
-
activeSession.clarificationQuestions
|
|
247
|
+
activeSession.clarificationQuestions,
|
|
248
|
+
activeSession.referenceResources
|
|
217
249
|
);
|
|
218
250
|
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
219
251
|
lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
@@ -237,7 +269,7 @@ async function executeWorkflow(ctx) {
|
|
|
237
269
|
}
|
|
238
270
|
if (activeSession.phase === "tdd") {
|
|
239
271
|
lines.push("");
|
|
240
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
272
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/9: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
|
|
241
273
|
lines.push("");
|
|
242
274
|
activeSession.testFiles = await generateTests(ctx.options.workingDirectory, activeSession);
|
|
243
275
|
lines.push(chalk9__default.default.green(" \u2713 \u6D4B\u8BD5\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
@@ -248,7 +280,7 @@ async function executeWorkflow(ctx) {
|
|
|
248
280
|
}
|
|
249
281
|
if (activeSession.phase === "develop") {
|
|
250
282
|
lines.push("");
|
|
251
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
283
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/9: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
|
|
252
284
|
lines.push("");
|
|
253
285
|
lines.push(chalk9__default.default.yellow(" \u{1F680} \u6B63\u5728\u8C03\u7528 AI \u751F\u6210\u4EE3\u7801..."));
|
|
254
286
|
try {
|
|
@@ -273,7 +305,7 @@ async function executeWorkflow(ctx) {
|
|
|
273
305
|
}
|
|
274
306
|
if (activeSession.phase === "review") {
|
|
275
307
|
lines.push("");
|
|
276
|
-
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5
|
|
308
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 9/9: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
|
|
277
309
|
lines.push("");
|
|
278
310
|
lines.push(chalk9__default.default.yellow(" \u{1F50D} \u6B63\u5728\u8FDB\u884C\u4EE3\u7801\u5BA1\u6838..."));
|
|
279
311
|
try {
|
|
@@ -815,13 +847,41 @@ function analyzeComplexity(requirement, context) {
|
|
|
815
847
|
if (!context.framework) score += 0.5;
|
|
816
848
|
return Math.max(1, Math.min(10, Math.round(score)));
|
|
817
849
|
}
|
|
818
|
-
function generateBDDScenarios(requirement, context, questions) {
|
|
850
|
+
function generateBDDScenarios(requirement, context, questions, references = []) {
|
|
819
851
|
const scenarios = [];
|
|
820
852
|
questions.find((q) => q.category === "ui" && q.answered)?.answer;
|
|
821
853
|
const interactionAnswer = questions.find((q) => q.category === "interaction" && q.answered)?.answer;
|
|
822
854
|
const edgeAnswer = questions.find((q) => q.category === "edge" && q.answered)?.answer;
|
|
855
|
+
if (references.length > 0) {
|
|
856
|
+
for (const ref of references) {
|
|
857
|
+
const refFeatures = extractFeaturesFromReference(ref);
|
|
858
|
+
for (const feature of refFeatures) {
|
|
859
|
+
const scenario = {
|
|
860
|
+
feature: feature.title,
|
|
861
|
+
description: feature.description,
|
|
862
|
+
scenarios: []
|
|
863
|
+
};
|
|
864
|
+
scenario.scenarios.push({
|
|
865
|
+
name: `\u6B63\u5E38\u6D41\u7A0B: ${feature.title}`,
|
|
866
|
+
given: [`\u7528\u6237\u8FDB\u5165\u76F8\u5173\u9875\u9762`],
|
|
867
|
+
when: [`\u7528\u6237\u6267\u884C "${feature.title}" \u64CD\u4F5C`],
|
|
868
|
+
then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5E76\u8FD4\u56DE\u9884\u671F\u7ED3\u679C`]
|
|
869
|
+
});
|
|
870
|
+
if (feature.hasInput) {
|
|
871
|
+
scenario.scenarios.push({
|
|
872
|
+
name: `\u8FB9\u754C\u60C5\u51B5: \u8F93\u5165\u9A8C\u8BC1`,
|
|
873
|
+
given: [`\u7528\u6237\u8FDB\u5165\u8F93\u5165\u754C\u9762`],
|
|
874
|
+
when: [`\u7528\u6237\u8F93\u5165\u8FB9\u754C\u503C\u6216\u7A7A\u503C`],
|
|
875
|
+
then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u8FB9\u754C\u60C5\u51B5`]
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
scenarios.push(scenario);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
823
882
|
const features = extractFeatures(requirement);
|
|
824
883
|
for (const feature of features) {
|
|
884
|
+
if (scenarios.some((s) => s.feature === feature.title)) continue;
|
|
825
885
|
const scenario = {
|
|
826
886
|
feature: feature.title,
|
|
827
887
|
description: feature.description,
|
|
@@ -853,6 +913,46 @@ function generateBDDScenarios(requirement, context, questions) {
|
|
|
853
913
|
}
|
|
854
914
|
return scenarios;
|
|
855
915
|
}
|
|
916
|
+
function extractFeaturesFromReference(ref) {
|
|
917
|
+
const features = [];
|
|
918
|
+
const analysis = ref.analysis.toLowerCase();
|
|
919
|
+
if (analysis.includes("\u8F93\u5165") || analysis.includes("\u8868\u5355")) {
|
|
920
|
+
features.push({
|
|
921
|
+
title: "\u8F93\u5165\u8868\u5355",
|
|
922
|
+
description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u8F93\u5165\u8868\u5355\u529F\u80FD",
|
|
923
|
+
hasInput: true
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
if (analysis.includes("\u6309\u94AE") || analysis.includes("\u64CD\u4F5C")) {
|
|
927
|
+
features.push({
|
|
928
|
+
title: "\u4EA4\u4E92\u6309\u94AE",
|
|
929
|
+
description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6309\u94AE\u4EA4\u4E92",
|
|
930
|
+
hasInput: false
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
if (analysis.includes("\u8868\u683C") || analysis.includes("\u5217\u8868")) {
|
|
934
|
+
features.push({
|
|
935
|
+
title: "\u6570\u636E\u5217\u8868",
|
|
936
|
+
description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6570\u636E\u5C55\u793A",
|
|
937
|
+
hasInput: false
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
if (analysis.includes("\u56FE\u8868") || analysis.includes("\u53EF\u89C6\u5316")) {
|
|
941
|
+
features.push({
|
|
942
|
+
title: "\u56FE\u8868\u5C55\u793A",
|
|
943
|
+
description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u56FE\u8868\u53EF\u89C6\u5316",
|
|
944
|
+
hasInput: false
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
if (features.length === 0) {
|
|
948
|
+
features.push({
|
|
949
|
+
title: "\u53C2\u8003\u529F\u80FD\u5B9E\u73B0",
|
|
950
|
+
description: `\u57FA\u4E8E\u53C2\u8003\u8D44\u6E90 ${ref.url} \u5B9E\u73B0\u7684\u529F\u80FD`,
|
|
951
|
+
hasInput: true
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
return features;
|
|
955
|
+
}
|
|
856
956
|
function extractFeatures(requirement) {
|
|
857
957
|
const features = [];
|
|
858
958
|
const urlMatch = requirement.match(/https?:\/\/[^\s]+/);
|
|
@@ -893,15 +993,26 @@ function extractFeatures(requirement) {
|
|
|
893
993
|
}
|
|
894
994
|
return features;
|
|
895
995
|
}
|
|
896
|
-
function generateSpecItems(requirement, context, bddScenarios, questions) {
|
|
996
|
+
function generateSpecItems(requirement, context, bddScenarios, questions, references = []) {
|
|
897
997
|
const items = [];
|
|
898
998
|
let id = 1;
|
|
999
|
+
for (const ref of references) {
|
|
1000
|
+
items.push({
|
|
1001
|
+
id: `T${id.toString().padStart(3, "0")}`,
|
|
1002
|
+
title: `\u53C2\u8003\u5206\u6790: ${ref.type}`,
|
|
1003
|
+
description: `\u5206\u6790\u53C2\u8003\u8D44\u6E90 ${ref.url}`,
|
|
1004
|
+
priority: "high",
|
|
1005
|
+
files: [],
|
|
1006
|
+
tests: []
|
|
1007
|
+
});
|
|
1008
|
+
id++;
|
|
1009
|
+
}
|
|
899
1010
|
for (const scenario of bddScenarios) {
|
|
900
1011
|
items.push({
|
|
901
1012
|
id: `T${id.toString().padStart(3, "0")}`,
|
|
902
1013
|
title: scenario.feature,
|
|
903
1014
|
description: scenario.description,
|
|
904
|
-
priority: id <=
|
|
1015
|
+
priority: id <= 3 ? "high" : "medium",
|
|
905
1016
|
files: [],
|
|
906
1017
|
tests: []
|
|
907
1018
|
});
|
|
@@ -944,6 +1055,19 @@ function formatSpecFile(session) {
|
|
|
944
1055
|
lines.push("---");
|
|
945
1056
|
lines.push("");
|
|
946
1057
|
}
|
|
1058
|
+
if (session.referenceResources.length > 0) {
|
|
1059
|
+
lines.push("## \u53C2\u8003\u8D44\u6E90");
|
|
1060
|
+
lines.push("");
|
|
1061
|
+
for (const ref of session.referenceResources) {
|
|
1062
|
+
lines.push(`### ${ref.url}`);
|
|
1063
|
+
lines.push(`> \u7C7B\u578B: ${ref.type}`);
|
|
1064
|
+
lines.push("");
|
|
1065
|
+
lines.push(ref.analysis);
|
|
1066
|
+
lines.push("");
|
|
1067
|
+
}
|
|
1068
|
+
lines.push("---");
|
|
1069
|
+
lines.push("");
|
|
1070
|
+
}
|
|
947
1071
|
if (session.clarificationQuestions.some((q) => q.answered)) {
|
|
948
1072
|
lines.push("## \u9700\u6C42\u6F84\u6E05");
|
|
949
1073
|
lines.push("");
|
|
@@ -1049,6 +1173,96 @@ function generateSessionId() {
|
|
|
1049
1173
|
const random = Math.random().toString(36).slice(2, 6);
|
|
1050
1174
|
return `WF-${timestamp}-${random}`.toUpperCase();
|
|
1051
1175
|
}
|
|
1176
|
+
function extractUrls(text) {
|
|
1177
|
+
const urlRegex = /https?:\/\/[^\s<>"{}|\\^`\[\]]+/gi;
|
|
1178
|
+
const matches = text.match(urlRegex);
|
|
1179
|
+
return matches ? [...new Set(matches)] : [];
|
|
1180
|
+
}
|
|
1181
|
+
async function fetchAndAnalyzeReference(url, ctx) {
|
|
1182
|
+
const type = detectResourceType(url);
|
|
1183
|
+
let content = "";
|
|
1184
|
+
let analysis = "";
|
|
1185
|
+
try {
|
|
1186
|
+
const response = await fetch(url, {
|
|
1187
|
+
headers: {
|
|
1188
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
if (!response.ok) {
|
|
1192
|
+
throw new Error(`HTTP ${response.status}`);
|
|
1193
|
+
}
|
|
1194
|
+
content = await response.text();
|
|
1195
|
+
if (ctx.modelService.getCurrentModel()) {
|
|
1196
|
+
analysis = await analyzeReferenceContent(url, content, type, ctx);
|
|
1197
|
+
} else {
|
|
1198
|
+
analysis = extractBasicInfo(content, type);
|
|
1199
|
+
}
|
|
1200
|
+
} catch (error) {
|
|
1201
|
+
throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u53C2\u8003\u8D44\u6E90: ${error.message}`);
|
|
1202
|
+
}
|
|
1203
|
+
return { url, type, content: content.slice(0, 1e4), analysis };
|
|
1204
|
+
}
|
|
1205
|
+
function detectResourceType(url) {
|
|
1206
|
+
if (url.includes("figma.com") || url.includes("lanhuapp.com")) {
|
|
1207
|
+
return "design";
|
|
1208
|
+
}
|
|
1209
|
+
if (/\.(png|jpg|jpeg|gif|webp|svg)$/i.test(url)) {
|
|
1210
|
+
return "image";
|
|
1211
|
+
}
|
|
1212
|
+
if (/api\//i.test(url)) {
|
|
1213
|
+
return "api";
|
|
1214
|
+
}
|
|
1215
|
+
return "webpage";
|
|
1216
|
+
}
|
|
1217
|
+
async function analyzeReferenceContent(url, content, type, ctx) {
|
|
1218
|
+
const typePrompts = {
|
|
1219
|
+
webpage: "\u5206\u6790\u8FD9\u4E2A\u7F51\u9875\u7684\u529F\u80FD\u3001UI\u7EC4\u4EF6\u548C\u4EA4\u4E92\u65B9\u5F0F",
|
|
1220
|
+
design: "\u5206\u6790\u8FD9\u4E2A\u8BBE\u8BA1\u7A3F\u7684\u5E03\u5C40\u3001\u7EC4\u4EF6\u548C\u6837\u5F0F",
|
|
1221
|
+
image: "\u63CF\u8FF0\u8FD9\u4E2A\u56FE\u7247\u7684\u5185\u5BB9\u548C\u8BBE\u8BA1\u5143\u7D20",
|
|
1222
|
+
api: "\u5206\u6790\u8FD9\u4E2AAPI\u7684\u7ED3\u6784\u548C\u53C2\u6570"
|
|
1223
|
+
};
|
|
1224
|
+
const prompt2 = `
|
|
1225
|
+
\u8BF7\u5206\u6790\u4EE5\u4E0B\u53C2\u8003\u8D44\u6E90\u7684 URL\uFF0C\u63D0\u53D6\u5BF9\u5F00\u53D1\u6709\u7528\u7684\u4FE1\u606F\uFF1A
|
|
1226
|
+
|
|
1227
|
+
URL: ${url}
|
|
1228
|
+
\u7C7B\u578B: ${type}
|
|
1229
|
+
|
|
1230
|
+
\u5185\u5BB9\u6458\u8981:
|
|
1231
|
+
${content.slice(0, 5e3)}
|
|
1232
|
+
|
|
1233
|
+
${typePrompts[type]}
|
|
1234
|
+
|
|
1235
|
+
\u8BF7\u63D0\u53D6\uFF1A
|
|
1236
|
+
1. \u4E3B\u8981\u529F\u80FD\u70B9
|
|
1237
|
+
2. UI\u7EC4\u4EF6\u7ED3\u6784
|
|
1238
|
+
3. \u4EA4\u4E92\u65B9\u5F0F
|
|
1239
|
+
4. \u6570\u636E\u7ED3\u6784\uFF08\u5982\u679C\u6709\uFF09
|
|
1240
|
+
5. \u6280\u672F\u5B9E\u73B0\u5EFA\u8BAE
|
|
1241
|
+
|
|
1242
|
+
\u4EE5\u7B80\u6D01\u7684\u8981\u70B9\u5F62\u5F0F\u8F93\u51FA\u3002
|
|
1243
|
+
`;
|
|
1244
|
+
try {
|
|
1245
|
+
const response = await ctx.modelService.sendMessage([
|
|
1246
|
+
{ role: "user", content: prompt2 }
|
|
1247
|
+
], { temperature: 0.3, maxTokens: 2e3 });
|
|
1248
|
+
return response.content;
|
|
1249
|
+
} catch {
|
|
1250
|
+
return extractBasicInfo(content, type);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
function extractBasicInfo(content, type) {
|
|
1254
|
+
const titleMatch = content.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
1255
|
+
const descMatch = content.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']+)["']/i);
|
|
1256
|
+
const parts = [];
|
|
1257
|
+
if (titleMatch) {
|
|
1258
|
+
parts.push(`\u6807\u9898: ${titleMatch[1]}`);
|
|
1259
|
+
}
|
|
1260
|
+
if (descMatch) {
|
|
1261
|
+
parts.push(`\u63CF\u8FF0: ${descMatch[1]}`);
|
|
1262
|
+
}
|
|
1263
|
+
parts.push(`\u8D44\u6E90\u7C7B\u578B: ${type}`);
|
|
1264
|
+
return parts.join("\n");
|
|
1265
|
+
}
|
|
1052
1266
|
function generateComplexityBar(score) {
|
|
1053
1267
|
const filled = Math.round(score / 2);
|
|
1054
1268
|
const empty = 5 - filled;
|
|
@@ -1058,6 +1272,7 @@ function getPhaseLabel(phase) {
|
|
|
1058
1272
|
const labels = {
|
|
1059
1273
|
context: "\u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6",
|
|
1060
1274
|
clarify: "\u9700\u6C42\u6F84\u6E05",
|
|
1275
|
+
reference: "\u53C2\u8003\u8D44\u6E90\u5206\u6790",
|
|
1061
1276
|
analysis: "\u590D\u6742\u5EA6\u8BC4\u4F30",
|
|
1062
1277
|
bdd: "BDD \u573A\u666F\u62C6\u89E3",
|
|
1063
1278
|
spec: "OpenSpec \u89C4\u683C",
|