sdd-flow-kit 1.2.1 → 1.2.3

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.
@@ -19,7 +19,7 @@ function createManualAdapter(name, displayName, bins) {
19
19
  async checkAvailable() {
20
20
  return bins.some((bin) => hasCommand(bin));
21
21
  },
22
- async runFlow() {
22
+ async runFlow(_args) {
23
23
  return false;
24
24
  },
25
25
  };
@@ -71,10 +71,88 @@ async function runClaudeFlow(args) {
71
71
  return false;
72
72
  return /SDD flow completed/i.test(commandResult.stdout || "");
73
73
  }
74
+ async function runCursorFlow(args) {
75
+ var _a;
76
+ /**
77
+ * Cursor Agent 自动执行开关:
78
+ * - 默认开启(符合“除澄清外全自动”的产品预期)
79
+ * - 如需关闭:SDD_FLOW_KIT_ENABLE_CURSOR_AUTORUN=0
80
+ */
81
+ if (process_1.default.env.SDD_FLOW_KIT_ENABLE_CURSOR_AUTORUN === "0") {
82
+ return false;
83
+ }
84
+ if (!hasCommand("cursor"))
85
+ return false;
86
+ const sddPrompt = await (0, fs_1.readFileIfExists)(path_1.default.join(args.outputRoot, "02-需求分析提示词.md"));
87
+ if (!sddPrompt)
88
+ return false;
89
+ const prompt = [
90
+ `你在项目目录内执行 SDD 流程(runId=${args.runId})。目标:除“需求澄清”外全自动推进。`,
91
+ "",
92
+ "强约束:",
93
+ "1) 在 docs 阶段(docModeOnly=true)只允许改 openspec/PRD/**,禁止改 src/。",
94
+ "2) 若矛盾点池未闭合:仅更新 03-待确认问题清单.md 并停止,等待用户确认点。",
95
+ "3) 若矛盾点池已闭合:同一回合生成 01/02/04,并自动衔接 openspec+superpowers(autoChainOpsx=true 时)。",
96
+ "",
97
+ "执行顺序:",
98
+ "A) 先按 01-获取需求文档指引.md 执行 confluence-doc.py,把 PRD 回填到 source/PRD.md。",
99
+ "B) 再执行 02-需求分析提示词.md(如下)生成/更新 03(必要时)或生成 01/02/04。",
100
+ "C) 若满足自动串联条件(autoChainOpsx!==false 且用户未说只提案):继续按 06-opsx-自动串联指引.md 走 propose→apply→delivery-pipeline。",
101
+ "",
102
+ "完成判定:",
103
+ "- 若停在澄清:输出一句 `SDD_STATUS=AWAIT_CONFIRMATION`。",
104
+ "- 若全链路完成:输出一句 `SDD_STATUS=COMPLETE`。",
105
+ "",
106
+ "以下是第 B 步提示词:",
107
+ sddPrompt,
108
+ ].join("\n");
109
+ const commandResult = (0, child_process_1.spawnSync)("cursor", [
110
+ "agent",
111
+ "--print",
112
+ "--trust",
113
+ "--workspace",
114
+ args.projectRoot,
115
+ prompt,
116
+ ], {
117
+ cwd: args.outputRoot,
118
+ encoding: "utf8",
119
+ env: process_1.default.env,
120
+ });
121
+ await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(args.outputRoot, "AUTO-RUN-LOG.md"), [
122
+ "# AUTO-RUN-LOG",
123
+ "",
124
+ "agent: cursor-agent",
125
+ `status: ${(_a = commandResult.status) !== null && _a !== void 0 ? _a : "unknown"}`,
126
+ "",
127
+ "## stdout",
128
+ commandResult.stdout || "",
129
+ "",
130
+ "## stderr",
131
+ commandResult.stderr || "",
132
+ ].join("\n"));
133
+ if (commandResult.status !== 0)
134
+ return false;
135
+ return /SDD_STATUS=COMPLETE/i.test(commandResult.stdout || "");
136
+ }
74
137
  function getAdapter(name) {
75
138
  switch (name) {
76
139
  case "cursor":
77
- return createManualAdapter("cursor", "Cursor", ["cursor"]);
140
+ return {
141
+ name: "cursor",
142
+ displayName: "Cursor",
143
+ async checkAvailable() {
144
+ return hasCommand("cursor");
145
+ },
146
+ async runFlow(args) {
147
+ return runCursorFlow({
148
+ projectRoot: args.projectRoot,
149
+ outputRoot: args.outputRoot,
150
+ runId: args.runId,
151
+ product: args.product,
152
+ version: args.version,
153
+ });
154
+ },
155
+ };
78
156
  case "claude-code":
79
157
  return {
80
158
  name: "claude-code",
package/dist/cli.js CHANGED
@@ -62,8 +62,10 @@ function printHelp() {
62
62
  "8) 阶段推进(更新 session + NEXT.md):",
63
63
  " npx sdd-flow-kit phase advance --project-root . --run-id <runId> --to after-prd|docs-done|propose-done|impl|shipped",
64
64
  "",
65
- "9) 提案 / 交付:",
65
+ "9) 提案 / 实现 / 交付:",
66
66
  " npx sdd-flow-kit propose --project-root . --run-id <runId> --change <name>",
67
+ " npx sdd-flow-kit phase advance --project-root . --run-id <runId> --to impl --change <name>",
68
+ " # 在 AI 工具执行 /opsx-apply,按 tasks.md 逐条实现并勾选 [x]",
67
69
  " npx sdd-flow-kit deliver --project-root . --run-id <runId> --change <name>",
68
70
  "",
69
71
  "可选参数:",
@@ -363,7 +365,7 @@ async function main() {
363
365
  // eslint-disable-next-line no-console
364
366
  console.log(`流程已初始化:openspec/PRD/${result.runId}/`);
365
367
  // eslint-disable-next-line no-console
366
- console.log(`请打开 openspec/PRD/${result.runId}/NEXT.md,严格按 gate→phase→propose→deliver 执行;确认点前禁止改 src/。`);
368
+ console.log(`请打开 openspec/PRD/${result.runId}/NEXT.md,严格按 gate→phase→propose→impl(/opsx-apply)→deliver 执行;确认点前禁止改 src/。`);
367
369
  // eslint-disable-next-line no-console
368
370
  console.log(`agent=${result.adapterName}, cli=${result.adapterAvailable ? "detected" : "missing"}, autoExecute=${result.executed ? "yes" : "manual"}`);
369
371
  // eslint-disable-next-line no-console
@@ -40,9 +40,7 @@ function gitDiffNameOnly(projectRoot) {
40
40
  /** 业务实现路径:命中则视为「实现层改动」 */
41
41
  const IMPL_PATH_PATTERNS = [
42
42
  /^src\//,
43
- /^e2e\//,
44
43
  /^frontend\/src\//,
45
- /^frontend\/e2e\//,
46
44
  /^app\//,
47
45
  /^pages\//,
48
46
  /^components\//,
@@ -42,9 +42,14 @@ async function writeInitialNext(outputRoot, projectRoot, runId) {
42
42
  `npx sdd-flow-kit phase advance --project-root "${pr}" --run-id ${runId} --to propose-done --change <kebab-name>`,
43
43
  "```",
44
44
  "",
45
- "## 5. 阶段 D — 实现 + 交付",
45
+ "## 5. 阶段 D — /opsx-apply 实现 tasks(必做)",
46
46
  "```bash",
47
47
  `npx sdd-flow-kit phase advance --project-root "${pr}" --run-id ${runId} --to impl --change <kebab-name>`,
48
+ "# 然后在 AI 工具中执行 /opsx-apply,按 tasks.md 逐条实现并勾选为 [x]",
49
+ "```",
50
+ "",
51
+ "## 6. 阶段 E — 交付与收尾",
52
+ "```bash",
48
53
  `npx sdd-flow-kit deliver --project-root "${pr}" --run-id ${runId} --change <kebab-name>`,
49
54
  `npx sdd-flow-kit phase advance --project-root "${pr}" --run-id ${runId} --to shipped --change <kebab-name>`,
50
55
  "```",
@@ -53,6 +53,7 @@ async function runFlow(options) {
53
53
  : await adapter.runFlow({
54
54
  runId: scaffold.runId,
55
55
  outputRoot: scaffold.outputRoot,
56
+ projectRoot: options.projectRoot,
56
57
  product: options.product,
57
58
  version: options.version,
58
59
  });
@@ -117,6 +117,7 @@ async function runPhaseAdvance(options) {
117
117
  await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(installRoot, ".opsx-active-change"), `${changeName}\n`);
118
118
  await writeNextMd(outputRoot, [
119
119
  "## 当前:阶段 C 完成 → 进入 D(实现)",
120
+ "说明:先进入 impl,再在 AI 工具执行 `/opsx-apply` 按 tasks.md 实现;完成后才可 deliver。",
120
121
  "```bash",
121
122
  `npx sdd-flow-kit phase advance --project-root ${options.projectRoot} --run-id ${runId} --to impl --change ${changeName}`,
122
123
  "```",
@@ -158,6 +159,7 @@ async function runPhaseAdvance(options) {
158
159
  "```bash",
159
160
  `npx sdd-flow-kit gate --project-root ${options.projectRoot} --run-id ${runId} --expect impl-allowed --change ${changeName}`,
160
161
  "```",
162
+ "在 AI 工具中执行:`/opsx-apply`(必须先完成 tasks.md 全部 [x])",
161
163
  "完成后交付:",
162
164
  "```bash",
163
165
  `npx sdd-flow-kit deliver --project-root ${options.projectRoot} --run-id ${runId} --change ${changeName}`,
@@ -51,7 +51,9 @@ async function runPropose(options) {
51
51
  "",
52
52
  `change: \`${options.change}\``,
53
53
  "",
54
- "AI 须按 openspec-propose skill 生成 proposal/design/specs/tasks,完成后执行:",
54
+ "AI 须按 openspec-propose skill 生成 proposal/design/specs/tasks",
55
+ "注意:propose 结束后不能直接 deliver,必须先 `/opsx-apply` 执行 tasks。",
56
+ "完成提案后执行:",
55
57
  "```bash",
56
58
  `npx sdd-flow-kit gate --project-root ${options.projectRoot} --run-id ${loaded.resolved.runId} --expect propose-ready --change ${options.change}`,
57
59
  `npx sdd-flow-kit phase advance --project-root ${options.projectRoot} --run-id ${loaded.resolved.runId} --to propose-done --change ${options.change}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdd-flow-kit",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "private": false,
5
5
  "description": "Cross-agent SDD automated development workflow kit (ADI/ADI-like).",
6
6
  "license": "MIT",