speccore 8.3.333 → 8.3.341

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 (309) hide show
  1. package/.agents/skills/spec-ask/SKILL.md +4 -0
  2. package/.agents/skills/spec-unitize/SKILL.md +9 -1
  3. package/.agents/skills/speccore-router/SKILL.md +12 -11
  4. package/README.en.md +3 -11
  5. package/README.md +3 -13
  6. package/dist/cli.js +64 -206
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/analyze.d.ts.map +1 -1
  9. package/dist/commands/analyze.js +530 -481
  10. package/dist/commands/analyze.js.map +1 -1
  11. package/dist/commands/ask.d.ts.map +1 -1
  12. package/dist/commands/ask.js +6 -0
  13. package/dist/commands/ask.js.map +1 -1
  14. package/dist/commands/completion.d.ts.map +1 -1
  15. package/dist/commands/completion.js +9 -7
  16. package/dist/commands/completion.js.map +1 -1
  17. package/dist/commands/doc2spec.d.ts +44 -1
  18. package/dist/commands/doc2spec.d.ts.map +1 -1
  19. package/dist/commands/doc2spec.js +257 -5
  20. package/dist/commands/doc2spec.js.map +1 -1
  21. package/dist/commands/doctor.js +3 -3
  22. package/dist/commands/doctor.js.map +1 -1
  23. package/dist/commands/done.js +1 -5
  24. package/dist/commands/done.js.map +1 -1
  25. package/dist/commands/execute.js +118 -66
  26. package/dist/commands/execute.js.map +1 -1
  27. package/dist/commands/help.js +6 -54
  28. package/dist/commands/help.js.map +1 -1
  29. package/dist/commands/init.d.ts.map +1 -1
  30. package/dist/commands/init.js +71 -47
  31. package/dist/commands/init.js.map +1 -1
  32. package/dist/commands/iteration/create.d.ts.map +1 -1
  33. package/dist/commands/iteration/create.js +72 -10
  34. package/dist/commands/iteration/create.js.map +1 -1
  35. package/dist/commands/iteration/taskify.d.ts.map +1 -1
  36. package/dist/commands/iteration/taskify.js +133 -35
  37. package/dist/commands/iteration/taskify.js.map +1 -1
  38. package/dist/commands/pr.d.ts.map +1 -1
  39. package/dist/commands/pr.js +24 -2
  40. package/dist/commands/pr.js.map +1 -1
  41. package/dist/commands/prompts.d.ts +6 -0
  42. package/dist/commands/prompts.d.ts.map +1 -1
  43. package/dist/commands/prompts.js +19 -10
  44. package/dist/commands/prompts.js.map +1 -1
  45. package/dist/commands/search.js +1 -1
  46. package/dist/commands/search.js.map +1 -1
  47. package/dist/commands/status-panel.d.ts.map +1 -1
  48. package/dist/commands/status-panel.js +23 -34
  49. package/dist/commands/status-panel.js.map +1 -1
  50. package/dist/commands/unitize.d.ts +3 -0
  51. package/dist/commands/unitize.d.ts.map +1 -1
  52. package/dist/commands/unitize.js +32 -9
  53. package/dist/commands/unitize.js.map +1 -1
  54. package/dist/commands/update-env-configs.d.ts.map +1 -1
  55. package/dist/commands/update-env-configs.js +2 -1
  56. package/dist/commands/update-env-configs.js.map +1 -1
  57. package/dist/commands/update.d.ts +4 -0
  58. package/dist/commands/update.d.ts.map +1 -1
  59. package/dist/commands/update.js +41 -1
  60. package/dist/commands/update.js.map +1 -1
  61. package/dist/commands/welcome.d.ts.map +1 -1
  62. package/dist/commands/welcome.js +41 -0
  63. package/dist/commands/welcome.js.map +1 -1
  64. package/dist/core/analyze-engine.js +3 -3
  65. package/dist/core/analyze-engine.js.map +1 -1
  66. package/dist/core/arbitration/l3-human-arbiter.js +1 -1
  67. package/dist/core/arbitration/l3-human-arbiter.js.map +1 -1
  68. package/dist/core/arbitration/verdict-generator.js +1 -1
  69. package/dist/core/arbitration/verdict-generator.js.map +1 -1
  70. package/dist/core/ask-context.d.ts.map +1 -1
  71. package/dist/core/ask-context.js +14 -3
  72. package/dist/core/ask-context.js.map +1 -1
  73. package/dist/core/ask-engine.d.ts.map +1 -1
  74. package/dist/core/ask-engine.js +55 -49
  75. package/dist/core/ask-engine.js.map +1 -1
  76. package/dist/core/code-graph/reporter.d.ts.map +1 -1
  77. package/dist/core/code-graph/reporter.js +3 -12
  78. package/dist/core/code-graph/reporter.js.map +1 -1
  79. package/dist/core/code-graph/requirement-linker.js +1 -1
  80. package/dist/core/code-graph/requirement-linker.js.map +1 -1
  81. package/dist/core/code-scanner.js +1 -1
  82. package/dist/core/code-scanner.js.map +1 -1
  83. package/dist/core/deploy/engine.d.ts.map +1 -1
  84. package/dist/core/deploy/engine.js +58 -44
  85. package/dist/core/deploy/engine.js.map +1 -1
  86. package/dist/core/environment-config.d.ts +13 -0
  87. package/dist/core/environment-config.d.ts.map +1 -1
  88. package/dist/core/environment-config.js +28 -1
  89. package/dist/core/environment-config.js.map +1 -1
  90. package/dist/core/error-diagnosis.js +2 -2
  91. package/dist/core/error-diagnosis.js.map +1 -1
  92. package/dist/core/git-integration.d.ts +5 -7
  93. package/dist/core/git-integration.d.ts.map +1 -1
  94. package/dist/core/git-integration.js +137 -12
  95. package/dist/core/git-integration.js.map +1 -1
  96. package/dist/core/global-knowledge.d.ts.map +1 -1
  97. package/dist/core/global-knowledge.js +25 -11
  98. package/dist/core/global-knowledge.js.map +1 -1
  99. package/dist/core/handoff-generator.d.ts.map +1 -1
  100. package/dist/core/handoff-generator.js +3 -1
  101. package/dist/core/handoff-generator.js.map +1 -1
  102. package/dist/core/index-guard.d.ts.map +1 -1
  103. package/dist/core/index-guard.js +4 -26
  104. package/dist/core/index-guard.js.map +1 -1
  105. package/dist/core/intent-recognition.d.ts +1 -1
  106. package/dist/core/intent-recognition.d.ts.map +1 -1
  107. package/dist/core/intent-recognition.js +68 -68
  108. package/dist/core/intent-recognition.js.map +1 -1
  109. package/dist/core/knowledge-graph.d.ts.map +1 -1
  110. package/dist/core/knowledge-graph.js +6 -4
  111. package/dist/core/knowledge-graph.js.map +1 -1
  112. package/dist/core/name-validator.d.ts.map +1 -1
  113. package/dist/core/name-validator.js +41 -20
  114. package/dist/core/name-validator.js.map +1 -1
  115. package/dist/core/pinyin-initials.d.ts +10 -0
  116. package/dist/core/pinyin-initials.d.ts.map +1 -0
  117. package/dist/core/pinyin-initials.js +44 -0
  118. package/dist/core/pinyin-initials.js.map +1 -0
  119. package/dist/core/prompt-builder.js +1 -1
  120. package/dist/core/prompt-builder.js.map +1 -1
  121. package/dist/core/prompt-plugins/analyze-graph-plugin.js +1 -1
  122. package/dist/core/prompt-plugins/analyze-graph-plugin.js.map +1 -1
  123. package/dist/core/reindex-engine.js +4 -4
  124. package/dist/core/reindex-engine.js.map +1 -1
  125. package/dist/core/skeleton-residue.d.ts +13 -0
  126. package/dist/core/skeleton-residue.d.ts.map +1 -1
  127. package/dist/core/skeleton-residue.js +83 -14
  128. package/dist/core/skeleton-residue.js.map +1 -1
  129. package/dist/core/spec-merger.d.ts.map +1 -1
  130. package/dist/core/spec-merger.js +3 -2
  131. package/dist/core/spec-merger.js.map +1 -1
  132. package/dist/core/state.d.ts +10 -0
  133. package/dist/core/state.d.ts.map +1 -1
  134. package/dist/core/state.js +20 -1
  135. package/dist/core/state.js.map +1 -1
  136. package/dist/core/structured-extractor.d.ts +6 -0
  137. package/dist/core/structured-extractor.d.ts.map +1 -1
  138. package/dist/core/structured-extractor.js +6 -0
  139. package/dist/core/structured-extractor.js.map +1 -1
  140. package/dist/core/task-paths.d.ts +12 -0
  141. package/dist/core/task-paths.d.ts.map +1 -1
  142. package/dist/core/task-paths.js +33 -1
  143. package/dist/core/task-paths.js.map +1 -1
  144. package/dist/core/unified-config.d.ts +7 -1
  145. package/dist/core/unified-config.d.ts.map +1 -1
  146. package/dist/core/unified-config.js +70 -21
  147. package/dist/core/unified-config.js.map +1 -1
  148. package/dist/core/unit-staffing.d.ts +21 -4
  149. package/dist/core/unit-staffing.d.ts.map +1 -1
  150. package/dist/core/unit-staffing.js +59 -12
  151. package/dist/core/unit-staffing.js.map +1 -1
  152. package/dist/core/usage-analytics.js +1 -1
  153. package/dist/core/usage-analytics.js.map +1 -1
  154. package/dist/core/validator.d.ts.map +1 -1
  155. package/dist/core/validator.js +45 -5
  156. package/dist/core/validator.js.map +1 -1
  157. package/dist/core/verify-report-aggregator.d.ts.map +1 -1
  158. package/dist/core/verify-report-aggregator.js +19 -2
  159. package/dist/core/verify-report-aggregator.js.map +1 -1
  160. package/dist/utils/task-utils.d.ts +4 -1
  161. package/dist/utils/task-utils.d.ts.map +1 -1
  162. package/dist/utils/task-utils.js +30 -4
  163. package/dist/utils/task-utils.js.map +1 -1
  164. package/package.json +4 -3
  165. package/templates/deploy-examples.yaml +33 -5
  166. package/templates/html/speccore-ask-explain.html +1 -1
  167. package/templates/html/speccore-ask-guide.html +1 -1
  168. package/templates/html/speccore-ask-match.html +1 -1
  169. package/templates/html/speccore-ask-pipeline.html +1 -1
  170. package/templates/html/speccore-ask-result.html +1 -1
  171. package/templates/html/speccore-help.html +2 -2
  172. package/templates/speccore-yml-example.yml +174 -54
  173. package/templates/verify-spec-example.yaml +66 -1
  174. package/dist/commands/audit.d.ts +0 -12
  175. package/dist/commands/audit.d.ts.map +0 -1
  176. package/dist/commands/audit.js +0 -540
  177. package/dist/commands/audit.js.map +0 -1
  178. package/dist/commands/backup.d.ts +0 -18
  179. package/dist/commands/backup.d.ts.map +0 -1
  180. package/dist/commands/backup.js +0 -102
  181. package/dist/commands/backup.js.map +0 -1
  182. package/dist/commands/baseline.d.ts +0 -13
  183. package/dist/commands/baseline.d.ts.map +0 -1
  184. package/dist/commands/baseline.js +0 -227
  185. package/dist/commands/baseline.js.map +0 -1
  186. package/dist/commands/chain.d.ts +0 -55
  187. package/dist/commands/chain.d.ts.map +0 -1
  188. package/dist/commands/chain.js +0 -501
  189. package/dist/commands/chain.js.map +0 -1
  190. package/dist/commands/clarify.d.ts +0 -17
  191. package/dist/commands/clarify.d.ts.map +0 -1
  192. package/dist/commands/clarify.js +0 -351
  193. package/dist/commands/clarify.js.map +0 -1
  194. package/dist/commands/code-index.d.ts +0 -21
  195. package/dist/commands/code-index.d.ts.map +0 -1
  196. package/dist/commands/code-index.js +0 -193
  197. package/dist/commands/code-index.js.map +0 -1
  198. package/dist/commands/context.d.ts +0 -10
  199. package/dist/commands/context.d.ts.map +0 -1
  200. package/dist/commands/context.js +0 -213
  201. package/dist/commands/context.js.map +0 -1
  202. package/dist/commands/current.d.ts +0 -10
  203. package/dist/commands/current.d.ts.map +0 -1
  204. package/dist/commands/current.js +0 -53
  205. package/dist/commands/current.js.map +0 -1
  206. package/dist/commands/dev.d.ts +0 -18
  207. package/dist/commands/dev.d.ts.map +0 -1
  208. package/dist/commands/dev.js +0 -854
  209. package/dist/commands/dev.js.map +0 -1
  210. package/dist/commands/diff.d.ts +0 -10
  211. package/dist/commands/diff.d.ts.map +0 -1
  212. package/dist/commands/diff.js +0 -160
  213. package/dist/commands/diff.js.map +0 -1
  214. package/dist/commands/global-status.d.ts +0 -9
  215. package/dist/commands/global-status.d.ts.map +0 -1
  216. package/dist/commands/global-status.js +0 -135
  217. package/dist/commands/global-status.js.map +0 -1
  218. package/dist/commands/graph.d.ts +0 -25
  219. package/dist/commands/graph.d.ts.map +0 -1
  220. package/dist/commands/graph.js +0 -523
  221. package/dist/commands/graph.js.map +0 -1
  222. package/dist/commands/handover.d.ts +0 -11
  223. package/dist/commands/handover.d.ts.map +0 -1
  224. package/dist/commands/handover.js +0 -170
  225. package/dist/commands/handover.js.map +0 -1
  226. package/dist/commands/health.d.ts +0 -7
  227. package/dist/commands/health.d.ts.map +0 -1
  228. package/dist/commands/health.js +0 -80
  229. package/dist/commands/health.js.map +0 -1
  230. package/dist/commands/history.d.ts +0 -9
  231. package/dist/commands/history.d.ts.map +0 -1
  232. package/dist/commands/history.js +0 -117
  233. package/dist/commands/history.js.map +0 -1
  234. package/dist/commands/impact.d.ts +0 -12
  235. package/dist/commands/impact.d.ts.map +0 -1
  236. package/dist/commands/impact.js +0 -238
  237. package/dist/commands/impact.js.map +0 -1
  238. package/dist/commands/import.d.ts +0 -19
  239. package/dist/commands/import.d.ts.map +0 -1
  240. package/dist/commands/import.js +0 -673
  241. package/dist/commands/import.js.map +0 -1
  242. package/dist/commands/knowledge.d.ts +0 -6
  243. package/dist/commands/knowledge.d.ts.map +0 -1
  244. package/dist/commands/knowledge.js +0 -94
  245. package/dist/commands/knowledge.js.map +0 -1
  246. package/dist/commands/lifecycle.d.ts +0 -9
  247. package/dist/commands/lifecycle.d.ts.map +0 -1
  248. package/dist/commands/lifecycle.js +0 -288
  249. package/dist/commands/lifecycle.js.map +0 -1
  250. package/dist/commands/merge-check.d.ts +0 -10
  251. package/dist/commands/merge-check.d.ts.map +0 -1
  252. package/dist/commands/merge-check.js +0 -183
  253. package/dist/commands/merge-check.js.map +0 -1
  254. package/dist/commands/notify.d.ts +0 -13
  255. package/dist/commands/notify.d.ts.map +0 -1
  256. package/dist/commands/notify.js +0 -63
  257. package/dist/commands/notify.js.map +0 -1
  258. package/dist/commands/rag-index.d.ts +0 -19
  259. package/dist/commands/rag-index.d.ts.map +0 -1
  260. package/dist/commands/rag-index.js +0 -286
  261. package/dist/commands/rag-index.js.map +0 -1
  262. package/dist/commands/recommend.d.ts +0 -13
  263. package/dist/commands/recommend.d.ts.map +0 -1
  264. package/dist/commands/recommend.js +0 -37
  265. package/dist/commands/recommend.js.map +0 -1
  266. package/dist/commands/refresh.d.ts +0 -21
  267. package/dist/commands/refresh.d.ts.map +0 -1
  268. package/dist/commands/refresh.js +0 -211
  269. package/dist/commands/refresh.js.map +0 -1
  270. package/dist/commands/rollback.d.ts +0 -8
  271. package/dist/commands/rollback.d.ts.map +0 -1
  272. package/dist/commands/rollback.js +0 -113
  273. package/dist/commands/rollback.js.map +0 -1
  274. package/dist/commands/status.d.ts +0 -7
  275. package/dist/commands/status.d.ts.map +0 -1
  276. package/dist/commands/status.js +0 -262
  277. package/dist/commands/status.js.map +0 -1
  278. package/dist/commands/trace.d.ts +0 -12
  279. package/dist/commands/trace.d.ts.map +0 -1
  280. package/dist/commands/trace.js +0 -163
  281. package/dist/commands/trace.js.map +0 -1
  282. package/dist/commands/tracker.d.ts +0 -2
  283. package/dist/commands/tracker.d.ts.map +0 -1
  284. package/dist/commands/tracker.js +0 -28
  285. package/dist/commands/tracker.js.map +0 -1
  286. package/dist/commands/verdict.d.ts +0 -16
  287. package/dist/commands/verdict.d.ts.map +0 -1
  288. package/dist/commands/verdict.js +0 -189
  289. package/dist/commands/verdict.js.map +0 -1
  290. package/dist/commands/workspace.d.ts +0 -20
  291. package/dist/commands/workspace.d.ts.map +0 -1
  292. package/dist/commands/workspace.js +0 -142
  293. package/dist/commands/workspace.js.map +0 -1
  294. package/dist/core/constraint-set.d.ts +0 -67
  295. package/dist/core/constraint-set.d.ts.map +0 -1
  296. package/dist/core/constraint-set.js +0 -151
  297. package/dist/core/constraint-set.js.map +0 -1
  298. package/dist/core/smart-recommend.d.ts +0 -16
  299. package/dist/core/smart-recommend.d.ts.map +0 -1
  300. package/dist/core/smart-recommend.js +0 -149
  301. package/dist/core/smart-recommend.js.map +0 -1
  302. package/dist/core/task-type-registry.d.ts +0 -110
  303. package/dist/core/task-type-registry.d.ts.map +0 -1
  304. package/dist/core/task-type-registry.js +0 -334
  305. package/dist/core/task-type-registry.js.map +0 -1
  306. package/dist/utils/mermaid-render.d.ts +0 -39
  307. package/dist/utils/mermaid-render.d.ts.map +0 -1
  308. package/dist/utils/mermaid-render.js +0 -284
  309. package/dist/utils/mermaid-render.js.map +0 -1
