@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/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
- var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
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 document = data.document || data;
2396
+ const document2 = data.document || data;
1823
2397
  return {
1824
2398
  id: nodeId || fileKey,
1825
- name: document.name || "\u672A\u547D\u540D\u8BBE\u8BA1\u7A3F",
2399
+ name: document2.name || "\u672A\u547D\u540D\u8BBE\u8BA1\u7A3F",
1826
2400
  platform: "figma",
1827
2401
  url,
1828
- width: document.absoluteBoundingBox?.width || 0,
1829
- height: document.absoluteBoundingBox?.height || 0,
2402
+ width: document2.absoluteBoundingBox?.width || 0,
2403
+ height: document2.absoluteBoundingBox?.height || 0,
1830
2404
  scale: 1,
1831
- layers: this.parseFigmaLayers(document.children || []),
1832
- styles: this.extractStylesFromDocument(document),
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(document) {
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(document);
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
- \u{1F4CB} ${existingState.title || existingState.id}`) + chalk9__default.default.gray(`
6924
- \u7C7B\u578B: ${existingState.type} | \u590D\u6742\u5EA6: ${existingState.complexity}/10`) + chalk9__default.default.cyan(`
7530
+ // src/commands/runner.ts
7531
+ init_new();
6925
7532
 
6926
- \u8FDB\u5EA6: ${existingState.steps.map((s) => {
6927
- const icon = s.status === "completed" ? "\u2713" : s.status === "running" ? "\u25CF" : "\u25CB";
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 ${state.currentStep} \u4E0D\u652F\u6301\u56DE\u6EDA`)
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(state.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")
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
- var ALLOWED_COMMANDS_WITHOUT_WORKFLOW = [
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 workflowCheck = this.checkWorkflowPermission(command, ctx);
8368
- if (!workflowCheck.allowed) {
8369
- return { output: workflowCheck.message };
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;