super-engineer-workflow 0.1.5 → 0.1.7

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.
Files changed (27) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +6 -10
  3. package/docs/se/345/221/275/344/273/244/345/215/217/350/256/256.md +42 -297
  4. package/docs//350/267/250/345/271/263/345/217/260/346/224/257/346/214/201/347/237/251/351/230/265.md +34 -0
  5. package/docs//351/241/271/347/233/256/346/236/266/346/236/204/344/270/216/350/256/276/350/256/241/350/257/264/346/230/216.md +3 -2
  6. package/package.json +1 -1
  7. package/scripts/se-cli.py +146 -2
  8. package/scripts/se-e2e-test.py +168 -0
  9. package/scripts/se-setup.py +13 -2
  10. package/super-engineer-workflow/SKILL.md +20 -5
  11. package/super-engineer-workflow/references/commands/apply.md +28 -0
  12. package/super-engineer-workflow/references/commands/archive.md +23 -0
  13. package/super-engineer-workflow/references/commands/bridge.md +25 -0
  14. package/super-engineer-workflow/references/commands/common.md +32 -0
  15. package/super-engineer-workflow/references/commands/plan.md +25 -0
  16. package/super-engineer-workflow/references/commands/propose.md +25 -0
  17. package/super-engineer-workflow/references/commands/review.md +22 -0
  18. package/super-engineer-workflow/references/commands/status.md +22 -0
  19. package/super-engineer-workflow/references/commands/verify.md +23 -0
  20. package/super-engineer-workflow/scripts/bootstrap-openspec.py +3 -1
  21. package/super-engineer-workflow/scripts/common.py +143 -7
  22. package/super-engineer-workflow/scripts/generate-discovery.py +44 -0
  23. package/super-engineer-workflow/scripts/generate-smart-plan.py +12 -2
  24. package/super-engineer-workflow/scripts/prepare-archive-openspec.py +4 -0
  25. package/super-engineer-workflow/scripts/run-workflow.py +108 -33
  26. package/super-engineer-workflow/scripts/writeback-openspec.py +5 -1
  27. package/super-engineer-workflow/references/se-commands.md +0 -586
package/scripts/se-cli.py CHANGED
@@ -5,6 +5,7 @@ import argparse
5
5
  import importlib.util
6
6
  import json
7
7
  import os
8
+ import platform
8
9
  import shutil
9
10
  import subprocess
10
11
  import sys
@@ -28,6 +29,65 @@ WORKSPACE_TEMPLATES: dict[str, str] = {
28
29
  }
29
30
 
30
31
 
32
+ SE_COMMANDS: dict[str, str] = {
33
+ "propose.md": """---
34
+ description: Super Engineer:生成或完善 OpenSpec change
35
+ argument-hint: <change-name>
36
+ ---
37
+
38
+ 请使用 super-engineer-workflow skill 执行:`/se:propose $ARGUMENTS`。
39
+ 如果 `$ARGUMENTS` 为空,请先询问用户提供 OpenSpec change 名称。
40
+ """,
41
+ "propose-fix.md": """---
42
+ description: Super Engineer:需求补充后修正当前 OpenSpec change
43
+ argument-hint: <change-name>
44
+ ---
45
+
46
+ 请使用 super-engineer-workflow skill 执行:`/se:propose $ARGUMENTS`。
47
+ 当前需求有补充,请修正当前 OpenSpec change;不要创建新的 change,不要改代码。
48
+ """,
49
+ "bridge.md": """---
50
+ description: Super Engineer:生成桥接 todo
51
+ ---
52
+
53
+ 请使用 super-engineer-workflow skill 执行:`/se:bridge`。
54
+ 生成桥接 todo 并总结待审核项,不要改代码,不要进入实现。
55
+ """,
56
+ "plan.md": """---
57
+ description: Super Engineer:只生成实施计划
58
+ ---
59
+
60
+ 请使用 super-engineer-workflow skill 执行:`/se:plan`。
61
+ 只生成计划,不要改代码。
62
+ """,
63
+ "apply.md": """---
64
+ description: Super Engineer:审核 todo 后进入交付阶段
65
+ ---
66
+
67
+ 请使用 super-engineer-workflow skill 执行:`/se:apply`。
68
+ 我已审核当前桥接 todo,可以进入交付阶段。
69
+ """,
70
+ "archive-check.md": """---
71
+ description: Super Engineer:检查 OpenSpec 归档条件
72
+ ---
73
+
74
+ 请使用 super-engineer-workflow skill 执行:`/se:archive-check`。
75
+ """,
76
+ "archive.md": """---
77
+ description: Super Engineer:归档 OpenSpec change
78
+ ---
79
+
80
+ 请使用 super-engineer-workflow skill 执行:`/se:archive`。
81
+ """,
82
+ "status.md": """---
83
+ description: Super Engineer:查看工作流状态
84
+ ---
85
+
86
+ 请使用 super-engineer-workflow skill 执行:`/se:status`。
87
+ """,
88
+ }
89
+
90
+
31
91
  def main() -> None:
