@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/dist/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import chalk9 from 'chalk';
|
|
|
10
10
|
import { v4 } from 'uuid';
|
|
11
11
|
import { prompt } from 'enquirer';
|
|
12
12
|
import { spawn } from 'child_process';
|
|
13
|
+
import { createRequire } from 'module';
|
|
13
14
|
|
|
14
15
|
// src/services/config.ts
|
|
15
16
|
var DEFAULT_CONFIG = {
|
|
@@ -6622,15 +6623,32 @@ var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
|
6622
6623
|
var COMPLEXITY_THRESHOLD = 6;
|
|
6623
6624
|
async function handleNew(args, ctx) {
|
|
6624
6625
|
const workingDir = ctx.options.workingDirectory;
|
|
6626
|
+
const workflowEngine = ctx.workflowEngine;
|
|
6627
|
+
if (workflowEngine) {
|
|
6628
|
+
const existingState = workflowEngine.getState();
|
|
6629
|
+
if (existingState && existingState.status === "running") {
|
|
6630
|
+
return {
|
|
6631
|
+
output: chalk9.yellow("\u5F53\u524D\u5DF2\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray(`
|
|
6632
|
+
|
|
6633
|
+
\u5DE5\u4F5C\u6D41: ${existingState.title}`) + chalk9.gray(`
|
|
6634
|
+
\u5F53\u524D\u9636\u6BB5: ${existingState.currentStep}`) + chalk9.gray(`
|
|
6635
|
+
|
|
6636
|
+
\u9009\u9879:`) + chalk9.gray(`
|
|
6637
|
+
1. \u7EE7\u7EED\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:${existingState.currentStep}`) + chalk9.gray(`
|
|
6638
|
+
2. \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:cancel`) + chalk9.gray(`
|
|
6639
|
+
3. \u67E5\u770B\u5DE5\u4F5C\u6D41\u72B6\u6001: /opsx:status`)
|
|
6640
|
+
};
|
|
6641
|
+
}
|
|
6642
|
+
}
|
|
6625
6643
|
const { requirement, forceComplexity } = parseArgs(args);
|
|
6626
6644
|
if (!requirement) {
|
|
6627
6645
|
return {
|
|
6628
6646
|
output: chalk9.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray("\n\u9009\u9879:") + chalk9.gray("\n --simple \u5F3A\u5236\u4F7F\u7528\u7B80\u5355\u6D41\u7A0B") + chalk9.gray("\n --complex \u5F3A\u5236\u4F7F\u7528\u590D\u6742\u6D41\u7A0B")
|
|
6629
6647
|
};
|
|
6630
6648
|
}
|
|
6631
|
-
return newFeature({ requirement, forceComplexity }, workingDir);
|
|
6649
|
+
return newFeature({ requirement, forceComplexity }, workingDir, workflowEngine);
|
|
6632
6650
|
}
|
|
6633
|
-
async function newFeature(options, workingDir) {
|
|
6651
|
+
async function newFeature(options, workingDir, workflowEngine) {
|
|
6634
6652
|
const cwd = workingDir || process.cwd();
|
|
6635
6653
|
const { requirement, forceComplexity } = options;
|
|
6636
6654
|
try {
|
|
@@ -6648,8 +6666,10 @@ async function newFeature(options, workingDir) {
|
|
|
6648
6666
|
try {
|
|
6649
6667
|
const context = await readProjectContext(cwd);
|
|
6650
6668
|
const analysis = forceComplexity ? createForcedAnalysis(forceComplexity) : analyzeComplexity(requirement, context);
|
|
6651
|
-
const workflow = new WorkflowEngine();
|
|
6652
|
-
|
|
6669
|
+
const workflow = workflowEngine || new WorkflowEngine();
|
|
6670
|
+
if (!workflowEngine) {
|
|
6671
|
+
await workflow.initialize(cwd);
|
|
6672
|
+
}
|
|
6653
6673
|
const state = await workflow.start(requirement, analysis.score, {
|
|
6654
6674
|
title: extractTitle(requirement)
|
|
6655
6675
|
});
|
|
@@ -7203,8 +7223,9 @@ ${generateConfirmationPrompt(e.point)}`) + chalk9.cyan(`
|
|
|
7203
7223
|
throw e;
|
|
7204
7224
|
}
|
|
7205
7225
|
}
|
|
7206
|
-
|
|
7207
|
-
|
|
7226
|
+
var require2 = createRequire(import.meta.url);
|
|
7227
|
+
var packageJson = require2("../../package.json");
|
|
7228
|
+
var VERSION2 = packageJson.version;
|
|
7208
7229
|
async function runSlashCommand(command, args, ctx) {
|
|
7209
7230
|
const normalizedCommand = normalizeCommand(command);
|
|
7210
7231
|
switch (normalizedCommand) {
|
|
@@ -7232,6 +7253,11 @@ async function runSlashCommand(command, args, ctx) {
|
|
|
7232
7253
|
case "new":
|
|
7233
7254
|
case "n":
|
|
7234
7255
|
return handleNew(args, ctx);
|
|
7256
|
+
case "version":
|
|
7257
|
+
case "v":
|
|
7258
|
+
return {
|
|
7259
|
+
output: chalk9.cyan(`sf-cli v${VERSION2}`)
|
|
7260
|
+
};
|
|
7235
7261
|
default:
|
|
7236
7262
|
if (normalizedCommand.startsWith("opsx:")) {
|
|
7237
7263
|
return handleOpsx(normalizedCommand, args, ctx);
|
|
@@ -7342,12 +7368,75 @@ async function handleNaturalLanguage(input, ctx) {
|
|
|
7342
7368
|
}
|
|
7343
7369
|
|
|
7344
7370
|
// src/cli/executor.ts
|
|
7371
|
+
var ALLOWED_COMMANDS_WITHOUT_WORKFLOW = [
|
|
7372
|
+
"help",
|
|
7373
|
+
"h",
|
|
7374
|
+
"?",
|
|
7375
|
+
"init",
|
|
7376
|
+
"i",
|
|
7377
|
+
"model",
|
|
7378
|
+
"m",
|
|
7379
|
+
"new",
|
|
7380
|
+
"n",
|
|
7381
|
+
"exit",
|
|
7382
|
+
"e",
|
|
7383
|
+
"q",
|
|
7384
|
+
"quit",
|
|
7385
|
+
"clear",
|
|
7386
|
+
"c",
|
|
7387
|
+
"update",
|
|
7388
|
+
"u",
|
|
7389
|
+
"version",
|
|
7390
|
+
"v"
|
|
7391
|
+
];
|
|
7392
|
+
var STAGE_PERMISSIONS = {
|
|
7393
|
+
"explore": {
|
|
7394
|
+
canRead: true,
|
|
7395
|
+
canWrite: false,
|
|
7396
|
+
canRunShell: false,
|
|
7397
|
+
allowedAgents: ["architect"]
|
|
7398
|
+
},
|
|
7399
|
+
"new": {
|
|
7400
|
+
canRead: true,
|
|
7401
|
+
canWrite: true,
|
|
7402
|
+
canRunShell: false,
|
|
7403
|
+
allowedAgents: ["frontend-dev", "architect"]
|
|
7404
|
+
},
|
|
7405
|
+
"continue": {
|
|
7406
|
+
canRead: true,
|
|
7407
|
+
canWrite: true,
|
|
7408
|
+
canRunShell: true,
|
|
7409
|
+
allowedAgents: ["frontend-dev", "tester"]
|
|
7410
|
+
},
|
|
7411
|
+
"propose": {
|
|
7412
|
+
canRead: true,
|
|
7413
|
+
canWrite: true,
|
|
7414
|
+
canRunShell: true,
|
|
7415
|
+
allowedAgents: ["frontend-dev"]
|
|
7416
|
+
},
|
|
7417
|
+
"apply": {
|
|
7418
|
+
canRead: true,
|
|
7419
|
+
canWrite: true,
|
|
7420
|
+
canRunShell: true,
|
|
7421
|
+
allowedAgents: ["code-reviewer"]
|
|
7422
|
+
},
|
|
7423
|
+
"archive": {
|
|
7424
|
+
canRead: true,
|
|
7425
|
+
canWrite: false,
|
|
7426
|
+
canRunShell: false,
|
|
7427
|
+
allowedAgents: []
|
|
7428
|
+
}
|
|
7429
|
+
};
|
|
7345
7430
|
var CommandExecutor = class {
|
|
7346
7431
|
async execute(parseResult, ctx) {
|
|
7347
7432
|
if (!parseResult.success || !parseResult.command) {
|
|
7348
7433
|
return { output: chalk9.red(`\u9519\u8BEF: ${parseResult.error}`) };
|
|
7349
7434
|
}
|
|
7350
7435
|
const { command } = parseResult;
|
|
7436
|
+
const workflowCheck = this.checkWorkflowPermission(command, ctx);
|
|
7437
|
+
if (!workflowCheck.allowed) {
|
|
7438
|
+
return { output: workflowCheck.message };
|
|
7439
|
+
}
|
|
7351
7440
|
switch (command.type) {
|
|
7352
7441
|
case "slash" /* SLASH */:
|
|
7353
7442
|
return this.executeSlashCommand(command, ctx);
|
|
@@ -7365,13 +7454,75 @@ var CommandExecutor = class {
|
|
|
7365
7454
|
return { output: chalk9.red("\u672A\u77E5\u7684\u547D\u4EE4\u7C7B\u578B") };
|
|
7366
7455
|
}
|
|
7367
7456
|
}
|
|
7457
|
+
/**
|
|
7458
|
+
* 检查工作流权限
|
|
7459
|
+
*/
|
|
7460
|
+
checkWorkflowPermission(command, ctx) {
|
|
7461
|
+
const workflowEngine = ctx.workflowEngine;
|
|
7462
|
+
const workflowState = workflowEngine?.getState();
|
|
7463
|
+
if (!workflowState) {
|
|
7464
|
+
if (command.type === "slash" /* SLASH */) {
|
|
7465
|
+
const cmd = command.command?.toLowerCase();
|
|
7466
|
+
if (!ALLOWED_COMMANDS_WITHOUT_WORKFLOW.includes(cmd)) {
|
|
7467
|
+
return {
|
|
7468
|
+
allowed: false,
|
|
7469
|
+
message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
7470
|
+
};
|
|
7471
|
+
}
|
|
7472
|
+
}
|
|
7473
|
+
if (command.type === "natural" /* NATURAL */) {
|
|
7474
|
+
return {
|
|
7475
|
+
allowed: false,
|
|
7476
|
+
message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
7477
|
+
};
|
|
7478
|
+
}
|
|
7479
|
+
if (command.type === "dollar" /* DOLLAR */) {
|
|
7480
|
+
return {
|
|
7481
|
+
allowed: false,
|
|
7482
|
+
message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u8C03\u7528 Agent") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
7483
|
+
};
|
|
7484
|
+
}
|
|
7485
|
+
if (command.type === "shell" /* SHELL */) {
|
|
7486
|
+
return {
|
|
7487
|
+
allowed: false,
|
|
7488
|
+
message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u6267\u884C Shell \u547D\u4EE4") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
|
|
7489
|
+
};
|
|
7490
|
+
}
|
|
7491
|
+
return { allowed: true };
|
|
7492
|
+
}
|
|
7493
|
+
const currentStep = workflowState.currentStep;
|
|
7494
|
+
const permissions = STAGE_PERMISSIONS[currentStep];
|
|
7495
|
+
if (command.type === "at" /* AT */ && !permissions.canRead) {
|
|
7496
|
+
return {
|
|
7497
|
+
allowed: false,
|
|
7498
|
+
message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8BFB\u53D6\u6587\u4EF6`)
|
|
7499
|
+
};
|
|
7500
|
+
}
|
|
7501
|
+
if (command.type === "dollar" /* DOLLAR */) {
|
|
7502
|
+
const agentId = command.agent?.toLowerCase().replace("$", "");
|
|
7503
|
+
if (!permissions.allowedAgents.includes(agentId)) {
|
|
7504
|
+
return {
|
|
7505
|
+
allowed: false,
|
|
7506
|
+
message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8C03\u7528 $${agentId} Agent`) + chalk9.gray(`
|
|
7507
|
+
\u5F53\u524D\u9636\u6BB5\u5141\u8BB8\u7684 Agent: ${permissions.allowedAgents.map((a) => `$${a}`).join(", ") || "\u65E0"}`)
|
|
7508
|
+
};
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
7511
|
+
if (command.type === "shell" /* SHELL */ && !permissions.canRunShell) {
|
|
7512
|
+
return {
|
|
7513
|
+
allowed: false,
|
|
7514
|
+
message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u6267\u884C Shell \u547D\u4EE4`)
|
|
7515
|
+
};
|
|
7516
|
+
}
|
|
7517
|
+
return { allowed: true };
|
|
7518
|
+
}
|
|
7368
7519
|
async executeSlashCommand(command, ctx) {
|
|
7369
7520
|
const result = await runSlashCommand(
|
|
7370
7521
|
command.command,
|
|
7371
7522
|
command.args || [],
|
|
7372
7523
|
ctx
|
|
7373
7524
|
);
|
|
7374
|
-
return { output: result.output };
|
|
7525
|
+
return { output: result.output, exit: result.exit };
|
|
7375
7526
|
}
|
|
7376
7527
|
async executeFileReference(command, ctx) {
|
|
7377
7528
|
const result = await handleFileReference(command.path, ctx);
|