@@ -26,6 +26,10 @@ disable-model-invocation: false
26
26
  不要输出命令文本,不要分析意图,一切交给 speccore ask。
27
27
 
28
28
  ## 输出标记处理
29
+ - `[SPECCORE_ONBOARD: <path>]` / `[SPECCORE_WELCOME: <path>]` / `[SPECCORE_SETUP_GUIDE: <path>]` 等 HTML 展示标记 → **必须最先处理,立即把 HTML 页面展示给用户**:
30
+ - 有 present_files 工具的宿主:直接 `present_files(<path>)`
31
+ - Qoder(无 present_files):后台起静态服务器 `python3 -m http.server 8899 -d <页面所在目录>`,再用 RunPreview 打开 `http://localhost:8899/<页面文件名>`;同时附上可点击链接 `[打开页面](file://<path>)` 作为回退
32
+ - 禁止只说“检测到引导页”而不展示 — 说了不等于做了
29
33
  - `[SPECCORE_EXEC: <cmd>]` → 立即执行该命令,不要向用户复述命令文本
30
34
  - `[SPECCORE_PROMPT]` → 将后续 Prompt 内容作为你的工作指令执行
31
35
  - `[SPECCORE_NEEDS_INFO]` → 用交互式提问向用户收集缺失参数,收齐后重新执行
