sdd-flow-kit 1.3.14 → 1.3.15
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/cli.js +81 -10
- package/dist/core/versionIntent.js +65 -0
- package/dist/steps/invokeFlow.js +5 -19
- package/dist/steps/runGuard.js +44 -0
- package/dist/steps/setupProject.js +28 -0
- package/package.json +1 -1
- package/src/templates/artifacts/06-agent-skill.template.md +3 -3
- package/src/templates/rules/sdd-version-trigger.mdc.template +56 -0
- package/src/templates/skills/version-trigger.SKILL.md.template +56 -0
package/dist/cli.js
CHANGED
|
@@ -22,8 +22,10 @@ const runPrdDiff_1 = require("./steps/runPrdDiff");
|
|
|
22
22
|
const runPrdRemediate_1 = require("./steps/runPrdRemediate");
|
|
23
23
|
const runChain_1 = require("./steps/runChain");
|
|
24
24
|
const runSessionMode_1 = require("./steps/runSessionMode");
|
|
25
|
+
const runGuard_1 = require("./steps/runGuard");
|
|
25
26
|
const bootstrap_1 = require("./core/bootstrap");
|
|
26
27
|
const projectRoots_1 = require("./core/projectRoots");
|
|
28
|
+
const versionIntent_1 = require("./core/versionIntent");
|
|
27
29
|
const ALLOWED_AGENTS = ["cursor", "claude-code", "codex", "openclaw", "custom"];
|
|
28
30
|
function getArgValue(flag) {
|
|
29
31
|
const idx = process_1.default.argv.indexOf(flag);
|
|
@@ -34,6 +36,42 @@ function getArgValue(flag) {
|
|
|
34
36
|
return null;
|
|
35
37
|
return v;
|
|
36
38
|
}
|
|
39
|
+
function getFreeTextArgs(startIndex) {
|
|
40
|
+
const flagsWithValue = new Set([
|
|
41
|
+
"--agent",
|
|
42
|
+
"--project",
|
|
43
|
+
"--product",
|
|
44
|
+
"--version",
|
|
45
|
+
"--project-root",
|
|
46
|
+
"--projectRoot",
|
|
47
|
+
"--run-id",
|
|
48
|
+
"--runId",
|
|
49
|
+
"--change",
|
|
50
|
+
"--branch",
|
|
51
|
+
"--from",
|
|
52
|
+
"--to",
|
|
53
|
+
"--expect",
|
|
54
|
+
"--execution-mode",
|
|
55
|
+
"--executionMode",
|
|
56
|
+
"--text",
|
|
57
|
+
]);
|
|
58
|
+
const parts = [];
|
|
59
|
+
const tokens = process_1.default.argv.slice(startIndex);
|
|
60
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
61
|
+
const token = tokens[i];
|
|
62
|
+
if (token === "-y" || token === "--dry-run" || token === "--plan-json" || token === "--strict-commands") {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (flagsWithValue.has(token)) {
|
|
66
|
+
i += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (token.startsWith("--"))
|
|
70
|
+
continue;
|
|
71
|
+
parts.push(token);
|
|
72
|
+
}
|
|
73
|
+
return parts.join(" ").trim();
|
|
74
|
+
}
|
|
37
75
|
function printHelp() {
|
|
38
76
|
// eslint-disable-next-line no-console
|
|
39
77
|
console.log([
|
|
@@ -51,7 +89,8 @@ function printHelp() {
|
|
|
51
89
|
"3) 生成骨架并进入可执行模式(推荐):",
|
|
52
90
|
" npx sdd-flow-kit run --product ADI --version 2.3.2 --agent claude-code",
|
|
53
91
|
"",
|
|
54
|
-
"4)
|
|
92
|
+
"4) 一句话触发(版本开发强制入口):",
|
|
93
|
+
" npx sdd-flow-kit guard \"开发 ADI_V2.3.4版本\" -y --agent cursor",
|
|
55
94
|
" npx sdd-flow-kit invoke \"开发 XXX 1.2.3 需求\"",
|
|
56
95
|
"",
|
|
57
96
|
"5) 环境健检:",
|
|
@@ -111,7 +150,7 @@ function printHelp() {
|
|
|
111
150
|
].join("\n"));
|
|
112
151
|
}
|
|
113
152
|
async function main() {
|
|
114
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
153
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
115
154
|
const cmd = process_1.default.argv[2];
|
|
116
155
|
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
117
156
|
printHelp();
|
|
@@ -144,6 +183,7 @@ async function main() {
|
|
|
144
183
|
cmd !== "install" &&
|
|
145
184
|
cmd !== "doctor" &&
|
|
146
185
|
cmd !== "ensure-opsx" &&
|
|
186
|
+
cmd !== "guard" &&
|
|
147
187
|
cmd !== "invoke" &&
|
|
148
188
|
cmd !== "gate" &&
|
|
149
189
|
cmd !== "phase" &&
|
|
@@ -169,7 +209,11 @@ async function main() {
|
|
|
169
209
|
const dryRun = process_1.default.argv.includes("--dry-run");
|
|
170
210
|
const planJson = process_1.default.argv.includes("--plan-json");
|
|
171
211
|
const agentValue = (_g = getArgValue("--agent")) !== null && _g !== void 0 ? _g : "claude-code";
|
|
172
|
-
const
|
|
212
|
+
const rawGuardText = cmd === "guard"
|
|
213
|
+
? ((_h = getArgValue("--text")) !== null && _h !== void 0 ? _h : getFreeTextArgs(3)).trim()
|
|
214
|
+
: "";
|
|
215
|
+
const guardIntent = rawGuardText ? (0, versionIntent_1.parseVersionIntent)(rawGuardText) : null;
|
|
216
|
+
const projectKind = ((_k = (_j = getArgValue("--project")) !== null && _j !== void 0 ? _j : guardIntent === null || guardIntent === void 0 ? void 0 : guardIntent.product) !== null && _k !== void 0 ? _k : "OMS");
|
|
173
217
|
if (!ALLOWED_AGENTS.includes(agentValue)) {
|
|
174
218
|
// eslint-disable-next-line no-console
|
|
175
219
|
console.error(`不支持的 --agent: ${agentValue}`);
|
|
@@ -189,6 +233,7 @@ async function main() {
|
|
|
189
233
|
const bootstrapCommands = new Set([
|
|
190
234
|
"doctor",
|
|
191
235
|
"ensure-opsx",
|
|
236
|
+
"guard",
|
|
192
237
|
"run",
|
|
193
238
|
"invoke",
|
|
194
239
|
"install",
|
|
@@ -211,6 +256,36 @@ async function main() {
|
|
|
211
256
|
projectKind: projectKind,
|
|
212
257
|
});
|
|
213
258
|
}
|
|
259
|
+
if (cmd === "guard") {
|
|
260
|
+
const text = rawGuardText;
|
|
261
|
+
if (!text) {
|
|
262
|
+
// eslint-disable-next-line no-console
|
|
263
|
+
console.error("guard 需要自然语言文本,例如:npx sdd-flow-kit guard \"开发 ADI_V2.3.4版本\" -y --agent cursor");
|
|
264
|
+
process_1.default.exitCode = 1;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const result = await (0, runGuard_1.runGuard)({
|
|
268
|
+
text,
|
|
269
|
+
projectRoot,
|
|
270
|
+
branch,
|
|
271
|
+
yes,
|
|
272
|
+
dryRun,
|
|
273
|
+
agent,
|
|
274
|
+
});
|
|
275
|
+
// eslint-disable-next-line no-console
|
|
276
|
+
console.log(result.ok ? `✅ ${result.detail}` : `ℹ️ ${result.detail}`);
|
|
277
|
+
if (result.ok && result.nextPath) {
|
|
278
|
+
// eslint-disable-next-line no-console
|
|
279
|
+
console.log(`下一步:读取 ${result.nextPath} 与同目录 .session-state.json`);
|
|
280
|
+
}
|
|
281
|
+
if (planJson) {
|
|
282
|
+
// eslint-disable-next-line no-console
|
|
283
|
+
console.log(JSON.stringify({ command: "guard", projectRoot, dryRun, result }, null, 2));
|
|
284
|
+
}
|
|
285
|
+
if (!result.ok)
|
|
286
|
+
process_1.default.exitCode = 2;
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
214
289
|
if (cmd === "gate") {
|
|
215
290
|
const expect = getArgValue("--expect");
|
|
216
291
|
if (!expect || !GATE_EXPECTS.includes(expect)) {
|
|
@@ -376,7 +451,7 @@ async function main() {
|
|
|
376
451
|
process_1.default.exitCode = 1;
|
|
377
452
|
return;
|
|
378
453
|
}
|
|
379
|
-
const from = ((
|
|
454
|
+
const from = ((_l = getArgValue("--from")) !== null && _l !== void 0 ? _l : "docs-done");
|
|
380
455
|
if (!CHAIN_FROM.includes(from)) {
|
|
381
456
|
// eslint-disable-next-line no-console
|
|
382
457
|
console.error(`chain 需要 --from ${CHAIN_FROM.join("|")}`);
|
|
@@ -405,7 +480,7 @@ async function main() {
|
|
|
405
480
|
process_1.default.exitCode = 1;
|
|
406
481
|
return;
|
|
407
482
|
}
|
|
408
|
-
const modeArg = (
|
|
483
|
+
const modeArg = (_m = getArgValue("--execution-mode")) !== null && _m !== void 0 ? _m : getArgValue("--executionMode");
|
|
409
484
|
const textArg = getArgValue("--text");
|
|
410
485
|
const strictCommands = process_1.default.argv.includes("--strict-commands");
|
|
411
486
|
const result = await (0, runSessionMode_1.runSessionMode)({
|
|
@@ -474,11 +549,7 @@ async function main() {
|
|
|
474
549
|
}
|
|
475
550
|
if (!product || !version) {
|
|
476
551
|
if (cmd === "invoke") {
|
|
477
|
-
const raw =
|
|
478
|
-
.slice(3)
|
|
479
|
-
.filter((token) => !token.startsWith("--") && token !== "-y")
|
|
480
|
-
.join(" ")
|
|
481
|
-
.trim();
|
|
552
|
+
const raw = getFreeTextArgs(3);
|
|
482
553
|
const fromFlag = getArgValue("--text");
|
|
483
554
|
const text = (fromFlag !== null && fromFlag !== void 0 ? fromFlag : raw).trim();
|
|
484
555
|
const parsed = (0, invokeFlow_1.parseInvokeText)(text);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVersionIntent = parseVersionIntent;
|
|
4
|
+
exports.normalizeProductName = normalizeProductName;
|
|
5
|
+
exports.isVersionDevelopmentIntent = isVersionDevelopmentIntent;
|
|
6
|
+
exports.getVersionIntentInvokeCommand = getVersionIntentInvokeCommand;
|
|
7
|
+
/**
|
|
8
|
+
* 解析“开发某产品某版本”的自然语言意图。
|
|
9
|
+
* 该解析器只负责提取产品与版本,不承担后续流程执行。
|
|
10
|
+
*/
|
|
11
|
+
function parseVersionIntent(text) {
|
|
12
|
+
const normalized = text.trim();
|
|
13
|
+
if (!normalized)
|
|
14
|
+
return null;
|
|
15
|
+
const normalizedText = normalized
|
|
16
|
+
.replace(/[::,,。;;!!??]/g, " ")
|
|
17
|
+
.replace(/[_-]/g, " ")
|
|
18
|
+
.replace(/\s+/g, " ")
|
|
19
|
+
.trim();
|
|
20
|
+
const patterns = [
|
|
21
|
+
/(?:开发|进行|实现|处理|做)\s*([\u4e00-\u9fa5A-Za-z][\u4e00-\u9fa5A-Za-z\s]*?)\s*[Vv]?\s*([0-9]+(?:\.[0-9]+){1,3})\s*(?:版本|需求|PRD)?/i,
|
|
22
|
+
/([\u4e00-\u9fa5A-Za-z][\u4e00-\u9fa5A-Za-z\s]*?)\s*[Vv]?\s*([0-9]+(?:\.[0-9]+){1,3})\s*(?:版本|需求)?\s*(?:开发|进行|实现|处理|做)?/i,
|
|
23
|
+
];
|
|
24
|
+
for (const re of patterns) {
|
|
25
|
+
const match = normalizedText.match(re);
|
|
26
|
+
if (!match)
|
|
27
|
+
continue;
|
|
28
|
+
const product = normalizeProductName(match[1]);
|
|
29
|
+
const version = match[2];
|
|
30
|
+
if (!product || !version)
|
|
31
|
+
continue;
|
|
32
|
+
return { product, version };
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function normalizeProductName(raw) {
|
|
37
|
+
const value = raw
|
|
38
|
+
.replace(/\b(PRD|需求|版本|开发|进行|实现|处理|做)\b/gi, " ")
|
|
39
|
+
.replace(/需求|版本|开发|进行|实现|处理|做/g, " ")
|
|
40
|
+
.replace(/\s+/g, " ")
|
|
41
|
+
.trim();
|
|
42
|
+
if (!value)
|
|
43
|
+
return "";
|
|
44
|
+
const upper = value.toUpperCase();
|
|
45
|
+
if (upper === "ADI" || /ADINSIGHT/i.test(value))
|
|
46
|
+
return "ADI";
|
|
47
|
+
if (upper === "OMS" || /OPERATION/i.test(value))
|
|
48
|
+
return "OMS";
|
|
49
|
+
if (/BREAK\s*X/i.test(value) || /BREAKX/i.test(value))
|
|
50
|
+
return "BreakX";
|
|
51
|
+
if (/欢盟|HUANMENG|HM/i.test(value))
|
|
52
|
+
return "欢盟";
|
|
53
|
+
if (/AD\s*TOOLS/i.test(value) || /ADTOOLS/i.test(value))
|
|
54
|
+
return "AD Tools";
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function isVersionDevelopmentIntent(text) {
|
|
58
|
+
return parseVersionIntent(text) !== null;
|
|
59
|
+
}
|
|
60
|
+
function getVersionIntentInvokeCommand(options) {
|
|
61
|
+
const parsed = parseVersionIntent(options.rawText);
|
|
62
|
+
if (!parsed)
|
|
63
|
+
return null;
|
|
64
|
+
return `npx sdd-flow-kit invoke "开发 ${parsed.product} ${parsed.version} 需求" -y --agent ${options.agent}`;
|
|
65
|
+
}
|
package/dist/steps/invokeFlow.js
CHANGED
|
@@ -2,26 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseInvokeText = parseInvokeText;
|
|
4
4
|
exports.toRunOptions = toRunOptions;
|
|
5
|
+
const versionIntent_1 = require("../core/versionIntent");
|
|
5
6
|
function parseInvokeText(text) {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/([A-Za-z]+)[_\s-]([0-9]+(?:\.[0-9]+){2,3})(?:\s|$)/i,
|
|
11
|
-
];
|
|
12
|
-
for (const re of patterns) {
|
|
13
|
-
const match = normalized.match(re);
|
|
14
|
-
if (!match)
|
|
15
|
-
continue;
|
|
16
|
-
let product = match[1].replace(/[-_\s]+$/g, "").trim();
|
|
17
|
-
product = product.replace(/^进行/, "").trim();
|
|
18
|
-
if (/^adi$/i.test(product) || product.toUpperCase() === "ADI")
|
|
19
|
-
product = "ADI";
|
|
20
|
-
if (/^oms$/i.test(product))
|
|
21
|
-
product = "OMS";
|
|
22
|
-
return { product: product.toUpperCase(), version: match[2] };
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
7
|
+
const parsed = (0, versionIntent_1.parseVersionIntent)(text);
|
|
8
|
+
if (!parsed)
|
|
9
|
+
return null;
|
|
10
|
+
return { product: parsed.product, version: parsed.version };
|
|
25
11
|
}
|
|
26
12
|
function toRunOptions(args) {
|
|
27
13
|
var _a, _b;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runGuard = runGuard;
|
|
4
|
+
const runFlow_1 = require("./runFlow");
|
|
5
|
+
const invokeFlow_1 = require("./invokeFlow");
|
|
6
|
+
const runSessionMode_1 = require("./runSessionMode");
|
|
7
|
+
/**
|
|
8
|
+
* 识别“开发产品版本”的自然语言入口,并在命中时直接启动 SDD 流程。
|
|
9
|
+
* 该守卫用于压过普通 OpenSpec/OPSX 入口,避免版本需求误走自由提案流程。
|
|
10
|
+
*/
|
|
11
|
+
async function runGuard(options) {
|
|
12
|
+
const text = options.text.trim();
|
|
13
|
+
const parsed = (0, invokeFlow_1.parseInvokeText)(text);
|
|
14
|
+
if (!parsed) {
|
|
15
|
+
return {
|
|
16
|
+
ok: false,
|
|
17
|
+
action: "noop",
|
|
18
|
+
input: text,
|
|
19
|
+
detail: "未识别到版本开发意图,无需启动 sdd-flow-kit invoke。",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const runOptions = (0, invokeFlow_1.toRunOptions)({
|
|
23
|
+
parsed,
|
|
24
|
+
projectRoot: options.projectRoot,
|
|
25
|
+
branch: options.branch,
|
|
26
|
+
yes: options.yes,
|
|
27
|
+
dryRun: options.dryRun,
|
|
28
|
+
agent: options.agent,
|
|
29
|
+
});
|
|
30
|
+
const result = await (0, runFlow_1.runFlow)(runOptions);
|
|
31
|
+
if (!options.dryRun) {
|
|
32
|
+
await (0, runSessionMode_1.applyInvokeTextToSession)(options.projectRoot, result.runId, text);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
ok: true,
|
|
36
|
+
action: "invoke",
|
|
37
|
+
input: text,
|
|
38
|
+
product: parsed.product,
|
|
39
|
+
version: parsed.version,
|
|
40
|
+
runId: result.runId,
|
|
41
|
+
nextPath: `openspec/PRD/${result.runId}/NEXT.md`,
|
|
42
|
+
detail: `已识别版本开发意图并启动 SDD 流程:${parsed.product} ${parsed.version} -> runId=${result.runId}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -152,6 +152,28 @@ async function installAgentSkill(projectRoot, projectKind) {
|
|
|
152
152
|
await (0, fs_1.writeTextFileEnsuredDir)(layeredPath, layered);
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
async function installSddVersionTriggerRule(projectRoot, agent) {
|
|
156
|
+
const template = await (0, templates_1.loadTemplateText)("rules/sdd-version-trigger.mdc.template");
|
|
157
|
+
const content = renderVars(template, {
|
|
158
|
+
AGENT_NAME: agent,
|
|
159
|
+
});
|
|
160
|
+
if (agent === "cursor" || agent === "custom") {
|
|
161
|
+
const rulePath = path_1.default.join(projectRoot, ".cursor", "rules", "00-sdd-flow-kit-version-trigger.mdc");
|
|
162
|
+
await (0, fs_1.writeTextFileEnsuredDir)(rulePath, content);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function installSddVersionTriggerSkills(projectRoot) {
|
|
166
|
+
const template = await (0, templates_1.loadTemplateText)("skills/version-trigger.SKILL.md.template");
|
|
167
|
+
const targets = [
|
|
168
|
+
{ agent: "cursor", relPath: ".cursor/skills/00-sdd-flow-kit-version-trigger/SKILL.md" },
|
|
169
|
+
{ agent: "claude-code", relPath: ".claude/skills/00-sdd-flow-kit-version-trigger/SKILL.md" },
|
|
170
|
+
{ agent: "codex", relPath: ".codex/skills/00-sdd-flow-kit-version-trigger/SKILL.md" },
|
|
171
|
+
{ agent: "openclaw", relPath: ".openclaw/skills/00-sdd-flow-kit-version-trigger/SKILL.md" },
|
|
172
|
+
];
|
|
173
|
+
for (const target of targets) {
|
|
174
|
+
await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(projectRoot, target.relPath), renderVars(template, { AGENT_NAME: target.agent }));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
155
177
|
async function installSddCursorRule(projectRoot) {
|
|
156
178
|
const rulePath = path_1.default.join(projectRoot, ".cursor", "rules", "sdd-flow-kit-gates.mdc");
|
|
157
179
|
const template = await (0, templates_1.loadTemplateText)("rules/sdd-no-implement-until-apply.mdc.template");
|
|
@@ -343,6 +365,8 @@ async function setupProject(options) {
|
|
|
343
365
|
const { dir } = docSkillDirName(selectedKind);
|
|
344
366
|
plannedActions.push(`would install docs skill: ${path_1.default.join(installRoot, "docs", dir)}`);
|
|
345
367
|
plannedActions.push(`would install opsx config: ${path_1.default.join(installRoot, ".opsx", "config.json")}`);
|
|
368
|
+
plannedActions.push(`would install highest-priority version trigger rule: ${path_1.default.join(installRoot, ".cursor", "rules", "00-sdd-flow-kit-version-trigger.mdc")}`);
|
|
369
|
+
plannedActions.push("would install cross-agent version trigger skills: cursor/claude-code/codex/openclaw");
|
|
346
370
|
plannedActions.push(`would install cursor rule: ${path_1.default.join(installRoot, ".cursor", "rules", "sdd-flow-kit-gates.mdc")}`);
|
|
347
371
|
}
|
|
348
372
|
else {
|
|
@@ -352,6 +376,10 @@ async function setupProject(options) {
|
|
|
352
376
|
plannedActions.push("added pnpm.onlyBuiltDependencies: sdd-flow-kit");
|
|
353
377
|
}
|
|
354
378
|
await installAgentSkill(installRoot, selectedKind);
|
|
379
|
+
await installSddVersionTriggerRule(installRoot, selectedAgent);
|
|
380
|
+
await installSddVersionTriggerSkills(installRoot);
|
|
381
|
+
plannedActions.push("installed highest-priority version trigger rule (.cursor/rules/00-sdd-flow-kit-version-trigger.mdc)");
|
|
382
|
+
plannedActions.push("installed cross-agent version trigger skills (cursor/claude-code/codex/openclaw)");
|
|
355
383
|
await installSddCursorRule(installRoot);
|
|
356
384
|
skillInstalled = true;
|
|
357
385
|
await installDocsSkill(installRoot, selectedKind);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sdd-flow-kit
|
|
3
|
-
description:
|
|
3
|
+
description: 最高优先级触发。凡用户表达“开发/进行/实现 <产品> <版本> 需求/版本”,例如 ADI_V2.3.4、OMS V1.24.5、BreakX 1.0.2、欢盟 V2.1.0,必须第一步执行 `npx sdd-flow-kit guard "<用户原话>" -y --agent {{AGENT_NAME}}` 或 invoke/run。禁止先执行 openspec new change、OPSX Propose 或修改 src/e2e;成功后必须读取 NEXT.md 与 .session-state.json。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDD Flow Kit({{PROJECT_KIND}} — 脚本门禁)
|
|
@@ -10,10 +10,10 @@ description: 用户说「开发/进行 {{DEFAULT_PRODUCT}} x.x.x 版本/需求
|
|
|
10
10
|
用户一旦表达版本开发意图,**在本回合终端执行**(项目根 = 安装 sdd-flow-kit 的目录,如 `frontend/`):
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npx sdd-flow-kit
|
|
13
|
+
npx sdd-flow-kit guard "<用户原话>" -y --agent {{AGENT_NAME}}
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
若 `guard` 不可用,再退化为:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
npx sdd-flow-kit run --product {{DEFAULT_PRODUCT}} --version <版本号> -y --agent {{AGENT_NAME}}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 最高优先级:识别“开发/进行/实现 产品 版本”时必须先执行 sdd-flow-kit guard/invoke,禁止先走 OpenSpec/OPSX 或修改业务代码
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDD Flow Kit 版本开发强制入口(最高优先级)
|
|
7
|
+
|
|
8
|
+
当用户输入匹配以下任一意图时:
|
|
9
|
+
|
|
10
|
+
- `开发 <产品> <版本>`
|
|
11
|
+
- `进行 <产品> <版本> 需求`
|
|
12
|
+
- `实现 <产品> <版本> 版本`
|
|
13
|
+
- `<产品>_V<版本>` / `<产品>-V<版本>`
|
|
14
|
+
- 示例:`开发 ADI_V2.3.4版本`、`开发 OMS V1.24.5`、`进行 BreakX 1.0.2 需求`、`欢盟 V2.1.0 版本开发`
|
|
15
|
+
|
|
16
|
+
## 第一动作(必须)
|
|
17
|
+
|
|
18
|
+
必须先执行:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx sdd-flow-kit guard "<用户原话>" -y --agent {{AGENT_NAME}}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
若无法使用 `guard`,退化为:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx sdd-flow-kit invoke "开发 <产品> <版本> 需求" -y --agent {{AGENT_NAME}}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 严格禁止
|
|
31
|
+
|
|
32
|
+
在 `guard/invoke` 成功前,禁止:
|
|
33
|
+
|
|
34
|
+
- 创建 `openspec/changes/**`
|
|
35
|
+
- 执行 `openspec new change`
|
|
36
|
+
- 执行 OPSX / OpenSpec Propose
|
|
37
|
+
- 修改 `src/**`、`frontend/src/**`、`e2e/**`
|
|
38
|
+
- 用自然语言计划替代脚本入口
|
|
39
|
+
|
|
40
|
+
## 成功后继续
|
|
41
|
+
|
|
42
|
+
`guard/invoke` 成功后,必须读取并遵循:
|
|
43
|
+
|
|
44
|
+
- `openspec/PRD/<runId>/NEXT.md`
|
|
45
|
+
- `openspec/PRD/<runId>/.session-state.json`
|
|
46
|
+
|
|
47
|
+
若 `.session-state.json` 中 `docModeOnly=true`,仍然禁止修改业务代码,直到 `gate docs-closed`、`gate ac-ready`、`phase impl` 与 `gate impl-allowed` 全部通过。
|
|
48
|
+
|
|
49
|
+
## 优先级
|
|
50
|
+
|
|
51
|
+
本规则优先于普通 OpenSpec/OPSX 自然语言需求入口:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
版本开发意图 → sdd-flow-kit guard/invoke → NEXT.md
|
|
55
|
+
普通代码需求 → OPSX/OpenSpec
|
|
56
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 00-sdd-flow-kit-version-trigger
|
|
3
|
+
description: 最高优先级触发。凡用户表达“开发/进行/实现 <产品> <版本> 需求/版本”,例如 ADI_V2.3.4、OMS V1.24.5、BreakX 1.0.2、欢盟 V2.1.0,必须第一步执行 `npx sdd-flow-kit guard "<用户原话>" -y --agent {{AGENT_NAME}}`。禁止先执行 openspec new change、OPSX Propose 或修改 src/e2e。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDD Flow Kit 版本开发强制入口
|
|
7
|
+
|
|
8
|
+
## 适用范围
|
|
9
|
+
|
|
10
|
+
当用户输入匹配以下任一意图时,本 skill 优先于普通 OpenSpec / OPSX 流程:
|
|
11
|
+
|
|
12
|
+
- `开发 <产品> <版本>`
|
|
13
|
+
- `进行 <产品> <版本> 需求`
|
|
14
|
+
- `实现 <产品> <版本> 版本`
|
|
15
|
+
- `<产品>_V<版本>` / `<产品>-V<版本>`
|
|
16
|
+
- 示例:`开发 ADI_V2.3.4版本`、`开发 OMS V1.24.5`、`进行 BreakX 1.0.2 需求`、`欢盟 V2.1.0 版本开发`
|
|
17
|
+
|
|
18
|
+
## 第一动作(必须)
|
|
19
|
+
|
|
20
|
+
在项目根目录立即执行:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx sdd-flow-kit guard "<用户原话>" -y --agent {{AGENT_NAME}}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
若 `guard` 不可用,退化为:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx sdd-flow-kit invoke "开发 <产品> <版本> 需求" -y --agent {{AGENT_NAME}}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 严格禁止
|
|
33
|
+
|
|
34
|
+
在 `guard/invoke` 成功前,禁止:
|
|
35
|
+
|
|
36
|
+
- 创建 `openspec/changes/**`
|
|
37
|
+
- 执行 `openspec new change`
|
|
38
|
+
- 执行 OPSX / OpenSpec Propose
|
|
39
|
+
- 修改 `src/**`、`frontend/src/**`、`e2e/**`
|
|
40
|
+
- 用自然语言计划替代脚本入口
|
|
41
|
+
|
|
42
|
+
## 成功后继续
|
|
43
|
+
|
|
44
|
+
`guard/invoke` 成功后,必须读取并遵循:
|
|
45
|
+
|
|
46
|
+
- `openspec/PRD/<runId>/NEXT.md`
|
|
47
|
+
- `openspec/PRD/<runId>/.session-state.json`
|
|
48
|
+
|
|
49
|
+
若 `.session-state.json` 中 `docModeOnly=true`,仍然禁止修改业务代码,直到 `gate docs-closed`、`gate ac-ready`、`phase impl` 与 `gate impl-allowed` 全部通过。
|
|
50
|
+
|
|
51
|
+
## 优先级
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
版本开发意图 → sdd-flow-kit guard/invoke → NEXT.md
|
|
55
|
+
普通代码需求 → OPSX/OpenSpec
|
|
56
|
+
```
|