32
92
  if len(sys.argv) == 1:
33
93
  run_setup([])
@@ -56,6 +116,7 @@ def main() -> None:
56
116
  doctor_parser = subparsers.add_parser("doctor", help="检查本机环境和工作区配置。")
57
117
  doctor_parser.add_argument("--workspace", default=".", help="工作区目录,默认当前目录。")
58
118
  doctor_parser.add_argument("--json", action="store_true", help="输出 JSON。")
119
+ doctor_parser.add_argument("--fix", action="store_true", help="尽量自动补齐 skill 和快捷命令。")
59
120
 
60
121
  migrate_parser = subparsers.add_parser("migrate", help="补齐旧工作区缺失的 workspace.yml 配置项。")
61
122
  migrate_parser.add_argument("--workspace", default=".", help="工作区目录,默认当前目录。")
@@ -63,6 +124,17 @@ def main() -> None:
63
124
 
64
125
  subparsers.add_parser("templates", help="列出内置 workspace.yml 模板。")
65
126
 
127
+ commands_parser = subparsers.add_parser("commands", help="安装 AI 编码工具快捷命令模板。")
128
+ commands_subparsers = commands_parser.add_subparsers(dest="commands_action")
129
+ commands_install = commands_subparsers.add_parser("install", help="安装 /se:* 快捷命令模板。")
130
+ commands_install.add_argument("--workspace", default=".", help="工作区目录,默认当前目录。")
131
+ commands_install.add_argument(
132
+ "--target",
133
+ choices=["claude", "codex", "cursor", "trae", "kimi", "all"],
134
+ default="claude",
135
+ help="目标 AI 编码工具。",
136
+ )
137
+
66
138
  template_parser = subparsers.add_parser("template", help="查看或复制内置 workspace.yml 模板。")
67
139
  template_subparsers = template_parser.add_subparsers(dest="template_action")
68
140
  template_show = template_subparsers.add_parser("show", help="打印指定模板内容。")
@@ -87,7 +159,7 @@ def main() -> None:
87
159
  install_targets(args.target, force=True)
88
160
  return
89
161
  if args.command == "doctor":
90
- exit_code = doctor(Path(args.workspace).expanduser().resolve(), output_json=args.json)
162
+ exit_code = doctor(Path(args.workspace).expanduser().resolve(), output_json=args.json, fix=args.fix)
91
163
  raise SystemExit(exit_code)
92
164
  if args.command == "migrate":
93
165
  exit_code = migrate(Path(args.workspace).expanduser().resolve(), dry_run=args.dry_run)
@@ -95,6 +167,12 @@ def main() -> None:
95
167
  if args.command == "templates":
96
168
  list_templates()
97
169
  return
170
+ if args.command == "commands":
171
+ if args.commands_action == "install":
172
+ install_commands(Path(args.workspace).expanduser().resolve(), args.target)
173
+ return
174
+ commands_parser.print_help()
175
+ return
98
176
  if args.command == "template":
99
177
  if args.template_action == "show":
100
178
  show_template(args.name)