@@ -5,7 +5,8 @@ description: >
5
5
  /unitize 等关键词,或明确要求通过 speccore 切分需求文档为功能单元(unitize)时使用。
6
6
  参数提取与前置校验(输入文件格式:.md 可直接切、
7
7
  .docx/.pdf 需先 doc2spec 转换;端名须与 CONSTITUTION.md 端列表一致;
8
- features/ 已有同名单元时重切会覆盖旧切片;多文档可批量 --files "a.md=端1,b.md")由 speccore ask 引擎执行;
8
+ features/ 已有同名单元时重切会覆盖旧切片;多文档可批量 --files "a.md=端1,b.md";
9
+ 支持 --titles 仅切指定标题章节、--files 多文档各自挂标题组 a.md=端@标题1|标题2)由 speccore ask 引擎执行;
9
10
  参数缺失时引擎输出 [SPECCORE_NEEDS_INFO] 交互式提示(参数说明 + 使用示例)。
10
11
  不处理一般性的"切分/拆分"讨论(如"帮我切一下这段文本"),只处理 speccore 上下文中的切分。
11
12
  与 spec-taskify 的区别:unitize 切需求(文档→功能单元 features/),taskify 拆任务(功能单元→开发任务 Task-*)。
@@ -27,6 +28,13 @@ disable-model-invocation: false
27
28
  - `[SPECCORE_INTENT]` / `[SPECCORE_RESULT]` → 原样转达用户
