@nick848/sf-cli 1.0.0 → 1.0.1
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/README.md +61 -0
- package/dist/cli/index.js +212 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +254 -245
- package/dist/index.d.ts +254 -245
- package/dist/index.js +169 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -48,6 +48,20 @@ spfe
|
|
|
48
48
|
/model
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## 命令行参数
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# 查看版本号
|
|
55
|
+
sf-cli -v
|
|
56
|
+
# 或
|
|
57
|
+
spfe -v
|
|
58
|
+
|
|
59
|
+
# 查看帮助
|
|
60
|
+
sf-cli -h
|
|
61
|
+
# 或
|
|
62
|
+
spfe -h
|
|
63
|
+
```
|
|
64
|
+
|
|
51
65
|
## 命令
|
|
52
66
|
|
|
53
67
|
### 斜杠命令
|
|
@@ -59,6 +73,7 @@ spfe
|
|
|
59
73
|
| `/model` | 配置AI模型 |
|
|
60
74
|
| `/new` | 创建新需求 |
|
|
61
75
|
| `/clear` | 清空对话历史 |
|
|
76
|
+
| `/version` | 查看版本号 |
|
|
62
77
|
| `/exit` | 退出CLI |
|
|
63
78
|
| `/update` | 检查更新 |
|
|
64
79
|
|
|
@@ -87,6 +102,29 @@ spfe
|
|
|
87
102
|
|
|
88
103
|
## 工作流
|
|
89
104
|
|
|
105
|
+
### 强制工作流机制
|
|
106
|
+
|
|
107
|
+
CLI 强制执行 OpenSpec 工作流,任何代码修改需求都必须走工作流流程:
|
|
108
|
+
|
|
109
|
+
1. **无工作流状态**:只允许执行基础命令
|
|
110
|
+
- `/help`, `/init`, `/model`, `/new`, `/exit`, `/clear`, `/update`, `/version`
|
|
111
|
+
- 其他操作会提示先启动工作流
|
|
112
|
+
|
|
113
|
+
2. **有工作流状态**:根据当前阶段限制操作
|
|
114
|
+
- 各阶段有权限控制,只能执行该阶段允许的操作
|
|
115
|
+
- Agent 调用受阶段限制
|
|
116
|
+
|
|
117
|
+
### 各阶段权限
|
|
118
|
+
|
|
119
|
+
| 阶段 | 读文件 | 写文件 | Shell | 允许的 Agent |
|
|
120
|
+
|------|--------|--------|-------|--------------|
|
|
121
|
+
| explore | ✓ | ✗ | ✗ | architect |
|
|
122
|
+
| new | ✓ | ✓ | ✗ | frontend-dev, architect |
|
|
123
|
+
| continue | ✓ | ✓ | ✓ | frontend-dev, tester |
|
|
124
|
+
| propose | ✓ | ✓ | ✓ | frontend-dev |
|
|
125
|
+
| apply | ✓ | ✓ | ✓ | code-reviewer |
|
|
126
|
+
| archive | ✓ | ✗ | ✗ | - |
|
|
127
|
+
|
|
90
128
|
### 复杂需求流程(复杂度 >= 6)
|
|
91
129
|
|
|
92
130
|
```
|
|
@@ -146,6 +184,29 @@ await norms.scanProject(projectPath);
|
|
|
146
184
|
const result = await runAgent('frontend-dev', ['创建登录组件'], ctx);
|
|
147
185
|
```
|
|
148
186
|
|
|
187
|
+
## Changelog
|
|
188
|
+
|
|
189
|
+
### v1.0.1 (2026-03-21)
|
|
190
|
+
|
|
191
|
+
**新增功能**
|
|
192
|
+
|
|
193
|
+
- 🔒 强制工作流机制 - 所有代码修改必须走工作流流程
|
|
194
|
+
- 📊 状态栏显示工作流阶段
|
|
195
|
+
- 🔐 各阶段权限控制 - 读/写/Shell/Agent 受限
|
|
196
|
+
|
|
197
|
+
### v1.0.0 (2026-03-21)
|
|
198
|
+
|
|
199
|
+
**首次发布**
|
|
200
|
+
|
|
201
|
+
- 🤖 AI驱动 - 支持 GLM-5、GPT-4o、Claude 等多种AI模型
|
|
202
|
+
- 📋 标准化流程 - BDD+TDD+OpenSpec 规范支持
|
|
203
|
+
- 📚 规范学习 - 自动从代码和对话中学习开发规范
|
|
204
|
+
- 🔧 Sub Agent - 专业化 Agent 协作(前端开发、代码审核、架构师、测试)
|
|
205
|
+
- 🔄 工作流控制 - 三阶段人工确认、回滚机制
|
|
206
|
+
- 🔌 MCP集成 - 支持蓝湖、Figma 设计稿
|
|
207
|
+
- 💻 双命令入口 - `sf-cli` 和 `spfe` 均可启动
|
|
208
|
+
- 📝 交互式命令 - 支持 `/` 斜杠命令和命令行参数模式
|
|
209
|
+
|
|
149
210
|
## License
|
|
150
211
|
|
|
151
212
|
[MIT](LICENSE)
|
package/dist/cli/index.js
CHANGED
|
@@ -15,6 +15,7 @@ require('@modelcontextprotocol/sdk/client/index.js');
|
|
|
15
15
|
require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
16
16
|
var child_process = require('child_process');
|
|
17
17
|
require('uuid');
|
|
18
|
+
var module$1 = require('module');
|
|
18
19
|
|
|
19
20
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
21
|
|
|
@@ -44,6 +45,10 @@ var fsSync__namespace = /*#__PURE__*/_interopNamespace(fsSync);
|
|
|
44
45
|
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
45
46
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
46
47
|
|
|
48
|
+
// node_modules/tsup/assets/cjs_shims.js
|
|
49
|
+
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
50
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
51
|
+
|
|
47
52
|
// src/cli/parser.ts
|
|
48
53
|
var CommandParser = class {
|
|
49
54
|
slashCommands = [
|
|
@@ -3959,15 +3964,32 @@ var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
|
3959
3964
|
var COMPLEXITY_THRESHOLD = 6;
|
|
3960
3965
|
async function handleNew(args, ctx) {
|
|
3961
3966
|
const workingDir = ctx.options.workingDirectory;
|
|
3967
|
+
const workflowEngine = ctx.workflowEngine;
|
|
3968
|
+
if (workflowEngine) {
|
|
3969
|
+
const existingState = workflowEngine.getState();
|
|
3970
|
+
if (existingState && existingState.status === "running") {
|
|
3971
|
+
return {
|
|
3972
|
+
output: chalk9__default.default.yellow("\u5F53\u524D\u5DF2\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9__default.default.gray(`
|
|
3973
|
+
|
|
3974
|
+
\u5DE5\u4F5C\u6D41: ${existingState.title}`) + chalk9__default.default.gray(`
|
|
3975
|
+
\u5F53\u524D\u9636\u6BB5: ${existingState.currentStep}`) + chalk9__default.default.gray(`
|
|
3976
|
+
|
|
3977
|
+
\u9009\u9879:`) + chalk9__default.default.gray(`
|
|
3978
|
+
1. \u7EE7\u7EED\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:${existingState.currentStep}`) + chalk9__default.default.gray(`
|
|
3979
|
+
2. \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:cancel`) + chalk9__default.default.gray(`
|
|
3980
|
+
3. \u67E5\u770B\u5DE5\u4F5C\u6D41\u72B6\u6001: /opsx:status`)
|
|
3981
|
+
};
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3962
3984
|
const { requirement, forceComplexity } = parseArgs(args);
|
|
3963
3985
|
if (!requirement) {
|
|
3964
3986
|
return {
|
|
3965
3987
|
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")
|
|
3966
3988
|
};
|
|
3967
3989
|
}
|
|
3968
|
-
return newFeature({ requirement, forceComplexity }, workingDir);
|
|
3990
|
+
return newFeature({ requirement, forceComplexity }, workingDir, workflowEngine);
|
|
3969
3991
|
}
|
|
3970
|
-
async function newFeature(options, workingDir) {
|
|
3992
|
+
async function newFeature(options, workingDir, workflowEngine) {
|
|
3971
3993
|
const cwd = workingDir || process.cwd();
|
|
3972
3994
|
const { requirement, forceComplexity } = options;
|
|
3973
3995
|
try {
|
|
@@ -3985,8 +4007,10 @@ async function newFeature(options, workingDir) {
|
|
|
3985
4007
|
try {
|
|
3986
4008
|
const context = await readProjectContext(cwd);
|
|
3987
4009
|
const analysis = forceComplexity ? createForcedAnalysis(forceComplexity) : analyzeComplexity(requirement, context);
|
|
3988
|
-
const workflow = new WorkflowEngine();
|
|
3989
|
-
|
|
4010
|
+
const workflow = workflowEngine || new WorkflowEngine();
|
|
4011
|
+
if (!workflowEngine) {
|
|
4012
|
+
await workflow.initialize(cwd);
|
|
4013
|
+
}
|
|
3990
4014
|
const state = await workflow.start(requirement, analysis.score, {
|
|
3991
4015
|
title: extractTitle(requirement)
|
|
3992
4016
|
});
|
|
@@ -5157,8 +5181,9 @@ ${generateConfirmationPrompt(e.point)}`) + chalk9__default.default.cyan(`
|
|
|
5157
5181
|
throw e;
|
|
5158
5182
|
}
|
|
5159
5183
|
}
|
|
5160
|
-
|
|
5161
|
-
|
|
5184
|
+
var require2 = module$1.createRequire(importMetaUrl);
|
|
5185
|
+
var packageJson = require2("../../package.json");
|
|
5186
|
+
var VERSION2 = packageJson.version;
|
|
5162
5187
|
async function runSlashCommand(command, args, ctx) {
|
|
5163
5188
|
const normalizedCommand = normalizeCommand(command);
|
|
5164
5189
|
switch (normalizedCommand) {
|
|
@@ -5186,6 +5211,11 @@ async function runSlashCommand(command, args, ctx) {
|
|
|
5186
5211
|
case "new":
|
|
5187
5212
|
case "n":
|
|
5188
5213
|
return handleNew(args, ctx);
|
|
5214
|
+
case "version":
|
|
5215
|
+
case "v":
|
|
5216
|
+
return {
|
|
5217
|
+
output: chalk9__default.default.cyan(`sf-cli v${VERSION2}`)
|
|
5218
|
+
};
|
|
5189
5219
|
default:
|
|
5190
5220
|
if (normalizedCommand.startsWith("opsx:")) {
|
|
5191
5221
|
return handleOpsx(normalizedCommand, args, ctx);
|
|
@@ -5296,12 +5326,75 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
5296
5326
|
}
|
|
5297
5327
|
|
|
5298
5328
|
// src/cli/executor.ts
|
|
5329
|
+
var ALLOWED_COMMANDS_WITHOUT_WORKFLOW = [
|
|
5330
|
+
"help",
|
|
5331
|
+
"h",
|
|
5332
|
+
"?",
|
|
5333
|
+
"init",
|
|
5334
|
+
"i",
|
|
5335
|
+
"model",
|
|
5336
|
+
"m",
|
|
5337
|
+
"new",
|
|
5338
|
+
"n",
|
|
5339
|
+
"exit",
|
|
5340
|
+
"e",
|
|
5341
|
+
"q",
|
|
5342
|
+
"quit",
|
|
5343
|
+
"clear",
|
|
5344
|
+
"c",
|
|
5345
|
+
"update",
|
|
5346
|
+
"u",
|
|
5347
|
+
"version",
|
|
5348
|
+
"v"
|
|
5349
|
+
];
|
|
5350
|
+
var STAGE_PERMISSIONS = {
|
|
5351
|
+
"explore": {
|
|
5352
|
+
canRead: true,
|
|
5353
|
+
canWrite: false,
|
|
5354
|
+
canRunShell: false,
|
|
5355
|
+
allowedAgents: ["architect"]
|
|
5356
|
+
},
|
|
5357
|
+
"new": {
|
|
5358
|
+
canRead: true,
|
|
5359
|
+
canWrite: true,
|
|
5360
|
+
canRunShell: false,
|
|
5361
|
+
allowedAgents: ["frontend-dev", "architect"]
|
|
5362
|
+
},
|
|
5363
|
+
"continue": {
|
|
5364
|
+
canRead: true,
|
|
5365
|
+
canWrite: true,
|
|
5366
|
+
canRunShell: true,
|
|
5367
|
+
allowedAgents: ["frontend-dev", "tester"]
|
|
5368
|
+
},
|
|
5369
|
+
"propose": {
|
|
5370
|
+
canRead: true,
|
|
5371
|
+
canWrite: true,
|
|
5372
|
+
canRunShell: true,
|
|
5373
|
+
allowedAgents: ["frontend-dev"]
|
|
5374
|
+
},
|
|
5375
|
+
"apply": {
|
|
5376
|
+
canRead: true,
|
|
5377
|
+
canWrite: true,
|
|
5378
|
+
canRunShell: true,
|
|
5379
|
+
allowedAgents: ["code-reviewer"]
|
|
5380
|
+
},
|
|
5381
|
+
"archive": {
|
|
5382
|
+
canRead: true,
|
|
5383
|
+
canWrite: false,
|
|
5384
|
+
canRunShell: false,
|
|
5385
|
+
allowedAgents: []
|
|
5386
|
+
}
|
|
5387
|
+
};
|
|
5299
5388
|
var CommandExecutor = class {
|
|
5300
5389
|
async execute(parseResult, ctx) {
|
|
5301
5390
|
if (!parseResult.success || !parseResult.command) {
|
|
5302
5391
|
return { output: chalk9__default.default.red(`\u9519\u8BEF: ${parseResult.error}`) };
|
|
5303
5392
|
}
|
|
5304
5393
|
const { command } = parseResult;
|
|
5394
|
+
const workflowCheck = this.checkWorkflowPermission(command, ctx);
|
|
5395
|
+
if (!workflowCheck.allowed) {
|
|
5396
|
+
return { output: workflowCheck.message };
|
|
5397
|
+
}
|
|
5305
5398
|
switch (command.type) {
|
|
5306
5399
|
case "slash" /* SLASH */:
|
|
5307
5400
|
return this.executeSlashCommand(command, ctx);
|
|
@@ -5319,13 +5412,75 @@ var CommandExecutor = class {
|
|
|
5319
5412
|
return { output: chalk9__default.default.red("\u672A\u77E5\u7684\u547D\u4EE4\u7C7B\u578B") };
|
|
5320
5413
|
}
|
|
5321
5414
|
}
|
|
5415
|
+
/**
|
|
5416
|
+
* 检查工作流权限
|
|
5417
|
+
*/
|
|
5418
|
+
checkWorkflowPermission(command, ctx) {
|
|
5419
|
+
const workflowEngine = ctx.workflowEngine;
|
|
5420
|
+
const workflowState = workflowEngine?.getState();
|
|
5421
|
+
if (!workflowState) {
|
|
5422
|
+
if (command.type === "slash" /* SLASH */) {
|
|
5423
|
+
const cmd = command.command?.toLowerCase();
|
|
5424
|
+
if (!ALLOWED_COMMANDS_WITHOUT_WORKFLOW.includes(cmd)) {
|
|
5425
|
+
return {
|
|
5426
|
+
allowed: false,
|
|
5427
|
+
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")
|
|
5428
|
+
};
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5431
|
+
if (command.type === "natural" /* NATURAL */) {
|
|
5432
|
+
return {
|
|
5433
|
+
allowed: false,
|
|
5434
|
+
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")
|
|
5435
|
+
};
|
|
5436
|
+
}
|
|
5437
|
+
if (command.type === "dollar" /* DOLLAR */) {
|
|
5438
|
+
return {
|
|
5439
|
+
allowed: false,
|
|
5440
|
+
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")
|
|
5441
|
+
};
|
|
5442
|
+
}
|
|
5443
|
+
if (command.type === "shell" /* SHELL */) {
|
|
5444
|
+
return {
|
|
5445
|
+
allowed: false,
|
|
5446
|
+
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")
|
|
5447
|
+
};
|
|
5448
|
+
}
|
|
5449
|
+
return { allowed: true };
|
|
5450
|
+
}
|
|
5451
|
+
const currentStep = workflowState.currentStep;
|
|
5452
|
+
const permissions = STAGE_PERMISSIONS[currentStep];
|
|
5453
|
+
if (command.type === "at" /* AT */ && !permissions.canRead) {
|
|
5454
|
+
return {
|
|
5455
|
+
allowed: false,
|
|
5456
|
+
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8BFB\u53D6\u6587\u4EF6`)
|
|
5457
|
+
};
|
|
5458
|
+
}
|
|
5459
|
+
if (command.type === "dollar" /* DOLLAR */) {
|
|
5460
|
+
const agentId = command.agent?.toLowerCase().replace("$", "");
|
|
5461
|
+
if (!permissions.allowedAgents.includes(agentId)) {
|
|
5462
|
+
return {
|
|
5463
|
+
allowed: false,
|
|
5464
|
+
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8C03\u7528 $${agentId} Agent`) + chalk9__default.default.gray(`
|
|
5465
|
+
\u5F53\u524D\u9636\u6BB5\u5141\u8BB8\u7684 Agent: ${permissions.allowedAgents.map((a) => `$${a}`).join(", ") || "\u65E0"}`)
|
|
5466
|
+
};
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
if (command.type === "shell" /* SHELL */ && !permissions.canRunShell) {
|
|
5470
|
+
return {
|
|
5471
|
+
allowed: false,
|
|
5472
|
+
message: chalk9__default.default.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u6267\u884C Shell \u547D\u4EE4`)
|
|
5473
|
+
};
|
|
5474
|
+
}
|
|
5475
|
+
return { allowed: true };
|
|
5476
|
+
}
|
|
5322
5477
|
async executeSlashCommand(command, ctx) {
|
|
5323
5478
|
const result = await runSlashCommand(
|
|
5324
5479
|
command.command,
|
|
5325
5480
|
command.args || [],
|
|
5326
5481
|
ctx
|
|
5327
5482
|
);
|
|
5328
|
-
return { output: result.output };
|
|
5483
|
+
return { output: result.output, exit: result.exit };
|
|
5329
5484
|
}
|
|
5330
5485
|
async executeFileReference(command, ctx) {
|
|
5331
5486
|
const result = await handleFileReference(command.path, ctx);
|
|
@@ -5663,11 +5818,28 @@ ${summary}`,
|
|
|
5663
5818
|
return tokens.toString();
|
|
5664
5819
|
}
|
|
5665
5820
|
};
|
|
5821
|
+
var STEP_DISPLAY_NAMES = {
|
|
5822
|
+
"explore": "\u63A2\u7D22",
|
|
5823
|
+
"new": "\u8BBE\u8BA1",
|
|
5824
|
+
"continue": "\u5F00\u53D1",
|
|
5825
|
+
"propose": "\u63D0\u6848",
|
|
5826
|
+
"apply": "\u5BA1\u67E5",
|
|
5827
|
+
"archive": "\u5F52\u6863"
|
|
5828
|
+
};
|
|
5829
|
+
var STEP_COLORS = {
|
|
5830
|
+
"explore": chalk9__default.default.magenta,
|
|
5831
|
+
"new": chalk9__default.default.blue,
|
|
5832
|
+
"continue": chalk9__default.default.cyan,
|
|
5833
|
+
"propose": chalk9__default.default.green,
|
|
5834
|
+
"apply": chalk9__default.default.yellow,
|
|
5835
|
+
"archive": chalk9__default.default.gray
|
|
5836
|
+
};
|
|
5666
5837
|
function displayStatus(info) {
|
|
5667
5838
|
const dirDisplay = info.directory.length > 30 ? "..." + info.directory.slice(-27) : info.directory;
|
|
5668
5839
|
const contextKB = Math.round(info.contextLeft / 1024);
|
|
5669
5840
|
const contextDisplay = contextKB > 100 ? chalk9__default.default.green(`${contextKB}KB`) : contextKB > 50 ? chalk9__default.default.yellow(`${contextKB}KB`) : chalk9__default.default.red(`${contextKB}KB`);
|
|
5670
5841
|
const servicesDisplay = info.services.length > 0 ? info.services.map((s) => `${s.name}:${s.port}`).join(", ") : chalk9__default.default.gray("\u65E0");
|
|
5842
|
+
const workflowDisplay = info.workflowStep ? STEP_COLORS[info.workflowStep](`[${STEP_DISPLAY_NAMES[info.workflowStep]}]`) : chalk9__default.default.gray("[\u65E0\u5DE5\u4F5C\u6D41]");
|
|
5671
5843
|
console.log(chalk9__default.default.gray("\u2500".repeat(60)));
|
|
5672
5844
|
console.log(
|
|
5673
5845
|
chalk9__default.default.cyan("\u{1F4C1}"),
|
|
@@ -5677,7 +5849,10 @@ function displayStatus(info) {
|
|
|
5677
5849
|
chalk9__default.default.white(info.model),
|
|
5678
5850
|
chalk9__default.default.cyan("\u2502"),
|
|
5679
5851
|
chalk9__default.default.cyan("\u{1F4CA}"),
|
|
5680
|
-
contextDisplay
|
|
5852
|
+
contextDisplay,
|
|
5853
|
+
chalk9__default.default.cyan("\u2502"),
|
|
5854
|
+
chalk9__default.default.cyan("\u{1F504}"),
|
|
5855
|
+
workflowDisplay
|
|
5681
5856
|
);
|
|
5682
5857
|
console.log(
|
|
5683
5858
|
chalk9__default.default.cyan("\u{1F50C}"),
|
|
@@ -5901,10 +6076,17 @@ async function startInteractiveMode(options) {
|
|
|
5901
6076
|
const contextManager = new ContextManager();
|
|
5902
6077
|
const configManager = new ConfigManager();
|
|
5903
6078
|
const modelService = new ModelService(configManager);
|
|
6079
|
+
const workflowEngine = new WorkflowEngine();
|
|
6080
|
+
const normsManager = new NormsManager({
|
|
6081
|
+
projectPath: options.workingDirectory,
|
|
6082
|
+
normsDir: path5__namespace.join(options.workingDirectory, ".sf-cli", "norms")
|
|
6083
|
+
});
|
|
5904
6084
|
await configManager.load(options.workingDirectory);
|
|
5905
6085
|
await contextManager.initialize(options.workingDirectory);
|
|
5906
6086
|
const statsDir = path5__namespace.join(options.workingDirectory, ".sf-cli");
|
|
5907
6087
|
await modelService.initialize(statsDir);
|
|
6088
|
+
await workflowEngine.initialize(options.workingDirectory);
|
|
6089
|
+
await normsManager.initialize();
|
|
5908
6090
|
const state = {
|
|
5909
6091
|
isRunning: true,
|
|
5910
6092
|
currentTask: null,
|
|
@@ -5913,12 +6095,23 @@ async function startInteractiveMode(options) {
|
|
|
5913
6095
|
// 512K
|
|
5914
6096
|
};
|
|
5915
6097
|
const currentModel = modelService.getCurrentModel() || "GLM-5";
|
|
6098
|
+
const workflowState = workflowEngine.getState();
|
|
5916
6099
|
displayStatus({
|
|
5917
6100
|
directory: options.workingDirectory,
|
|
5918
6101
|
model: currentModel,
|
|
5919
6102
|
contextLeft: state.contextLimit - state.contextUsed,
|
|
5920
|
-
services: []
|
|
6103
|
+
services: [],
|
|
6104
|
+
workflowStep: workflowState?.currentStep
|
|
5921
6105
|
});
|
|
6106
|
+
if (workflowState) {
|
|
6107
|
+
console.log(chalk9__default.default.cyan(`
|
|
6108
|
+
\u{1F4CB} \u6D3B\u8DC3\u5DE5\u4F5C\u6D41: ${workflowState.title}`));
|
|
6109
|
+
console.log(chalk9__default.default.gray(` \u5F53\u524D\u9636\u6BB5: ${workflowState.currentStep} | \u72B6\u6001: ${workflowState.status}`));
|
|
6110
|
+
console.log(chalk9__default.default.gray(` \u8F93\u5165 /opsx:status \u67E5\u770B\u8BE6\u60C5
|
|
6111
|
+
`));
|
|
6112
|
+
} else {
|
|
6113
|
+
console.log(chalk9__default.default.gray("\n\u{1F4A1} \u4F7F\u7528 /new <\u9700\u6C42\u63CF\u8FF0> \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41\n"));
|
|
6114
|
+
}
|
|
5922
6115
|
const saveHistory = async () => {
|
|
5923
6116
|
try {
|
|
5924
6117
|
await fs5__namespace.mkdir(path5__namespace.dirname(historyFile), { recursive: true });
|
|
@@ -5963,6 +6156,8 @@ async function startInteractiveMode(options) {
|
|
|
5963
6156
|
contextManager,
|
|
5964
6157
|
configManager,
|
|
5965
6158
|
modelService,
|
|
6159
|
+
normsManager,
|
|
6160
|
+
workflowEngine,
|
|
5966
6161
|
state,
|
|
5967
6162
|
options
|
|
5968
6163
|
});
|
|
@@ -5981,23 +6176,25 @@ async function startInteractiveMode(options) {
|
|
|
5981
6176
|
console.log(chalk9__default.default.red(`\u9519\u8BEF: ${error.message}`));
|
|
5982
6177
|
}
|
|
5983
6178
|
const currentModel2 = modelService.getCurrentModel() || "GLM-5";
|
|
6179
|
+
const workflowState2 = workflowEngine.getState();
|
|
5984
6180
|
displayStatus({
|
|
5985
6181
|
directory: options.workingDirectory,
|
|
5986
6182
|
model: currentModel2,
|
|
5987
6183
|
contextLeft: state.contextLimit - state.contextUsed,
|
|
5988
|
-
services: []
|
|
6184
|
+
services: [],
|
|
6185
|
+
workflowStep: workflowState2?.currentStep
|
|
5989
6186
|
});
|
|
5990
6187
|
rl.prompt();
|
|
5991
6188
|
}
|
|
5992
6189
|
}
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
var
|
|
6190
|
+
var require3 = module$1.createRequire(importMetaUrl);
|
|
6191
|
+
var packageJson2 = require3("../../package.json");
|
|
6192
|
+
var VERSION3 = packageJson2.version;
|
|
5996
6193
|
var NAME = "sf-cli";
|
|
5997
|
-
commander.program.name(NAME).description("\u4E13\u4E3A\u524D\u7AEF\u5F00\u53D1\u8BBE\u8BA1\u7684AI\u9A71\u52A8CLI\u5DE5\u5177").version(
|
|
6194
|
+
commander.program.name(NAME).description("\u4E13\u4E3A\u524D\u7AEF\u5F00\u53D1\u8BBE\u8BA1\u7684AI\u9A71\u52A8CLI\u5DE5\u5177").version(VERSION3, "-v, --version", "\u663E\u793A\u7248\u672C\u53F7");
|
|
5998
6195
|
commander.program.argument("[directory]", "\u5DE5\u4F5C\u76EE\u5F55", process.cwd()).option("-m, --model <model>", "\u6307\u5B9AAI\u6A21\u578B").option("-y, --yolo", "\u81EA\u52A8\u786E\u8BA4\u6240\u6709\u64CD\u4F5C").action(async (directory, options) => {
|
|
5999
6196
|
console.log(chalk9__default.default.cyan.bold(`
|
|
6000
|
-
\u{1F680} ${NAME} v${
|
|
6197
|
+
\u{1F680} ${NAME} v${VERSION3}`));
|
|
6001
6198
|
console.log(chalk9__default.default.gray("\u4E13\u4E3A\u524D\u7AEF\u5F00\u53D1\u8BBE\u8BA1\u7684AI\u9A71\u52A8CLI\u5DE5\u5177\n"));
|
|
6002
6199
|
await startInteractiveMode({
|
|
6003
6200
|
workingDirectory: directory,
|