@nick848/sf-cli 1.0.7 → 1.0.10
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 +44 -0
- package/dist/cli/index.js +4777 -4618
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +374 -382
- package/dist/index.d.ts +374 -382
- package/dist/index.js +733 -716
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +725 -709
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var chalk9 = require('chalk');
|
|
3
4
|
var fs4 = require('fs/promises');
|
|
4
|
-
var fs10 = require('fs');
|
|
5
5
|
var path4 = require('path');
|
|
6
|
+
var fs10 = require('fs');
|
|
6
7
|
var crypto = require('crypto');
|
|
7
8
|
var os = require('os');
|
|
8
9
|
var tiktoken = require('tiktoken');
|
|
9
10
|
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
|
|
10
11
|
var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
11
|
-
var chalk9 = require('chalk');
|
|
12
12
|
var uuid = require('uuid');
|
|
13
13
|
var enquirer = require('enquirer');
|
|
14
14
|
var child_process = require('child_process');
|
|
@@ -33,14 +33,567 @@ function _interopNamespace(e) {
|
|
|
33
33
|
return Object.freeze(n);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
|
|
36
37
|
var fs4__namespace = /*#__PURE__*/_interopNamespace(fs4);
|
|
37
|
-
var fs10__namespace = /*#__PURE__*/_interopNamespace(fs10);
|
|
38
38
|
var path4__namespace = /*#__PURE__*/_interopNamespace(path4);
|
|
39
|
+
var fs10__namespace = /*#__PURE__*/_interopNamespace(fs10);
|
|
39
40
|
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
40
41
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
41
|
-
|
|
42
|
+
|
|
43
|
+
var __defProp = Object.defineProperty;
|
|
44
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
45
|
+
var __esm = (fn, res) => function __init() {
|
|
46
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
47
|
+
};
|
|
48
|
+
var __export = (target, all) => {
|
|
49
|
+
for (var name in all)
|
|
50
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// node_modules/tsup/assets/cjs_shims.js
|
|
54
|
+
var init_cjs_shims = __esm({
|
|
55
|
+
"node_modules/tsup/assets/cjs_shims.js"() {
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/commands/new.ts
|
|
60
|
+
var new_exports = {};
|
|
61
|
+
__export(new_exports, {
|
|
62
|
+
clearActiveSession: () => clearActiveSession,
|
|
63
|
+
default: () => new_default,
|
|
64
|
+
getActiveSession: () => getActiveSession,
|
|
65
|
+
handleNew: () => handleNew,
|
|
66
|
+
handleWorkflowInput: () => handleWorkflowInput
|
|
67
|
+
});
|
|
68
|
+
async function handleNew(args, ctx) {
|
|
69
|
+
ctx.options.workingDirectory;
|
|
70
|
+
if (activeSession) {
|
|
71
|
+
return handleActiveSession();
|
|
72
|
+
}
|
|
73
|
+
const requirement = args.join(" ").trim();
|
|
74
|
+
if (!requirement) {
|
|
75
|
+
return {
|
|
76
|
+
output: chalk9__default.default.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9__default.default.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>")
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
activeSession = {
|
|
80
|
+
id: generateSessionId(),
|
|
81
|
+
requirement,
|
|
82
|
+
phase: "context",
|
|
83
|
+
context: null,
|
|
84
|
+
complexity: 0,
|
|
85
|
+
bddScenarios: [],
|
|
86
|
+
specItems: [],
|
|
87
|
+
testFiles: [],
|
|
88
|
+
implFiles: [],
|
|
89
|
+
reviewPassed: false,
|
|
90
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
91
|
+
};
|
|
92
|
+
return executeWorkflow(ctx);
|
|
93
|
+
}
|
|
94
|
+
function handleActiveSession(ctx) {
|
|
95
|
+
if (!activeSession) {
|
|
96
|
+
return { output: chalk9__default.default.red("\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") };
|
|
97
|
+
}
|
|
98
|
+
const lines = [];
|
|
99
|
+
lines.push(chalk9__default.default.cyan("\u{1F4CB} \u5F53\u524D\u5DE5\u4F5C\u6D41\u72B6\u6001"));
|
|
100
|
+
lines.push("");
|
|
101
|
+
lines.push(chalk9__default.default.white(`\u9700\u6C42: ${activeSession.requirement}`));
|
|
102
|
+
lines.push(chalk9__default.default.gray(`\u9636\u6BB5: ${getPhaseLabel(activeSession.phase)}`));
|
|
103
|
+
lines.push("");
|
|
104
|
+
if (activeSession.phase === "spec") {
|
|
105
|
+
lines.push(chalk9__default.default.yellow("\u23F8\uFE0F \u7B49\u5F85\u89C4\u683C\u786E\u8BA4"));
|
|
106
|
+
lines.push("");
|
|
107
|
+
lines.push(chalk9__default.default.green(" y - \u786E\u8BA4\u89C4\u683C\uFF0C\u7EE7\u7EED\u5DE5\u4F5C\u6D41"));
|
|
108
|
+
lines.push(chalk9__default.default.red(" n - \u4E0D\u6EE1\u610F\uFF0C\u91CD\u65B0\u751F\u6210\u89C4\u683C"));
|
|
109
|
+
lines.push(chalk9__default.default.gray(" c - \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41"));
|
|
110
|
+
} else {
|
|
111
|
+
lines.push(chalk9__default.default.yellow("\u5DE5\u4F5C\u6D41\u8FDB\u884C\u4E2D..."));
|
|
112
|
+
lines.push(chalk9__default.default.gray("\u8F93\u5165\u4EFB\u610F\u5185\u5BB9\u7EE7\u7EED"));
|
|
113
|
+
}
|
|
114
|
+
return { output: lines.join("\n") };
|
|
115
|
+
}
|
|
116
|
+
async function executeWorkflow(ctx) {
|
|
117
|
+
if (!activeSession) {
|
|
118
|
+
return { output: chalk9__default.default.red("\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") };
|
|
119
|
+
}
|
|
120
|
+
const lines = [];
|
|
121
|
+
try {
|
|
122
|
+
if (activeSession.phase === "context") {
|
|
123
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/7: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
|
|
124
|
+
lines.push("");
|
|
125
|
+
activeSession.context = await readProjectContext(ctx.options.workingDirectory);
|
|
126
|
+
lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
|
|
127
|
+
lines.push(chalk9__default.default.gray(` \u7C7B\u578B: ${activeSession.context.type}`));
|
|
128
|
+
lines.push(chalk9__default.default.gray(` \u6846\u67B6: ${activeSession.context.framework || "\u672A\u8BC6\u522B"}`));
|
|
129
|
+
lines.push(chalk9__default.default.gray(` \u6280\u672F\u6808: ${activeSession.context.techStack.join(", ") || "\u672A\u8BC6\u522B"}`));
|
|
130
|
+
if (activeSession.context.devStandards) {
|
|
131
|
+
lines.push(chalk9__default.default.green(" \u2713 \u5DF2\u8BFB\u53D6\u5F00\u53D1\u89C4\u8303"));
|
|
132
|
+
}
|
|
133
|
+
activeSession.phase = "analysis";
|
|
134
|
+
}
|
|
135
|
+
if (activeSession.phase === "analysis") {
|
|
136
|
+
lines.push("");
|
|
137
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/7: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
|
|
138
|
+
lines.push("");
|
|
139
|
+
activeSession.complexity = analyzeComplexity(activeSession.requirement, activeSession.context);
|
|
140
|
+
const complexityBar = generateComplexityBar(activeSession.complexity);
|
|
141
|
+
lines.push(chalk9__default.default.gray(` \u590D\u6742\u5EA6: ${complexityBar} ${activeSession.complexity}/10`));
|
|
142
|
+
if (activeSession.complexity >= COMPLEXITY_THRESHOLD) {
|
|
143
|
+
lines.push(chalk9__default.default.yellow(" \u5224\u5B9A: \u590D\u6742\u9700\u6C42\uFF0C\u5EFA\u8BAE\u67B6\u6784\u5E08\u4ECB\u5165"));
|
|
144
|
+
} else {
|
|
145
|
+
lines.push(chalk9__default.default.green(" \u5224\u5B9A: \u7B80\u5355\u9700\u6C42\uFF0C\u76F4\u63A5\u8FDB\u5165\u89C4\u683C\u62C6\u89E3"));
|
|
146
|
+
}
|
|
147
|
+
activeSession.phase = "bdd";
|
|
148
|
+
}
|
|
149
|
+
if (activeSession.phase === "bdd") {
|
|
150
|
+
lines.push("");
|
|
151
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/7: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
|
|
152
|
+
lines.push("");
|
|
153
|
+
activeSession.bddScenarios = generateBDDScenarios(activeSession.requirement, activeSession.context);
|
|
154
|
+
for (const scenario of activeSession.bddScenarios) {
|
|
155
|
+
lines.push(chalk9__default.default.white(` Feature: ${scenario.feature}`));
|
|
156
|
+
for (const s of scenario.scenarios.slice(0, 3)) {
|
|
157
|
+
lines.push(chalk9__default.default.gray(` - ${s.name}`));
|
|
158
|
+
}
|
|
159
|
+
if (scenario.scenarios.length > 3) {
|
|
160
|
+
lines.push(chalk9__default.default.gray(` ... \u5171 ${scenario.scenarios.length} \u4E2A\u573A\u666F`));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
activeSession.phase = "spec";
|
|
164
|
+
}
|
|
165
|
+
if (activeSession.phase === "spec") {
|
|
166
|
+
lines.push("");
|
|
167
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/7: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
|
|
168
|
+
lines.push("");
|
|
169
|
+
activeSession.specItems = generateSpecItems(activeSession.requirement, activeSession.context, activeSession.bddScenarios);
|
|
170
|
+
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
171
|
+
lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
172
|
+
lines.push(chalk9__default.default.gray(` \u8DEF\u5F84: ${specPath}`));
|
|
173
|
+
lines.push("");
|
|
174
|
+
lines.push(chalk9__default.default.cyan(" \u4EFB\u52A1\u6982\u89C8:"));
|
|
175
|
+
for (const item of activeSession.specItems.slice(0, 5)) {
|
|
176
|
+
const icon = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
177
|
+
lines.push(chalk9__default.default.gray(` ${icon} [${item.id}] ${item.title}`));
|
|
178
|
+
}
|
|
179
|
+
if (activeSession.specItems.length > 5) {
|
|
180
|
+
lines.push(chalk9__default.default.gray(` ... \u5171 ${activeSession.specItems.length} \u4E2A\u4EFB\u52A1`));
|
|
181
|
+
}
|
|
182
|
+
lines.push("");
|
|
183
|
+
lines.push(chalk9__default.default.yellow.bold("\u23F8\uFE0F \u7B49\u5F85\u89C4\u683C\u786E\u8BA4"));
|
|
184
|
+
lines.push("");
|
|
185
|
+
lines.push(chalk9__default.default.green(" y - \u786E\u8BA4\u89C4\u683C\uFF0C\u7EE7\u7EED\u5DE5\u4F5C\u6D41"));
|
|
186
|
+
lines.push(chalk9__default.default.red(" n - \u4E0D\u6EE1\u610F\uFF0C\u91CD\u65B0\u751F\u6210\u89C4\u683C"));
|
|
187
|
+
lines.push(chalk9__default.default.gray(" c - \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41"));
|
|
188
|
+
return { output: lines.join("\n") };
|
|
189
|
+
}
|
|
190
|
+
if (activeSession.phase === "tdd") {
|
|
191
|
+
lines.push("");
|
|
192
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/7: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
|
|
193
|
+
lines.push("");
|
|
194
|
+
activeSession.testFiles = await generateTests(ctx.options.workingDirectory, activeSession);
|
|
195
|
+
lines.push(chalk9__default.default.green(" \u2713 \u6D4B\u8BD5\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
196
|
+
for (const file of activeSession.testFiles) {
|
|
197
|
+
lines.push(chalk9__default.default.gray(` - ${file}`));
|
|
198
|
+
}
|
|
199
|
+
activeSession.phase = "develop";
|
|
200
|
+
}
|
|
201
|
+
if (activeSession.phase === "develop") {
|
|
202
|
+
lines.push("");
|
|
203
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/7: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
|
|
204
|
+
lines.push("");
|
|
205
|
+
lines.push(chalk9__default.default.yellow(" \u{1F4DD} \u5F00\u53D1\u9636\u6BB5"));
|
|
206
|
+
lines.push(chalk9__default.default.gray(" \u8BF7\u8C03\u7528 $frontend-dev \u6267\u884C\u5F00\u53D1\u4EFB\u52A1"));
|
|
207
|
+
lines.push(chalk9__default.default.gray(" \u6216\u624B\u52A8\u5B9E\u73B0\u4EE3\u7801\u540E\u8F93\u5165 continue \u7EE7\u7EED"));
|
|
208
|
+
return { output: lines.join("\n") };
|
|
209
|
+
}
|
|
210
|
+
if (activeSession.phase === "review") {
|
|
211
|
+
lines.push("");
|
|
212
|
+
lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/7: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
|
|
213
|
+
lines.push("");
|
|
214
|
+
lines.push(chalk9__default.default.yellow(" \u{1F50D} \u4EE3\u7801\u5BA1\u6838\u9636\u6BB5"));
|
|
215
|
+
lines.push(chalk9__default.default.gray(" \u8BF7\u8C03\u7528 $code-reviewer \u6267\u884C\u4EE3\u7801\u5BA1\u6838"));
|
|
216
|
+
lines.push(chalk9__default.default.gray(" \u6216\u8F93\u5165 review \u5B8C\u6210\u5BA1\u6838"));
|
|
217
|
+
}
|
|
218
|
+
return { output: lines.join("\n") };
|
|
219
|
+
} catch (error) {
|
|
220
|
+
lines.push(chalk9__default.default.red(`\u9519\u8BEF: ${error.message}`));
|
|
221
|
+
return { output: lines.join("\n") };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function handleWorkflowInput(input, ctx) {
|
|
225
|
+
if (!activeSession) return null;
|
|
226
|
+
const trimmed = input.trim().toLowerCase();
|
|
227
|
+
if (trimmed === "c" || trimmed === "cancel" || trimmed === "\u53D6\u6D88") {
|
|
228
|
+
activeSession = null;
|
|
229
|
+
return {
|
|
230
|
+
output: chalk9__default.default.yellow("\u2713 \u5DE5\u4F5C\u6D41\u5DF2\u53D6\u6D88")
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
if (activeSession.phase === "spec") {
|
|
234
|
+
if (trimmed === "y" || trimmed === "yes" || trimmed === "\u786E\u8BA4") {
|
|
235
|
+
activeSession.phase = "tdd";
|
|
236
|
+
return executeWorkflow(ctx);
|
|
237
|
+
}
|
|
238
|
+
if (trimmed === "n" || trimmed === "no" || trimmed === "\u91CD\u65B0") {
|
|
239
|
+
activeSession.bddScenarios = generateBDDScenarios(activeSession.requirement, activeSession.context);
|
|
240
|
+
activeSession.specItems = generateSpecItems(activeSession.requirement, activeSession.context, activeSession.bddScenarios);
|
|
241
|
+
const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
|
|
242
|
+
return {
|
|
243
|
+
output: chalk9__default.default.cyan("\u{1F504} \u89C4\u683C\u5DF2\u91CD\u65B0\u751F\u6210") + chalk9__default.default.gray(`
|
|
244
|
+
\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 - \u518D\u6B21\u91CD\u65B0\u751F\u6210")
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (activeSession.phase === "develop") {
|
|
249
|
+
if (trimmed === "continue" || trimmed === "\u7EE7\u7EED" || trimmed === "done" || trimmed === "\u5B8C\u6210") {
|
|
250
|
+
activeSession.phase = "review";
|
|
251
|
+
return executeWorkflow(ctx);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (activeSession.phase === "review") {
|
|
255
|
+
if (trimmed === "review" || trimmed === "\u5BA1\u6838" || trimmed === "pass" || trimmed === "\u901A\u8FC7") {
|
|
256
|
+
await archiveWorkflow(ctx.options.workingDirectory);
|
|
257
|
+
const summary = activeSession.requirement;
|
|
258
|
+
activeSession = null;
|
|
259
|
+
return {
|
|
260
|
+
output: chalk9__default.default.green("\u2713 \u5DE5\u4F5C\u6D41\u5DF2\u5B8C\u6210") + chalk9__default.default.gray(`
|
|
261
|
+
\u9700\u6C42: ${summary}`) + chalk9__default.default.cyan("\n\n\u4F7F\u7528 /new <\u9700\u6C42> \u5F00\u59CB\u65B0\u7684\u5DE5\u4F5C\u6D41")
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (trimmed === "fail" || trimmed === "\u5931\u8D25" || trimmed === "reject" || trimmed === "\u62D2\u7EDD") {
|
|
265
|
+
activeSession.phase = "spec";
|
|
266
|
+
return {
|
|
267
|
+
output: chalk9__default.default.yellow("\u21A9\uFE0F \u5BA1\u6838\u672A\u901A\u8FC7\uFF0C\u56DE\u9000\u5230\u89C4\u683C\u9636\u6BB5") + chalk9__default.default.gray("\n\u8BF7\u91CD\u65B0\u786E\u8BA4\u6216\u4FEE\u6539\u89C4\u683C") + chalk9__default.default.yellow("\n\n\u4F7F\u7528 y \u786E\u8BA4\uFF0Cn \u91CD\u65B0\u751F\u6210")
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
async function readProjectContext(workingDir) {
|
|
274
|
+
const context = {
|
|
275
|
+
name: path4__namespace.basename(workingDir),
|
|
276
|
+
type: "unknown",
|
|
277
|
+
framework: null,
|
|
278
|
+
techStack: [],
|
|
279
|
+
description: "",
|
|
280
|
+
devStandards: "",
|
|
281
|
+
agentsMd: "",
|
|
282
|
+
configYaml: ""
|
|
283
|
+
};
|
|
284
|
+
const agentsPath = path4__namespace.join(workingDir, "AGENTS.md");
|
|
285
|
+
try {
|
|
286
|
+
const stats = await fs4__namespace.stat(agentsPath);
|
|
287
|
+
if (stats.size <= MAX_FILE_SIZE2) {
|
|
288
|
+
context.agentsMd = await fs4__namespace.readFile(agentsPath, "utf-8");
|
|
289
|
+
const nameMatch = context.agentsMd.match(/\|\s*项目名称\s*\|\s*([^\s|]+)/);
|
|
290
|
+
if (nameMatch) context.name = nameMatch[1];
|
|
291
|
+
const typeMatch = context.agentsMd.match(/\|\s*项目类型\s*\|\s*([^\s|]+)/);
|
|
292
|
+
if (typeMatch) context.type = typeMatch[1];
|
|
293
|
+
const frameworkMatch = context.agentsMd.match(/\|\s*技术框架\s*\|\s*([^\s|]+)/);
|
|
294
|
+
if (frameworkMatch && frameworkMatch[1] !== "\u5F85\u8BC6\u522B") {
|
|
295
|
+
context.framework = frameworkMatch[1];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} catch {
|
|
299
|
+
}
|
|
300
|
+
const configPath = path4__namespace.join(workingDir, "openspec", "config.yaml");
|
|
301
|
+
try {
|
|
302
|
+
const stats = await fs4__namespace.stat(configPath);
|
|
303
|
+
if (stats.size <= MAX_FILE_SIZE2) {
|
|
304
|
+
context.configYaml = await fs4__namespace.readFile(configPath, "utf-8");
|
|
305
|
+
const nameMatch = context.configYaml.match(/name:\s*(.+)/);
|
|
306
|
+
if (nameMatch) context.name = nameMatch[1].trim();
|
|
307
|
+
const typeMatch = context.configYaml.match(/type:\s*(.+)/);
|
|
308
|
+
if (typeMatch) context.type = typeMatch[1].trim();
|
|
309
|
+
const frameworkMatch = context.configYaml.match(/framework:\s*(.+)/);
|
|
310
|
+
if (frameworkMatch && frameworkMatch[1].trim() !== "null") {
|
|
311
|
+
context.framework = frameworkMatch[1].trim();
|
|
312
|
+
}
|
|
313
|
+
const techStackMatch = context.configYaml.match(/techStack:\s*([\s\S]+?)(?=\n\w)/);
|
|
314
|
+
if (techStackMatch) {
|
|
315
|
+
const techLines = techStackMatch[1].match(/-\s*(.+)/g);
|
|
316
|
+
if (techLines) {
|
|
317
|
+
context.techStack = techLines.map((l) => l.replace(/-\s*/, "").trim());
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
} catch {
|
|
322
|
+
}
|
|
323
|
+
const devStandardsPath = path4__namespace.join(workingDir, ".sf-cli", "norms", "devstanded.md");
|
|
324
|
+
try {
|
|
325
|
+
const stats = await fs4__namespace.stat(devStandardsPath);
|
|
326
|
+
if (stats.size <= MAX_FILE_SIZE2) {
|
|
327
|
+
context.devStandards = await fs4__namespace.readFile(devStandardsPath, "utf-8");
|
|
328
|
+
}
|
|
329
|
+
} catch {
|
|
330
|
+
}
|
|
331
|
+
return context;
|
|
332
|
+
}
|
|
333
|
+
function analyzeComplexity(requirement, context) {
|
|
334
|
+
let score = 3;
|
|
335
|
+
if (requirement.length > 100) score += 1;
|
|
336
|
+
if (requirement.length > 200) score += 1;
|
|
337
|
+
const complexKeywords = ["\u67B6\u6784", "\u91CD\u6784", "\u8FC1\u79FB", "\u96C6\u6210", "\u7CFB\u7EDF", "\u6A21\u5757", "\u5DE5\u4F5C\u6D41", "\u6D41\u7A0B", "\u6743\u9650", "\u5B89\u5168"];
|
|
338
|
+
for (const keyword of complexKeywords) {
|
|
339
|
+
if (requirement.includes(keyword)) score += 1;
|
|
340
|
+
}
|
|
341
|
+
const simpleKeywords = ["\u4FEE\u590D", "\u8C03\u6574", "\u4F18\u5316", "\u66F4\u65B0", "\u6DFB\u52A0", "\u6837\u5F0F", "\u6587\u672C"];
|
|
342
|
+
for (const keyword of simpleKeywords) {
|
|
343
|
+
if (requirement.includes(keyword)) score -= 0.5;
|
|
344
|
+
}
|
|
345
|
+
const connectors = ["\u548C", "\u4EE5\u53CA", "\u540C\u65F6", "\u53E6\u5916", "\u6B64\u5916", "\u3001"];
|
|
346
|
+
for (const conn of connectors) {
|
|
347
|
+
const count = (requirement.match(new RegExp(conn, "g")) || []).length;
|
|
348
|
+
score += count * 0.3;
|
|
349
|
+
}
|
|
350
|
+
if (requirement.match(/https?:\/\//)) score += 0.5;
|
|
351
|
+
if (!context.framework) score += 0.5;
|
|
352
|
+
return Math.max(1, Math.min(10, Math.round(score)));
|
|
353
|
+
}
|
|
354
|
+
function generateBDDScenarios(requirement, context) {
|
|
355
|
+
const scenarios = [];
|
|
356
|
+
const features = extractFeatures(requirement);
|
|
357
|
+
for (const feature of features) {
|
|
358
|
+
const scenario = {
|
|
359
|
+
feature: feature.title,
|
|
360
|
+
description: feature.description,
|
|
361
|
+
scenarios: []
|
|
362
|
+
};
|
|
363
|
+
scenario.scenarios.push({
|
|
364
|
+
name: `\u6B63\u5E38\u6D41\u7A0B: ${feature.title}`,
|
|
365
|
+
given: [`\u7528\u6237\u8FDB\u5165\u76F8\u5173\u9875\u9762`],
|
|
366
|
+
when: [`\u7528\u6237\u6267\u884C "${feature.title}" \u64CD\u4F5C`],
|
|
367
|
+
then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5E76\u8FD4\u56DE\u9884\u671F\u7ED3\u679C`]
|
|
368
|
+
});
|
|
369
|
+
if (feature.hasInput) {
|
|
370
|
+
scenario.scenarios.push({
|
|
371
|
+
name: `\u8FB9\u754C\u60C5\u51B5: \u8F93\u5165\u9A8C\u8BC1`,
|
|
372
|
+
given: [`\u7528\u6237\u8FDB\u5165\u8F93\u5165\u754C\u9762`],
|
|
373
|
+
when: [`\u7528\u6237\u8F93\u5165\u8FB9\u754C\u503C\u6216\u7A7A\u503C`],
|
|
374
|
+
then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u8FB9\u754C\u60C5\u51B5`]
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
scenarios.push(scenario);
|
|
378
|
+
}
|
|
379
|
+
return scenarios;
|
|
380
|
+
}
|
|
381
|
+
function extractFeatures(requirement) {
|
|
382
|
+
const features = [];
|
|
383
|
+
const urlMatch = requirement.match(/https?:\/\/[^\s]+/);
|
|
384
|
+
if (urlMatch) {
|
|
385
|
+
features.push({
|
|
386
|
+
title: "\u53C2\u8003\u754C\u9762\u5206\u6790",
|
|
387
|
+
description: `\u5206\u6790\u53C2\u8003\u754C\u9762 ${urlMatch[0]}`,
|
|
388
|
+
hasInput: false
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
const featurePatterns = [
|
|
392
|
+
{ pattern: /排盘|计算|算法/, title: "\u6838\u5FC3\u7B97\u6CD5\u5B9E\u73B0", hasInput: true },
|
|
393
|
+
{ pattern: /界面|UI|页面|显示|展示/, title: "\u754C\u9762\u5F00\u53D1", hasInput: true },
|
|
394
|
+
{ pattern: /表格|列表/, title: "\u6570\u636E\u5C55\u793A", hasInput: false },
|
|
395
|
+
{ pattern: /图表|图形|可视化/, title: "\u56FE\u8868\u53EF\u89C6\u5316", hasInput: false },
|
|
396
|
+
{ pattern: /表单|输入/, title: "\u8868\u5355\u5904\u7406", hasInput: true },
|
|
397
|
+
{ pattern: /登录|注册|认证/, title: "\u7528\u6237\u8BA4\u8BC1", hasInput: true },
|
|
398
|
+
{ pattern: /接口|API/, title: "API \u63A5\u53E3", hasInput: false },
|
|
399
|
+
{ pattern: /存储|缓存/, title: "\u6570\u636E\u5B58\u50A8", hasInput: false },
|
|
400
|
+
{ pattern: /导出|下载/, title: "\u5BFC\u51FA\u529F\u80FD", hasInput: false },
|
|
401
|
+
{ pattern: /配置|设置/, title: "\u914D\u7F6E\u7BA1\u7406", hasInput: true }
|
|
402
|
+
];
|
|
403
|
+
for (const { pattern, title, hasInput } of featurePatterns) {
|
|
404
|
+
if (pattern.test(requirement)) {
|
|
405
|
+
features.push({
|
|
406
|
+
title,
|
|
407
|
+
description: `${title}\u76F8\u5173\u529F\u80FD`,
|
|
408
|
+
hasInput
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (features.length === 0) {
|
|
413
|
+
features.push({
|
|
414
|
+
title: "\u6838\u5FC3\u529F\u80FD\u5B9E\u73B0",
|
|
415
|
+
description: requirement,
|
|
416
|
+
hasInput: true
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
return features;
|
|
420
|
+
}
|
|
421
|
+
function generateSpecItems(requirement, context, bddScenarios) {
|
|
422
|
+
const items = [];
|
|
423
|
+
let id = 1;
|
|
424
|
+
for (const scenario of bddScenarios) {
|
|
425
|
+
items.push({
|
|
426
|
+
id: `T${id.toString().padStart(3, "0")}`,
|
|
427
|
+
title: scenario.feature,
|
|
428
|
+
description: scenario.description,
|
|
429
|
+
priority: id <= 2 ? "high" : "medium",
|
|
430
|
+
files: [],
|
|
431
|
+
tests: []
|
|
432
|
+
});
|
|
433
|
+
id++;
|
|
434
|
+
}
|
|
435
|
+
items.push({
|
|
436
|
+
id: `T${id.toString().padStart(3, "0")}`,
|
|
437
|
+
title: "\u5355\u5143\u6D4B\u8BD5",
|
|
438
|
+
description: "\u7F16\u5199\u6D4B\u8BD5\u7528\u4F8B\u786E\u4FDD\u529F\u80FD\u6B63\u786E\u6027",
|
|
439
|
+
priority: "medium",
|
|
440
|
+
files: [],
|
|
441
|
+
tests: []
|
|
442
|
+
});
|
|
443
|
+
return items;
|
|
444
|
+
}
|
|
445
|
+
async function saveSpecFile(workingDir, session) {
|
|
446
|
+
const specDir = path4__namespace.join(workingDir, "openspec", "changes");
|
|
447
|
+
await fs4__namespace.mkdir(specDir, { recursive: true });
|
|
448
|
+
const specPath = path4__namespace.join(specDir, `${session.id}-spec.md`);
|
|
449
|
+
const content = formatSpecFile(session);
|
|
450
|
+
await fs4__namespace.writeFile(specPath, content, "utf-8");
|
|
451
|
+
return specPath;
|
|
452
|
+
}
|
|
453
|
+
function formatSpecFile(session) {
|
|
454
|
+
const lines = [];
|
|
455
|
+
lines.push(`# \u9700\u6C42\u89C4\u683C: ${session.requirement.slice(0, 50)}`);
|
|
456
|
+
lines.push("");
|
|
457
|
+
lines.push(`> \u53D8\u66F4ID: ${session.id}`);
|
|
458
|
+
lines.push(`> \u590D\u6742\u5EA6: ${session.complexity}/10`);
|
|
459
|
+
lines.push(`> \u751F\u6210\u65F6\u95F4: ${session.createdAt.toISOString()}`);
|
|
460
|
+
lines.push("");
|
|
461
|
+
lines.push("---");
|
|
462
|
+
lines.push("");
|
|
463
|
+
lines.push("## BDD \u573A\u666F");
|
|
464
|
+
lines.push("");
|
|
465
|
+
for (const scenario of session.bddScenarios) {
|
|
466
|
+
lines.push(`### Feature: ${scenario.feature}`);
|
|
467
|
+
lines.push("");
|
|
468
|
+
for (const s of scenario.scenarios) {
|
|
469
|
+
lines.push(`**Scenario: ${s.name}**`);
|
|
470
|
+
for (const g of s.given) lines.push(` Given ${g}`);
|
|
471
|
+
for (const w of s.when) lines.push(` When ${w}`);
|
|
472
|
+
for (const t of s.then) lines.push(` Then ${t}`);
|
|
473
|
+
lines.push("");
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
lines.push("## \u4EFB\u52A1\u5217\u8868");
|
|
477
|
+
lines.push("");
|
|
478
|
+
for (const item of session.specItems) {
|
|
479
|
+
const priority = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
480
|
+
lines.push(`- [ ] ${priority} [${item.id}] ${item.title}`);
|
|
481
|
+
}
|
|
482
|
+
lines.push("");
|
|
483
|
+
lines.push("---");
|
|
484
|
+
lines.push("");
|
|
485
|
+
lines.push("**\u786E\u8BA4\u72B6\u6001**: \u23F3 \u7B49\u5F85\u786E\u8BA4");
|
|
486
|
+
return lines.join("\n");
|
|
487
|
+
}
|
|
488
|
+
async function generateTests(workingDir, session) {
|
|
489
|
+
const testDir = path4__namespace.join(workingDir, "tests");
|
|
490
|
+
await fs4__namespace.mkdir(testDir, { recursive: true });
|
|
491
|
+
const testFiles = [];
|
|
492
|
+
for (const scenario of session.bddScenarios) {
|
|
493
|
+
const testName = scenario.feature.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_");
|
|
494
|
+
const testPath = path4__namespace.join(testDir, `${testName}.test.ts`);
|
|
495
|
+
const content = generateTestFile(scenario);
|
|
496
|
+
await fs4__namespace.writeFile(testPath, content, "utf-8");
|
|
497
|
+
testFiles.push(`tests/${testName}.test.ts`);
|
|
498
|
+
}
|
|
499
|
+
return testFiles;
|
|
500
|
+
}
|
|
501
|
+
function generateTestFile(scenario) {
|
|
502
|
+
const lines = [];
|
|
503
|
+
lines.push(`import { describe, it, expect } from 'vitest';`);
|
|
504
|
+
lines.push("");
|
|
505
|
+
lines.push(`describe('${scenario.feature}', () => {`);
|
|
506
|
+
for (const s of scenario.scenarios) {
|
|
507
|
+
lines.push(` it('${s.name}', () => {`);
|
|
508
|
+
lines.push(` // Given: ${s.given.join(", ")}`);
|
|
509
|
+
lines.push(` // When: ${s.when.join(", ")}`);
|
|
510
|
+
lines.push(` // Then: ${s.then.join(", ")}`);
|
|
511
|
+
lines.push(` expect(true).toBe(true); // TODO: \u5B9E\u73B0\u6D4B\u8BD5`);
|
|
512
|
+
lines.push(` });`);
|
|
513
|
+
lines.push("");
|
|
514
|
+
}
|
|
515
|
+
lines.push(`});`);
|
|
516
|
+
return lines.join("\n");
|
|
517
|
+
}
|
|
518
|
+
async function archiveWorkflow(workingDir) {
|
|
519
|
+
if (!activeSession) return;
|
|
520
|
+
const archiveDir = path4__namespace.join(workingDir, "openspec", "spec");
|
|
521
|
+
await fs4__namespace.mkdir(archiveDir, { recursive: true });
|
|
522
|
+
const archivePath = path4__namespace.join(archiveDir, `${activeSession.id}.md`);
|
|
523
|
+
const content = `# \u5F52\u6863: ${activeSession.requirement.slice(0, 50)}
|
|
524
|
+
|
|
525
|
+
> \u5F52\u6863\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
526
|
+
> \u590D\u6742\u5EA6: ${activeSession.complexity}/10
|
|
527
|
+
|
|
528
|
+
## \u5B8C\u6210\u60C5\u51B5
|
|
529
|
+
|
|
530
|
+
- [x] \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6
|
|
531
|
+
- [x] \u590D\u6742\u5EA6\u8BC4\u4F30
|
|
532
|
+
- [x] BDD \u573A\u666F\u62C6\u89E3
|
|
533
|
+
- [x] OpenSpec \u89C4\u683C
|
|
534
|
+
- [x] TDD \u6D4B\u8BD5\u751F\u6210
|
|
535
|
+
- [x] \u5F00\u53D1\u5B9E\u73B0
|
|
536
|
+
- [x] \u4EE3\u7801\u5BA1\u6838
|
|
537
|
+
|
|
538
|
+
## \u6D4B\u8BD5\u6587\u4EF6
|
|
539
|
+
|
|
540
|
+
${activeSession.testFiles.map((f) => `- ${f}`).join("\n") || "\u65E0"}
|
|
541
|
+
`;
|
|
542
|
+
await fs4__namespace.writeFile(archivePath, content, "utf-8");
|
|
543
|
+
}
|
|
544
|
+
function generateSessionId() {
|
|
545
|
+
const timestamp = Date.now().toString(36);
|
|
546
|
+
const random = Math.random().toString(36).slice(2, 6);
|
|
547
|
+
return `WF-${timestamp}-${random}`.toUpperCase();
|
|
548
|
+
}
|
|
549
|
+
function generateComplexityBar(score) {
|
|
550
|
+
const filled = Math.round(score / 2);
|
|
551
|
+
const empty = 5 - filled;
|
|
552
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
553
|
+
}
|
|
554
|
+
function getPhaseLabel(phase) {
|
|
555
|
+
const labels = {
|
|
556
|
+
context: "\u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6",
|
|
557
|
+
analysis: "\u590D\u6742\u5EA6\u8BC4\u4F30",
|
|
558
|
+
bdd: "BDD \u573A\u666F\u62C6\u89E3",
|
|
559
|
+
spec: "OpenSpec \u89C4\u683C",
|
|
560
|
+
tdd: "TDD \u6D4B\u8BD5\u751F\u6210",
|
|
561
|
+
develop: "\u5F00\u53D1\u5B9E\u73B0",
|
|
562
|
+
review: "\u4EE3\u7801\u5BA1\u6838"
|
|
563
|
+
};
|
|
564
|
+
return labels[phase];
|
|
565
|
+
}
|
|
566
|
+
function getActiveSession() {
|
|
567
|
+
return activeSession;
|
|
568
|
+
}
|
|
569
|
+
function clearActiveSession() {
|
|
570
|
+
activeSession = null;
|
|
571
|
+
}
|
|
572
|
+
var MAX_FILE_SIZE2, COMPLEXITY_THRESHOLD, activeSession, new_default;
|
|
573
|
+
var init_new = __esm({
|
|
574
|
+
"src/commands/new.ts"() {
|
|
575
|
+
init_cjs_shims();
|
|
576
|
+
MAX_FILE_SIZE2 = 1024 * 1024;
|
|
577
|
+
COMPLEXITY_THRESHOLD = 6;
|
|
578
|
+
activeSession = null;
|
|
579
|
+
new_default = handleNew;
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// src/index.ts
|
|
584
|
+
init_cjs_shims();
|
|
585
|
+
|
|
586
|
+
// src/types/index.ts
|
|
587
|
+
init_cjs_shims();
|
|
588
|
+
|
|
589
|
+
// src/types/agent.ts
|
|
590
|
+
init_cjs_shims();
|
|
591
|
+
|
|
592
|
+
// src/types/mcp.ts
|
|
593
|
+
init_cjs_shims();
|
|
42
594
|
|
|
43
595
|
// src/services/config.ts
|
|
596
|
+
init_cjs_shims();
|
|
44
597
|
var DEFAULT_CONFIG = {
|
|
45
598
|
model: "GLM-5",
|
|
46
599
|
apiKey: "",
|
|
@@ -168,7 +721,11 @@ var ConfigManager = class {
|
|
|
168
721
|
}
|
|
169
722
|
};
|
|
170
723
|
|
|
724
|
+
// src/services/model.ts
|
|
725
|
+
init_cjs_shims();
|
|
726
|
+
|
|
171
727
|
// src/types/model.ts
|
|
728
|
+
init_cjs_shims();
|
|
172
729
|
var ModelError = class extends Error {
|
|
173
730
|
code;
|
|
174
731
|
provider;
|
|
@@ -258,6 +815,12 @@ var AVAILABLE_MODELS = [
|
|
|
258
815
|
function getModelInfo(modelId) {
|
|
259
816
|
return AVAILABLE_MODELS.find((m) => m.id === modelId);
|
|
260
817
|
}
|
|
818
|
+
|
|
819
|
+
// src/services/adapters/index.ts
|
|
820
|
+
init_cjs_shims();
|
|
821
|
+
|
|
822
|
+
// src/services/adapters/base.ts
|
|
823
|
+
init_cjs_shims();
|
|
261
824
|
var BaseAdapter = class {
|
|
262
825
|
config = null;
|
|
263
826
|
initialized = false;
|
|
@@ -379,6 +942,7 @@ var BaseAdapter = class {
|
|
|
379
942
|
};
|
|
380
943
|
|
|
381
944
|
// src/services/adapters/glm.ts
|
|
945
|
+
init_cjs_shims();
|
|
382
946
|
var GLMAdapter = class extends BaseAdapter {
|
|
383
947
|
name = "GLM-5";
|
|
384
948
|
provider = "glm";
|
|
@@ -540,6 +1104,7 @@ var GLMAdapter = class extends BaseAdapter {
|
|
|
540
1104
|
};
|
|
541
1105
|
|
|
542
1106
|
// src/services/adapters/openai.ts
|
|
1107
|
+
init_cjs_shims();
|
|
543
1108
|
var OpenAIAdapter = class extends BaseAdapter {
|
|
544
1109
|
name = "OpenAI";
|
|
545
1110
|
provider = "openai";
|
|
@@ -716,6 +1281,7 @@ var OpenAIAdapter = class extends BaseAdapter {
|
|
|
716
1281
|
};
|
|
717
1282
|
|
|
718
1283
|
// src/services/adapters/claude.ts
|
|
1284
|
+
init_cjs_shims();
|
|
719
1285
|
var ClaudeAdapter = class extends BaseAdapter {
|
|
720
1286
|
name = "Claude";
|
|
721
1287
|
provider = "anthropic";
|
|
@@ -1212,6 +1778,12 @@ var ModelService = class {
|
|
|
1212
1778
|
return new ModelError("UNKNOWN_ERROR", err.message, { retryable: false });
|
|
1213
1779
|
}
|
|
1214
1780
|
};
|
|
1781
|
+
|
|
1782
|
+
// src/services/mcp/index.ts
|
|
1783
|
+
init_cjs_shims();
|
|
1784
|
+
|
|
1785
|
+
// src/services/mcp/base.ts
|
|
1786
|
+
init_cjs_shims();
|
|
1215
1787
|
var MCPAdapterBase = class {
|
|
1216
1788
|
client = null;
|
|
1217
1789
|
transport = null;
|
|
@@ -1393,6 +1965,7 @@ var MCPAdapterBase = class {
|
|
|
1393
1965
|
};
|
|
1394
1966
|
|
|
1395
1967
|
// src/services/mcp/lanhu.ts
|
|
1968
|
+
init_cjs_shims();
|
|
1396
1969
|
var LanhuMCPAdapter = class extends MCPAdapterBase {
|
|
1397
1970
|
name = "lanhu";
|
|
1398
1971
|
platform = "lanhu";
|
|
@@ -1771,6 +2344,7 @@ ${children}
|
|
|
1771
2344
|
};
|
|
1772
2345
|
|
|
1773
2346
|
// src/services/mcp/figma.ts
|
|
2347
|
+
init_cjs_shims();
|
|
1774
2348
|
var FigmaMCPAdapter = class extends MCPAdapterBase {
|
|
1775
2349
|
name = "figma";
|
|
1776
2350
|
platform = "figma";
|
|
@@ -1819,17 +2393,17 @@ var FigmaMCPAdapter = class extends MCPAdapterBase {
|
|
|
1819
2393
|
* 解析设计规格
|
|
1820
2394
|
*/
|
|
1821
2395
|
parseDesignSpec(data, url, fileKey, nodeId) {
|
|
1822
|
-
const
|
|
2396
|
+
const document2 = data.document || data;
|
|
1823
2397
|
return {
|
|
1824
2398
|
id: nodeId || fileKey,
|
|
1825
|
-
name:
|
|
2399
|
+
name: document2.name || "\u672A\u547D\u540D\u8BBE\u8BA1\u7A3F",
|
|
1826
2400
|
platform: "figma",
|
|
1827
2401
|
url,
|
|
1828
|
-
width:
|
|
1829
|
-
height:
|
|
2402
|
+
width: document2.absoluteBoundingBox?.width || 0,
|
|
2403
|
+
height: document2.absoluteBoundingBox?.height || 0,
|
|
1830
2404
|
scale: 1,
|
|
1831
|
-
layers: this.parseFigmaLayers(
|
|
1832
|
-
styles: this.extractStylesFromDocument(
|
|
2405
|
+
layers: this.parseFigmaLayers(document2.children || []),
|
|
2406
|
+
styles: this.extractStylesFromDocument(document2),
|
|
1833
2407
|
assets: this.parseAssets(data.assets || []),
|
|
1834
2408
|
extractedAt: /* @__PURE__ */ new Date()
|
|
1835
2409
|
};
|
|
@@ -1925,7 +2499,7 @@ var FigmaMCPAdapter = class extends MCPAdapterBase {
|
|
|
1925
2499
|
/**
|
|
1926
2500
|
* 从文档提取全局样式
|
|
1927
2501
|
*/
|
|
1928
|
-
extractStylesFromDocument(
|
|
2502
|
+
extractStylesFromDocument(document2) {
|
|
1929
2503
|
const styles = {
|
|
1930
2504
|
colors: [],
|
|
1931
2505
|
typography: [],
|
|
@@ -1951,7 +2525,7 @@ var FigmaMCPAdapter = class extends MCPAdapterBase {
|
|
|
1951
2525
|
node.children.forEach(traverse);
|
|
1952
2526
|
}
|
|
1953
2527
|
};
|
|
1954
|
-
traverse(
|
|
2528
|
+
traverse(document2);
|
|
1955
2529
|
styles.colors = this.deduplicateColors(styles.colors);
|
|
1956
2530
|
styles.typography = this.deduplicateTypography(styles.typography);
|
|
1957
2531
|
return styles;
|
|
@@ -2193,6 +2767,7 @@ const Container = styled.div\`
|
|
|
2193
2767
|
};
|
|
2194
2768
|
|
|
2195
2769
|
// src/services/mcp/manager.ts
|
|
2770
|
+
init_cjs_shims();
|
|
2196
2771
|
var MCPManager = class {
|
|
2197
2772
|
adapters = /* @__PURE__ */ new Map();
|
|
2198
2773
|
connectionStates = /* @__PURE__ */ new Map();
|
|
@@ -2437,7 +3012,11 @@ function createMCPManager() {
|
|
|
2437
3012
|
return new MCPManager();
|
|
2438
3013
|
}
|
|
2439
3014
|
|
|
3015
|
+
// src/agents/runner.ts
|
|
3016
|
+
init_cjs_shims();
|
|
3017
|
+
|
|
2440
3018
|
// src/agents/definitions.ts
|
|
3019
|
+
init_cjs_shims();
|
|
2441
3020
|
var FRONTEND_DEV_AGENT = {
|
|
2442
3021
|
id: "frontend-dev",
|
|
2443
3022
|
name: "\u524D\u7AEF\u5F00\u53D1",
|
|
@@ -3062,6 +3641,9 @@ ${divider}
|
|
|
3062
3641
|
|
|
3063
3642
|
${content}`;
|
|
3064
3643
|
}
|
|
3644
|
+
|
|
3645
|
+
// src/agents/executor.ts
|
|
3646
|
+
init_cjs_shims();
|
|
3065
3647
|
var AgentExecutor = class {
|
|
3066
3648
|
modelService;
|
|
3067
3649
|
normsManager;
|
|
@@ -3447,7 +4029,11 @@ function createAgentExecutor(modelService, normsManager, contextManager) {
|
|
|
3447
4029
|
return new AgentExecutor(modelService, normsManager, contextManager);
|
|
3448
4030
|
}
|
|
3449
4031
|
|
|
4032
|
+
// src/agents/index.ts
|
|
4033
|
+
init_cjs_shims();
|
|
4034
|
+
|
|
3450
4035
|
// src/agents/scheduler.ts
|
|
4036
|
+
init_cjs_shims();
|
|
3451
4037
|
var SCHEDULE_RULES = {
|
|
3452
4038
|
"explore": {
|
|
3453
4039
|
agent: "architect",
|
|
@@ -3625,7 +4211,11 @@ function getScheduleRuleDescription(step) {
|
|
|
3625
4211
|
return `${strategyText[rule.strategy]} $${rule.agent} (${agent?.name})`;
|
|
3626
4212
|
}
|
|
3627
4213
|
|
|
4214
|
+
// src/workflow/index.ts
|
|
4215
|
+
init_cjs_shims();
|
|
4216
|
+
|
|
3628
4217
|
// src/workflow/checkpoint.ts
|
|
4218
|
+
init_cjs_shims();
|
|
3629
4219
|
var DEFAULT_CONFIRMATION_POINTS = [
|
|
3630
4220
|
{
|
|
3631
4221
|
type: "spec-review",
|
|
@@ -3667,8 +4257,8 @@ var ROLLBACK_RULES = {
|
|
|
3667
4257
|
// 可回滚到 explore
|
|
3668
4258
|
"continue": ["new", "explore"],
|
|
3669
4259
|
// 可回滚到 new 或 explore
|
|
3670
|
-
"propose": [],
|
|
3671
|
-
//
|
|
4260
|
+
"propose": ["propose"],
|
|
4261
|
+
// 可重新生成规格(回滚到自身)
|
|
3672
4262
|
"apply": ["new", "explore", "propose"],
|
|
3673
4263
|
// 代码审查未通过,可回滚到 new/explore (复杂) 或 propose (简单)
|
|
3674
4264
|
"archive": []
|
|
@@ -4462,6 +5052,9 @@ var ConfirmationRequiredError = class extends Error {
|
|
|
4462
5052
|
this.name = "ConfirmationRequiredError";
|
|
4463
5053
|
}
|
|
4464
5054
|
};
|
|
5055
|
+
|
|
5056
|
+
// src/norms/index.ts
|
|
5057
|
+
init_cjs_shims();
|
|
4465
5058
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
4466
5059
|
var MAX_FILES_TO_SCAN = 500;
|
|
4467
5060
|
var IGNORED_DIRS = ["node_modules", "dist", "build", ".git", "coverage", ".next", ".nuxt"];
|
|
@@ -5390,6 +5983,9 @@ ${standard.examples[0]}
|
|
|
5390
5983
|
return /:\s*(string|number|boolean|void|any|unknown|never|object|React\.\w+|[A-Z]\w+)(\s*[\)=\{\[;<>]|>)/.test(content);
|
|
5391
5984
|
}
|
|
5392
5985
|
};
|
|
5986
|
+
|
|
5987
|
+
// src/context/index.ts
|
|
5988
|
+
init_cjs_shims();
|
|
5393
5989
|
var DEFAULT_LIMIT = 512 * 1024;
|
|
5394
5990
|
var COMPRESSION_THRESHOLD = 0.9;
|
|
5395
5991
|
var MIN_MESSAGES_TO_KEEP = 10;
|
|
@@ -5696,6 +6292,7 @@ ${summary}`,
|
|
|
5696
6292
|
};
|
|
5697
6293
|
|
|
5698
6294
|
// src/cli/parser.ts
|
|
6295
|
+
init_cjs_shims();
|
|
5699
6296
|
var CommandType = /* @__PURE__ */ ((CommandType3) => {
|
|
5700
6297
|
CommandType3["SLASH"] = "slash";
|
|
5701
6298
|
CommandType3["AT"] = "at";
|
|
@@ -5861,6 +6458,18 @@ var CommandParser = class {
|
|
|
5861
6458
|
};
|
|
5862
6459
|
}
|
|
5863
6460
|
};
|
|
6461
|
+
|
|
6462
|
+
// src/cli/executor.ts
|
|
6463
|
+
init_cjs_shims();
|
|
6464
|
+
|
|
6465
|
+
// src/commands/index.ts
|
|
6466
|
+
init_cjs_shims();
|
|
6467
|
+
|
|
6468
|
+
// src/commands/runner.ts
|
|
6469
|
+
init_cjs_shims();
|
|
6470
|
+
|
|
6471
|
+
// src/commands/init.ts
|
|
6472
|
+
init_cjs_shims();
|
|
5864
6473
|
async function handleInit(args, ctx) {
|
|
5865
6474
|
const options = {
|
|
5866
6475
|
force: args.includes("-f") || args.includes("--force")
|
|
@@ -6299,6 +6908,9 @@ async function fileExists(filePath) {
|
|
|
6299
6908
|
return false;
|
|
6300
6909
|
}
|
|
6301
6910
|
}
|
|
6911
|
+
|
|
6912
|
+
// src/commands/help.ts
|
|
6913
|
+
init_cjs_shims();
|
|
6302
6914
|
var COMMAND_DETAILS = {
|
|
6303
6915
|
help: {
|
|
6304
6916
|
usage: "/help [command]",
|
|
@@ -6452,6 +7064,14 @@ ${chalk9__default.default.yellow("\u793A\u4F8B:")}
|
|
|
6452
7064
|
`;
|
|
6453
7065
|
return { output: help };
|
|
6454
7066
|
}
|
|
7067
|
+
|
|
7068
|
+
// src/commands/model.ts
|
|
7069
|
+
init_cjs_shims();
|
|
7070
|
+
|
|
7071
|
+
// src/services/index.ts
|
|
7072
|
+
init_cjs_shims();
|
|
7073
|
+
|
|
7074
|
+
// src/commands/model.ts
|
|
6455
7075
|
async function handleModel(args, ctx) {
|
|
6456
7076
|
const subCommand = args[0];
|
|
6457
7077
|
const configManager = ctx.configManager;
|
|
@@ -6669,6 +7289,9 @@ function createSpinner(message) {
|
|
|
6669
7289
|
stop: () => process.stdout.write(" ".repeat(message.length + 10) + "\r")
|
|
6670
7290
|
};
|
|
6671
7291
|
}
|
|
7292
|
+
|
|
7293
|
+
// src/commands/update.ts
|
|
7294
|
+
init_cjs_shims();
|
|
6672
7295
|
function getPackageInfo() {
|
|
6673
7296
|
const possiblePaths = [
|
|
6674
7297
|
path4__namespace.resolve(__dirname, "..", "..", "package.json"),
|
|
@@ -6834,6 +7457,9 @@ function extractTargetVersion(args) {
|
|
|
6834
7457
|
}
|
|
6835
7458
|
return void 0;
|
|
6836
7459
|
}
|
|
7460
|
+
|
|
7461
|
+
// src/commands/clear.ts
|
|
7462
|
+
init_cjs_shims();
|
|
6837
7463
|
async function handleClear(args, ctx) {
|
|
6838
7464
|
const options = {
|
|
6839
7465
|
force: args.includes("-f") || args.includes("--force"),
|
|
@@ -6865,6 +7491,9 @@ async function clearHistory(ctx, options = {}) {
|
|
|
6865
7491
|
}
|
|
6866
7492
|
return { output };
|
|
6867
7493
|
}
|
|
7494
|
+
|
|
7495
|
+
// src/commands/exit.ts
|
|
7496
|
+
init_cjs_shims();
|
|
6868
7497
|
async function handleExit(args, ctx) {
|
|
6869
7498
|
const options = {
|
|
6870
7499
|
force: args.includes("-f") || args.includes("--force")
|
|
@@ -6897,588 +7526,12 @@ async function exitCLI(ctx, options = {}) {
|
|
|
6897
7526
|
exit: true
|
|
6898
7527
|
};
|
|
6899
7528
|
}
|
|
6900
|
-
var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
6901
|
-
var COMPLEXITY_THRESHOLD = 6;
|
|
6902
|
-
async function handleNew(args, ctx) {
|
|
6903
|
-
const workingDir = ctx.options.workingDirectory;
|
|
6904
|
-
const workflowEngine = ctx.workflowEngine;
|
|
6905
|
-
if (workflowEngine) {
|
|
6906
|
-
const existingState = workflowEngine.getState();
|
|
6907
|
-
if (existingState && existingState.status === "running") {
|
|
6908
|
-
if (existingState.currentStep === "explore" || existingState.currentStep === "propose") {
|
|
6909
|
-
const specPath = path4__namespace.join(workingDir, "openspec", "changes", `${existingState.id}-spec.md`);
|
|
6910
|
-
if (fs10__namespace.existsSync(specPath)) {
|
|
6911
|
-
return {
|
|
6912
|
-
output: chalk9__default.default.yellow("\u5F53\u524D\u5DE5\u4F5C\u6D41\u6B63\u5728\u7B49\u5F85\u89C4\u683C\u786E\u8BA4") + chalk9__default.default.gray(`
|
|
6913
|
-
|
|
6914
|
-
\u5DE5\u4F5C\u6D41: ${existingState.title}`) + chalk9__default.default.gray(`
|
|
6915
|
-
\u53D8\u66F4ID: ${existingState.id}`) + chalk9__default.default.cyan("\n\n\u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210:") + chalk9__default.default.white(`
|
|
6916
|
-
${specPath}`) + chalk9__default.default.yellow("\n\n\u8BF7\u786E\u8BA4\u89C4\u683C\u540E\u7EE7\u7EED:") + chalk9__default.default.gray("\n /opsx:confirm spec-review - \u786E\u8BA4\u89C4\u683C") + chalk9__default.default.gray("\n /opsx:status - \u67E5\u770B\u8BE6\u60C5")
|
|
6917
|
-
};
|
|
6918
|
-
}
|
|
6919
|
-
}
|
|
6920
|
-
return {
|
|
6921
|
-
output: chalk9__default.default.yellow("\u5F53\u524D\u5DF2\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9__default.default.white(`
|
|
6922
7529
|
|
|
6923
|
-
|
|
6924
|
-
|
|
7530
|
+
// src/commands/runner.ts
|
|
7531
|
+
init_new();
|
|
6925
7532
|
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
return `${icon} ${s.step}`;
|
|
6929
|
-
}).join(" \u2192 ")}`) + chalk9__default.default.yellow("\n\n\u53EF\u7528\u547D\u4EE4:") + chalk9__default.default.white("\n /opsx:status - \u67E5\u770B\u5DE5\u4F5C\u6D41\u8BE6\u60C5") + chalk9__default.default.white("\n /opsx:cancel - \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41")
|
|
6930
|
-
};
|
|
6931
|
-
}
|
|
6932
|
-
}
|
|
6933
|
-
const { requirement, forceComplexity } = parseArgs(args);
|
|
6934
|
-
if (!requirement) {
|
|
6935
|
-
return {
|
|
6936
|
-
output: chalk9__default.default.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9__default.default.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray("\n\u9009\u9879:") + chalk9__default.default.gray("\n --simple \u5F3A\u5236\u4F7F\u7528\u7B80\u5355\u6D41\u7A0B") + chalk9__default.default.gray("\n --complex \u5F3A\u5236\u4F7F\u7528\u590D\u6742\u6D41\u7A0B")
|
|
6937
|
-
};
|
|
6938
|
-
}
|
|
6939
|
-
return newFeature({ requirement, forceComplexity }, workingDir, workflowEngine);
|
|
6940
|
-
}
|
|
6941
|
-
async function newFeature(options, workingDir, workflowEngine) {
|
|
6942
|
-
const cwd = workingDir || process.cwd();
|
|
6943
|
-
const { requirement, forceComplexity } = options;
|
|
6944
|
-
const lines = [];
|
|
6945
|
-
try {
|
|
6946
|
-
const stats = await fs4__namespace.stat(cwd);
|
|
6947
|
-
if (!stats.isDirectory()) {
|
|
6948
|
-
return {
|
|
6949
|
-
output: chalk9__default.default.red(`\u9519\u8BEF: ${cwd} \u4E0D\u662F\u6709\u6548\u76EE\u5F55`)
|
|
6950
|
-
};
|
|
6951
|
-
}
|
|
6952
|
-
} catch {
|
|
6953
|
-
return {
|
|
6954
|
-
output: chalk9__default.default.red(`\u9519\u8BEF: \u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u9650\u8BBF\u95EE ${cwd}`)
|
|
6955
|
-
};
|
|
6956
|
-
}
|
|
6957
|
-
lines.push(chalk9__default.default.cyan("\u{1F50D} \u5206\u6790\u9879\u76EE..."));
|
|
6958
|
-
const context = await readProjectContext(cwd);
|
|
6959
|
-
lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${context.name}`));
|
|
6960
|
-
lines.push(chalk9__default.default.gray(` \u7C7B\u578B: ${context.type}`));
|
|
6961
|
-
lines.push(chalk9__default.default.gray(` \u6846\u67B6: ${context.framework || "\u672A\u8BC6\u522B"}`));
|
|
6962
|
-
lines.push("");
|
|
6963
|
-
lines.push(chalk9__default.default.cyan("\u{1F4CA} \u5206\u6790\u9700\u6C42\u590D\u6742\u5EA6..."));
|
|
6964
|
-
const analysis = forceComplexity ? createForcedAnalysis(forceComplexity) : analyzeComplexity(requirement, context);
|
|
6965
|
-
lines.push(chalk9__default.default.gray(` \u590D\u6742\u5EA6: ${analysis.score}/10`));
|
|
6966
|
-
lines.push(chalk9__default.default.gray(` \u6D41\u7A0B\u7C7B\u578B: ${analysis.recommendation === "complex" ? "\u590D\u6742\u6D41\u7A0B" : "\u7B80\u5355\u6D41\u7A0B"}`));
|
|
6967
|
-
for (const factor of analysis.factors) {
|
|
6968
|
-
lines.push(chalk9__default.default.gray(` - ${factor}`));
|
|
6969
|
-
}
|
|
6970
|
-
lines.push("");
|
|
6971
|
-
lines.push(chalk9__default.default.cyan("\u{1F4CB} \u521D\u59CB\u5316\u5DE5\u4F5C\u6D41..."));
|
|
6972
|
-
const workflow = workflowEngine || new WorkflowEngine();
|
|
6973
|
-
if (!workflowEngine) {
|
|
6974
|
-
await workflow.initialize(cwd);
|
|
6975
|
-
}
|
|
6976
|
-
const state = await workflow.start(requirement, analysis.score, {
|
|
6977
|
-
title: extractTitle(requirement)
|
|
6978
|
-
});
|
|
6979
|
-
lines.push(chalk9__default.default.gray(` \u53D8\u66F4ID: ${state.id}`));
|
|
6980
|
-
lines.push(chalk9__default.default.gray(` \u5DE5\u4F5C\u6D41: ${state.type}`));
|
|
6981
|
-
lines.push("");
|
|
6982
|
-
lines.push(chalk9__default.default.cyan("\u{1F4DD} \u751F\u6210\u89C4\u683C\u62C6\u5206..."));
|
|
6983
|
-
const spec = await generateSpec(requirement, context, analysis, state.id);
|
|
6984
|
-
const specPath = await saveSpecFile(cwd, spec);
|
|
6985
|
-
lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
|
|
6986
|
-
lines.push(chalk9__default.default.gray(` \u8DEF\u5F84: ${specPath}`));
|
|
6987
|
-
lines.push("");
|
|
6988
|
-
lines.push(chalk9__default.default.cyan.bold("\u{1F4CB} \u89C4\u683C\u6982\u89C8:"));
|
|
6989
|
-
lines.push(chalk9__default.default.white(`
|
|
6990
|
-
${spec.summary}`));
|
|
6991
|
-
if (spec.items.length > 0) {
|
|
6992
|
-
lines.push("");
|
|
6993
|
-
lines.push(chalk9__default.default.cyan(" \u4EFB\u52A1\u62C6\u5206:"));
|
|
6994
|
-
for (const item of spec.items) {
|
|
6995
|
-
const priorityIcon = item.priority === "high" ? "\u{1F534}" : item.priority === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
6996
|
-
lines.push(chalk9__default.default.gray(` ${priorityIcon} [${item.id}] ${item.title}`));
|
|
6997
|
-
}
|
|
6998
|
-
}
|
|
6999
|
-
if (spec.risks.length > 0) {
|
|
7000
|
-
lines.push("");
|
|
7001
|
-
lines.push(chalk9__default.default.yellow(" \u26A0\uFE0F \u98CE\u9669\u63D0\u793A:"));
|
|
7002
|
-
for (const risk of spec.risks) {
|
|
7003
|
-
lines.push(chalk9__default.default.gray(` - ${risk}`));
|
|
7004
|
-
}
|
|
7005
|
-
}
|
|
7006
|
-
lines.push("");
|
|
7007
|
-
lines.push(chalk9__default.default.yellow.bold("\u23F3 \u7B49\u5F85\u89C4\u683C\u786E\u8BA4"));
|
|
7008
|
-
lines.push(chalk9__default.default.gray("\n\u8BF7\u68C0\u67E5\u751F\u6210\u7684\u89C4\u683C\u6587\u4EF6\uFF0C\u786E\u8BA4\u540E\u7EE7\u7EED:"));
|
|
7009
|
-
lines.push(chalk9__default.default.white("\n /opsx:confirm spec-review - \u786E\u8BA4\u89C4\u683C\uFF0C\u8FDB\u5165\u4E0B\u4E00\u9636\u6BB5"));
|
|
7010
|
-
lines.push(chalk9__default.default.white(" /opsx:rollback explore - \u89C4\u683C\u4E0D\u7B26\uFF0C\u91CD\u65B0\u62C6\u5206"));
|
|
7011
|
-
lines.push(chalk9__default.default.white(" /opsx:status - \u67E5\u770B\u5DE5\u4F5C\u6D41\u72B6\u6001"));
|
|
7012
|
-
return { output: lines.join("\n") };
|
|
7013
|
-
}
|
|
7014
|
-
async function generateSpec(requirement, context, analysis, changeId) {
|
|
7015
|
-
const spec = {
|
|
7016
|
-
changeId,
|
|
7017
|
-
requirement,
|
|
7018
|
-
summary: "",
|
|
7019
|
-
items: [],
|
|
7020
|
-
architectureNotes: [],
|
|
7021
|
-
risks: [],
|
|
7022
|
-
suggestions: []
|
|
7023
|
-
};
|
|
7024
|
-
spec.summary = generateSummary(requirement);
|
|
7025
|
-
if (analysis.recommendation === "complex") {
|
|
7026
|
-
spec.items = generateComplexTasks(requirement, context, analysis);
|
|
7027
|
-
spec.architectureNotes = generateArchitectureNotes(requirement, context);
|
|
7028
|
-
} else {
|
|
7029
|
-
spec.items = generateSimpleTasks(requirement);
|
|
7030
|
-
}
|
|
7031
|
-
spec.risks = generateRisks(requirement, context, analysis);
|
|
7032
|
-
spec.suggestions = generateSuggestions(requirement, context, analysis);
|
|
7033
|
-
return spec;
|
|
7034
|
-
}
|
|
7035
|
-
function generateSummary(requirement) {
|
|
7036
|
-
const firstSentence = requirement.split(/[。!?\n]/)[0];
|
|
7037
|
-
return firstSentence.length > 100 ? firstSentence.slice(0, 97) + "..." : firstSentence;
|
|
7038
|
-
}
|
|
7039
|
-
function generateComplexTasks(requirement, context, analysis) {
|
|
7040
|
-
const items = [];
|
|
7041
|
-
let itemId = 1;
|
|
7042
|
-
const featurePatterns = [
|
|
7043
|
-
{ pattern: /用户|登录|注册|认证|权限/, title: "\u7528\u6237\u8BA4\u8BC1\u6A21\u5757", priority: "high" },
|
|
7044
|
-
{ pattern: /数据|存储|缓存|数据库/, title: "\u6570\u636E\u5C42\u5B9E\u73B0", priority: "high" },
|
|
7045
|
-
{ pattern: /接口|API|请求|响应/, title: "API \u63A5\u53E3\u5F00\u53D1", priority: "high" },
|
|
7046
|
-
{ pattern: /界面|页面|组件|UI/, title: "\u754C\u9762\u5F00\u53D1", priority: "medium" },
|
|
7047
|
-
{ pattern: /测试|单测|覆盖/, title: "\u6D4B\u8BD5\u7528\u4F8B\u7F16\u5199", priority: "medium" },
|
|
7048
|
-
{ pattern: /文档|说明/, title: "\u6587\u6863\u7F16\u5199", priority: "low" },
|
|
7049
|
-
{ pattern: /配置|设置/, title: "\u914D\u7F6E\u7BA1\u7406", priority: "low" },
|
|
7050
|
-
{ pattern: /优化|性能/, title: "\u6027\u80FD\u4F18\u5316", priority: "medium" },
|
|
7051
|
-
{ pattern: /安全|加密/, title: "\u5B89\u5168\u5B9E\u73B0", priority: "high" },
|
|
7052
|
-
{ pattern: /日志|监控/, title: "\u65E5\u5FD7\u76D1\u63A7", priority: "low" }
|
|
7053
|
-
];
|
|
7054
|
-
for (const { pattern, title, priority } of featurePatterns) {
|
|
7055
|
-
if (pattern.test(requirement)) {
|
|
7056
|
-
items.push({
|
|
7057
|
-
id: `T${itemId.toString().padStart(3, "0")}`,
|
|
7058
|
-
title,
|
|
7059
|
-
description: `${title}\u76F8\u5173\u7684\u529F\u80FD\u5B9E\u73B0`,
|
|
7060
|
-
priority,
|
|
7061
|
-
dependencies: itemId > 1 ? [`T${(itemId - 1).toString().padStart(3, "0")}`] : [],
|
|
7062
|
-
estimatedComplexity: priority === "high" ? 3 : priority === "medium" ? 2 : 1
|
|
7063
|
-
});
|
|
7064
|
-
itemId++;
|
|
7065
|
-
}
|
|
7066
|
-
}
|
|
7067
|
-
if (items.length === 0) {
|
|
7068
|
-
items.push({
|
|
7069
|
-
id: "T001",
|
|
7070
|
-
title: "\u9700\u6C42\u5206\u6790\u4E0E\u8BBE\u8BA1",
|
|
7071
|
-
description: "\u5206\u6790\u9700\u6C42\u7EC6\u8282\uFF0C\u8BBE\u8BA1\u5B9E\u73B0\u65B9\u6848",
|
|
7072
|
-
priority: "high",
|
|
7073
|
-
dependencies: [],
|
|
7074
|
-
estimatedComplexity: 2
|
|
7075
|
-
});
|
|
7076
|
-
items.push({
|
|
7077
|
-
id: "T002",
|
|
7078
|
-
title: "\u6838\u5FC3\u529F\u80FD\u5B9E\u73B0",
|
|
7079
|
-
description: requirement,
|
|
7080
|
-
priority: "high",
|
|
7081
|
-
dependencies: ["T001"],
|
|
7082
|
-
estimatedComplexity: analysis.score
|
|
7083
|
-
});
|
|
7084
|
-
items.push({
|
|
7085
|
-
id: "T003",
|
|
7086
|
-
title: "\u6D4B\u8BD5\u4E0E\u9A8C\u8BC1",
|
|
7087
|
-
description: "\u7F16\u5199\u6D4B\u8BD5\u7528\u4F8B\uFF0C\u9A8C\u8BC1\u529F\u80FD\u6B63\u786E\u6027",
|
|
7088
|
-
priority: "medium",
|
|
7089
|
-
dependencies: ["T002"],
|
|
7090
|
-
estimatedComplexity: 2
|
|
7091
|
-
});
|
|
7092
|
-
}
|
|
7093
|
-
return items;
|
|
7094
|
-
}
|
|
7095
|
-
function generateSimpleTasks(requirement, context) {
|
|
7096
|
-
return [
|
|
7097
|
-
{
|
|
7098
|
-
id: "T001",
|
|
7099
|
-
title: "\u5B9E\u73B0\u53D8\u66F4",
|
|
7100
|
-
description: requirement,
|
|
7101
|
-
priority: "high",
|
|
7102
|
-
dependencies: [],
|
|
7103
|
-
estimatedComplexity: 3
|
|
7104
|
-
},
|
|
7105
|
-
{
|
|
7106
|
-
id: "T002",
|
|
7107
|
-
title: "\u6D4B\u8BD5\u9A8C\u8BC1",
|
|
7108
|
-
description: "\u9A8C\u8BC1\u53D8\u66F4\u6B63\u786E\u6027",
|
|
7109
|
-
priority: "medium",
|
|
7110
|
-
dependencies: ["T001"],
|
|
7111
|
-
estimatedComplexity: 1
|
|
7112
|
-
}
|
|
7113
|
-
];
|
|
7114
|
-
}
|
|
7115
|
-
function generateArchitectureNotes(requirement, context) {
|
|
7116
|
-
const notes = [];
|
|
7117
|
-
if (context.framework) {
|
|
7118
|
-
notes.push(`\u9879\u76EE\u4F7F\u7528 ${context.framework} \u6846\u67B6\uFF0C\u9700\u9075\u5FAA\u5176\u6700\u4F73\u5B9E\u8DF5`);
|
|
7119
|
-
}
|
|
7120
|
-
if (requirement.includes("\u6A21\u5757") || requirement.includes("\u7EC4\u4EF6")) {
|
|
7121
|
-
notes.push("\u5EFA\u8BAE\u91C7\u7528\u6A21\u5757\u5316\u8BBE\u8BA1\uFF0C\u4FDD\u6301\u7EC4\u4EF6\u804C\u8D23\u5355\u4E00");
|
|
7122
|
-
}
|
|
7123
|
-
if (requirement.includes("API") || requirement.includes("\u63A5\u53E3")) {
|
|
7124
|
-
notes.push("API \u8BBE\u8BA1\u9700\u8003\u8651\u7248\u672C\u63A7\u5236\u548C\u5411\u540E\u517C\u5BB9");
|
|
7125
|
-
}
|
|
7126
|
-
if (context.structure.srcStructure) {
|
|
7127
|
-
notes.push(`\u73B0\u6709\u6E90\u7801\u7ED3\u6784: ${context.structure.srcStructure}`);
|
|
7128
|
-
}
|
|
7129
|
-
return notes;
|
|
7130
|
-
}
|
|
7131
|
-
function generateRisks(requirement, context, analysis) {
|
|
7132
|
-
const risks = [];
|
|
7133
|
-
if (!context.framework) {
|
|
7134
|
-
risks.push("\u9879\u76EE\u6846\u67B6\u672A\u8BC6\u522B\uFF0C\u53EF\u80FD\u5F71\u54CD\u4EE3\u7801\u98CE\u683C\u4E00\u81F4\u6027");
|
|
7135
|
-
}
|
|
7136
|
-
if (analysis.score >= 7) {
|
|
7137
|
-
risks.push("\u9700\u6C42\u590D\u6742\u5EA6\u8F83\u9AD8\uFF0C\u5EFA\u8BAE\u5206\u9636\u6BB5\u5B9E\u73B0");
|
|
7138
|
-
}
|
|
7139
|
-
if (requirement.includes("\u8FC1\u79FB") || requirement.includes("\u91CD\u6784")) {
|
|
7140
|
-
risks.push("\u6D89\u53CA\u73B0\u6709\u4EE3\u7801\u4FEE\u6539\uFF0C\u9700\u6CE8\u610F\u56DE\u5F52\u6D4B\u8BD5");
|
|
7141
|
-
}
|
|
7142
|
-
if (requirement.includes("\u6743\u9650") || requirement.includes("\u5B89\u5168")) {
|
|
7143
|
-
risks.push("\u6D89\u53CA\u5B89\u5168\u654F\u611F\u529F\u80FD\uFF0C\u9700\u8981\u989D\u5916\u5BA1\u67E5");
|
|
7144
|
-
}
|
|
7145
|
-
return risks;
|
|
7146
|
-
}
|
|
7147
|
-
function generateSuggestions(requirement, context, analysis) {
|
|
7148
|
-
const suggestions = [];
|
|
7149
|
-
if (context.norms.devStandards) {
|
|
7150
|
-
suggestions.push("\u9879\u76EE\u5DF2\u6709\u5F00\u53D1\u89C4\u8303\uFF0C\u8BF7\u9075\u5FAA\u73B0\u6709\u89C4\u8303");
|
|
7151
|
-
}
|
|
7152
|
-
if (analysis.recommendation === "complex") {
|
|
7153
|
-
suggestions.push("\u590D\u6742\u9700\u6C42\u5EFA\u8BAE\u5148\u8FDB\u884C\u6280\u672F\u8BC4\u5BA1");
|
|
7154
|
-
suggestions.push("\u5EFA\u8BAE\u8C03\u7528 $architect \u83B7\u53D6\u67B6\u6784\u5EFA\u8BAE");
|
|
7155
|
-
}
|
|
7156
|
-
if (context.techStack.length > 0) {
|
|
7157
|
-
suggestions.push(`\u6280\u672F\u6808: ${context.techStack.join(", ")}`);
|
|
7158
|
-
}
|
|
7159
|
-
return suggestions;
|
|
7160
|
-
}
|
|
7161
|
-
async function saveSpecFile(cwd, spec) {
|
|
7162
|
-
const changesDir = path4__namespace.join(cwd, "openspec", "changes");
|
|
7163
|
-
await fs4__namespace.mkdir(changesDir, { recursive: true });
|
|
7164
|
-
const specPath = path4__namespace.join(changesDir, `${spec.changeId}-spec.md`);
|
|
7165
|
-
const content = formatSpecFile(spec);
|
|
7166
|
-
await fs4__namespace.writeFile(specPath, content, "utf-8");
|
|
7167
|
-
return specPath;
|
|
7168
|
-
}
|
|
7169
|
-
function formatSpecFile(spec) {
|
|
7170
|
-
const lines = [];
|
|
7171
|
-
lines.push(`# Spec: ${spec.summary}`);
|
|
7172
|
-
lines.push("");
|
|
7173
|
-
lines.push(`> \u53D8\u66F4ID: ${spec.changeId}`);
|
|
7174
|
-
lines.push(`> \u751F\u6210\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
7175
|
-
lines.push("");
|
|
7176
|
-
lines.push("---");
|
|
7177
|
-
lines.push("");
|
|
7178
|
-
lines.push("## \u9700\u6C42\u6982\u8FF0");
|
|
7179
|
-
lines.push("");
|
|
7180
|
-
lines.push(spec.requirement);
|
|
7181
|
-
lines.push("");
|
|
7182
|
-
lines.push("## \u4EFB\u52A1\u62C6\u5206");
|
|
7183
|
-
lines.push("");
|
|
7184
|
-
for (const item of spec.items) {
|
|
7185
|
-
const priorityLabel = item.priority === "high" ? "\u{1F534} \u9AD8" : item.priority === "medium" ? "\u{1F7E1} \u4E2D" : "\u{1F7E2} \u4F4E";
|
|
7186
|
-
lines.push(`### ${item.id}: ${item.title}`);
|
|
7187
|
-
lines.push("");
|
|
7188
|
-
lines.push(`- **\u4F18\u5148\u7EA7**: ${priorityLabel}`);
|
|
7189
|
-
lines.push(`- **\u63CF\u8FF0**: ${item.description}`);
|
|
7190
|
-
lines.push(`- **\u9884\u4F30\u590D\u6742\u5EA6**: ${item.estimatedComplexity}/5`);
|
|
7191
|
-
if (item.dependencies.length > 0) {
|
|
7192
|
-
lines.push(`- **\u4F9D\u8D56**: ${item.dependencies.join(", ")}`);
|
|
7193
|
-
}
|
|
7194
|
-
lines.push("");
|
|
7195
|
-
}
|
|
7196
|
-
if (spec.architectureNotes.length > 0) {
|
|
7197
|
-
lines.push("## \u67B6\u6784\u8BF4\u660E");
|
|
7198
|
-
lines.push("");
|
|
7199
|
-
for (const note of spec.architectureNotes) {
|
|
7200
|
-
lines.push(`- ${note}`);
|
|
7201
|
-
}
|
|
7202
|
-
lines.push("");
|
|
7203
|
-
}
|
|
7204
|
-
if (spec.risks.length > 0) {
|
|
7205
|
-
lines.push("## \u26A0\uFE0F \u98CE\u9669\u8BC4\u4F30");
|
|
7206
|
-
lines.push("");
|
|
7207
|
-
for (const risk of spec.risks) {
|
|
7208
|
-
lines.push(`- ${risk}`);
|
|
7209
|
-
}
|
|
7210
|
-
lines.push("");
|
|
7211
|
-
}
|
|
7212
|
-
if (spec.suggestions.length > 0) {
|
|
7213
|
-
lines.push("## \u{1F4A1} \u5EFA\u8BAE");
|
|
7214
|
-
lines.push("");
|
|
7215
|
-
for (const suggestion of spec.suggestions) {
|
|
7216
|
-
lines.push(`- ${suggestion}`);
|
|
7217
|
-
}
|
|
7218
|
-
lines.push("");
|
|
7219
|
-
}
|
|
7220
|
-
lines.push("---");
|
|
7221
|
-
lines.push("");
|
|
7222
|
-
lines.push("## \u786E\u8BA4\u72B6\u6001");
|
|
7223
|
-
lines.push("");
|
|
7224
|
-
lines.push("- [ ] \u89C4\u683C\u5DF2\u5BA1\u9605");
|
|
7225
|
-
lines.push("- [ ] \u4EFB\u52A1\u62C6\u5206\u5DF2\u786E\u8BA4");
|
|
7226
|
-
lines.push("");
|
|
7227
|
-
lines.push("**\u786E\u8BA4\u540E\u6267\u884C**: `/opsx:confirm spec-review`");
|
|
7228
|
-
return lines.join("\n");
|
|
7229
|
-
}
|
|
7230
|
-
function parseArgs(args) {
|
|
7231
|
-
let forceComplexity;
|
|
7232
|
-
const filteredArgs = [];
|
|
7233
|
-
for (const arg of args) {
|
|
7234
|
-
if (arg === "--simple") {
|
|
7235
|
-
forceComplexity = "simple";
|
|
7236
|
-
} else if (arg === "--complex") {
|
|
7237
|
-
forceComplexity = "complex";
|
|
7238
|
-
} else {
|
|
7239
|
-
filteredArgs.push(arg);
|
|
7240
|
-
}
|
|
7241
|
-
}
|
|
7242
|
-
return {
|
|
7243
|
-
requirement: filteredArgs.join(" ").trim(),
|
|
7244
|
-
forceComplexity
|
|
7245
|
-
};
|
|
7246
|
-
}
|
|
7247
|
-
async function readProjectContext(cwd) {
|
|
7248
|
-
const defaultContext = {
|
|
7249
|
-
name: path4__namespace.basename(cwd),
|
|
7250
|
-
type: "unknown",
|
|
7251
|
-
framework: null,
|
|
7252
|
-
techStack: [],
|
|
7253
|
-
description: "",
|
|
7254
|
-
structure: {
|
|
7255
|
-
directories: [],
|
|
7256
|
-
keyFiles: [],
|
|
7257
|
-
srcStructure: ""
|
|
7258
|
-
},
|
|
7259
|
-
norms: {
|
|
7260
|
-
devStandards: "",
|
|
7261
|
-
patterns: "",
|
|
7262
|
-
weights: ""
|
|
7263
|
-
}
|
|
7264
|
-
};
|
|
7265
|
-
const [agentsContext, configContext, normsContext, structureContext] = await Promise.all([
|
|
7266
|
-
readAgentsMd(cwd),
|
|
7267
|
-
readConfigYaml(cwd),
|
|
7268
|
-
readNorms(cwd),
|
|
7269
|
-
analyzeStructure(cwd)
|
|
7270
|
-
]);
|
|
7271
|
-
return {
|
|
7272
|
-
...defaultContext,
|
|
7273
|
-
...agentsContext,
|
|
7274
|
-
...configContext,
|
|
7275
|
-
norms: normsContext,
|
|
7276
|
-
structure: structureContext
|
|
7277
|
-
};
|
|
7278
|
-
}
|
|
7279
|
-
async function readAgentsMd(cwd) {
|
|
7280
|
-
const agentsPath = path4__namespace.join(cwd, "AGENTS.md");
|
|
7281
|
-
try {
|
|
7282
|
-
const stats = await fs4__namespace.stat(agentsPath);
|
|
7283
|
-
if (stats.size > MAX_FILE_SIZE2) {
|
|
7284
|
-
console.warn(`\u8B66\u544A: AGENTS.md \u6587\u4EF6\u8FC7\u5927 (${stats.size} bytes)\uFF0C\u8DF3\u8FC7\u8BFB\u53D6`);
|
|
7285
|
-
return {};
|
|
7286
|
-
}
|
|
7287
|
-
const content = await fs4__namespace.readFile(agentsPath, "utf-8");
|
|
7288
|
-
return parseAgentsMd(content);
|
|
7289
|
-
} catch (e) {
|
|
7290
|
-
const err = e;
|
|
7291
|
-
if (err.code !== "ENOENT") {
|
|
7292
|
-
console.warn(`\u8B66\u544A: \u65E0\u6CD5\u8BFB\u53D6 AGENTS.md - ${err.message}`);
|
|
7293
|
-
}
|
|
7294
|
-
return {};
|
|
7295
|
-
}
|
|
7296
|
-
}
|
|
7297
|
-
function parseAgentsMd(content) {
|
|
7298
|
-
const context = {};
|
|
7299
|
-
const nameMatch = content.match(/\|\s*项目名称\s*\|\s*([^\s|]+)/);
|
|
7300
|
-
if (nameMatch) {
|
|
7301
|
-
context.name = nameMatch[1];
|
|
7302
|
-
}
|
|
7303
|
-
const typeMatch = content.match(/\|\s*项目类型\s*\|\s*([^\s|]+)/);
|
|
7304
|
-
if (typeMatch) {
|
|
7305
|
-
context.type = typeMatch[1];
|
|
7306
|
-
}
|
|
7307
|
-
const frameworkMatch = content.match(/\|\s*技术框架\s*\|\s*([^\s|]+)/);
|
|
7308
|
-
if (frameworkMatch && frameworkMatch[1] !== "\u5F85\u8BC6\u522B") {
|
|
7309
|
-
context.framework = frameworkMatch[1];
|
|
7310
|
-
}
|
|
7311
|
-
const descMatch = content.match(/###\s*1\.2\s*项目描述\s*\n+([^\n#]+)/);
|
|
7312
|
-
if (descMatch) {
|
|
7313
|
-
context.description = descMatch[1].trim();
|
|
7314
|
-
}
|
|
7315
|
-
const techStackMatch = content.match(/技术栈[::]\s*([^\n]+)/);
|
|
7316
|
-
if (techStackMatch) {
|
|
7317
|
-
context.techStack = techStackMatch[1].split(/[,,、]/).map((s) => s.trim()).filter(Boolean);
|
|
7318
|
-
}
|
|
7319
|
-
return context;
|
|
7320
|
-
}
|
|
7321
|
-
async function readConfigYaml(cwd) {
|
|
7322
|
-
const configPath = path4__namespace.join(cwd, "openspec", "config.yaml");
|
|
7323
|
-
try {
|
|
7324
|
-
const stats = await fs4__namespace.stat(configPath);
|
|
7325
|
-
if (stats.size > MAX_FILE_SIZE2) {
|
|
7326
|
-
console.warn("\u8B66\u544A: config.yaml \u6587\u4EF6\u8FC7\u5927\uFF0C\u8DF3\u8FC7\u8BFB\u53D6");
|
|
7327
|
-
return {};
|
|
7328
|
-
}
|
|
7329
|
-
const content = await fs4__namespace.readFile(configPath, "utf-8");
|
|
7330
|
-
return parseConfigYaml(content);
|
|
7331
|
-
} catch (e) {
|
|
7332
|
-
const err = e;
|
|
7333
|
-
if (err.code !== "ENOENT") {
|
|
7334
|
-
console.warn(`\u8B66\u544A: \u65E0\u6CD5\u8BFB\u53D6 config.yaml - ${err.message}`);
|
|
7335
|
-
}
|
|
7336
|
-
return {};
|
|
7337
|
-
}
|
|
7338
|
-
}
|
|
7339
|
-
function parseConfigYaml(content) {
|
|
7340
|
-
const context = {};
|
|
7341
|
-
const nameMatch = content.match(/name:\s*(.+)/);
|
|
7342
|
-
if (nameMatch) {
|
|
7343
|
-
context.name = nameMatch[1].trim();
|
|
7344
|
-
}
|
|
7345
|
-
const typeMatch = content.match(/type:\s*(.+)/);
|
|
7346
|
-
if (typeMatch) {
|
|
7347
|
-
context.type = typeMatch[1].trim();
|
|
7348
|
-
}
|
|
7349
|
-
const frameworkMatch = content.match(/framework:\s*(.+)/);
|
|
7350
|
-
if (frameworkMatch && frameworkMatch[1].trim() !== "null") {
|
|
7351
|
-
context.framework = frameworkMatch[1].trim();
|
|
7352
|
-
}
|
|
7353
|
-
return context;
|
|
7354
|
-
}
|
|
7355
|
-
async function readNorms(cwd) {
|
|
7356
|
-
const normsDir = path4__namespace.join(cwd, ".sf-cli", "norms");
|
|
7357
|
-
const norms = {
|
|
7358
|
-
devStandards: "",
|
|
7359
|
-
patterns: "",
|
|
7360
|
-
weights: ""
|
|
7361
|
-
};
|
|
7362
|
-
try {
|
|
7363
|
-
const devStandardsPath = path4__namespace.join(normsDir, "devstanded.md");
|
|
7364
|
-
norms.devStandards = await fs4__namespace.readFile(devStandardsPath, "utf-8").catch(() => "");
|
|
7365
|
-
} catch {
|
|
7366
|
-
}
|
|
7367
|
-
try {
|
|
7368
|
-
const patternsPath = path4__namespace.join(normsDir, "patterns.json");
|
|
7369
|
-
norms.patterns = await fs4__namespace.readFile(patternsPath, "utf-8").catch(() => "");
|
|
7370
|
-
} catch {
|
|
7371
|
-
}
|
|
7372
|
-
try {
|
|
7373
|
-
const weightsPath = path4__namespace.join(normsDir, "weights.json");
|
|
7374
|
-
norms.weights = await fs4__namespace.readFile(weightsPath, "utf-8").catch(() => "");
|
|
7375
|
-
} catch {
|
|
7376
|
-
}
|
|
7377
|
-
return norms;
|
|
7378
|
-
}
|
|
7379
|
-
async function analyzeStructure(cwd) {
|
|
7380
|
-
const structure = {
|
|
7381
|
-
directories: [],
|
|
7382
|
-
keyFiles: [],
|
|
7383
|
-
srcStructure: ""
|
|
7384
|
-
};
|
|
7385
|
-
try {
|
|
7386
|
-
const entries = await fs4__namespace.readdir(cwd, { withFileTypes: true });
|
|
7387
|
-
for (const entry of entries) {
|
|
7388
|
-
if (entry.isDirectory() && !["node_modules", "dist", ".git", "build"].includes(entry.name)) {
|
|
7389
|
-
structure.directories.push(entry.name);
|
|
7390
|
-
}
|
|
7391
|
-
}
|
|
7392
|
-
const keyFiles = [
|
|
7393
|
-
"package.json",
|
|
7394
|
-
"tsconfig.json",
|
|
7395
|
-
"AGENTS.md",
|
|
7396
|
-
"README.md"
|
|
7397
|
-
];
|
|
7398
|
-
for (const file of keyFiles) {
|
|
7399
|
-
const filePath = path4__namespace.join(cwd, file);
|
|
7400
|
-
try {
|
|
7401
|
-
await fs4__namespace.access(filePath);
|
|
7402
|
-
structure.keyFiles.push(file);
|
|
7403
|
-
} catch {
|
|
7404
|
-
}
|
|
7405
|
-
}
|
|
7406
|
-
const srcDir = path4__namespace.join(cwd, "src");
|
|
7407
|
-
try {
|
|
7408
|
-
const srcEntries = await fs4__namespace.readdir(srcDir, { withFileTypes: true });
|
|
7409
|
-
structure.srcStructure = srcEntries.filter((e) => e.isDirectory()).map((e) => e.name).join("/");
|
|
7410
|
-
} catch {
|
|
7411
|
-
}
|
|
7412
|
-
} catch (e) {
|
|
7413
|
-
}
|
|
7414
|
-
return { structure };
|
|
7415
|
-
}
|
|
7416
|
-
function analyzeComplexity(requirement, context) {
|
|
7417
|
-
let score = 3;
|
|
7418
|
-
const factors = [];
|
|
7419
|
-
if (requirement.length > 200) {
|
|
7420
|
-
score += 1;
|
|
7421
|
-
factors.push("\u9700\u6C42\u63CF\u8FF0\u8F83\u957F");
|
|
7422
|
-
}
|
|
7423
|
-
const complexKeywords = ["\u67B6\u6784", "\u91CD\u6784", "\u8FC1\u79FB", "\u96C6\u6210", "\u7CFB\u7EDF", "\u6A21\u5757", "\u5DE5\u4F5C\u6D41", "\u6D41\u7A0B"];
|
|
7424
|
-
const negationWords = ["\u4E0D\u9700\u8981", "\u4E0D\u7528", "\u65E0\u9700", "\u907F\u514D"];
|
|
7425
|
-
for (const keyword of complexKeywords) {
|
|
7426
|
-
if (requirement.includes(keyword)) {
|
|
7427
|
-
const keywordIndex = requirement.indexOf(keyword);
|
|
7428
|
-
const contextStart = Math.max(0, keywordIndex - 10);
|
|
7429
|
-
const contextText = requirement.slice(contextStart, keywordIndex);
|
|
7430
|
-
const hasNegation = negationWords.some((neg) => contextText.includes(neg));
|
|
7431
|
-
if (!hasNegation) {
|
|
7432
|
-
score += 1;
|
|
7433
|
-
factors.push(`\u6D89\u53CA"${keyword}"`);
|
|
7434
|
-
}
|
|
7435
|
-
}
|
|
7436
|
-
}
|
|
7437
|
-
const simpleKeywords = ["\u4FEE\u590D", "\u8C03\u6574", "\u4F18\u5316", "\u66F4\u65B0", "\u4FEE\u6539", "\u6DFB\u52A0", "\u6837\u5F0F"];
|
|
7438
|
-
for (const keyword of simpleKeywords) {
|
|
7439
|
-
if (requirement.includes(keyword)) {
|
|
7440
|
-
score -= 0.5;
|
|
7441
|
-
factors.push(`\u7B80\u5355\u4FEE\u6539"${keyword}"`);
|
|
7442
|
-
}
|
|
7443
|
-
}
|
|
7444
|
-
const featureCount = (requirement.match(/和|以及|同时|另外|此外/g) || []).length;
|
|
7445
|
-
if (featureCount > 0) {
|
|
7446
|
-
score += featureCount * 0.5;
|
|
7447
|
-
factors.push(`\u6D89\u53CA\u591A\u4E2A\u529F\u80FD\u70B9 (${featureCount + 1}\u4E2A)`);
|
|
7448
|
-
}
|
|
7449
|
-
if (!context.framework) {
|
|
7450
|
-
score += 0.5;
|
|
7451
|
-
factors.push("\u9879\u76EE\u6846\u67B6\u672A\u8BC6\u522B");
|
|
7452
|
-
}
|
|
7453
|
-
if (requirement.includes("\u6570\u636E") || requirement.includes("\u63A5\u53E3") || requirement.includes("API")) {
|
|
7454
|
-
score += 1;
|
|
7455
|
-
factors.push("\u6D89\u53CA\u6570\u636E\u4EA4\u4E92");
|
|
7456
|
-
}
|
|
7457
|
-
if (requirement.includes("\u6743\u9650") || requirement.includes("\u5B89\u5168") || requirement.includes("\u8BA4\u8BC1")) {
|
|
7458
|
-
score += 1.5;
|
|
7459
|
-
factors.push("\u6D89\u53CA\u6743\u9650\u6216\u5B89\u5168");
|
|
7460
|
-
}
|
|
7461
|
-
score = Math.max(1, Math.min(10, Math.round(score)));
|
|
7462
|
-
return {
|
|
7463
|
-
score,
|
|
7464
|
-
factors: factors.length > 0 ? factors : ["\u9700\u6C42\u76F8\u5BF9\u7B80\u5355"],
|
|
7465
|
-
recommendation: score >= COMPLEXITY_THRESHOLD ? "complex" : "simple"
|
|
7466
|
-
};
|
|
7467
|
-
}
|
|
7468
|
-
function createForcedAnalysis(type) {
|
|
7469
|
-
return {
|
|
7470
|
-
score: type === "complex" ? 8 : 3,
|
|
7471
|
-
factors: [`\u7528\u6237\u6307\u5B9A${type === "complex" ? "\u590D\u6742" : "\u7B80\u5355"}\u6D41\u7A0B`],
|
|
7472
|
-
recommendation: type
|
|
7473
|
-
};
|
|
7474
|
-
}
|
|
7475
|
-
function extractTitle(requirement) {
|
|
7476
|
-
const firstSentence = requirement.split(/[。!?\n]/)[0];
|
|
7477
|
-
if (firstSentence.length <= 50) {
|
|
7478
|
-
return firstSentence;
|
|
7479
|
-
}
|
|
7480
|
-
return requirement.slice(0, 47) + "...";
|
|
7481
|
-
}
|
|
7533
|
+
// src/commands/opsx.ts
|
|
7534
|
+
init_cjs_shims();
|
|
7482
7535
|
var autoScheduleEnabled = true;
|
|
7483
7536
|
var DEFAULT_REGRESSION_CONFIG = {
|
|
7484
7537
|
enabled: true,
|
|
@@ -7574,7 +7627,7 @@ async function handleOpsx(command, args, ctx) {
|
|
|
7574
7627
|
case "cancel":
|
|
7575
7628
|
return handleCancel(workflow, args);
|
|
7576
7629
|
case "rollback":
|
|
7577
|
-
return handleRollback(workflow, args);
|
|
7630
|
+
return handleRollback(workflow, args, ctx);
|
|
7578
7631
|
case "confirm":
|
|
7579
7632
|
return handleConfirm(workflow, args, ctx);
|
|
7580
7633
|
case "next":
|
|
@@ -7908,16 +7961,20 @@ async function handleRollback(workflow, args, ctx) {
|
|
|
7908
7961
|
output: chalk9__default.default.red("\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41")
|
|
7909
7962
|
};
|
|
7910
7963
|
}
|
|
7964
|
+
const currentStep = state.currentStep;
|
|
7911
7965
|
const rollbackTargets = workflow.getRollbackTargets();
|
|
7912
7966
|
if (rollbackTargets.length === 0) {
|
|
7913
7967
|
return {
|
|
7914
|
-
output: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 ${
|
|
7968
|
+
output: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 ${currentStep} \u4E0D\u652F\u6301\u56DE\u6EDA`)
|
|
7915
7969
|
};
|
|
7916
7970
|
}
|
|
7971
|
+
if (currentStep === "propose" && rollbackTargets.includes("propose")) {
|
|
7972
|
+
return handleRegenerateSpec(workflow, ctx);
|
|
7973
|
+
}
|
|
7917
7974
|
const targetStep = args[0];
|
|
7918
7975
|
if (!targetStep || !rollbackTargets.includes(targetStep)) {
|
|
7919
7976
|
return {
|
|
7920
|
-
output: generateRollbackPrompt(
|
|
7977
|
+
output: generateRollbackPrompt(currentStep) + chalk9__default.default.cyan("\n\n\u7528\u6CD5: /opsx:rollback <\u76EE\u6807\u9636\u6BB5> <\u539F\u56E0>") + chalk9__default.default.gray("\n\u539F\u56E0: code-review-failed | requirement-changed | design-issue | user-request")
|
|
7921
7978
|
};
|
|
7922
7979
|
}
|
|
7923
7980
|
const reason = args[1] || "user-request";
|
|
@@ -7938,6 +7995,33 @@ ${result.message}`) + chalk9__default.default.cyan(`
|
|
|
7938
7995
|
};
|
|
7939
7996
|
}
|
|
7940
7997
|
}
|
|
7998
|
+
async function handleRegenerateSpec(workflow, ctx) {
|
|
7999
|
+
const state = workflow.getState();
|
|
8000
|
+
if (!state) {
|
|
8001
|
+
return { output: chalk9__default.default.red("\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") };
|
|
8002
|
+
}
|
|
8003
|
+
const workingDir = ctx.options.workingDirectory;
|
|
8004
|
+
const specPath = path4__namespace.join(workingDir, "openspec", "changes", `${state.id}-spec.md`);
|
|
8005
|
+
workflow.confirm("spec-review", "regenerate");
|
|
8006
|
+
const lines = [];
|
|
8007
|
+
lines.push(chalk9__default.default.cyan("\u{1F504} \u91CD\u65B0\u751F\u6210\u89C4\u683C..."));
|
|
8008
|
+
lines.push("");
|
|
8009
|
+
const { readProjectContext: readProjectContext2, analyzeComplexity: analyzeComplexity2, generateSpecContent } = await Promise.resolve().then(() => (init_new(), new_exports));
|
|
8010
|
+
const context = await readProjectContext2(workingDir);
|
|
8011
|
+
const analysis = analyzeComplexity2(state.requirement, context);
|
|
8012
|
+
const specContent = await generateSpecContent(state.id, state.requirement, analysis, context);
|
|
8013
|
+
await fs10__namespace.promises.writeFile(specPath, specContent, "utf-8");
|
|
8014
|
+
lines.push(chalk9__default.default.green("\u2713 \u89C4\u683C\u5DF2\u91CD\u65B0\u751F\u6210"));
|
|
8015
|
+
lines.push(chalk9__default.default.gray(`\u8DEF\u5F84: ${specPath}`));
|
|
8016
|
+
lines.push("");
|
|
8017
|
+
lines.push(chalk9__default.default.cyan("\u{1F4CB} \u89C4\u683C\u6982\u89C8:"));
|
|
8018
|
+
lines.push(chalk9__default.default.white(` ${state.requirement}`));
|
|
8019
|
+
lines.push("");
|
|
8020
|
+
lines.push(chalk9__default.default.yellow("\u8BF7\u68C0\u67E5\u65B0\u7684\u89C4\u683C\u6587\u4EF6\uFF0C\u786E\u8BA4\u540E\u8F93\u5165:"));
|
|
8021
|
+
lines.push(chalk9__default.default.green(" y - \u786E\u8BA4\u89C4\u683C\uFF0C\u8FDB\u5165\u4E0B\u4E00\u9636\u6BB5"));
|
|
8022
|
+
lines.push(chalk9__default.default.red(" n - \u4E0D\u6EE1\u610F\uFF0C\u518D\u6B21\u91CD\u65B0\u751F\u6210"));
|
|
8023
|
+
return { output: lines.join("\n") };
|
|
8024
|
+
}
|
|
7941
8025
|
async function handleConfirm(workflow, args, ctx) {
|
|
7942
8026
|
const state = workflow.getState();
|
|
7943
8027
|
if (!state) {
|
|
@@ -8197,6 +8281,12 @@ async function runSlashCommand(command, args, ctx) {
|
|
|
8197
8281
|
function normalizeCommand(command) {
|
|
8198
8282
|
return command.toLowerCase().trim();
|
|
8199
8283
|
}
|
|
8284
|
+
|
|
8285
|
+
// src/commands/index.ts
|
|
8286
|
+
init_new();
|
|
8287
|
+
|
|
8288
|
+
// src/commands/reference.ts
|
|
8289
|
+
init_cjs_shims();
|
|
8200
8290
|
async function handleFileReference(filePath, ctx) {
|
|
8201
8291
|
const cwd = ctx.options.workingDirectory;
|
|
8202
8292
|
const absolutePath = path4__namespace.isAbsolute(filePath) ? filePath : path4__namespace.join(cwd, filePath);
|
|
@@ -8236,6 +8326,9 @@ ${preview}`) + (truncated ? chalk9__default.default.gray(`
|
|
|
8236
8326
|
};
|
|
8237
8327
|
}
|
|
8238
8328
|
}
|
|
8329
|
+
|
|
8330
|
+
// src/commands/shell.ts
|
|
8331
|
+
init_cjs_shims();
|
|
8239
8332
|
async function executeShell(command, ctx) {
|
|
8240
8333
|
const dangerousCommands = ["rm -rf", "del /", "format", "mkfs", "dd if="];
|
|
8241
8334
|
const isDangerous = dangerousCommands.some(
|
|
@@ -8282,7 +8375,22 @@ async function executeShell(command, ctx) {
|
|
|
8282
8375
|
}, 6e4);
|
|
8283
8376
|
});
|
|
8284
8377
|
}
|
|
8378
|
+
|
|
8379
|
+
// src/commands/natural.ts
|
|
8380
|
+
init_cjs_shims();
|
|
8381
|
+
init_new();
|
|
8285
8382
|
async function handleNaturalLanguage(input, ctx) {
|
|
8383
|
+
input.trim().toLowerCase();
|
|
8384
|
+
const session = getActiveSession();
|
|
8385
|
+
if (session) {
|
|
8386
|
+
const result = await handleWorkflowInput(input, ctx);
|
|
8387
|
+
if (result) {
|
|
8388
|
+
return {
|
|
8389
|
+
output: result.output,
|
|
8390
|
+
contextUsed: 0
|
|
8391
|
+
};
|
|
8392
|
+
}
|
|
8393
|
+
}
|
|
8286
8394
|
ctx.contextManager.addMessage({
|
|
8287
8395
|
role: "user",
|
|
8288
8396
|
content: input
|
|
@@ -8295,7 +8403,8 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
8295
8403
|
}
|
|
8296
8404
|
|
|
8297
8405
|
// src/cli/executor.ts
|
|
8298
|
-
|
|
8406
|
+
init_new();
|
|
8407
|
+
var BASIC_COMMANDS = [
|
|
8299
8408
|
"help",
|
|
8300
8409
|
"h",
|
|
8301
8410
|
"?",
|
|
@@ -8314,59 +8423,32 @@ var ALLOWED_COMMANDS_WITHOUT_WORKFLOW = [
|
|
|
8314
8423
|
"update",
|
|
8315
8424
|
"u",
|
|
8316
8425
|
"version",
|
|
8317
|
-
"v"
|
|
8318
|
-
// OpenSpec 工作流管理命令(始终允许)
|
|
8319
|
-
"opsx:status",
|
|
8320
|
-
"opsx:cancel",
|
|
8321
|
-
"opsx:rollback"
|
|
8426
|
+
"v"
|
|
8322
8427
|
];
|
|
8323
|
-
var STAGE_PERMISSIONS = {
|
|
8324
|
-
"explore": {
|
|
8325
|
-
canRead: true,
|
|
8326
|
-
canWrite: false,
|
|
8327
|
-
canRunShell: false,
|
|
8328
|
-
allowedAgents: ["architect"]
|
|
8329
|
-
},
|
|
8330
|
-
"new": {
|
|
8331
|
-
canRead: true,
|
|
8332
|
-
canWrite: true,
|
|
8333
|
-
canRunShell: false,
|
|
8334
|
-
allowedAgents: ["frontend-dev", "architect"]
|
|
8335
|
-
},
|
|
8336
|
-
"continue": {
|
|
8337
|
-
canRead: true,
|
|
8338
|
-
canWrite: true,
|
|
8339
|
-
canRunShell: true,
|
|
8340
|
-
allowedAgents: ["frontend-dev", "tester"]
|
|
8341
|
-
},
|
|
8342
|
-
"propose": {
|
|
8343
|
-
canRead: true,
|
|
8344
|
-
canWrite: true,
|
|
8345
|
-
canRunShell: true,
|
|
8346
|
-
allowedAgents: ["frontend-dev"]
|
|
8347
|
-
},
|
|
8348
|
-
"apply": {
|
|
8349
|
-
canRead: true,
|
|
8350
|
-
canWrite: true,
|
|
8351
|
-
canRunShell: true,
|
|
8352
|
-
allowedAgents: ["code-reviewer"]
|
|
8353
|
-
},
|
|
8354
|
-
"archive": {
|
|
8355
|
-
canRead: true,
|
|
8356
|
-
canWrite: false,
|
|
8357
|
-
canRunShell: false,
|
|
8358
|
-
allowedAgents: []
|
|
8359
|
-
}
|
|
8360
|
-
};
|
|
8361
8428
|
var CommandExecutor = class {
|
|
8362
8429
|
async execute(parseResult, ctx) {
|
|
8363
8430
|
if (!parseResult.success || !parseResult.command) {
|
|
8364
8431
|
return { output: chalk9__default.default.red(`\u9519\u8BEF: ${parseResult.error}`) };
|
|
8365
8432
|
}
|
|
8366
8433
|
const { command } = parseResult;
|
|
8367
|
-
const
|
|
8368
|
-
if (!
|
|
8369
|
-
|
|
8434
|
+
const hasActiveWorkflow = getActiveSession() !== null;
|
|
8435
|
+
if (!hasActiveWorkflow) {
|
|
8436
|
+
if (command.type === "slash" /* SLASH */) {
|
|
8437
|
+
const cmd = command.command?.toLowerCase() || "";
|
|
8438
|
+
if (!BASIC_COMMANDS.includes(cmd)) {
|
|
8439
|
+
return {
|
|
8440
|
+
output: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8441
|
+
};
|
|
8442
|
+
}
|
|
8443
|
+
} else if (command.type === "dollar" /* DOLLAR */) {
|
|
8444
|
+
return {
|
|
8445
|
+
output: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u8C03\u7528 Agent") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8446
|
+
};
|
|
8447
|
+
} else if (command.type === "shell" /* SHELL */) {
|
|
8448
|
+
return {
|
|
8449
|
+
output: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u6267\u884C Shell \u547D\u4EE4") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8450
|
+
};
|
|
8451
|
+
}
|
|
8370
8452
|
}
|
|
8371
8453
|
switch (command.type) {
|
|
8372
8454
|
case "slash" /* SLASH */:
|
|
@@ -8385,98 +8467,30 @@ var CommandExecutor = class {
|
|
|
8385
8467
|
return { output: chalk9__default.default.red("\u672A\u77E5\u7684\u547D\u4EE4\u7C7B\u578B") };
|
|
8386
8468
|
}
|
|
8387
8469
|
}
|
|
8388
|
-
/**
|
|
8389
|
-
* 检查工作流权限
|
|
8390
|
-
*/
|
|
8391
|
-
checkWorkflowPermission(command, ctx) {
|
|
8392
|
-
const workflowEngine = ctx.workflowEngine;
|
|
8393
|
-
const workflowState = workflowEngine?.getState();
|
|
8394
|
-
if (command.type === "slash" /* SLASH */) {
|
|
8395
|
-
const cmd = command.command?.toLowerCase();
|
|
8396
|
-
if (cmd?.startsWith("opsx:")) {
|
|
8397
|
-
return { allowed: true };
|
|
8398
|
-
}
|
|
8399
|
-
}
|
|
8400
|
-
if (!workflowState) {
|
|
8401
|
-
if (command.type === "slash" /* SLASH */) {
|
|
8402
|
-
const cmd = command.command?.toLowerCase();
|
|
8403
|
-
if (!ALLOWED_COMMANDS_WITHOUT_WORKFLOW.includes(cmd)) {
|
|
8404
|
-
return {
|
|
8405
|
-
allowed: false,
|
|
8406
|
-
message: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8407
|
-
};
|
|
8408
|
-
}
|
|
8409
|
-
}
|
|
8410
|
-
if (command.type === "natural" /* NATURAL */) {
|
|
8411
|
-
return {
|
|
8412
|
-
allowed: false,
|
|
8413
|
-
message: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8414
|
-
};
|
|
8415
|
-
}
|
|
8416
|
-
if (command.type === "dollar" /* DOLLAR */) {
|
|
8417
|
-
return {
|
|
8418
|
-
allowed: false,
|
|
8419
|
-
message: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u8C03\u7528 Agent") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8420
|
-
};
|
|
8421
|
-
}
|
|
8422
|
-
if (command.type === "shell" /* SHELL */) {
|
|
8423
|
-
return {
|
|
8424
|
-
allowed: false,
|
|
8425
|
-
message: chalk9__default.default.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u6267\u884C Shell \u547D\u4EE4") + chalk9__default.default.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9__default.default.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
8426
|
-
};
|
|
8427
|
-
}
|
|
8428
|
-
return { allowed: true };
|
|
8429
|
-
}
|
|
8430
|
-
const currentStep = workflowState.currentStep;
|
|
8431
|
-
const permissions = STAGE_PERMISSIONS[currentStep];
|
|
8432
|
-
if (command.type === "at" /* AT */ && !permissions.canRead) {
|
|
8433
|
-
return {
|
|
8434
|
-
allowed: false,
|
|
8435
|
-
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8BFB\u53D6\u6587\u4EF6`)
|
|
8436
|
-
};
|
|
8437
|
-
}
|
|
8438
|
-
if (command.type === "dollar" /* DOLLAR */) {
|
|
8439
|
-
const agentId = command.agent?.toLowerCase().replace("$", "");
|
|
8440
|
-
if (!permissions.allowedAgents.includes(agentId)) {
|
|
8441
|
-
return {
|
|
8442
|
-
allowed: false,
|
|
8443
|
-
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8C03\u7528 $${agentId} Agent`) + chalk9__default.default.gray(`
|
|
8444
|
-
\u5F53\u524D\u9636\u6BB5\u5141\u8BB8\u7684 Agent: ${permissions.allowedAgents.map((a) => `$${a}`).join(", ") || "\u65E0"}`)
|
|
8445
|
-
};
|
|
8446
|
-
}
|
|
8447
|
-
}
|
|
8448
|
-
if (command.type === "shell" /* SHELL */ && !permissions.canRunShell) {
|
|
8449
|
-
return {
|
|
8450
|
-
allowed: false,
|
|
8451
|
-
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u6267\u884C Shell \u547D\u4EE4`)
|
|
8452
|
-
};
|
|
8453
|
-
}
|
|
8454
|
-
return { allowed: true };
|
|
8455
|
-
}
|
|
8456
8470
|
async executeSlashCommand(command, ctx) {
|
|
8457
8471
|
const result = await runSlashCommand(
|
|
8458
|
-
command.command,
|
|
8472
|
+
command.command || "",
|
|
8459
8473
|
command.args || [],
|
|
8460
8474
|
ctx
|
|
8461
8475
|
);
|
|
8462
8476
|
return { output: result.output, exit: result.exit };
|
|
8463
8477
|
}
|
|
8464
8478
|
async executeFileReference(command, ctx) {
|
|
8465
|
-
const result = await handleFileReference(command.path, ctx);
|
|
8479
|
+
const result = await handleFileReference(command.path || "", ctx);
|
|
8466
8480
|
return {
|
|
8467
8481
|
output: result.output,
|
|
8468
8482
|
contextUsed: result.contextUsed
|
|
8469
8483
|
};
|
|
8470
8484
|
}
|
|
8471
8485
|
async executeAgent(command, ctx) {
|
|
8472
|
-
const result = await runAgent(command.agent, command.args || [], ctx);
|
|
8486
|
+
const result = await runAgent(command.agent || "", command.args || [], ctx);
|
|
8473
8487
|
return {
|
|
8474
8488
|
output: result.output,
|
|
8475
8489
|
contextUsed: result.contextUsed
|
|
8476
8490
|
};
|
|
8477
8491
|
}
|
|
8478
8492
|
async executeShell(command, ctx) {
|
|
8479
|
-
const result = await executeShell(command.shellCommand, ctx);
|
|
8493
|
+
const result = await executeShell(command.shellCommand || "", ctx);
|
|
8480
8494
|
return { output: result.output };
|
|
8481
8495
|
}
|
|
8482
8496
|
async executeNaturalLanguage(command, ctx) {
|
|
@@ -8493,6 +8507,9 @@ var CommandExecutor = class {
|
|
|
8493
8507
|
};
|
|
8494
8508
|
}
|
|
8495
8509
|
};
|
|
8510
|
+
|
|
8511
|
+
// src/cli/completer.ts
|
|
8512
|
+
init_cjs_shims();
|
|
8496
8513
|
var Completer = class {
|
|
8497
8514
|
parser;
|
|
8498
8515
|
workingDirectory;
|