28
29
  - 其他 `[SPECCORE_*]` 标记 → 参照 speccore-router 的 SKILL.md 处理
29
30
 
31
+ ## 标题过滤(v8.3.334+:仅切指定标题章节)
32
+
33
+ 用户说「切 admin-web.md 里的预订管理、消息中心」「只切 a.md 的订单确认和 b.md 的扫码签到」时,ask 引擎自动提取文档与标题组合生成命令,无需宿主改写:
34
+ - 单文档:speccore unitize --file x.md --titles "标题1,标题2"
35
+ - 多文档各自标题:--files "a.md=端1@标题1|标题2,b.md=端2@标题3"
36
+ - 匹配语义:模糊包含(「预订管理」命中「3.1 预订管理」),未命中标题 CLI 会警告;全局章节不受过滤影响照常归 overview/
37
+
30
38
  ## 英译接力剧本(宿主 AI 接手翻译)
31
39
 
32
40
  unitize 执行时(auto 默认;v8.3.289+ auto 模式会消费 auto_host_ai 配置),若当前环境无直连 LLM(无 providers 池/SPECCORE_LLM_KEY/OPENAI_API_KEY),且项目处于宿主模式(ai.provider=host 或 auto_host_ai: true),CLI 会:
@@ -23,18 +23,21 @@ allowed-tools: ["Bash", "Read", "Write", "Edit"]
23
23
 
24
24
  执行任何 `speccore` 命令后,检查 stdout 中的标记:
25
25
  - `[SPECCORE_ONBOARD: <path>]` → **🚨 必须最先处理,不可跳过,不可只口头提及**:
26
- 1. **立即执行** `present_files(<path>)` 展示 HTML 引导页(Qoder/Trae/Cursor 均支持)
26
+ 1. **立即展示 HTML 引导页给用户**,按宿主环境选择方式:
27
+ - **有 present_files 工具的宿主**(Trae/Cursor 等):直接 `present_files(<path>)`
28
+ - **Qoder(无 present_files)**:后台起静态服务器 `python3 -m http.server 8899 -d <页面所在目录>`,再用 RunPreview 打开 `http://localhost:8899/<页面文件名>`;同时附上可点击链接 `[打开页面](file://<path>)` 作为回退
27
29
  2. ❌ 禁止只说“检测到引导页”而不执行展示动作 — 说了不等于做了
28
30
  3. ❌ 禁止用文字描述引导页内容代替实际展示 — 必须让用户看到 HTML 页面
29
31
  4. **展示完成后**,再继续处理其他输出
30
- - `[SPECCORE_SETUP_GUIDE: <path>]` → **立即执行** `present_files(<path>)` 展示配置引导页
31
- - `[SPECCORE_ABOUT: <path>]` → **立即执行** `present_files(<path>)` 展示版本信息页
32
- - `[SPECCORE_HELP: <path>]` → **立即执行** `present_files(<path>)` 展示帮助中心页
33
- - `[SPECCORE_WELCOME: <path>]` → **立即执行** `present_files(<path>)` 展示项目名片页
34
- - `[SPECCORE_KNOWLEDGE: <path>]` → **立即执行** `present_files(<path>)` 展示知识图谱页
35
- - `[SPECCORE_PLAN: <path>]` → **立即执行** `present_files(<path>)` 展示执行计划页
36
- - `[SPECCORE_RETRO: <path>]` → **立即执行** `present_files(<path>)` 展示回顾报告页
37
- - `[SPECCORE_DASHBOARD: <path>]` → **立即执行** `present_files(<path>)` 展示仪表盘页
32
+ - `[SPECCORE_SETUP_GUIDE: <path>]` → **立即展示配置引导页**(方式同上,Qoder 用静态服务器 + RunPreview)
33
+ - `[SPECCORE_ABOUT: <path>]` → **立即展示版本信息页**(方式同上)
34
+ - `[SPECCORE_HELP: <path>]` → **立即展示帮助中心页**(方式同上)
35
+ - `[SPECCORE_WELCOME: <path>]` → **立即展示项目名片页**(方式同上)
36
+ - `[SPECCORE_KNOWLEDGE: <path>]` → **立即展示知识图谱页**(方式同上)
37
+ - `[SPECCORE_PLAN: <path>]` → **立即展示执行计划页**(方式同上)
38
+ - `[SPECCORE_RETRO: <path>]` → **立即展示回顾报告页**(方式同上)
39
+ - `[SPECCORE_DASHBOARD: <path>]` → **立即展示仪表盘页**(方式同上)
40
+ - `[SPECCORE_PROMPTS: <path>]` → **立即展示提示词库页**(方式同上)
38
41
  - `[SPECCORE_EXEC: <cmd>]` → 直接 `execute_command` 执行
39
42
  - `[SPECCORE_PROMPT]` → 将后续 Prompt 内容作为你的工作指令执行(不要改写、不要略过)
40
43
  - `[SPECCORE_NEEDS_INFO]` → 用交互式提问向用户收集缺失参数,收齐后重新执行
@@ -278,8 +281,6 @@ allowed-tools: ["Bash", "Read", "Write", "Edit"]
278
281
  | 合规检查 | iter? | `speccore validate -I {iter}` |
279
282
  | 搜索 "{keyword}" | keyword | `speccore search "{keyword}"` |
280
283
  | 全局搜索 "{keyword}" | keyword | `speccore search "{keyword}" --global` |
281
- | 追溯 {req} | req | `speccore track --req {req}` |
282
- | 影响分析 {req} | req | `speccore impact --req {req}` |
283
284
 
284
285
  ### 知识库与索引