@@ -196,14 +274,23 @@ def copy_template(name: str, workspace: Path, demand_name: str, code_path: str,
196
274
  print(f"✓ 已写入模板:{target}")
197
275
 
198
276
 
199
- def doctor(workspace: Path, output_json: bool) -> int:
277
+ def doctor(workspace: Path, output_json: bool, fix: bool = False) -> int:
278
+ if fix:
279
+ install_targets("both", force=True)
280
+ install_commands(workspace, "all")
281
+
200
282
  checks: list[dict[str, str]] = []
283
+ add_check(checks, "platform", "ok", f"{platform.system()} {platform.release()}")
201
284
  add_check(checks, "python", "ok", sys.version.split()[0])
285
+ add_check(checks, "node", "ok" if shutil.which("node") else "fail", shutil.which("node") or "未安装")
286
+ add_check(checks, "npm", "ok" if shutil.which("npm") else "fail", shutil.which("npm") or "未安装")
202
287
  add_check(checks, "skill_source", "ok" if SKILL_DIR.exists() else "fail", str(SKILL_DIR))
203
288
  add_check(checks, "codex_skill", "ok" if skill_target("codex").exists() else "warn", str(skill_target("codex")))
204
289
  add_check(checks, "claude_skill", "ok" if skill_target("claude").exists() else "warn", str(skill_target("claude")))
205
290
  add_check(checks, "openspec_cli", "ok" if shutil.which("openspec") else "warn", shutil.which("openspec") or "未安装")
206
291
  add_check(checks, "workspace", "ok" if workspace.exists() else "fail", str(workspace))
292
+ add_check(checks, "workspace.commands.se", "ok" if workspace_commands_ready(workspace) else "warn", str(workspace / ".claude" / "commands" / "se"))
293
+ add_check(checks, "workspace.openspec.root", "ok" if (workspace / "openspec").exists() else "warn", str(workspace / "openspec"))
207
294
 
208
295
  workspace_yml = workspace / "workspace.yml"
209
296
  add_check(checks, "workspace_yml", "ok" if workspace_yml.exists() else "fail", str(workspace_yml))
@@ -223,10 +310,67 @@ def doctor(workspace: Path, output_json: bool) -> int:
223
310
  for check in checks:
224
311
  mark = {"ok": "✓", "warn": "!", "fail": "✗"}[check["status"]]
225
312
  print(f"{mark} {check['name']}: {check['message']}")
313
+ suggestions = doctor_suggestions(checks)
314
+ if suggestions:
315
+ print("\n建议:")
316
+ for item in suggestions:
317
+ print(f"- {item}")
226
318
 
227
319
  return 1 if any(item["status"] == "fail" for item in checks) else 0
228
320
 
229
321
 
322
+ def workspace_commands_ready(workspace: Path) -> bool:
323
+ commands_dir = workspace / ".claude" / "commands" / "se"
324
+ required = ["propose.md", "bridge.md", "plan.md", "apply.md", "status.md"]
325
+ return all((commands_dir / name).exists() for name in required)
326
+
327
+
328
+ def ensure_workspace_commands(workspace: Path) -> None:
329
+ install_commands(workspace, "claude")
330
+
331
+
332
+ def command_target_dirs(workspace: Path, target: str) -> list[tuple[str, Path]]:
333
+ home = Path.home()
334
+ mapping: dict[str, Path] = {
335
+ "claude": workspace / ".claude" / "commands" / "se",
336
+ "codex": Path(os.environ.get("CODEX_HOME", str(home / ".codex"))).expanduser() / "prompts",
337
+ "cursor": workspace / ".cursor" / "commands" / "se",
338
+ "trae": workspace / ".trae" / "commands" / "se",
339
+ "kimi": workspace / ".kimi" / "commands" / "se",
340
+ }
341
+ if target == "all":
342
+ return list(mapping.items())
343
+ return [(target, mapping[target])]
344
+
345
+
346
+ def install_commands(workspace: Path, target: str) -> None:
347
+ workspace.mkdir(parents=True, exist_ok=True)
348
+ for name, directory in command_target_dirs(workspace, target):
349
+ directory.mkdir(parents=True, exist_ok=True)
350
+ for filename, content in SE_COMMANDS.items():
351
+ output_name = f"se-{filename}" if name == "codex" else filename
352
+ (directory / output_name).write_text(content, encoding="utf-8")
353
+ print(f"✓ 已补齐 {name} 快捷命令: {directory}")
354
+
355
+
356
+ def doctor_suggestions(checks: list[dict[str, str]]) -> list[str]:
357
+ by_name = {item["name"]: item for item in checks}
358
+ suggestions: list[str] = []
359
+ if by_name.get("codex_skill", {}).get("status") != "ok" or by_name.get("claude_skill", {}).get("status") != "ok":
360
+ suggestions.append("执行 `se sync --target both` 同步最新 skill。")
361
+ if by_name.get("workspace.commands.se", {}).get("status") != "ok":
362
+ suggestions.append("执行 `se doctor --fix` 补齐工作区 `.claude/commands/se/*` 快捷命令。")
363
+ if by_name.get("workspace_yml", {}).get("status") != "ok":
364
+ suggestions.append("执行 `se init` 初始化工作区,或用 `se template copy <模板名>` 生成 workspace.yml。")
365
+ if by_name.get("openspec_cli", {}).get("status") != "ok":
366
+ suggestions.append("OpenSpec 模式建议先安装并初始化 OpenSpec;todo 模式可忽略。")
367
+ if by_name.get("workspace.openspec.root", {}).get("status") != "ok":
368
+ suggestions.append("OpenSpec 模式请在工作区执行 OpenSpec 初始化;todo 模式可忽略。")
369
+ if by_name.get("node", {}).get("status") != "ok" or by_name.get("npm", {}).get("status") != "ok":
370
+ suggestions.append("请先安装 Node.js/npm。")
371
+ return suggestions
372
+
373
+
230
374
  def add_check(checks: list[dict[str, str]], name: str, status: str, message: str) -> None:
231
375
  checks.append({"name": name, "status": status, "message": message})
232
376
 
@@ -24,6 +24,7 @@ def main() -> None:
24
24
  os.environ["USERPROFILE"] = str(home)
25
25
  test_templates_cli(root)
26
26
  test_openspec_state_and_bridge(root)
27
+ test_incomplete_plan_session_is_reused(root)
27
28
  test_todo_auto_session_and_verify_compaction(root)
28
29
  print("e2e_test=ok")
29
30
 
@@ -57,6 +58,22 @@ def test_templates_cli(root: Path) -> None:
57
58
  if "workflow_source: todo" not in workspace_yml or "9-e2e-template" not in workspace_yml:
58
59
  raise AssertionError("template copy did not render workspace.yml")
59
60
 
61
+ doctor_before = run(["node", str(CLI), "doctor", "--workspace", str(workspace)], check=False)
62
+ if "workspace.commands.se" not in doctor_before.output:
63
+ raise AssertionError("doctor should report workspace command status")
64
+ run(["node", str(CLI), "doctor", "--workspace", str(workspace), "--fix"], check=False)
65
+ if not (workspace / ".claude" / "commands" / "se" / "apply.md").exists():
66
+ raise AssertionError("doctor --fix should create se command templates")
67
+ run(["node", str(CLI), "commands", "install", "--workspace", str(workspace), "--target", "all"])
68
+ for command_path in [
69
+ workspace / ".cursor" / "commands" / "se" / "apply.md",
70
+ workspace / ".trae" / "commands" / "se" / "apply.md",
71
+ workspace / ".kimi" / "commands" / "se" / "apply.md",
72
+ home_prompt(root) / "se-apply.md",
73
+ ]:
74
+ if not command_path.exists():
75
+ raise AssertionError(f"commands install all missing {command_path}")
76
+
60
77
 
61
78
  def test_openspec_state_and_bridge(root: Path) -> None:
62
79
  workspace = root / "openspec-workspace"
@@ -164,6 +181,57 @@ def test_openspec_state_and_bridge(root: Path) -> None:
164
181
  if "demo-change" not in todo or "demo-service" not in todo:
165
182
  raise AssertionError("bridged todo.md missing expected OpenSpec context")
166
183
 
184
+ route_check = run(
185
+ [
186
+ sys.executable,
187
+ str(RUN_WORKFLOW),
188
+ "route-check",
189
+ "--workspace",
190
+ str(workspace),
191
+ "--command-text",
192
+ "/se:apply",
193
+ ]
194
+ )
195
+ route_payload = json.loads(route_check)
196
+ if not route_payload.get("allowed") or route_payload.get("run_command") != "apply":
197
+ raise AssertionError("route-check should return allowed JSON for bridged /se:apply")
198
+
199
+ (change_dir / "tasks.md").write_text(
200
+ "# Tasks\n\n"
201
+ "- [ ] 修改 demo-service controller 增加状态查询接口\n"
202
+ "- [ ] 补充验证,确认接口返回 ok\n"
203
+ "- [ ] 追加变更后必须重新桥接\n",
204
+ encoding="utf-8",
205
+ )
206
+ stale_apply = run(
207
+ [
208
+ sys.executable,
209
+ str(RUN_WORKFLOW),
210
+ "route-se",
211
+ "--workspace",
212
+ str(workspace),
213
+ "--command-text",
214
+ "/se:apply",
215
+ ],
216
+ check=False,
217
+ )
218
+ if stale_apply.returncode == 0 or "tasks.md 已变化" not in stale_apply.output:
219
+ raise AssertionError("changed tasks.md should require /se:bridge before /se:apply")
220
+
221
+ bridge_again = run(
222
+ [
223
+ sys.executable,
224
+ str(RUN_WORKFLOW),
225
+ "route-se",
226
+ "--workspace",
227
+ str(workspace),
228
+ "--command-text",
229
+ "/se:bridge",
230
+ ]
231
+ )
232
+ if "tasks_sha256=" not in bridge_again:
233
+ raise AssertionError("second /se:bridge should record tasks hash")
234
+
167
235
  first_plan = run(
168
236
  [
169
237
  sys.executable,
@@ -179,6 +247,9 @@ def test_openspec_state_and_bridge(root: Path) -> None:
179
247
  raise AssertionError("first /se:plan should create a session")
180
248
  first_session = read_json(workspace / ".super-engineer" / "current-session.json")
181
249
  first_session_id = first_session["session_id"]
250
+ data_dir = Path(first_session["data_dir"])
251
+ if not (data_dir / "discovery-summary.json").exists():
252
+ raise AssertionError("plan should create discovery-summary.json")
182
253
 
183
254
  second_plan = run(
184
255
  [
@@ -210,6 +281,21 @@ def test_openspec_state_and_bridge(root: Path) -> None:
210
281
  )
211
282
  if "apply_phase=implementing" not in apply_output:
212
283
  raise AssertionError("/se:apply should enter implementing after planned session")
284
+ apply_json_output = run(
285
+ [
286
+ sys.executable,
287
+ str(RUN_WORKFLOW),
288
+ "route-se",
289
+ "--workspace",
290
+ str(workspace),
291
+ "--command-text",
292
+ "/se:apply",
293
+ "--json",
294
+ ],
295
+ check=False,
296
+ )
297
+ if "route_result_json_begin" not in apply_json_output.output and "当前状态不允许进入实现" not in apply_json_output.output:
298
+ raise AssertionError("route-se --json should emit JSON summary or a state guard")
213
299
  blocked_plan = run(
214
300
  [
215
301
  sys.executable,
@@ -323,6 +409,84 @@ def test_todo_auto_session_and_verify_compaction(root: Path) -> None:
323
409
  raise AssertionError("notification should be marked skipped when no provider is configured")
324
410
 
325
411
 
412
+ def test_incomplete_plan_session_is_reused(root: Path) -> None:
413
+ workspace = root / "incomplete-plan-workspace"
414
+ code = root / "broken-code" / "not-a-project"
415
+ demand_dir = workspace / "superengineer" / "10-broken"
416
+ demand_dir.mkdir(parents=True)
417
+ code.mkdir(parents=True)
418
+ (workspace / "docs").mkdir(parents=True)
419
+ (workspace / "workspace.yml").write_text(
420
+ "\n".join(
421
+ [
422
+ "version: 1",
423
+ "mode: auto",
424
+ "workflow_source: todo",
425
+ "vars:",
426
+ " demand_name: 10-broken",
427
+ "todo_file: superengineer/${demand_name}/todo.md",
428
+ "reference_files: []",
429
+ "code_path: ../broken-code/not-a-project",
430
+ "output_dir: superengineer/${demand_name}/output",
431
+ "",
432
+ ]
433
+ ),
434
+ encoding="utf-8",
435
+ )
436
+ (demand_dir / "todo.md").write_text(
437
+ "# 限制条件\n"
438
+ "- 修改的服务是 broken-service\n\n"
439
+ "# 待办事项\n\n"
440
+ "- [ ] 增加一个测试接口\n",
441
+ encoding="utf-8",
442
+ )
443
+
444
+ first_apply = run(
445
+ [
446
+ sys.executable,
447
+ str(RUN_WORKFLOW),
448
+ "route-se",
449
+ "--workspace",
450
+ str(workspace),
451
+ "--command-text",
452
+ "/se:apply",
453
+ ],
454
+ check=False,
455
+ )
456
+ if first_apply.returncode == 0 or "未找到可识别的项目目录" not in first_apply.output:
457
+ raise AssertionError("first /se:apply should fail before plan is generated")
458
+ current = read_json(workspace / ".super-engineer" / "current-session.json")
459
+ first_session_id = current["session_id"]
460
+ sessions_dir = workspace / ".super-engineer" / "sessions"
461
+ output_dir = workspace / "superengineer" / "10-broken" / "output"
462
+ if len(list(sessions_dir.iterdir())) != 1:
463
+ raise AssertionError("first failed /se:apply should create exactly one reusable data session")
464
+ if output_dir.exists() and list(output_dir.iterdir()):
465
+ raise AssertionError("failed plan should not create an empty output report session")
466
+
467
+ second_apply = run(
468
+ [
469
+ sys.executable,
470
+ str(RUN_WORKFLOW),
471
+ "route-se",
472
+ "--workspace",
473
+ str(workspace),
474
+ "--command-text",
475
+ "/se:apply",
476
+ ],
477
+ check=False,
478
+ )
479
+ if second_apply.returncode == 0 or "session_action=reused_incomplete" not in second_apply.output:
480
+ raise AssertionError("second /se:apply should reuse the incomplete planning session")
481
+ current = read_json(workspace / ".super-engineer" / "current-session.json")
482
+ if current["session_id"] != first_session_id:
483
+ raise AssertionError("incomplete planning session should remain current")
484
+ if len(list(sessions_dir.iterdir())) != 1:
485
+ raise AssertionError("repeated failed /se:apply should not create another data session")
486
+ if output_dir.exists() and list(output_dir.iterdir()):
487
+ raise AssertionError("repeated failed /se:apply should not create output report sessions")
488
+
489
+
326
490
  def run(command: list[str], check: bool = True, env: dict[str, str] | None = None):
327
491
  result = subprocess.run(
328
492
  command,
@@ -341,6 +505,10 @@ def run(command: list[str], check: bool = True, env: dict[str, str] | None = Non
341
505
  return CommandResult(result.returncode, result.stdout)
342
506
 
343
507
 
508
+ def home_prompt(root: Path) -> Path:
509
+ return root / "home" / ".codex" / "prompts"
510
+
511
+
344
512
  class CommandResult:
345
513
  def __init__(self, returncode: int, output: str) -> None:
346
514
  self.returncode = returncode
@@ -423,14 +423,25 @@ def print_summary(workspace: Path, demand_name: str, source: str, mode: str) ->
423
423
  print(f"mode={mode}")
424
424
  print("")
425
425
  if source == "openspec":
426
- print("下一步提示词:")
426
+ print("推荐使用流程:")
427
427
  print(f"/se:propose <change-name>")
428
428
  print("请根据当前 workspace 的 demand_file 生成或完善 OpenSpec change。")
429
429
  print("不要改代码。过程中请使用中文。")
430
+ print("")
431
+ print("/se:bridge")
432
+ print("把 OpenSpec tasks.md 桥接为待审核 todo.md,不要改代码。")
433
+ print("")
434
+ print("人工审核 todo.md 后:")
435
+ print("/se:apply")
436
+ print("我已审核当前桥接 todo,可以进入交付阶段。")
430
437
  else:
431
- print("下一步提示词:")
438
+ print("推荐使用流程:")
439
+ print("先编辑 todo_file,确认任务和验收标准。")
440
+ print("")
432
441
  print("/se:apply")
433
442
  print("请根据当前 workspace 的 todo_file 推进交付工作流。过程中请使用中文。")
443
+ print("")
444
+ print("诊断命令:se doctor --workspace <workspace>")
434
445
 
435
446
 
436
447
  if __name__ == "__main__":
@@ -24,16 +24,27 @@ Supported commands:
24
24
  - `/se:archive`
25
25
  - `/se:status`
26
26
 
27
- For command details, read only the relevant section in [references/se-commands.md](references/se-commands.md).
27
+ For command details, read [references/commands/common.md](references/commands/common.md) plus only the matching command file:
28
+
29
+ - `/se:propose`: [references/commands/propose.md](references/commands/propose.md)
30
+ - `/se:bridge`: [references/commands/bridge.md](references/commands/bridge.md)
31
+ - `/se:plan`: [references/commands/plan.md](references/commands/plan.md)
32
+ - `/se:apply`: [references/commands/apply.md](references/commands/apply.md)
33
+ - `/se:review`: [references/commands/review.md](references/commands/review.md)
34
+ - `/se:verify`: [references/commands/verify.md](references/commands/verify.md)
35
+ - `/se:archive-check` and `/se:archive`: [references/commands/archive.md](references/commands/archive.md)
36
+ - `/se:status`: [references/commands/status.md](references/commands/status.md)
37
+
28
38
  For mode and artifact details, use [references/workflow.md](references/workflow.md) and [references/execution-modes.md](references/execution-modes.md) only when needed.
29
39
 
30
40
  ## Minimal Required Steps
31
41
 
32
42
  1. Read `<workspace>/workspace.yml`.
33
43
  2. Identify `workflow_source`, `mode`, `todo_file`, `demand_file`, `reference_files`, `code_path`, `output_dir`, and optional `openspec` fields.
34
- 3. Route the current command through `python3 scripts/run-workflow.py route-se --command-text "<command>"` when possible.
35
- 4. Obey script state validation and script reply constraints.
36
- 5. Report compactly: result, blockers, allowed next command, and key artifact paths.
44
+ 3. Preflight with `python3 scripts/run-workflow.py route-check --command-text "<command>"` when possible.
45
+ 4. Route the current command through `python3 scripts/run-workflow.py route-se --command-text "<command>"` when preflight passes.
46
+ 5. Obey script state validation and script reply constraints.
47
+ 6. Report compactly: result, blockers, allowed next command, and key artifact paths.
37
48
 
38
49
  ## Hard Constraints
39
50
 
@@ -59,6 +70,8 @@ For mode and artifact details, use [references/workflow.md](references/workflow.
59
70
  - `reference_files` are strong context, but scripts summarize large files by default; read full files only when necessary for the current command.
60
71
  - In OpenSpec mode, avoid rereading `proposal.md`, `design.md`, and `specs/**/*.md` unless the current stage needs them.
61
72
  - Prefer `plan-summary.json` for downstream context; use `plan.json` only when detailed planning data is required.
73
+ - Prefer `discovery-summary.json` over `discovery.json`; read full discovery only for detailed code evidence.
74
+ - Prefer `route-se --json` when a machine-readable execution summary is useful.
62
75
  - Final replies should be compact. Detailed reports belong in `output_dir/<session_id>/`.
63
76
 
64
77
  ## State Summary
@@ -75,10 +88,12 @@ Todo mode uses current session `status.json` and `todo-state.json`; do not write
75
88
 
76
89
  ## Script Entry Points
77
90
 
91
+ - Preflight router: `python3 scripts/run-workflow.py route-check --command-text "<command>"`
78
92
  - Main router: `python3 scripts/run-workflow.py route-se --command-text "<command>"`
93
+ - JSON router summary: `python3 scripts/run-workflow.py route-se --command-text "<command>" --json`
79
94
  - Status: `python3 scripts/run-workflow.py status`
80
95
  - Plan: `python3 scripts/run-workflow.py plan`
81
96
  - Review: `python3 scripts/run-workflow.py review`
82
97
  - Verify: `python3 scripts/run-workflow.py verify`
83
98
 
84
- OpenSpec-specific internal commands are listed in [references/se-commands.md](references/se-commands.md).
99
+ OpenSpec-specific execution details are enforced by the command files under [references/commands/](references/commands/).
@@ -0,0 +1,28 @@
1
+ # `/se:apply`
2
+
3
+ 用途:进入交付阶段,按计划实现、生成自查,并在 auto 模式继续 review/verify。
4
+
5
+ ## 前置
6
+
7
+ - todo 模式:存在有效 `todo.md`。
8
+ - openspec 模式:已经 `/se:bridge`,且用户已审核 `todo.md`。
9
+ - 如无计划,脚本可创建或复用标准 session 并生成计划。
10
+ - OpenSpec `tasks.md` hash 必须与最近 bridge 记录一致。
11
+
12
+ ## 执行
13
+
14
+ 1. 先执行公共 `route-check`。
15
+ 2. 再执行:
16
+ `python3 scripts/run-workflow.py route-se --command-text "/se:apply"`
17
+ 3. AI 按当前 `plan-summary.json` / `plan.json` 修改目标代码。
18
+ 4. 修改完成后调用 `finish-implement`,由脚本生成 self-check。
19
+ 5. auto 模式继续由标准脚本推进 review、verify 和通知。
20
+
21
+ ## 禁止
22
+
23
+ - 禁止第二次手工执行 `/se:plan` 创建新 session。
24
+ - 禁止手写状态文件或 output 报告。
25
+ - 禁止直接发飞书/PushPlus 通知。
26
+ - verify 通过前禁止提示 archive。
27
+
28
+ 最终回复汇报改动、review、verify、通知和允许的下一步。
@@ -0,0 +1,23 @@
1
+ # `/se:archive-check` 与 `/se:archive`
2
+
3
+ ## `/se:archive-check`
4
+
5
+ 用途:检查 OpenSpec change 是否可以安全归档。
6
+
7
+ 前置:`/se:verify` 已通过。
8
+
9
+ 执行:
10
+ `python3 scripts/run-workflow.py route-se --command-text "/se:archive-check"`
11
+
12
+ 只有 `archive_ready=true`、`merge_mode=safe_merge` 且无 spec 冲突时,才允许提示 `/se:archive`。
13
+
14
+ ## `/se:archive`
15
+
16
+ 用途:归档当前 OpenSpec change,沉淀长期 specs。
17
+
18
+ 前置:已完成 `/se:archive-check` 且结果为 safe merge。
19
+
20
+ 执行:
21
+ `python3 scripts/run-workflow.py route-se --command-text "/se:archive"`
22
+
23
+ 禁止跳过 archive-check 直接归档。
@@ -0,0 +1,25 @@
1
+ # `/se:bridge`
2
+
3
+ 用途:把当前 OpenSpec change 的 `tasks.md` 转成待审核 `todo.md`。
4
+
5
+ ## 前置
6
+
7
+ - 已有 active OpenSpec change。
8
+ - 已存在 `proposal.md`、`design.md`、`tasks.md`。
9
+ - 当前阶段为 `proposed` 或允许重新 bridge 的 `bridged`。
10
+
11
+ ## 执行
12
+
13
+ 1. 先执行公共 `route-check`。
14
+ 2. 再执行:
15
+ `python3 scripts/run-workflow.py route-se --command-text "/se:bridge"`
16
+ 3. 脚本生成 `todo.md`,并记录 `tasks.md` hash。
17
+ 4. 停在 `bridged` 阶段。
18
+
19
+ ## 禁止
20
+
21
+ - 禁止手工同步 `tasks.md` 到 `todo.md`。
22
+ - 禁止自动进入 `/se:plan` 或 `/se:apply`。
23
+ - 如果审核后发现需求或 todo 有偏差,先修正需求或重新 `/se:propose <change-name>`,再重新 `/se:bridge`。
24
+
25
+ 最终回复只能提示:请人工审核 `todo.md`,审核通过后发送 `/se:apply`。
@@ -0,0 +1,32 @@
1
+ # `/se:*` 公共协议
2
+
3
+ `/se:*` 是 Super Engineer Workflow 的 AI 阶段命令,不是 shell 命令,也不是 OpenSpec `/opsx:*`。
4
+
5
+ ## 必做
6
+
7
+ 1. 读取当前工作区 `workspace.yml`。
8
+ 2. 通过 `python3 scripts/run-workflow.py route-check --command-text "<用户命令>"` 做状态预检。
9
+ 3. 预检通过后,再执行 `python3 scripts/run-workflow.py route-se --command-text "<用户命令>"`。
10
+ 4. 遵守脚本输出的 `final_reply_must` 或 `se_reply_constraint_begin/end`。
11
+ 5. 最终回复只汇报结果、阻塞点、允许的下一步和关键相对路径。
12
+
13
+ ## 硬约束
14
+
15
+ - 禁止编辑 `workspace.yml`。
16
+ - 禁止手写 `.super-engineer/**/status.json`、`se-state.json`、`current-session.json`、`plan.json`、`review.json`、`verify.json`、`notification.json`。
17
+ - 标准状态、报告、通知只能由脚本生成。
18
+ - 一次只执行用户当前明确请求的一个 `/se:*` 命令。
19
+ - `/se:propose` 之后只能提示 `/se:bridge`。
20
+ - `/se:bridge` 之后只能提示人工审核 `todo.md`,审核后 `/se:apply`。
21
+ - `/se:apply` 之前必须已经完成 bridge 且用户已审核 todo。
22
+ - 通知只能由 `run-workflow.py verify` 发送,AI 禁止直接调用飞书或 PushPlus webhook。
23
+
24
+ ## 最小上下文
25
+
26
+ - `/se:propose`:`workspace.yml`、`demand_file`、必要 `reference_files` 摘要。
27
+ - `/se:bridge`:`tasks.md`、bridge context、`todo_file`。
28
+ - `/se:plan`:`todo.md`、`discovery-summary` 或脚本生成的 plan 产物。
29
+ - `/se:apply`:优先 `todo.md`、`plan-summary.json`、目标代码文件。
30
+ - `/se:review` / `/se:verify`:优先读取 summary 和脚本报告,不展开长 diff 或长日志。
31
+
32
+ 命令细节只允许读取 `references/commands/` 下的对应命令文件。
@@ -0,0 +1,25 @@
1
+ # `/se:plan`
2
+
3
+ 用途:只生成实施计划,不改代码。
4
+
5
+ ## 前置
6
+
7
+ - todo 模式:存在有效 `todo.md`。
8
+ - openspec 模式:已经 `/se:bridge`,且用户已审核 `todo.md`。
9
+ - 当前不存在已进入实现、review、verify 的活跃 session。
10
+
11
+ ## 执行
12
+
13
+ 1. 先执行公共 `route-check`。
14
+ 2. 再执行:
15
+ `python3 scripts/run-workflow.py route-se --command-text "/se:plan"`
16
+ 3. 脚本生成 `discovery.json`、`plan.json`、`plan-summary.json`、`plan.md`。
17
+ 4. 如果已有可复用计划 session,必须复用,不能新建空 session。
18
+
19
+ ## 禁止
20
+
21
+ - 禁止改代码。
22
+ - 禁止继续 review/verify。
23
+ - OpenSpec `tasks.md` hash 与 bridge 记录不一致时,必须停止并要求重新 `/se:bridge`。
24
+
25
+ 最终回复提示下一步 `/se:apply`。