285
286
  | 用户说法 | 提取参数 | CLI 命令 |
package/README.en.md CHANGED
@@ -158,14 +158,6 @@ speccore ask "from analyze to develop" # → run --from analyze --to ex
158
158
 
159
159
  One "spec once" phrase packs the whole requirement-to-deploy chain into a single session: entry (feature units / doc path / one-liner) → clarify → analyze → taskify → execute → local smoke → deploy verification. **Dual mode**: interactive by default (pauses at every node); say "full-auto / don't stop" to switch to auto mode (pauses only at three safety points: scope confirmation, quality-gate failure, smoke failure). Unsatisfied with a step? **Roll back and rerun**: re-analyze (`analyze --unit` overwrite + backup), re-taskify (`taskify --modules`), re-execute (`execute` single task), re-unitize (`unitize --on-duplicate`). Best for a few feature units (≤3); larger scope goes through `speccore run`.
160
160
 
161
- ### 🧠 Knowledge graph & code graph
162
-
163
- ```bash
164
- speccore graph query "order-related code" # natural-language query
165
- speccore graph path Task-001 Task-002 # shortest dependency path
166
- speccore knowledge # interactive HTML graph
167
- ```
168
-
169
161
  ### 📊 Dashboard
170
162
 
171
163
  `speccore dashboard` generates a Jira-standard 7-dimension board.
@@ -198,9 +190,9 @@ speccore verify -t Task-001 --ui
198
190
  | Finishing | `pipeline` `pr` `done` `spec2doc` |
199
191
  | Status / nav | `status` `next` `dashboard` `progress` |
200
192
  | Init / config | `init` `config` `doctor` `update` |
201
- | Management | `units` `pattern` `rollback` `history` `baseline` `rename` `cleanup` |
202
- | Change / special | `change` `retro` `verdict` `review` `sync` |
203
- | Knowledge | `graph` `knowledge` `query` `entity` `related` `path` `search` `stats` |
193
+ | Management | `units` `pattern` `rename` `cleanup` |
194
+ | Change / special | `change` `retro` `review` `sync` |
195
+ | Knowledge | `search` |
204
196
 
205
197
  ---
206
198
 
package/README.md CHANGED
@@ -159,16 +159,6 @@ speccore ask "分析本迭代需求,跳过澄清" # → analyze --skip-cla
159
159
 
160
160
  一句「spec once」把需求到部署整条链装进一次会话:需求入口(功能单元 / 文档地址 / 一句话需求)→ 澄清 → 分析 → 拆分任务 → 开发 → 本地冒烟 → 部署验证。**双模式**:默认人机交互(每个节点停下确认),说「全自动/别停」切全自动(仅范围确认、质量门禁失败、冒烟失败三个安全点停下)。哪一步不满意可**回退重跑**:重分析(`analyze --unit` 覆盖+备份)、重拆(`taskify --modules`)、重执行(`execute` 单任务)、重切(`unitize --on-duplicate`)。适合少量功能单元(≤3)的快速闭环,大范围走 `speccore run` 流水线。
161
161
 
162
- ### 🧠 知识图谱 & 代码图谱
163
-
164
- `speccore graph` 统一查询(知识 + 代码),`speccore knowledge` 可视化图谱:
165
-
166
- ```bash
167
- speccore graph query "订单相关代码" # 自然语言查询
168
- speccore graph path Task-001 Task-002 # 最短依赖路径
169
- speccore knowledge # 交互式 HTML 知识图谱
170
- ```
171
-
172
162
  ### 📊 仪表盘
173
163
 
174
164
  `speccore dashboard` 生成 Jira 标准 7 维度看板(需求状态 / 项目健康度 / 进度条)。
@@ -220,9 +210,9 @@ speccore run --skip-smoke # 单次跳过冒烟
220
210
  | 收尾 | `pipeline` `pr` `done` `spec2doc` |
221
211
  | 状态 / 导航 | `status` `next` `dashboard` `progress` |
222
212
  | 初始化 / 配置 | `init` `config` `doctor` `update` |
223
- | 管理工具 | `units` `pattern` `rollback` `history` `baseline` `rename` `cleanup` |
224
- | 变更 / 专项 | `change` `retro` `verdict` `review` `sync` |
225
- | 知识检索 | `graph` `knowledge` `query` `entity` `related` `path` `search` `stats` |
213
+ | 管理工具 | `units` `pattern` `rename` `cleanup` |
214
+ | 变更 / 专项 | `change` `retro` `review` `sync` |
215
+ | 知识检索 | `search` |
226
216
 
227
217
  > 💡 **全命令 Skill**:所有命令均支持 `/命令 + 自然语言` 快捷入口,如 `/deploy 部署到测试环境`、`/verify 跑冒烟测试`。
228
218
 
package/dist/cli.js CHANGED
@@ -58,36 +58,23 @@ const execute_1 = require("./commands/execute");
58
58
  const ask_1 = require("./commands/ask");
59
59
  const about_1 = require("./commands/about");
60
60
  const doctor_1 = require("./commands/doctor");
61
- const notify_1 = require("./commands/notify");
62
- const recommend_1 = require("./commands/recommend");
63
61
  const change_1 = require("./commands/change");
64
62
  const sync_1 = require("./commands/sync");
65
- const history_1 = require("./commands/history");
66
63
  const pattern_1 = require("./commands/pattern");
67
64
  const global_1 = require("./commands/global");
68
- const rollback_1 = require("./commands/rollback");
69
- const handover_1 = require("./commands/handover");
70
65
  const help_1 = require("./commands/help");
71
66
  const run_1 = require("./commands/run");
72
67
  const next_1 = require("./commands/next");
73
68
  const welcome_1 = require("./commands/welcome");
74
69
  const status_panel_1 = require("./commands/status-panel");
75
- const knowledge_1 = require("./commands/knowledge");
76
- const graph_1 = require("./commands/graph");
77
70
  const doc2spec_1 = require("./commands/doc2spec");
78
71
  const unitize_1 = require("./commands/unitize");
79
72
  const spec2doc_1 = require("./commands/spec2doc");
80
73
  const units_1 = require("./commands/units");
81
- const code_index_1 = require("./commands/code-index");
82
- const rag_index_1 = require("./commands/rag-index");
83
- const refresh_1 = require("./commands/refresh");
84
74
  // 全量层命令
85
75
  const iteration_from_global_1 = require("./commands/iteration-from-global");
86
76
  const sync_global_1 = require("./commands/sync-global");
87
77
  // P0/P1/P2 新增命令
88
- const impact_1 = require("./commands/impact");
89
- const baseline_1 = require("./commands/baseline");
90
- const audit_1 = require("./commands/audit");
91
78
  const analyze_1 = require("./commands/analyze");
92
79
  const req_doc_1 = require("./commands/req-doc");
93
80
  const pr_1 = require("./commands/pr");
@@ -97,8 +84,6 @@ const pipeline_1 = require("./commands/pipeline");
97
84
  const constitution_builder_1 = require("./core/constitution-builder");
98
85
  const context_output_1 = require("./commands/context-output");
99
86
  const done_1 = require("./commands/done");
100
- const verdict_1 = require("./commands/verdict");
101
- const workspace_1 = require("./commands/workspace");
102
87
  // rename 命令
103
88
  const rename_1 = require("./commands/rename");
104
89
  const retro_1 = require("./commands/retro");
@@ -106,9 +91,6 @@ const reindex_1 = require("./commands/reindex");
106
91
  const update_1 = require("./commands/update");
107
92
  const migrate_1 = require("./commands/migrate");
108
93
  const completion_1 = require("./commands/completion");
109
- const diff_1 = require("./commands/diff");
110
- const trace_1 = require("./commands/trace");
111
- const merge_check_1 = require("./commands/merge-check");
112
94
  const delete_1 = require("./commands/delete");
113
95
  const search_1 = require("./commands/search");
114
96
  const prompts_1 = require("./commands/prompts");
@@ -207,66 +189,6 @@ commander_1.program
207
189
  .option('--scope <scope>', '视图: iteration(默认/当前迭代) | global(全量)', 'iteration')
208
190
  .option('--group-by <key>', '任务分组维度: feature(按功能模块分组列出清单)')
209
191
  .action(status_panel_1.statusPanelCommand);
210
- commander_1.program
211
- .command('knowledge')
212
- .alias('kg')
213
- .description('知识图谱可视化:交互式图谱 + 衰减检测 + RAG 上下文预览')
214
- .option('-i, --iteration <iteration>', 'Target iteration')
215
- .option('--export <path>', 'Export HTML to custom path')
216
- .action(knowledge_1.knowledgeCommand);
217
- // v8.3.186+: knowledge-explain/path/query 已合并到 graph 子命令(graph 是超集,融合知识图谱+代码图谱)
218
- const graphCmd = commander_1.program
219
- .command('graph')
220
- .alias('g')
221
- .description('统一图谱查询:融合知识图谱 + 代码图谱');
222
- graphCmd
223
- .command('query <question>')
224
- .alias('q')
225
- .description('自然语言查询两种图谱(默认启用 LLM 语义增强)')
226
- .option('-t, --type <type>', '查询范围: all | knowledge | code', 'all')
227
- .option('-l, --limit <n>', '最多返回结果数', '10')
228
- .option('--smart', '启用 LLM 语义增强(默认开启)', true)
229
- .option('--fast', '快速模式,跳过 LLM 语义增强')
230
- .action((question, opts) => (0, graph_1.graphQueryCommand)(question, {
231
- type: opts.type,
232
- limit: parseInt(opts.limit, 10),
233
- smart: opts.fast ? false : opts.smart !== false,
234
- }));
235
- graphCmd
236
- .command('entity <id>')
237
- .alias('e')
238
- .description('查询特定实体详情')
239
- .option('-t, --type <type>', '查询范围: all | knowledge | code', 'all')
240
- .action((id, opts) => (0, graph_1.graphEntityCommand)(id, { type: opts.type }));
241
- graphCmd
242
- .command('related <id>')
243
- .alias('r')
244
- .description('查询实体的关联实体(一阶邻居)')
245
- .action((id) => (0, graph_1.graphRelatedCommand)(id, {}));
246
- graphCmd
247
- .command('path <from> <to>')
248
- .alias('p')
249
- .description('查找两实体间的最短路径')
250
- .option('-t, --type <type>', '查询范围: all | knowledge | code', 'all')
251
- .action((from, to, opts) => (0, graph_1.graphPathCommand)(from, to, { type: opts.type }));
252
- graphCmd
253
- .command('stats')
254
- .alias('s')
255
- .description('输出两种图谱的统计信息')
256
- .option('-t, --type <type>', '统计范围: all | knowledge | code', 'all')
257
- .action((opts) => (0, graph_1.graphStatsCommand)({ type: opts.type }));
258
- graphCmd
259
- .command('render [file]')
260
- .alias('r')
261
- .description('渲染 Mermaid 图表为 HTML(支持 .mmd 文件或从 Markdown 提取)')
262
- .option('--all', '批量渲染 diagrams/ 目录下所有 .mmd')
263
- .option('--extract', '从 Markdown 文件提取 Mermaid 代码块')
264
- .option('-o, --output <dir>', '输出目录')
265
- .action((file, opts) => (0, graph_1.graphRenderCommand)(file, {
266
- all: opts.all,
267
- extract: opts.extract,
268
- output: opts.output,
269
- }));
270
192
  commander_1.program
271
193
  .command('next')
272
194
  .alias('n')
@@ -546,7 +468,7 @@ commander_1.program
546
468
  .option('--backend', '仅后端任务(自动识别项目中的后端端名)')
547
469
  .option('--frontend', '仅前端任务(自动识别项目中的前端端名)')
548
470
  .option('--platform <platform>', '按端过滤(工程标识,如 CONSTITUTION.md 端列表中的端名)')
549
- .option('--module <module>', '按所属功能模块筛选(如 支付,匹配 .meta/feature)')
471
+ .option('--module <modules>', '按所属功能模块/模块目录名筛选(逗号分隔多值,模糊匹配,如 "支付,订单")')
550
472
  .option('--plan <id>', 'Execute a saved plan (from speccore plan --list)')
551
473
  .option('--interactive', 'Interactive selection')
552
474
  .option('--dry-run', 'Preview execution plan')
@@ -702,14 +624,6 @@ commander_1.program
702
624
  const { verifyCommand } = await Promise.resolve().then(() => __importStar(require('./commands/verify')));
703
625
  return verifyCommand(options);
704
626
  });
705
- // 源码索引
706
- (0, code_index_1.registerCodeIndexCommand)(commander_1.program);
707
- // RAG 索引管理
708
- (0, rag_index_1.registerRagIndexCommand)(commander_1.program);
709
- // 统一刷新所有检索层
710
- (0, refresh_1.registerRefreshCommand)(commander_1.program);
711
- (0, notify_1.registerNotifyCommand)(commander_1.program);
712
- (0, recommend_1.registerRecommendCommand)(commander_1.program);
713
627
  // 全量索引重建与一致性检查
714
628
  commander_1.program
715
629
  .command('reindex')
@@ -758,15 +672,6 @@ commander_1.program
758
672
  // ================================================================
759
673
  // 📦 归档与交接
760
674
  // ================================================================
761
- commander_1.program;
762
- commander_1.program
763
- .command('handover')
764
- .alias('ho')
765
- .description('Generate handover documentation for current iteration')
766
- .option('-i, --iteration <iteration>', 'Target iteration')
767
- .option('-o, --output <path>', 'Output file path')
768
- .option('--format <format>', 'Output format: md', 'md')
769
- .action(handover_1.handoverCommand);
770
675
  commander_1.program
771
676
  .command('archive')
772
677
  .alias('ar')
@@ -803,7 +708,7 @@ commander_1.program
803
708
  // --arch: 委托给 arch-update 逻辑
804
709
  const it = await require('../core/context').getDefaultIteration(opts.iteration);
805
710
  if (it)
806
- await (0, merge_check_1.updateArchitecture)(it, (opts.apis || '').split(',').filter(Boolean), (opts.tables || '').split(',').filter(Boolean));
711
+ await (0, update_1.updateArchitecture)(it, (opts.apis || '').split(',').filter(Boolean), (opts.tables || '').split(',').filter(Boolean));
807
712
  return;
808
713
  }
809
714
  return (0, update_1.updateCommand)(opts);
@@ -864,6 +769,7 @@ commander_1.program
864
769
  .option('--task <task>', '导入到指定 Task 目录')
865
770
  .option('--files <files>', '批量: "a.docx=平台1,b.pdf=平台2"')
866
771
  .option('--no-ai', '纯 pandoc 机械转换(终端快速模式)')
772
+ .option("--normalize", "按 SpecCore 标准标题体系重写标题(AI 语义调整,默认关闭;调整前版本快照 backup/)")
867
773
  .option("--prompt", "输出验证 Prompt 到 stdout(Skill 协作模式)")
868
774
  .option("--response <response>", "接收 AI 修正内容写入文件")
869
775
  .option("--classify", "AI 智能分类 sources/ 文档 → staging/(按类型提取)")
@@ -877,9 +783,10 @@ commander_1.program
877
783
  .alias('unitz')
878
784
  .description('切分需求文档为功能单元 → features/(独立能力;拆任务用 taskify)')
879
785
  .option('-f, --file <path>', '需求文档路径(.md,通常为 converted/*.md)')
880
- .option('--files <files>', '批量: "a.md=平台1,b.md=平台2"')
786
+ .option('--files <files>', '批量: "a.md=平台1,b.md=平台2"(v8.3.334+ 支持 a.md=端@标题1|标题2 仅切指定标题)')
881
787
  .option('-c, --content <text>', '直接切分一段文档内容(自动写入 converted/,配合 --title 指定文档名)')
882
788
  .option('--title <name>', '内容切分时的文档标题/文件名(配合 --content;缺省取内容首个 H1)')
789
+ .option('--titles <names>', '仅切分指定标题的章节(逗号/顿号分隔标题名,模糊包含匹配;配合 --file/--files/--content)')
883
790
  .option('-i, --iter <name>', '目标迭代(缺省用当前活跃迭代)')
884
791
  .option('-p, --platform <name>', '平台标识(端名,缺省由 analyze 端推断)')
885
792
  .option("--translate-en <mode>", "单元标题英译: auto(默认) | host | off")
@@ -928,46 +835,8 @@ commander_1.program
928
835
  .option('--force', 'Overwrite existing pattern')
929
836
  .action(pattern_1.patternCommand);
930
837
  // ================================================================
931
- // 🔙 回滚
932
- // ================================================================
933
- commander_1.program
934
- .command('rollback')
935
- .alias('rb')
936
- .description('Restore Spec files from .bak backups')
937
- .option('-t, --task <task>', 'Target task')
938
- .option('-i, --iteration <iteration>', 'Target iteration')
939
- .option('--list', 'List backups only, do not restore')
940
- .option('--confirm', 'Confirm restore (required to execute)')
941
- .action(rollback_1.rollbackCommand);
942
- commander_1.program
943
- .command('history')
944
- .alias('hi')
945
- .description('📜 历史记录:默认显示操作日志,--req 查看需求变更历史')
946
- .option('--req <reqId>', '需求 ID,查看指定需求的变更历史')
947
- .action(history_1.historyCommand);
948
- commander_1.program;
949
- // ================================================================
950
838
  // 🔗 P0/P1/P2 新增命令
951
839
  // ================================================================
952
- commander_1.program
953
- .command('impact')
954
- .alias('if')
955
- .description('Intelligent impact analysis: analyze upstream/downstream effects of changes')
956
- .option('--req <id>', 'Requirement ID (e.g., REQ-001)')
957
- .option('--task <id>', 'Task ID (e.g., Task-001)')
958
- .option('--depth <n>', 'Trace depth (default: 3)', '3')
959
- .option('--output <format>', 'Output format: report, graph', 'report')
960
- .action(impact_1.impactCommand);
961
- commander_1.program
962
- .command('baseline')
963
- .alias('bl')
964
- .description('Version baseline: create snapshots, compare, list, and rollback')
965
- .option('--name <name>', 'Baseline name')
966
- .option('--list', 'List all baselines')
967
- .option('--compare <name>', 'Compare current state with baseline')
968
- .option('--restore <name>', 'Restore to baseline')
969
- .option('--req <id>', 'Requirement ID for rollback')
970
- .action(baseline_1.baselineCommand);
971
840
  commander_1.program
972
841
  .command('analyze')
973
842
  .alias('al')
@@ -1093,25 +962,6 @@ commander_1.program
1093
962
  .action((input, opts) => {
1094
963
  (0, req_doc_1.reqDocCommand)({ ...opts, input });
1095
964
  });
1096
- commander_1.program
1097
- .command('workspace')
1098
- .alias('ws')
1099
- .description('管理临时工作区(list/show/clean)')
1100
- .option('--list', '列出所有条目(默认)')
1101
- .option('--show <entryId>', '查看条目详情')
1102
- .option('--clean', '清理旧条目')
1103
- .option('--days <n>', '清理天数阈值(默认 30)')
1104
- .option('--type <type>', '过滤类型: clarify | research')
1105
- .action(workspace_1.workspaceCommand);
1106
- commander_1.program
1107
- .command('audit')
1108
- .alias('ad')
1109
- .description('AI-powered audit: detect duplicates, ambiguity, and orphaned requirements')
1110
- .option('--fix', 'Auto-fix fixable issues')
1111
- .option('--detail', 'Show detailed analysis')
1112
- .option('--specs', 'Audit 020-specs/ quality: enum consistency, API path alignment, coverage gaps')
1113
- .option('-I, --iteration <name>', 'Target iteration for --specs audit')
1114
- .action(audit_1.auditCommand);
1115
965
  // 重命名
1116
966
  commander_1.program
1117
967
  .command('rename')
@@ -1155,45 +1005,11 @@ commander_1.program
1155
1005
  .option("--prompt", "输出验收总结 Prompt 到 stdout(Skill 协作模式)")
1156
1006
  .option("--response <response>", "接收 AI 验收总结")
1157
1007
  .action(done_1.doneCommand);
1158
- commander_1.program
1159
- .command('verdict')
1160
- .alias('vd')
1161
- .description('契约冲突裁决:查看冲突、人工裁决、查看裁决书')
1162
- .option('--list', '列出待裁决冲突')
1163
- .option('--conflict <id>', '指定冲突 ID 进行裁决')
1164
- .option('--decide <outcome>', '裁决结果: pass | pass-with-conditions | reject | defer')
1165
- .option('--reason <reason>', '裁决理由')
1166
- .option('--report <task>', '查看指定任务的裁决书')
1167
- .option('-t, --task <task>', '指定任务')
1168
- .option('-i, --iteration <iteration>', '指定迭代')
1169
- .action(verdict_1.verdictCommand);
1170
1008
  commander_1.program
1171
1009
  .command('completion [shell]')
1172
1010
  .alias('cmp')
1173
1011
  .description('Generate shell completion script (bash/zsh)')
1174
1012
  .action(completion_1.completionCommand);
1175
- commander_1.program
1176
- .command('diff')
1177
- .alias('df')
1178
- .description('Compare two iterations or baselines')
1179
- .requiredOption('--source <name>', 'Source iteration/baseline')
1180
- .requiredOption('--target <name>', 'Target iteration/baseline')
1181
- .action(diff_1.diffCommand);
1182
- commander_1.program
1183
- .command('merge-check')
1184
- .alias('mc')
1185
- .description('Predict merge conflicts across task branches')
1186
- .option('-i, --iteration <iteration>', 'Target iteration')
1187
- .action(async (options) => { const { getDefaultIteration } = await Promise.resolve().then(() => __importStar(require('./core/context'))); const it = await getDefaultIteration(options.iteration); if (it)
1188
- await (0, merge_check_1.mergeCheck)(it); });
1189
- commander_1.program
1190
- .command('track')
1191
- .alias('trk')
1192
- .description('REQ→Task→Code 全链路追踪')
1193
- .option('--req <id>', 'Trace from requirement ID')
1194
- .option('--task <id>', 'Trace from task ID')
1195
- .option('--full', 'Full project trace')
1196
- .action(trace_1.traceCommand);
1197
1013
  commander_1.program
1198
1014
  .command('delete')
1199
1015
  .alias('dl')
@@ -1262,7 +1078,40 @@ if (process.argv.length <= 2) {
1262
1078
  nextDesc = '需求分析';
1263
1079
  }
1264
1080
  else {
1265
- const tds = readdirSync(base).filter((d) => d.startsWith('Task-'));
1081
+ // v8.3.337+: 任务模块收集兼容新旧布局
1082
+ // (旧: 030-tasks/Task-* 或 Iteration 直接层;新: 030-tasks/{type}/{功能单元名})
1083
+ const { isTaskModuleDirName } = require('./core/task-paths');
1084
+ const { statSync } = require('fs');
1085
+ const collectModules = (dir, depth) => {
1086
+ const out = [];
1087
+ try {
1088
+ for (const d of readdirSync(dir)) {
1089
+ if (d.startsWith('.') || d.startsWith('_'))
1090
+ continue;
1091
+ const p = join(dir, d);
1092
+ let st;
1093
+ try {
1094
+ st = statSync(p);
1095
+ }
1096
+ catch {
1097
+ continue;
1098
+ }
1099
+ if (!st.isDirectory())
1100
+ continue;
1101
+ if (d.startsWith('Task-') || (depth <= 1 && isTaskModuleDirName(d)))
1102
+ out.push(p);
1103
+ else if (depth < 2)
1104
+ out.push(...collectModules(p, depth + 1));
1105
+ }
1106
+ }
1107
+ catch { }
1108
+ return out;
1109
+ };
1110
+ const tasksRoot = join(base, '030-tasks');
1111
+ let tds = existsSync(tasksRoot) ? collectModules(tasksRoot, 0) : [];
1112
+ if (tds.length === 0) {
1113
+ tds = readdirSync(base).filter((d) => d.startsWith('Task-')).map((d) => join(base, d));
1114
+ }
1266
1115
  if (tds.length === 0) {
1267
1116
  phase = 'taskify';
1268
1117
  nextCmd = 'speccore iteration taskify --iteration=' + iteration;
@@ -1270,36 +1119,45 @@ if (process.argv.length <= 2) {
1270
1119
  }
1271
1120
  else {
1272
1121
  total = tds.length;
1273
- for (const td of tds) {
1274
- // 扫描子目录中的 TASK.md 判断任务状态
1275
- const taskDirPath = join(base, td);
1276
- let found = false;
1277
- // 新结构: 扫描子目录中的 TASK.md
1122
+ // 递归探测 TASK.md(新旧子任务结构兼容,最多 4 层)
1123
+ const findDone = (dir, depth) => {
1278
1124
  try {
1279
- const subdirs = readdirSync(taskDirPath).filter((d) => !d.startsWith('.') && !d.startsWith('_') && !d.startsWith('9') &&
1280
- existsSync(join(taskDirPath, d)) &&
1281
- require('fs').statSync(join(taskDirPath, d)).isDirectory());
1282
- for (const sd of subdirs) {
1283
- const subTask = join(taskDirPath, sd, 'TASK.md');
1284
- if (existsSync(subTask) && readFileSync(subTask, 'utf-8').includes('已完成')) {
1285
- found = true;
1286
- break;
1125
+ for (const d of readdirSync(dir)) {
1126
+ if (d.startsWith('.') || d.startsWith('_'))
1127
+ continue;
1128
+ const p = join(dir, d);
1129
+ let st;
1130
+ try {
1131
+ st = statSync(p);
1132
+ }
1133
+ catch {
1134
+ continue;
1135
+ }
1136
+ if (st.isDirectory()) {
1137
+ if (depth < 4 && findDone(p, depth + 1))
1138
+ return true;
1139
+ }
1140
+ else if (d === 'TASK.md' && readFileSync(p, 'utf-8').includes('已完成')) {
1141
+ return true;
1287
1142
  }
1288
1143
  }
1289
1144
  }
1290
1145
  catch { }
1291
- if (found)
1146
+ return false;
1147
+ };
1148
+ for (const td of tds) {
1149
+ if (findDone(td, 0))
1292
1150
  done2++;
1293
1151
  }
1294
1152
  if (done2 < total) {
1295
1153
  phase = 'dev';
1296
- nextCmd = 'speccore execute --task=' + tds[done2] + ' --force';
1154
+ nextCmd = 'speccore execute --task=' + tds[done2].split('/').pop() + ' --force';
1297
1155
  nextDesc = '执行开发 (' + (done2 + 1) + '/' + total + ')';
1298
1156
  }
1299
1157
  else {
1300
1158
  phase = 'done';
1301
1159
  nextCmd = 'speccore pr';
1302
- nextDesc = '创建 PR 提交代码';
1160
+ nextDesc = '创建 PR 提交 代码';
1303
1161
  }
1304
1162
  }
1305
1163
  }