@gong-ym/ai-spec-auto 0.2.13 → 0.2.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.
Files changed (631) hide show
  1. package/.agents/commands/README.md +33 -33
  2. package/.agents/commands/claude/spec-start-review.md +88 -88
  3. package/.agents/commands/codex/spec-continue.md +74 -74
  4. package/.agents/commands/codex/spec-orchestrate.md +35 -35
  5. package/.agents/commands/codex/spec-start-review.md +88 -88
  6. package/.agents/commands/codex/spec-start.md +67 -67
  7. package/.agents/commands/codex/spec-status.md +22 -22
  8. package/.agents/commands/codex/spec-stop.md +29 -29
  9. package/.agents/commands/codex/spec-update.md +40 -40
  10. package/.agents/commands/common/branch-review.md +117 -117
  11. package/.agents/commands/common/project-init.md +25 -25
  12. package/.agents/commands/common/spec-continue.md +74 -74
  13. package/.agents/commands/common/spec-orchestrate.md +35 -35
  14. package/.agents/commands/common/spec-start-review.md +82 -82
  15. package/.agents/commands/common/spec-start.md +67 -67
  16. package/.agents/commands/common/spec-status.md +22 -22
  17. package/.agents/commands/common/spec-stop.md +29 -29
  18. package/.agents/commands/common/spec-update.md +60 -40
  19. package/.agents/commands/cursor/opsx-apply.md +55 -55
  20. package/.agents/commands/cursor/opsx-archive.md +48 -48
  21. package/.agents/commands/cursor/opsx-explore.md +45 -45
  22. package/.agents/commands/cursor/opsx-propose.md +59 -59
  23. package/.agents/commands/cursor/spec-continue.md +63 -63
  24. package/.agents/commands/cursor/spec-orchestrate.md +53 -53
  25. package/.agents/commands/cursor/spec-start-review.md +78 -78
  26. package/.agents/commands/cursor/spec-start.md +59 -59
  27. package/.agents/commands/cursor/spec-status.md +30 -30
  28. package/.agents/commands/cursor/spec-stop.md +29 -29
  29. package/.agents/commands/cursor/spec-update.md +41 -41
  30. package/.agents/flows/FRONTMATTER.md +263 -263
  31. package/.agents/flows/RUN_OUTPUT.md +263 -263
  32. package/.agents/flows/common/README.md +29 -29
  33. package/.agents/flows/common/bugfix-to-verification.md +95 -95
  34. package/.agents/flows/common/change-to-architecture-review.md +89 -89
  35. package/.agents/flows/common/change-to-release.md +94 -94
  36. package/.agents/flows/common/prd-to-delivery.md +184 -184
  37. package/.agents/flows/common/requirement-to-observability.md +97 -97
  38. package/.agents/orchestration/README.md +22 -22
  39. package/.agents/orchestration/expert-dispatch-spec.md +155 -155
  40. package/.agents/orchestration/expert-executor-spec.md +84 -84
  41. package/.agents/orchestration/expert-runtime-action-spec.md +73 -73
  42. package/.agents/orchestration/runtime-state-handoff-spec.md +264 -264
  43. package/.agents/orchestration/task-anchor-spec.md +212 -212
  44. package/.agents/orchestration/task-orchestrator-adapter-payload.md +153 -153
  45. package/.agents/orchestration/task-orchestrator-bootstrap-payload.md +145 -145
  46. package/.agents/orchestration/task-orchestrator-output-extractor-spec.md +93 -93
  47. package/.agents/orchestration/task-orchestrator-run-plan-template.md +312 -312
  48. package/.agents/orchestration/task-orchestrator-runtime-hooks.md +214 -214
  49. package/.agents/registry/README.md +63 -63
  50. package/.agents/registry/flows.json +125 -125
  51. package/.agents/registry/profiles.json +101 -101
  52. package/.agents/registry/roles.json +1265 -1265
  53. package/.agents/registry/rules.json +148 -148
  54. package/.agents/registry/scenario-packages.json +123 -123
  55. package/.agents/registry/skills.json +130 -130
  56. package/.agents/roles/INDEX.md +346 -346
  57. package/.agents/roles/common/README.md +76 -76
  58. package/.agents/roles/common/archive-change.md +80 -80
  59. package/.agents/roles/common/backend-implementer.md +92 -92
  60. package/.agents/roles/common/code-guardian.md +151 -151
  61. package/.agents/roles/common/frontend-implementer.md +146 -146
  62. package/.agents/roles/common/requirement-analyst.md +138 -138
  63. package/.agents/roles/common/task-orchestrator-routing.md +301 -301
  64. package/.agents/roles/common/task-orchestrator.md +224 -224
  65. package/.agents/roles/common/tooling-implementer.md +92 -92
  66. package/.agents/roles/domains/README.md +35 -35
  67. package/.agents/roles/domains/delivery/README.md +11 -11
  68. package/.agents/roles/domains/delivery/container-specialist.md +50 -50
  69. package/.agents/roles/domains/delivery/deployment-specialist.md +50 -50
  70. package/.agents/roles/domains/delivery/pipeline-specialist.md +50 -50
  71. package/.agents/roles/domains/demand-design/README.md +16 -16
  72. package/.agents/roles/domains/demand-design/api-contract-specialist.md +52 -52
  73. package/.agents/roles/domains/demand-design/design-collaborator.md +58 -58
  74. package/.agents/roles/domains/documentation/README.md +11 -11
  75. package/.agents/roles/domains/documentation/api-doc-specialist.md +50 -50
  76. package/.agents/roles/domains/documentation/component-doc-specialist.md +49 -49
  77. package/.agents/roles/domains/documentation/technical-writing-specialist.md +48 -48
  78. package/.agents/roles/domains/engineering/README.md +17 -17
  79. package/.agents/roles/domains/engineering/architecture-advisor.md +53 -53
  80. package/.agents/roles/domains/engineering/build-specialist.md +51 -51
  81. package/.agents/roles/domains/engineering/dependency-governor.md +52 -52
  82. package/.agents/roles/domains/governance/README.md +17 -17
  83. package/.agents/roles/domains/governance/api-governance-specialist.md +51 -51
  84. package/.agents/roles/domains/governance/lint-policy-specialist.md +49 -49
  85. package/.agents/roles/domains/governance/route-governance-specialist.md +52 -52
  86. package/.agents/roles/domains/observability/README.md +11 -11
  87. package/.agents/roles/domains/observability/error-tracker.md +50 -50
  88. package/.agents/roles/domains/observability/event-instrumentation-specialist.md +51 -51
  89. package/.agents/roles/domains/observability/rum-analyst.md +50 -50
  90. package/.agents/roles/domains/performance/README.md +11 -11
  91. package/.agents/roles/domains/performance/asset-optimizer.md +50 -50
  92. package/.agents/roles/domains/performance/performance-auditor.md +56 -56
  93. package/.agents/roles/domains/performance/vitals-analyst.md +50 -50
  94. package/.agents/roles/domains/security-a11y/README.md +11 -11
  95. package/.agents/roles/domains/security-a11y/a11y-auditor.md +50 -50
  96. package/.agents/roles/domains/security-a11y/aria-specialist.md +51 -51
  97. package/.agents/roles/domains/security-a11y/security-reviewer.md +49 -49
  98. package/.agents/roles/domains/testing/README.md +12 -12
  99. package/.agents/roles/domains/testing/coverage-analyst.md +50 -50
  100. package/.agents/roles/domains/testing/e2e-test-specialist.md +51 -51
  101. package/.agents/roles/domains/testing/unit-test-specialist.md +56 -56
  102. package/.agents/roles/domains/testing/verification-reviewer.md +67 -67
  103. package/.agents/rules/README.md +87 -87
  104. package/.agents/rules/common/02-/347/274/226/347/240/201/350/247/204/350/214/203.md +45 -45
  105. package/.agents/rules/common/08-/351/200/232/347/224/250/347/272/246/346/235/237.md +63 -63
  106. package/.agents/rules/common/10-/346/226/207/346/241/243/350/247/204/350/214/203.md +101 -101
  107. package/.agents/rules/common/12-Superpowers/346/211/247/350/241/214/350/247/204/350/214/203.md +46 -46
  108. package/.agents/rules/common/14-/345/256/241/350/256/241/346/261/207/346/212/245/350/247/204/350/214/203.md +107 -107
  109. package/.agents/rules/common/15-visual-gate-wait.md +90 -90
  110. package/.agents/rules/profiles/nestjs/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +27 -27
  111. package/.agents/rules/profiles/nestjs/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +20 -20
  112. package/.agents/rules/profiles/nestjs/04-/346/250/241/345/235/227/347/273/223/346/236/204/350/247/204/350/214/203.md +24 -24
  113. package/.agents/rules/profiles/nestjs/05-/346/216/245/345/217/243/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +24 -24
  114. package/.agents/rules/profiles/nestjs/06-/346/225/260/346/215/256/350/256/277/351/227/256/350/247/204/350/214/203.md +24 -24
  115. package/.agents/rules/profiles/nestjs/07-/351/205/215/347/275/256/344/270/216/350/277/220/350/241/214/346/227/266/350/247/204/350/214/203.md +20 -20
  116. package/.agents/rules/profiles/nestjs/09-/345/274/202/345/270/270/344/270/216/346/227/245/345/277/227/350/247/204/350/214/203.md +20 -20
  117. package/.agents/rules/profiles/nestjs/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +24 -24
  118. package/.agents/rules/profiles/nestjs/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +20 -20
  119. package/.agents/rules/profiles/node-tooling/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +30 -30
  120. package/.agents/rules/profiles/node-tooling/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +37 -37
  121. package/.agents/rules/profiles/node-tooling/04-CLI/344/270/216/346/250/241/345/235/227/350/247/204/350/214/203.md +42 -42
  122. package/.agents/rules/profiles/node-tooling/05-Contract/344/270/216Schema/350/247/204/350/214/203.md +42 -42
  123. package/.agents/rules/profiles/node-tooling/06-/350/277/220/350/241/214/346/227/266/346/226/207/344/273/266/350/247/204/350/214/203.md +30 -30
  124. package/.agents/rules/profiles/node-tooling/07-/346/227/245/345/277/227/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206/350/247/204/350/214/203.md +60 -60
  125. package/.agents/rules/profiles/node-tooling/09-/350/204/232/346/234/254/344/270/216/345/205/245/345/217/243/350/247/204/350/214/203.md +45 -45
  126. package/.agents/rules/profiles/node-tooling/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +41 -41
  127. package/.agents/rules/profiles/node-tooling/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +55 -55
  128. package/.agents/rules/profiles/react/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +29 -29
  129. package/.agents/rules/profiles/react/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +104 -104
  130. package/.agents/rules/profiles/react/04-/347/273/204/344/273/266/350/247/204/350/214/203.md +46 -46
  131. package/.agents/rules/profiles/react/05-API/350/247/204/350/214/203.md +67 -67
  132. package/.agents/rules/profiles/react/06-/350/267/257/347/224/261/350/247/204/350/214/203.md +54 -54
  133. package/.agents/rules/profiles/react/07-/347/212/266/346/200/201/347/256/241/347/220/206.md +226 -226
  134. package/.agents/rules/profiles/react/09-/346/240/267/345/274/217/350/247/204/350/214/203.md +71 -71
  135. package/.agents/rules/profiles/react/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +80 -80
  136. package/.agents/rules/profiles/react/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +159 -159
  137. package/.agents/rules/profiles/springboot/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +31 -31
  138. package/.agents/rules/profiles/springboot/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +37 -37
  139. package/.agents/rules/profiles/springboot/04-/345/210/206/345/261/202/350/247/204/350/214/203.md +33 -33
  140. package/.agents/rules/profiles/springboot/05-/346/216/245/345/217/243/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +51 -51
  141. package/.agents/rules/profiles/springboot/06-/346/225/260/346/215/256/350/256/277/351/227/256/350/247/204/350/214/203.md +34 -34
  142. package/.agents/rules/profiles/springboot/07-/351/205/215/347/275/256/344/270/216/350/277/220/350/241/214/346/227/266/350/247/204/350/214/203.md +38 -38
  143. package/.agents/rules/profiles/springboot/09-/345/274/202/345/270/270/344/270/216/346/227/245/345/277/227/350/247/204/350/214/203.md +48 -48
  144. package/.agents/rules/profiles/springboot/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +43 -43
  145. package/.agents/rules/profiles/springboot/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +48 -48
  146. package/.agents/rules/profiles/vue/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +47 -47
  147. package/.agents/rules/profiles/vue/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +106 -106
  148. package/.agents/rules/profiles/vue/04-/347/273/204/344/273/266/350/247/204/350/214/203.md +61 -61
  149. package/.agents/rules/profiles/vue/05-API/350/247/204/350/214/203.md +67 -67
  150. package/.agents/rules/profiles/vue/06-/350/267/257/347/224/261/350/247/204/350/214/203.md +69 -69
  151. package/.agents/rules/profiles/vue/07-/347/212/266/346/200/201/347/256/241/347/220/206.md +93 -93
  152. package/.agents/rules/profiles/vue/09-/346/240/267/345/274/217/350/247/204/350/214/203.md +67 -67
  153. package/.agents/rules/profiles/vue/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +80 -80
  154. package/.agents/rules/profiles/vue/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +159 -159
  155. package/.agents/skills/README.md +171 -171
  156. package/.agents/skills/common/archive-change/SKILL.md +180 -180
  157. package/.agents/skills/common/branch-code-reviewer/SKILL.md +533 -459
  158. package/.agents/skills/common/branch-code-reviewer/references/business-risk-guide.md +293 -293
  159. package/.agents/skills/common/branch-code-reviewer/references/html-template-guide.md +121 -121
  160. package/.agents/skills/common/config-and-secret-scan/SKILL.md +99 -99
  161. package/.agents/skills/common/create-proposal/SKILL.md +192 -192
  162. package/.agents/skills/common/create-proposal/evals/evals.json +16 -16
  163. package/.agents/skills/common/create-proposal/evals/train_queries.json +18 -18
  164. package/.agents/skills/common/create-proposal/evals/validation_queries.json +18 -18
  165. package/.agents/skills/common/create-proposal/references/interaction-spec-template.md +42 -42
  166. package/.agents/skills/common/create-test/SKILL.md +292 -292
  167. package/.agents/skills/common/dependency-impact-graph/SKILL.md +80 -80
  168. package/.agents/skills/common/execute-task/SKILL.md +206 -206
  169. package/.agents/skills/common/execute-task/evals/evals.json +16 -16
  170. package/.agents/skills/common/execute-task/evals/train_queries.json +18 -18
  171. package/.agents/skills/common/execute-task/evals/validation_queries.json +18 -18
  172. package/.agents/skills/common/find-skills/SKILL.md +144 -144
  173. package/.agents/skills/common/install-ai-spec-auto/SKILL.md +260 -260
  174. package/.agents/skills/common/install-ai-spec-auto/evals/evals.json +17 -17
  175. package/.agents/skills/common/install-ai-spec-auto/evals/train_queries.json +18 -18
  176. package/.agents/skills/common/install-ai-spec-auto/evals/validation_queries.json +18 -18
  177. package/.agents/skills/common/project-init/SKILL.md +178 -178
  178. package/.agents/skills/common/project-init/evals/evals.json +16 -16
  179. package/.agents/skills/common/project-init/evals/train_queries.json +18 -18
  180. package/.agents/skills/common/project-init/evals/validation_queries.json +18 -18
  181. package/.agents/skills/common/project-init/references/custom-rule-generation.md +89 -89
  182. package/.agents/skills/common/project-init/references/deep-scan-rules.md +67 -67
  183. package/.agents/skills/common/project-init/references/output-contracts.md +71 -71
  184. package/.agents/skills/common/project-init/references/repo-fact-gathering.md +83 -83
  185. package/.agents/skills/common/project-init/references/scope-resolution.md +76 -76
  186. package/.agents/skills/common/project-init/scripts/inspect-project.js +112 -112
  187. package/.agents/skills/common/skill-creator/LICENSE.txt +201 -201
  188. package/.agents/skills/common/skill-creator/SKILL.md +370 -370
  189. package/.agents/skills/common/skill-creator/evals/evals.json +16 -16
  190. package/.agents/skills/common/skill-creator/evals/train_queries.json +18 -18
  191. package/.agents/skills/common/skill-creator/evals/validation_queries.json +18 -18
  192. package/.agents/skills/common/skill-creator/references/output-patterns.md +82 -82
  193. package/.agents/skills/common/skill-creator/references/workflows.md +27 -27
  194. package/.agents/skills/common/skill-creator/scripts/init_skill.py +209 -209
  195. package/.agents/skills/common/skill-creator/scripts/package_skill.py +110 -110
  196. package/.agents/skills/common/skill-creator/scripts/quick_validate.py +51 -51
  197. package/.agents/skills/common/skill-optimizer/SKILL.md +102 -102
  198. package/.agents/skills/common/skill-optimizer/evals/evals.json +16 -16
  199. package/.agents/skills/common/skill-optimizer/evals/train_queries.json +18 -18
  200. package/.agents/skills/common/skill-optimizer/evals/validation_queries.json +18 -18
  201. package/.agents/skills/common/skill-optimizer/references/design-patterns.md +26 -26
  202. package/.agents/skills/common/skill-optimizer/references/review-checklist.md +22 -22
  203. package/.agents/skills/common/using-superpowers/SKILL.md +151 -151
  204. package/.agents/skills/common/wait-for-gate-signal/SKILL.md +85 -85
  205. package/.agents/skills/domains/README.md +19 -19
  206. package/.agents/skills/domains/ui-ux-pro-max/SKILL.md +58 -58
  207. package/.agents/skills/domains/web/design-analysis/SKILL.md +89 -89
  208. package/.agents/skills/domains/web/design-analysis/rules/analysis-order.md +61 -61
  209. package/.agents/skills/domains/web/design-analysis/rules/analysis-priorities.md +136 -136
  210. package/.agents/skills/domains/web/design-analysis/rules/checklist-common-misses.md +107 -107
  211. package/.agents/skills/domains/web/design-analysis/rules/implementation-common-errors.md +204 -204
  212. package/.agents/skills/domains/web/design-analysis/rules/implementation-guidelines.md +211 -211
  213. package/.agents/skills/domains/web/design-analysis/rules/output-analysis-checklist.md +247 -247
  214. package/.agents/skills/domains/web/design-analysis/rules/tools-design-guidelines.md +108 -108
  215. package/.agents/skills/domains/web/design-analysis/rules/workflow-element-extraction.md +162 -162
  216. package/.agents/skills/domains/web/design-analysis/rules/workflow-layout-map.md +131 -131
  217. package/.agents/skills/domains/web/design-analysis/rules/workflow-output-checklist.md +70 -70
  218. package/.agents/skills/domains/web/design-analysis/rules/workflow-style-summary.md +91 -91
  219. package/.agents/skills/domains/web/route-permission-map/SKILL.md +103 -103
  220. package/.agents/skills/domains/web/ui-verification/SKILL.md +114 -114
  221. package/.agents/skills/domains/web/ui-verification/evals/evals.json +16 -16
  222. package/.agents/skills/domains/web/ui-verification/evals/train_queries.json +18 -18
  223. package/.agents/skills/domains/web/ui-verification/evals/validation_queries.json +18 -18
  224. package/.agents/skills/domains/web/ui-verification/rules/comparison-content-image.md +34 -34
  225. package/.agents/skills/domains/web/ui-verification/rules/comparison-content-text.md +30 -30
  226. package/.agents/skills/domains/web/ui-verification/rules/comparison-hierarchy.md +33 -33
  227. package/.agents/skills/domains/web/ui-verification/rules/comparison-layout.md +35 -35
  228. package/.agents/skills/domains/web/ui-verification/rules/errors-alignment.md +42 -42
  229. package/.agents/skills/domains/web/ui-verification/rules/errors-button-dimensions.md +28 -28
  230. package/.agents/skills/domains/web/ui-verification/rules/errors-button-position.md +25 -25
  231. package/.agents/skills/domains/web/ui-verification/rules/errors-css-priority.md +50 -50
  232. package/.agents/skills/domains/web/ui-verification/rules/errors-flex-column-width.md +46 -46
  233. package/.agents/skills/domains/web/ui-verification/rules/errors-flex-layout.md +46 -46
  234. package/.agents/skills/domains/web/ui-verification/rules/errors-grid-container-width.md +44 -44
  235. package/.agents/skills/domains/web/ui-verification/rules/errors-page-container-width.md +39 -39
  236. package/.agents/skills/domains/web/ui-verification/rules/tools-browser-navigation.md +53 -53
  237. package/.agents/skills/domains/web/ui-verification/rules/tools-design-guidelines.md +53 -53
  238. package/.agents/skills/domains/web/ui-verification/rules/workflow-checklist.md +27 -27
  239. package/.agents/skills/domains/web/ui-verification/rules/workflow-problem-list.md +56 -56
  240. package/.agents/skills/domains/web/ui-verification/rules/workflow-reflection.md +44 -44
  241. package/.agents/skills/domains/web/ui-verification/rules/writing-alignment.md +44 -44
  242. package/.agents/skills/domains/web/ui-verification/rules/writing-element-completeness.md +63 -63
  243. package/.agents/skills/domains/web/ui-verification/rules/writing-list-layout.md +75 -75
  244. package/.agents/skills/domains/web/ui-verification/rules/writing-page-container-width.md +37 -37
  245. package/.agents/skills/domains/web/web-design-guidelines/SKILL.md +40 -40
  246. package/.agents/skills/profiles/nestjs/README.md +4 -4
  247. package/.agents/skills/profiles/node-tooling/README.md +9 -9
  248. package/.agents/skills/profiles/react/create-api/SKILL.md +145 -145
  249. package/.agents/skills/profiles/react/create-component/SKILL.md +160 -160
  250. package/.agents/skills/profiles/react/create-route/SKILL.md +168 -168
  251. package/.agents/skills/profiles/react/create-store/SKILL.md +262 -262
  252. package/.agents/skills/profiles/react/theme-variables/SKILL.md +82 -82
  253. package/.agents/skills/profiles/react/vercel-composition-patterns/AGENTS.md +899 -899
  254. package/.agents/skills/profiles/react/vercel-composition-patterns/SKILL.md +81 -81
  255. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -100
  256. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/architecture-compound-components.md +112 -112
  257. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -87
  258. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -100
  259. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-context-interface.md +191 -191
  260. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -113
  261. package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-lift-state.md +125 -125
  262. package/.agents/skills/profiles/react/vercel-react-best-practices/AGENTS.md +2934 -2934
  263. package/.agents/skills/profiles/react/vercel-react-best-practices/SKILL.md +136 -136
  264. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -55
  265. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-init-once.md +42 -42
  266. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-use-latest.md +39 -39
  267. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-api-routes.md +38 -38
  268. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-defer-await.md +80 -80
  269. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-dependencies.md +51 -51
  270. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-parallel.md +28 -28
  271. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -99
  272. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -59
  273. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-conditional.md +31 -31
  274. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -49
  275. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -35
  276. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-preload.md +50 -50
  277. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-event-listeners.md +74 -74
  278. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -71
  279. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -48
  280. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-swr-dedup.md +56 -56
  281. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -107
  282. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-function-results.md +80 -80
  283. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-property-access.md +28 -28
  284. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-storage.md +70 -70
  285. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-combine-iterations.md +32 -32
  286. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-early-exit.md +50 -50
  287. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -45
  288. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-index-maps.md +37 -37
  289. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-length-check-first.md +49 -49
  290. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-min-max-loop.md +82 -82
  291. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -24
  292. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -57
  293. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-activity.md +26 -26
  294. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -47
  295. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -40
  296. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -38
  297. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -46
  298. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -82
  299. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -30
  300. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -28
  301. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -75
  302. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -39
  303. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-dependencies.md +45 -45
  304. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -40
  305. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-derived-state.md +29 -29
  306. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -74
  307. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -58
  308. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -38
  309. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-memo.md +44 -44
  310. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -45
  311. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -35
  312. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-transitions.md +40 -40
  313. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -73
  314. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -73
  315. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-auth-actions.md +96 -96
  316. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-cache-lru.md +41 -41
  317. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-cache-react.md +76 -76
  318. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-dedup-props.md +65 -65
  319. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -83
  320. package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-serialization.md +38 -38
  321. package/.agents/skills/profiles/springboot/README.md +10 -10
  322. package/.agents/skills/profiles/vue/create-api/SKILL.md +105 -105
  323. package/.agents/skills/profiles/vue/create-component/SKILL.md +76 -76
  324. package/.agents/skills/profiles/vue/create-route/SKILL.md +141 -141
  325. package/.agents/skills/profiles/vue/create-store/SKILL.md +97 -97
  326. package/.agents/skills/profiles/vue/create-view/SKILL.md +81 -81
  327. package/.agents/skills/profiles/vue/theme-variables/SKILL.md +73 -73
  328. package/.agents/skills/profiles/vue/vue-best-practices/SKILL.md +166 -166
  329. package/.agents/skills/profiles/vue/vue-best-practices/references/animation-class-based-technique.md +254 -254
  330. package/.agents/skills/profiles/vue/vue-best-practices/references/animation-state-driven-technique.md +291 -291
  331. package/.agents/skills/profiles/vue/vue-best-practices/references/component-async.md +97 -97
  332. package/.agents/skills/profiles/vue/vue-best-practices/references/component-data-flow.md +307 -307
  333. package/.agents/skills/profiles/vue/vue-best-practices/references/component-fallthrough-attrs.md +174 -174
  334. package/.agents/skills/profiles/vue/vue-best-practices/references/component-keep-alive.md +137 -137
  335. package/.agents/skills/profiles/vue/vue-best-practices/references/component-slots.md +216 -216
  336. package/.agents/skills/profiles/vue/vue-best-practices/references/component-suspense.md +228 -228
  337. package/.agents/skills/profiles/vue/vue-best-practices/references/component-teleport.md +108 -108
  338. package/.agents/skills/profiles/vue/vue-best-practices/references/component-transition-group.md +128 -128
  339. package/.agents/skills/profiles/vue/vue-best-practices/references/component-transition.md +125 -125
  340. package/.agents/skills/profiles/vue/vue-best-practices/references/composables.md +290 -290
  341. package/.agents/skills/profiles/vue/vue-best-practices/references/directives.md +162 -162
  342. package/.agents/skills/profiles/vue/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -159
  343. package/.agents/skills/profiles/vue/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -182
  344. package/.agents/skills/profiles/vue/vue-best-practices/references/perf-virtualize-large-lists.md +187 -187
  345. package/.agents/skills/profiles/vue/vue-best-practices/references/plugins.md +166 -166
  346. package/.agents/skills/profiles/vue/vue-best-practices/references/reactivity.md +344 -344
  347. package/.agents/skills/profiles/vue/vue-best-practices/references/render-functions.md +201 -201
  348. package/.agents/skills/profiles/vue/vue-best-practices/references/sfc.md +310 -310
  349. package/.agents/skills/profiles/vue/vue-best-practices/references/state-management.md +135 -135
  350. package/.agents/skills/profiles/vue/vue-best-practices/references/updated-hook-performance.md +187 -187
  351. package/.agents/templates/common/README.md +23 -23
  352. package/.agents/templates/common/bugfix.md +22 -22
  353. package/.agents/templates/common/create-expert-package.md +458 -458
  354. package/.agents/templates/common/mock-page.md +28 -28
  355. package/.agents/templates/common/new-component.md +25 -25
  356. package/.agents/templates/common/new-page.md +31 -31
  357. package/.cursor/mcp.json +35 -35
  358. package/.qoder/mcp.json +26 -26
  359. package/bin/archive-change.js +560 -474
  360. package/bin/check-command.js +62 -62
  361. package/bin/cli.js +0 -0
  362. package/bin/command-template-renderer.js +40 -40
  363. package/bin/context-command.js +102 -102
  364. package/bin/demo-runtime-smoke.js +760 -760
  365. package/bin/execution-semantics.js +821 -821
  366. package/bin/executor-command.js +93 -93
  367. package/bin/expert-dispatch.js +334 -334
  368. package/bin/expert-executor.js +1148 -1148
  369. package/bin/guard-command.js +52 -52
  370. package/bin/hub-command.js +876 -876
  371. package/bin/ide-command.js +242 -242
  372. package/bin/init-command.js +193 -193
  373. package/bin/install-workflow.js +35 -3
  374. package/bin/manifest-export.js +34 -34
  375. package/bin/profile-registry.js +90 -90
  376. package/bin/protocol-workflow.js +452 -446
  377. package/bin/repair-command.js +161 -161
  378. package/bin/repo-map.js +177 -177
  379. package/bin/report-command.js +236 -236
  380. package/bin/runtime-bootstrap.js +428 -428
  381. package/bin/runtime-embedded.js +101 -101
  382. package/bin/runtime-fallback.js +106 -106
  383. package/bin/runtime-launcher.js +116 -116
  384. package/bin/runtime-paths.js +177 -177
  385. package/bin/runtime-registry.js +289 -289
  386. package/bin/runtime-state.js +2541 -2541
  387. package/bin/scan.js +96 -96
  388. package/bin/self-upgrade.js +206 -206
  389. package/bin/skill-spec-validator.js +457 -457
  390. package/bin/spec-command.js +366 -366
  391. package/bin/superpowers.js +384 -384
  392. package/bin/sync-command.js +59 -59
  393. package/bin/sync.js +1904 -1904
  394. package/bin/task-orchestrator-adapter.js +341 -341
  395. package/bin/task-orchestrator-extractor.js +274 -274
  396. package/bin/task-orchestrator-runner.js +1208 -1208
  397. package/bin/telemetry/README.md +66 -66
  398. package/bin/telemetry/aspect.js +153 -153
  399. package/bin/telemetry/collect.js +67 -67
  400. package/bin/telemetry/config.js +114 -114
  401. package/bin/telemetry/defaults.json +5 -5
  402. package/bin/telemetry/healthcheck.js +195 -195
  403. package/bin/telemetry/identity.js +53 -53
  404. package/bin/telemetry/index.js +25 -25
  405. package/bin/telemetry/reporter.js +83 -83
  406. package/bin/telemetry/safe.js +39 -39
  407. package/bin/validate-registry.js +740 -740
  408. package/bin/visual-bridge-config.js +117 -117
  409. package/bin/visual-bridge.js +287 -287
  410. package/bin/visual-command.js +432 -432
  411. package/bin/worktree-command.js +194 -194
  412. package/configs/common/.editorconfig +15 -15
  413. package/configs/common/.husky/commit-msg +4 -4
  414. package/configs/common/.husky/pre-commit +4 -4
  415. package/configs/common/.lintstagedrc +11 -11
  416. package/configs/common/.prettierignore +11 -11
  417. package/configs/common/.prettierrc.json +11 -11
  418. package/configs/common/.stylelintignore +14 -14
  419. package/configs/common/.stylelintrc.json +21 -21
  420. package/configs/common/commitlint.config.js +3 -3
  421. package/configs/profiles/nestjs/.gitkeep +1 -1
  422. package/configs/profiles/node-tooling/.gitkeep +1 -1
  423. package/configs/profiles/react/.eslintignore +6 -6
  424. package/configs/profiles/react/.eslintrc.js +16 -16
  425. package/configs/profiles/react/.stylelintrc.json +18 -18
  426. package/configs/profiles/springboot/.gitkeep +1 -1
  427. package/configs/profiles/vue/.eslintignore +6 -6
  428. package/configs/profiles/vue/.eslintrc.cjs +17 -17
  429. package/contracts/README.md +28 -28
  430. package/contracts/fixtures/asset-package.fixture.json +26 -26
  431. package/contracts/fixtures/asset-usage-feedback.fixture.json +14 -14
  432. package/contracts/fixtures/evidence-report.fixture.json +28 -28
  433. package/contracts/fixtures/manifest.fixture.json +20 -20
  434. package/contracts/fixtures/run-event.fixture.json +15 -15
  435. package/contracts/schemas/asset-package.schema.json +76 -76
  436. package/contracts/schemas/asset-usage-feedback.schema.json +57 -57
  437. package/contracts/schemas/evidence-report.schema.json +60 -60
  438. package/contracts/schemas/manifest.schema.json +63 -63
  439. package/contracts/schemas/run-event.schema.json +72 -72
  440. package/install.ps1 +35 -35
  441. package/install.sh +17 -17
  442. package/internal/ai-protocol-workflow.js +5824 -5600
  443. package/internal/hub-client.js +98 -98
  444. package/internal/hub-sync-selection.js +69 -69
  445. package/internal/visual-hooks/README.md +481 -481
  446. package/internal/visual-hooks/config-loader.js +218 -218
  447. package/internal/visual-hooks/control-puller.js +206 -206
  448. package/internal/visual-hooks/gate-signal.js +150 -150
  449. package/internal/visual-hooks/inbox-consumer.js +469 -469
  450. package/internal/visual-hooks/index.js +197 -197
  451. package/internal/visual-hooks/push-client.js +189 -189
  452. package/internal/visual-hooks/receipt-pusher.js +176 -176
  453. package/internal/visual-hooks/runtime-state-pusher.js +128 -128
  454. package/openspec/config.yaml.template +52 -52
  455. package/openspec/schemas/expert-delivery/schema.yaml +68 -68
  456. package/openspec/schemas/expert-delivery/templates/checklist.md +39 -39
  457. package/openspec/schemas/expert-delivery/templates/design.md +61 -61
  458. package/openspec/schemas/expert-delivery/templates/iterations.md +25 -25
  459. package/openspec/schemas/expert-delivery/templates/proposal.md +45 -45
  460. package/openspec/schemas/expert-delivery/templates/spec.md +29 -29
  461. package/openspec/schemas/expert-delivery/templates/tasks.md +24 -24
  462. package/package.json +1 -1
  463. package/scripts/acceptance-zero-intrusion.sh +168 -168
  464. package/scripts/hub-sync-assets.config.example.json +296 -296
  465. package/scripts/hub-sync-assets.js +2038 -2038
  466. package/scripts/local-verify.sh +280 -280
  467. package/scripts/post-publish-auto-fix-check.js +404 -404
  468. package/scripts/post-publish-verify.sh +175 -175
  469. package/scripts/setup-cursor-manual-test.sh +107 -107
  470. package/scripts/setup-cursor-spec-archive-test.sh +111 -111
  471. package/scripts/setup-visual-integration.sh +225 -225
  472. package/scripts/test-integration.sh +176 -176
  473. package/scripts/update-test-project.sh +93 -93
  474. package/scripts/upload-four-web.sh +57 -57
  475. package/scripts/verify-install-ps1-bom.js +26 -26
  476. package/src/agent/agent-context.js +259 -259
  477. package/src/agent/agent-profile.js +185 -185
  478. package/src/agent/agent-templates.js +161 -161
  479. package/src/agent/agent-types.js +108 -108
  480. package/src/agent/collaboration-protocol.js +333 -333
  481. package/src/agent/conflict-handler.js +364 -364
  482. package/src/agent/file-permission.js +121 -121
  483. package/src/agent/index.js +38 -38
  484. package/src/agent/permission-audit.js +151 -151
  485. package/src/agent/review-repair-loop.js +270 -270
  486. package/src/agent/tool-permission.js +101 -101
  487. package/src/asset/asset-dependency.js +322 -322
  488. package/src/asset/asset-feedback.js +350 -350
  489. package/src/asset/asset-fork.js +300 -300
  490. package/src/asset/asset-install.js +278 -278
  491. package/src/asset/asset-installer.js +497 -497
  492. package/src/asset/asset-lifecycle.js +324 -324
  493. package/src/asset/asset-manager.js +245 -245
  494. package/src/asset/asset-package-manager.js +349 -349
  495. package/src/asset/asset-package.js +186 -186
  496. package/src/asset/asset-quality.js +262 -262
  497. package/src/asset/asset-registry.js +387 -387
  498. package/src/asset/asset-version.js +293 -293
  499. package/src/asset/index.js +86 -86
  500. package/src/cache/agent-profile-cache.js +59 -59
  501. package/src/cache/asset-cache.js +63 -63
  502. package/src/cache/global-cache.js +61 -61
  503. package/src/cache/manifest-cache.js +30 -30
  504. package/src/check/check-service.js +32 -32
  505. package/src/config/config-layer.js +343 -343
  506. package/src/config/config-loader.js +60 -60
  507. package/src/config/defaults.js +49 -49
  508. package/src/connectors/hub/asset-package.js +72 -72
  509. package/src/connectors/hub/asset-usage-feedback.js +46 -46
  510. package/src/connectors/hub/hub-connector.js +44 -44
  511. package/src/connectors/hub/index.js +21 -21
  512. package/src/connectors/visual/evidence-report.js +49 -49
  513. package/src/connectors/visual/index.js +15 -15
  514. package/src/connectors/visual/queue.js +41 -41
  515. package/src/connectors/visual/run-event.js +81 -81
  516. package/src/connectors/visual/visual-connector.js +77 -77
  517. package/src/context/context-budget.js +59 -59
  518. package/src/context/context-builder.js +285 -285
  519. package/src/context/context-loader.js +116 -116
  520. package/src/context/context-planner.js +158 -158
  521. package/src/context/types.js +96 -96
  522. package/src/contracts/index.js +63 -63
  523. package/src/executor/executor-registry.js +78 -78
  524. package/src/executor/executor-result-parser.js +44 -44
  525. package/src/executor/executor-runner.js +141 -141
  526. package/src/executor/executor-selector.js +139 -139
  527. package/src/executor/executor-timeout.js +36 -36
  528. package/src/executor/providers/base-provider-utils.js +189 -189
  529. package/src/executor/providers/claude-code-executor-provider.js +128 -128
  530. package/src/executor/providers/codex-executor-provider.js +126 -126
  531. package/src/executor/providers/cursor-executor-provider.js +99 -99
  532. package/src/executor/types.js +137 -137
  533. package/src/git/branch-manager.js +71 -71
  534. package/src/git/dirty-checker.js +43 -43
  535. package/src/git/dirty-strategy-handler.js +29 -29
  536. package/src/git/git-command.js +37 -37
  537. package/src/git/git-repository-detector.js +45 -45
  538. package/src/git/multi-repo-worktree-planner.js +88 -88
  539. package/src/git/policy.js +19 -19
  540. package/src/git/strategies/block-dirty-strategy.js +34 -34
  541. package/src/git/strategies/ignore-dirty-strategy.js +33 -33
  542. package/src/git/strategies/patch-snapshot-strategy.js +53 -53
  543. package/src/git/strategies/wip-commit-strategy.js +38 -38
  544. package/src/git/types.js +71 -71
  545. package/src/git/worktree-manager.js +85 -85
  546. package/src/governance/asset-review.js +351 -351
  547. package/src/governance/audit-log.js +368 -368
  548. package/src/governance/gray-release.js +312 -312
  549. package/src/governance/index.js +31 -31
  550. package/src/governance/policy-types.js +56 -56
  551. package/src/governance/rbac-types.js +171 -171
  552. package/src/governance/rbac.js +382 -382
  553. package/src/governance/rollback.js +360 -360
  554. package/src/governance/security-policy.js +354 -354
  555. package/src/hook/hook-config-writer.js +125 -125
  556. package/src/hub/hub-client.js +186 -186
  557. package/src/hub/hub-config.js +39 -39
  558. package/src/hub/project-facts.js +31 -31
  559. package/src/hub/runtime-feedback-reporter.js +55 -55
  560. package/src/ide/adapters/adapter-protocol.js +385 -385
  561. package/src/ide/adapters/claude-adapter.js +419 -419
  562. package/src/ide/adapters/codex-adapter.js +60 -60
  563. package/src/ide/adapters/cursor-adapter.js +484 -484
  564. package/src/ide/adapters/index.js +24 -24
  565. package/src/ide/anchors/markdown-anchor-writer.js +152 -152
  566. package/src/ide/ide-service.js +270 -270
  567. package/src/ide/ide-types.js +94 -94
  568. package/src/ide/links/link-mode-resolver.js +160 -160
  569. package/src/ide/registry/ide-registry-builder.js +165 -165
  570. package/src/incident/incident-writer.js +47 -47
  571. package/src/incident/types.js +22 -22
  572. package/src/init/ide-linker.js +126 -126
  573. package/src/init/ide-pointer-injector.js +75 -75
  574. package/src/init/init-applier.js +197 -197
  575. package/src/init/init-plan.js +294 -294
  576. package/src/init/init-service.js +65 -65
  577. package/src/init/manifest-installer.js +302 -302
  578. package/src/init/types.js +26 -26
  579. package/src/project/config-writer.js +83 -83
  580. package/src/project/context-index-writer.js +82 -82
  581. package/src/project/json-utils.js +72 -72
  582. package/src/project/local-state-writer.js +50 -50
  583. package/src/project/lock-file-writer.js +98 -98
  584. package/src/project/manifest-writer.js +126 -126
  585. package/src/project/policy-config-writer.js +91 -91
  586. package/src/project/project-config-writer.js +74 -74
  587. package/src/project/project-files.js +39 -39
  588. package/src/project/registry-index-writer.js +43 -43
  589. package/src/project/workspace-config-writer.js +63 -63
  590. package/src/run/index.js +11 -11
  591. package/src/run/run-id.js +32 -32
  592. package/src/run/run-service.js +269 -269
  593. package/src/run/run-store.js +80 -80
  594. package/src/scanner/aggregator/detection-aggregator.js +23 -23
  595. package/src/scanner/boundary/boundary-resolver.js +229 -229
  596. package/src/scanner/detectors/detector-registry.js +44 -44
  597. package/src/scanner/detectors/fastapi-detector.js +46 -46
  598. package/src/scanner/detectors/go-detector.js +46 -46
  599. package/src/scanner/detectors/nestjs-detector.js +57 -57
  600. package/src/scanner/detectors/nextjs-detector.js +52 -52
  601. package/src/scanner/detectors/react-vite-detector.js +52 -52
  602. package/src/scanner/detectors/react-webpack-detector.js +57 -57
  603. package/src/scanner/detectors/springboot-detector.js +46 -46
  604. package/src/scanner/detectors/springcloud-detector.js +46 -46
  605. package/src/scanner/detectors/springmvc-detector.js +46 -46
  606. package/src/scanner/detectors/vue-vite-detector.js +52 -52
  607. package/src/scanner/engine.js +72 -72
  608. package/src/scanner/facts/fact-extractor.js +211 -211
  609. package/src/scanner/types.js +30 -30
  610. package/src/security/asset-tamper-checker.js +188 -188
  611. package/src/security/checksum.js +40 -40
  612. package/src/spec/spec-writer.js +302 -302
  613. package/src/state-machine/circuit-breaker.js +112 -112
  614. package/src/state-machine/escape-hatch.js +49 -49
  615. package/src/state-machine/stage-runner.js +281 -281
  616. package/src/state-machine/state-machine.js +24 -24
  617. package/src/state-machine/transition-guard.js +36 -36
  618. package/src/state-machine/types.js +37 -37
  619. package/src/sync/sync-service.js +192 -192
  620. package/src/visual/agent-visual.js +142 -142
  621. package/src/visual/event-gateway.js +357 -357
  622. package/src/visual/event-mapper.js +128 -128
  623. package/src/visual/hook-dashboard.js +216 -216
  624. package/src/visual/index.js +27 -27
  625. package/src/visual/metrics.js +287 -287
  626. package/src/visual/privacy-filter.js +100 -100
  627. package/src/visual/risk-board.js +252 -252
  628. package/src/visual/timeline.js +245 -245
  629. package/src/visual/visual-client.js +94 -94
  630. package/src/visual/visual-config.js +40 -40
  631. package/src/visual/visual-reporter.js +88 -88
@@ -1,1208 +1,1208 @@
1
- #!/usr/bin/env node
2
- const fs = require('fs');
3
- const path = require('path');
4
- const crypto = require('crypto');
5
- const runtimeState = require('./runtime-state');
6
- const extractor = require('./task-orchestrator-extractor');
7
- const expertDispatch = require('./expert-dispatch');
8
- const expertExecutor = require('./expert-executor');
9
- const {
10
- buildAutoRuntimeAction,
11
- guardRuntimeActionForIncompleteExecution,
12
- getRuntimeTransition,
13
- } = require('./execution-semantics');
14
- const {
15
- resolveRuntimePaths,
16
- getCandidatePaths,
17
- shouldPersistHistory,
18
- } = require('./runtime-paths');
19
-
20
- const INBOX_SPECS = [
21
- {
22
- kind: 'task-orchestrator-turn',
23
- pathKey: 'tmpTaskOrchestratorTurn',
24
- producer: 'task-orchestrator',
25
- },
26
- {
27
- kind: 'expert-dispatch',
28
- pathKey: 'tmpCurrentDispatch',
29
- producer: 'task-orchestrator',
30
- },
31
- {
32
- kind: 'expert-execution',
33
- pathKey: 'tmpCurrentExecution',
34
- producer: 'current-expert',
35
- },
36
- {
37
- kind: 'task-orchestrator-runtime-action',
38
- pathKey: 'tmpCurrentRuntimeAction',
39
- producer: 'task-orchestrator',
40
- },
41
- ];
42
-
43
- const TERMINAL_STATUSES = new Set(['success', 'failed', 'cancelled']);
44
- const AUTO_DISPATCH_ALLOWED_ACTIONS = new Set(['bootstrap', 'handoff', 'approve', 'resume']);
45
- const ROLE_METADATA = {
46
- 'requirement-analyst': {
47
- name: '需求解析专家',
48
- source: '.agents/roles/common/requirement-analyst.md',
49
- },
50
- 'frontend-implementer': {
51
- name: '前端实现专家',
52
- source: '.agents/roles/common/frontend-implementer.md',
53
- },
54
- 'code-guardian': {
55
- name: '规范守护者',
56
- source: '.agents/roles/common/code-guardian.md',
57
- },
58
- 'archive-change': {
59
- name: '归档专家',
60
- source: '.agents/roles/common/archive-change.md',
61
- },
62
- 'design-collaborator': {
63
- name: '设计协作专家',
64
- source: '.agents/roles/domains/demand-design/design-collaborator.md',
65
- },
66
- 'api-contract-specialist': {
67
- name: 'API 契约专家',
68
- source: '.agents/roles/domains/demand-design/api-contract-specialist.md',
69
- },
70
- 'unit-test-specialist': {
71
- name: '单元测试专家',
72
- source: '.agents/roles/domains/testing/unit-test-specialist.md',
73
- },
74
- 'verification-reviewer': {
75
- name: '验证评审专家',
76
- source: '.agents/roles/domains/testing/verification-reviewer.md',
77
- },
78
- 'performance-auditor': {
79
- name: '性能审计专家',
80
- source: '.agents/roles/domains/performance/performance-auditor.md',
81
- },
82
- };
83
- const ROLE_EXPECTED_OUTPUTS = {
84
- 'requirement-analyst': {
85
- compact: ['完成短版 proposal.md', '完成短版 spec.md', '完成短版 tasks.md'],
86
- full: ['完成 proposal.md', '完成 spec.md', '完成 tasks.md'],
87
- },
88
- 'frontend-implementer': {
89
- compact: ['完成最小必要实现', '保持改动最小化并记录验证结果'],
90
- full: ['完成当前范围内代码实现', '记录实现说明与验证结果'],
91
- },
92
- 'code-guardian': {
93
- compact: ['完成短版 checklist.md', '完成短版 iterations.md', '给出交付结论'],
94
- full: ['完成 checklist.md', '完成 iterations.md', '给出交付结论'],
95
- },
96
- 'archive-change': {
97
- compact: ['合并当前增量规范', '完成变更归档', '结束本次运行'],
98
- full: ['合并当前增量规范到 openspec/specs', '完成变更归档', '结束本次运行'],
99
- },
100
- 'design-collaborator': {
101
- compact: ['补充最小 UI 约束与设计疑问'],
102
- full: ['补充 UI 分析清单与设计待确认项'],
103
- },
104
- 'api-contract-specialist': {
105
- compact: ['补充最小接口契约约束'],
106
- full: ['补充接口契约说明与待确认字段'],
107
- },
108
- 'unit-test-specialist': {
109
- compact: ['补充关键测试建议'],
110
- full: ['补充单元测试策略与高风险边界场景'],
111
- },
112
- 'verification-reviewer': {
113
- compact: ['补充关键验收结论'],
114
- full: ['补充验证评审意见与验收风险'],
115
- },
116
- 'performance-auditor': {
117
- compact: ['补充关键性能风险'],
118
- full: ['补充性能审计结论与优化优先级'],
119
- },
120
- };
121
-
122
- function printUsage() {
123
- console.log(`Internal usage:
124
- require('./task-orchestrator-runner').advanceRunner({ target })
125
- require('./task-orchestrator-runner').buildStatus(target)
126
- require('./task-orchestrator-runner').replayReplies({ target, replies })
127
-
128
- Options:
129
- --reply <file> Path to a task-orchestrator Markdown reply file; can be repeated
130
- --target <dir> Target project directory (default: .)
131
- --json Print JSON result
132
- --pretty Print readable summary (default)
133
- --help Show this help
134
- `);
135
- }
136
-
137
- function parseArgs(argv) {
138
- const args = [...argv];
139
- const command = args.shift();
140
- const options = {
141
- target: '.',
142
- replies: [],
143
- pretty: true,
144
- json: false,
145
- };
146
-
147
- while (args.length > 0) {
148
- const arg = args.shift();
149
- switch (arg) {
150
- case '--reply':
151
- options.replies.push(args.shift());
152
- break;
153
- case '--target':
154
- options.target = args.shift();
155
- break;
156
- case '--json':
157
- options.json = true;
158
- options.pretty = false;
159
- break;
160
- case '--pretty':
161
- options.pretty = true;
162
- options.json = false;
163
- break;
164
- case '--help':
165
- case '-h':
166
- options.help = true;
167
- break;
168
- default:
169
- throw new Error(`Unknown argument: ${arg}`);
170
- }
171
- }
172
-
173
- return { command, options };
174
- }
175
-
176
- function readTextFile(filePath, label) {
177
- const raw = fs.readFileSync(filePath, 'utf8');
178
- if (!raw.trim()) {
179
- throw new Error(`${label} is empty: ${filePath}`);
180
- }
181
- return raw;
182
- }
183
-
184
- function readJsonFile(filePath, label) {
185
- const raw = fs.readFileSync(filePath, 'utf8');
186
- try {
187
- return JSON.parse(raw);
188
- } catch (error) {
189
- throw new Error(`${label} is not valid JSON: ${filePath}`);
190
- }
191
- }
192
-
193
- function ensureDir(dirPath) {
194
- fs.mkdirSync(dirPath, { recursive: true });
195
- }
196
-
197
- function loadJsonIfExists(filePath, label) {
198
- if (!fs.existsSync(filePath)) {
199
- return null;
200
- }
201
- return readJsonFile(filePath, label);
202
- }
203
-
204
- function parseScalar(value) {
205
- const trimmed = value.trim();
206
- if (trimmed === '') {
207
- return '';
208
- }
209
- if (trimmed === '[]') {
210
- return [];
211
- }
212
- if (
213
- (trimmed.startsWith('"') && trimmed.endsWith('"')) ||
214
- (trimmed.startsWith("'") && trimmed.endsWith("'"))
215
- ) {
216
- return trimmed.slice(1, -1);
217
- }
218
- return trimmed;
219
- }
220
-
221
- function parseFrontmatter(fileContent) {
222
- const lines = fileContent.split('\n');
223
- if (lines[0] !== '---') {
224
- return {};
225
- }
226
-
227
- const endIndex = lines.indexOf('---', 1);
228
- if (endIndex === -1) {
229
- return {};
230
- }
231
-
232
- const frontmatterLines = lines.slice(1, endIndex);
233
- const data = {};
234
- let currentKey = null;
235
-
236
- for (const line of frontmatterLines) {
237
- const listMatch = line.match(/^\s*-\s+(.*)$/);
238
- if (listMatch && currentKey) {
239
- if (!Array.isArray(data[currentKey])) {
240
- data[currentKey] = [];
241
- }
242
- data[currentKey].push(parseScalar(listMatch[1]));
243
- continue;
244
- }
245
-
246
- const keyMatch = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
247
- if (!keyMatch) {
248
- currentKey = null;
249
- continue;
250
- }
251
-
252
- const [, key, rawValue] = keyMatch;
253
- if (rawValue.trim() === '') {
254
- data[key] = [];
255
- currentKey = key;
256
- continue;
257
- }
258
-
259
- data[key] = parseScalar(rawValue);
260
- currentKey = null;
261
- }
262
-
263
- return data;
264
- }
265
-
266
- function loadRoleMetadata(targetDir, roleId) {
267
- const fallback = ROLE_METADATA[roleId] || {
268
- name: roleId,
269
- source: null,
270
- };
271
-
272
- if (!fallback.source) {
273
- return {
274
- id: roleId,
275
- name: fallback.name,
276
- source: null,
277
- preferred_skills: [],
278
- };
279
- }
280
-
281
- const sourcePath = path.join(targetDir, fallback.source);
282
- if (!fs.existsSync(sourcePath)) {
283
- return {
284
- id: roleId,
285
- name: fallback.name,
286
- source: fallback.source,
287
- preferred_skills: [],
288
- };
289
- }
290
-
291
- const frontmatter = parseFrontmatter(fs.readFileSync(sourcePath, 'utf8'));
292
- return {
293
- id: roleId,
294
- name: frontmatter.name || fallback.name,
295
- source: fallback.source,
296
- preferred_skills: Array.isArray(frontmatter.preferred_skills) ? frontmatter.preferred_skills : [],
297
- };
298
- }
299
-
300
- function inferProjectProfile(targetDir) {
301
- const manifestCandidates = [
302
- path.join(targetDir, '.ai-spec', 'manifest.json'),
303
- path.join(targetDir, 'manifest.json'),
304
- ];
305
-
306
- for (const filePath of manifestCandidates) {
307
- if (!fs.existsSync(filePath)) {
308
- continue;
309
- }
310
- try {
311
- const json = readJsonFile(filePath, 'manifest');
312
- if (json.profile) {
313
- return json.profile;
314
- }
315
- } catch (error) {
316
- // ignore malformed local manifest during runtime inference
317
- }
318
- }
319
-
320
- const packagePath = path.join(targetDir, 'package.json');
321
- if (fs.existsSync(packagePath)) {
322
- try {
323
- const pkg = readJsonFile(packagePath, 'package.json');
324
- const deps = {
325
- ...(pkg.dependencies || {}),
326
- ...(pkg.devDependencies || {}),
327
- };
328
- if (deps.vue) {
329
- return 'vue';
330
- }
331
- if (deps.react) {
332
- return 'react';
333
- }
334
- } catch (error) {
335
- // ignore
336
- }
337
- }
338
-
339
- return 'unknown';
340
- }
341
-
342
- function resolveExistingRuntimeEntry(entry) {
343
- for (const candidatePath of getCandidatePaths(entry)) {
344
- if (!fs.existsSync(candidatePath)) {
345
- continue;
346
- }
347
-
348
- return {
349
- path: candidatePath,
350
- relPath: candidatePath === entry.path ? entry.relPath : entry.legacyRelPath,
351
- exists: true,
352
- };
353
- }
354
-
355
- return {
356
- path: entry.path,
357
- relPath: entry.relPath,
358
- exists: false,
359
- };
360
- }
361
-
362
- function createRunnerSnapshot(targetDir) {
363
- const runtimePaths = resolveRuntimePaths(targetDir);
364
- const currentDispatchEntry = resolveExistingRuntimeEntry(runtimePaths.currentDispatch);
365
- const currentExecutionEntry = resolveExistingRuntimeEntry(runtimePaths.currentExecutionJson);
366
- const currentRuntimeActionEntry = resolveExistingRuntimeEntry(runtimePaths.currentRuntimeActionJson);
367
-
368
- const pendingInputs = [];
369
- for (const spec of INBOX_SPECS) {
370
- const entry = resolveExistingRuntimeEntry(runtimePaths[spec.pathKey]);
371
- if (!entry.exists) {
372
- continue;
373
- }
374
-
375
- pendingInputs.push({
376
- ...spec,
377
- path: entry.path,
378
- relPath: entry.relPath,
379
- exists: true,
380
- });
381
- }
382
-
383
- return {
384
- targetDir,
385
- runtimePaths,
386
- pendingInputs,
387
- current: {
388
- run: loadJsonIfExists(runtimePaths.currentRun.path, 'current run-state'),
389
- dispatch: currentDispatchEntry.exists ? readJsonFile(currentDispatchEntry.path, 'current dispatch') : null,
390
- execution: currentExecutionEntry.exists ? readJsonFile(currentExecutionEntry.path, 'current execution') : null,
391
- runtimeAction: currentRuntimeActionEntry.exists ? readJsonFile(currentRuntimeActionEntry.path, 'current runtime action') : null,
392
- },
393
- };
394
- }
395
-
396
- function resolvePendingInputs(targetDir, snapshot = null) {
397
- const activeSnapshot = snapshot || createRunnerSnapshot(targetDir);
398
- return activeSnapshot.pendingInputs.map((item) => ({ ...item }));
399
- }
400
-
401
- function loadCurrentArtifacts(targetDir, snapshot = null) {
402
- const activeSnapshot = snapshot || createRunnerSnapshot(targetDir);
403
- return {
404
- run: activeSnapshot.current.run,
405
- dispatch: activeSnapshot.current.dispatch,
406
- execution: activeSnapshot.current.execution,
407
- runtimeAction: activeSnapshot.current.runtimeAction,
408
- };
409
- }
410
-
411
- function buildNextExpectedFromSnapshot(snapshot) {
412
- const pendingInputs = snapshot.pendingInputs;
413
- const runtimePaths = snapshot.runtimePaths;
414
- if (pendingInputs.length > 0) {
415
- return {
416
- producer: 'runner',
417
- files: pendingInputs.map((item) => item.relPath),
418
- reason: 'runner inbox still has pending input; consume it before requesting new AI output',
419
- };
420
- }
421
-
422
- const current = snapshot.current;
423
-
424
- if (!current.run) {
425
- return {
426
- producer: 'task-orchestrator',
427
- files: [runtimePaths.tmpTaskOrchestratorTurn.relPath],
428
- reason: 'no current run-state yet; waiting for task-orchestrator bootstrap turn',
429
- };
430
- }
431
-
432
- if (TERMINAL_STATUSES.has(current.run.status)) {
433
- return {
434
- producer: null,
435
- files: [],
436
- reason: 'run is already in terminal state',
437
- };
438
- }
439
-
440
- if (String(current.run.status || '').trim().toLowerCase() === 'paused') {
441
- return {
442
- producer: 'task-orchestrator',
443
- files: [],
444
- reason: 'run is paused and waiting for resume',
445
- };
446
- }
447
-
448
- if (String(current.run.status || '').trim().toLowerCase() === 'waiting-confirm') {
449
- return {
450
- producer: 'task-orchestrator',
451
- files: [],
452
- reason: 'run is waiting at confirm gate before continuing',
453
- };
454
- }
455
-
456
- if (current.execution) {
457
- return {
458
- producer: 'task-orchestrator',
459
- files: [
460
- runtimePaths.tmpTaskOrchestratorTurn.relPath,
461
- runtimePaths.tmpCurrentRuntimeAction.relPath,
462
- ],
463
- reason: 'expert execution has been recorded; waiting for task-orchestrator runtime action',
464
- };
465
- }
466
-
467
- if (current.dispatch) {
468
- return {
469
- producer: current.dispatch.role?.id || 'current-expert',
470
- files: [runtimePaths.tmpCurrentExecution.relPath],
471
- reason: 'current expert dispatch is active; waiting for expert execution output',
472
- };
473
- }
474
-
475
- if (current.run.pending_gate) {
476
- return {
477
- producer: 'task-orchestrator',
478
- files: [
479
- runtimePaths.tmpTaskOrchestratorTurn.relPath,
480
- runtimePaths.tmpCurrentRuntimeAction.relPath,
481
- ],
482
- reason: `run is waiting at approval gate "${current.run.pending_gate}"`,
483
- };
484
- }
485
-
486
- return {
487
- producer: 'task-orchestrator',
488
- files: [runtimePaths.tmpCurrentDispatch.relPath],
489
- reason: 'run-state is ready for the next expert dispatch',
490
- };
491
- }
492
-
493
- function buildNextExpected(targetDir, snapshot = null) {
494
- return buildNextExpectedFromSnapshot(snapshot || createRunnerSnapshot(targetDir));
495
- }
496
-
497
- function buildStatus(targetDir) {
498
- const snapshot = createRunnerSnapshot(targetDir);
499
- const pendingInputs = snapshot.pendingInputs;
500
- const current = snapshot.current;
501
- const nextExpected = buildNextExpectedFromSnapshot(snapshot);
502
-
503
- return {
504
- kind: 'task-orchestrator-runner-status',
505
- status: pendingInputs.length > 1 ? 'blocked' : 'ready',
506
- target: targetDir,
507
- pending_inputs: pendingInputs.map((item) => ({
508
- kind: item.kind,
509
- producer: item.producer,
510
- path: item.relPath,
511
- })),
512
- current: {
513
- run_id: current.run?.run_id || null,
514
- run_status: current.run?.status || null,
515
- mode: current.run?.mode || null,
516
- review_policy: current.run?.review_policy || null,
517
- current_role: current.run?.current_role || null,
518
- pending_gate: current.run?.pending_gate || null,
519
- dispatch_role: current.dispatch?.role?.id || null,
520
- execution_role: current.execution?.role?.id || null,
521
- runtime_action: current.runtimeAction?.action || null,
522
- },
523
- next_expected: nextExpected,
524
- };
525
- }
526
-
527
- function archiveConsumedInput(targetDir, filePath, kind) {
528
- if (!fs.existsSync(filePath)) {
529
- return null;
530
- }
531
-
532
- if (!shouldPersistHistory()) {
533
- fs.unlinkSync(filePath);
534
- return null;
535
- }
536
-
537
- const runtimePaths = resolveRuntimePaths(targetDir);
538
- const consumedDir = runtimePaths.runnerConsumedDir.path;
539
- ensureDir(consumedDir);
540
-
541
- const stamp = new Date().toISOString().replace(/[:.]/g, '-');
542
- const archivedPath = path.join(consumedDir, `${stamp}__${kind}__${path.basename(filePath)}`);
543
- fs.renameSync(filePath, archivedPath);
544
-
545
- return archivedPath;
546
- }
547
-
548
- function summarizeAppliedState(applied) {
549
- if (!applied || !applied.result || !applied.result.state) {
550
- return null;
551
- }
552
-
553
- return {
554
- adapter_action: applied.adapter_action,
555
- run_id: applied.result.state.run_id || null,
556
- status: applied.result.state.status || null,
557
- current_role: applied.result.state.current_role || null,
558
- pending_gate: applied.result.state.pending_gate || null,
559
- };
560
- }
561
-
562
- function buildRuntimeOptionsFromPayload(payload, targetDir) {
563
- const options = {
564
- target: targetDir,
565
- };
566
- const mappings = [
567
- ['runId', ['run_id', 'runId']],
568
- ['toRole', ['to_role', 'toRole']],
569
- ['nextRole', ['next_role', 'nextRole']],
570
- ['fromRole', ['from_role', 'fromRole']],
571
- ['gate', ['gate']],
572
- ['pendingGate', ['pending_gate', 'pendingGate']],
573
- ['blockedByRole', ['blocked_by_role', 'blockedByRole']],
574
- ['resumeToRole', ['resume_to_role', 'resumeToRole']],
575
- ['requiredUserAction', ['required_user_action', 'requiredUserAction']],
576
- ['blockedReason', ['blocked_reason', 'blockedReason']],
577
- ['message', ['message']],
578
- ['error', ['error']],
579
- ['eventType', ['event_type', 'eventType']],
580
- ['status', ['status']],
581
- ];
582
-
583
- for (const [targetKey, sourceKeys] of mappings) {
584
- for (const sourceKey of sourceKeys) {
585
- if (Object.prototype.hasOwnProperty.call(payload, sourceKey)) {
586
- options[targetKey] = payload[sourceKey];
587
- break;
588
- }
589
- }
590
- }
591
-
592
- if (Object.prototype.hasOwnProperty.call(payload, 'clear_pending_gate') || Object.prototype.hasOwnProperty.call(payload, 'clearPendingGate')) {
593
- options.clearPendingGate = Boolean(
594
- Object.prototype.hasOwnProperty.call(payload, 'clear_pending_gate')
595
- ? payload.clear_pending_gate
596
- : payload.clearPendingGate,
597
- );
598
- }
599
-
600
- if (payload.task_anchor || payload.taskAnchor) {
601
- options.taskAnchorData = payload.task_anchor || payload.taskAnchor;
602
- }
603
- if (payload.artifacts && typeof payload.artifacts === 'object') {
604
- options.artifactsData = payload.artifacts;
605
- }
606
- if (payload.verification && typeof payload.verification === 'object') {
607
- options.verificationData = payload.verification;
608
- }
609
- if (payload.auto_fix && typeof payload.auto_fix === 'object') {
610
- options.autoFixData = payload.auto_fix;
611
- }
612
- if (Object.prototype.hasOwnProperty.call(payload, 'skip_artifact_check') || Object.prototype.hasOwnProperty.call(payload, 'skipArtifactCheck')) {
613
- options.skipArtifactCheck = Boolean(
614
- Object.prototype.hasOwnProperty.call(payload, 'skip_artifact_check')
615
- ? payload.skip_artifact_check
616
- : payload.skipArtifactCheck
617
- );
618
- }
619
-
620
- return options;
621
- }
622
-
623
- function clearCurrentExpertArtifacts(targetDir) {
624
- return {
625
- dispatch: expertDispatch.clearDispatch({ target: targetDir }),
626
- execution: expertExecutor.clearExecution({ target: targetDir }),
627
- runtime_action: expertExecutor.clearRuntimeAction({ target: targetDir }),
628
- };
629
- }
630
-
631
- function applyRuntimeMutation({ targetDir, action, payload, payloadSource }) {
632
- const guardedPayload = guardRuntimeActionForIncompleteExecution(targetDir, payload);
633
- const normalizedAction = String(guardedPayload.action || action || '').toLowerCase();
634
- let result = null;
635
-
636
- if (normalizedAction === 'bootstrap') {
637
- result = runtimeState.bootstrapRunState({
638
- target: targetDir,
639
- payloadData: guardedPayload,
640
- });
641
- } else {
642
- const runtimeOptions = buildRuntimeOptionsFromPayload(guardedPayload, targetDir);
643
- switch (normalizedAction) {
644
- case 'handoff':
645
- result = runtimeState.handoffRunState(runtimeOptions);
646
- break;
647
- case 'approve':
648
- result = runtimeState.approveRunState(runtimeOptions);
649
- break;
650
- case 'resume':
651
- result = runtimeState.resumeRunState(runtimeOptions);
652
- break;
653
- case 'pause':
654
- case 'paused':
655
- result = runtimeState.pauseRunState(runtimeOptions);
656
- break;
657
- case 'gate-blocked':
658
- case 'blocked':
659
- result = runtimeState.gateBlockedRunState(runtimeOptions);
660
- break;
661
- case 'status':
662
- result = runtimeState.statusRunState(runtimeOptions);
663
- break;
664
- case 'complete':
665
- case 'completed':
666
- result = runtimeState.completeRunState(runtimeOptions);
667
- break;
668
- case 'fail':
669
- case 'failed':
670
- result = runtimeState.failRunState(runtimeOptions);
671
- break;
672
- case 'cancel':
673
- case 'cancelled':
674
- result = runtimeState.cancelRunState(runtimeOptions);
675
- break;
676
- default:
677
- throw new Error(`Unsupported runtime action: ${action}`);
678
- }
679
- }
680
-
681
- const applied = {
682
- adapter_action: normalizedAction === 'completed' ? 'complete' : normalizedAction,
683
- adapter_source: payloadSource,
684
- result,
685
- };
686
-
687
- if (['bootstrap', 'handoff', 'approve', 'resume', 'pause', 'gate-blocked', 'complete', 'fail', 'cancel'].includes(applied.adapter_action)) {
688
- return {
689
- ...applied,
690
- ...clearCurrentExpertArtifacts(targetDir),
691
- };
692
- }
693
-
694
- return applied;
695
- }
696
-
697
- function tryReadJsonValue(filePath) {
698
- try {
699
- return readJsonFile(filePath, 'task-orchestrator turn');
700
- } catch (error) {
701
- return null;
702
- }
703
- }
704
-
705
- function resolveTaskOrchestratorTurn(filePath) {
706
- const parsed = tryReadJsonValue(filePath);
707
- if (parsed && typeof parsed === 'object') {
708
- if (parsed.kind === 'run-plan' || parsed.kind === 'task-orchestrator-bootstrap' || parsed.run_plan || parsed.runPlan) {
709
- return {
710
- action: 'bootstrap',
711
- payload: parsed,
712
- };
713
- }
714
-
715
- if (parsed.kind === 'task-orchestrator-runtime-action' || parsed.kind === 'task-orchestrator-runtime-event') {
716
- return {
717
- action: parsed.action || parsed.event,
718
- payload: parsed,
719
- };
720
- }
721
- }
722
-
723
- const replyText = readTextFile(filePath, 'task-orchestrator turn');
724
- const extracted = extractor.extractPayloadFromText(replyText, filePath);
725
- return {
726
- action: extracted.action,
727
- payload: extracted.payload,
728
- };
729
- }
730
-
731
- function readCurrentRun(targetDir) {
732
- return createRunnerSnapshot(targetDir).current.run;
733
- }
734
-
735
- function buildTaskAnchorForRole(currentRun, currentRole, nextRole) {
736
- const anchor = currentRun.anchor || {};
737
- return {
738
- schema_version: 1,
739
- kind: 'task-anchor',
740
- task: {
741
- ...(anchor.task || {}),
742
- raw_goal: anchor.task?.raw_goal || currentRun.trigger?.raw_input || null,
743
- change_id: anchor.task?.change_id || currentRun.task?.change_id || null,
744
- input_kind: anchor.task?.input_kind || currentRun.task?.input_kind || 'natural-language',
745
- },
746
- stage: {
747
- ...(anchor.stage || {}),
748
- flow_id: anchor.stage?.flow_id || currentRun.flow?.id || null,
749
- current_role: currentRole,
750
- next_role: nextRole,
751
- },
752
- constraints: anchor.constraints || null,
753
- artifacts: anchor.artifacts || currentRun.artifacts || null,
754
- expected_output: anchor.expected_output || [],
755
- };
756
- }
757
-
758
- function buildAutoDispatch(targetDir, currentRun) {
759
- if (!currentRun || !currentRun.current_role || TERMINAL_STATUSES.has(currentRun.status)) {
760
- return null;
761
- }
762
- if (currentRun.pending_gate) {
763
- return null;
764
- }
765
-
766
- const roleId = currentRun.current_role;
767
- const transition = getRuntimeTransition(targetDir, currentRun.flow?.id || '', roleId);
768
- const role = loadRoleMetadata(targetDir, roleId);
769
- const artifactProfile = currentRun.artifact_profile || 'full';
770
- const deliveryProfile = currentRun.delivery_profile || null;
771
- const expectedOutput = ROLE_EXPECTED_OUTPUTS[roleId]?.[artifactProfile] || ROLE_EXPECTED_OUTPUTS[roleId]?.full || [];
772
- const immediateNextRole = transition?.action === 'handoff'
773
- ? transition.to_role || null
774
- : transition?.next_role || null;
775
- const nextRole = currentRun.anchor?.stage?.next_role !== undefined
776
- ? currentRun.anchor?.stage?.next_role
777
- : immediateNextRole;
778
- const preferredSkills = Array.isArray(role.preferred_skills)
779
- ? role.preferred_skills.filter((id) => {
780
- if (deliveryProfile !== 'micro') {
781
- return true;
782
- }
783
- const microAllowlist = {
784
- 'requirement-analyst': new Set(['create-proposal', 'design-analysis']),
785
- 'frontend-implementer': new Set(['create-view', 'create-route', 'create-api', 'theme-variables', 'create-component', 'create-store']),
786
- 'code-guardian': new Set(['ui-verification', 'web-design-guidelines']),
787
- };
788
- return microAllowlist[roleId]?.has(id) ?? true;
789
- })
790
- : [];
791
-
792
- return {
793
- schema_version: 1,
794
- kind: 'expert-dispatch',
795
- run_id: currentRun.run_id,
796
- status: currentRun.status === 'planned' ? 'planned' : 'running',
797
- role,
798
- task: {
799
- raw_goal: currentRun.anchor?.task?.raw_goal || currentRun.trigger?.raw_input || null,
800
- change_id: currentRun.task?.change_id || currentRun.anchor?.task?.change_id || null,
801
- },
802
- flow: {
803
- id: currentRun.flow?.id || null,
804
- },
805
- execution: {
806
- profile: inferProjectProfile(targetDir),
807
- delivery_profile: deliveryProfile,
808
- artifact_profile: currentRun.artifact_profile || null,
809
- current_role: roleId,
810
- next_role: nextRole,
811
- pending_gate: currentRun.pending_gate || null,
812
- expected_output: expectedOutput,
813
- skills: preferredSkills.map((id) => ({ id })),
814
- },
815
- anchor: buildTaskAnchorForRole(currentRun, roleId, nextRole),
816
- instructions: {
817
- source: role.source,
818
- markdown: `# ${roleId}`,
819
- },
820
- };
821
- }
822
-
823
- function maybeAutoDispatchCurrentRole(targetDir, applied) {
824
- if (!applied || !AUTO_DISPATCH_ALLOWED_ACTIONS.has(applied.adapter_action)) {
825
- return null;
826
- }
827
-
828
- const snapshot = createRunnerSnapshot(targetDir);
829
- const currentRun = snapshot.current.run;
830
- if (
831
- !currentRun ||
832
- !currentRun.current_role ||
833
- currentRun.pending_gate ||
834
- String(currentRun.status || '').trim().toLowerCase() === 'waiting-confirm' ||
835
- TERMINAL_STATUSES.has(currentRun.status)
836
- ) {
837
- return null;
838
- }
839
-
840
- if (snapshot.current.dispatch) {
841
- return null;
842
- }
843
-
844
- const payload = buildAutoDispatch(targetDir, currentRun);
845
- if (!payload) {
846
- return null;
847
- }
848
-
849
- return expertDispatch.applyDispatchData({
850
- target: targetDir,
851
- payloadData: payload,
852
- source: 'runner-auto-dispatch',
853
- });
854
- }
855
-
856
- function formatAdvanceRecorded(recorded) {
857
- if (!recorded) {
858
- return null;
859
- }
860
-
861
- return {
862
- dispatch: recorded.dispatch
863
- ? {
864
- run_id: recorded.dispatch.payload.run_id,
865
- role: recorded.dispatch.payload.role.id,
866
- dispatch_id: recorded.dispatch.payload.dispatch_id,
867
- }
868
- : null,
869
- execution: recorded.execution
870
- ? {
871
- run_id: recorded.execution.payload.run_id,
872
- role: recorded.execution.payload.role.id,
873
- execution_id: recorded.execution.payload.execution_id,
874
- }
875
- : null,
876
- runtime_action: recorded.runtime_action
877
- ? {
878
- run_id: recorded.runtime_action.payload.run_id || null,
879
- action: recorded.runtime_action.payload.action || null,
880
- action_id: recorded.runtime_action.payload.action_id || null,
881
- }
882
- : null,
883
- };
884
- }
885
-
886
- function advanceRunner(options) {
887
- const targetDir = path.resolve(process.cwd(), options.target || '.');
888
- const pendingInputs = resolvePendingInputs(targetDir);
889
-
890
- if (pendingInputs.length === 0) {
891
- return {
892
- kind: 'task-orchestrator-runner-advance-result',
893
- status: 'idle',
894
- target: targetDir,
895
- consumed: null,
896
- recorded: null,
897
- applied: null,
898
- next_expected: buildNextExpected(targetDir),
899
- };
900
- }
901
-
902
- if (pendingInputs.length > 1) {
903
- const pendingLabels = pendingInputs.map((item) => item.relPath).join(', ');
904
- throw new Error(`runner inbox has multiple pending inputs: ${pendingLabels}`);
905
- }
906
-
907
- const pending = pendingInputs[0];
908
- let recorded = null;
909
- let applied = null;
910
-
911
- if (pending.kind === 'task-orchestrator-turn') {
912
- const orchestratorTurn = resolveTaskOrchestratorTurn(pending.path);
913
- if (orchestratorTurn.action !== 'bootstrap') {
914
- recorded = {
915
- runtime_action: {
916
- payload: orchestratorTurn.payload,
917
- source: pending.path,
918
- },
919
- };
920
- }
921
- applied = applyRuntimeMutation({
922
- targetDir,
923
- action: orchestratorTurn.action,
924
- payload: orchestratorTurn.payload,
925
- payloadSource: pending.path,
926
- });
927
- } else if (pending.kind === 'expert-dispatch') {
928
- recorded = {
929
- dispatch: expertDispatch.applyDispatch({
930
- target: targetDir,
931
- payload: pending.path,
932
- }),
933
- };
934
- } else if (pending.kind === 'expert-execution') {
935
- recorded = {
936
- execution: expertExecutor.applyExecution({
937
- target: targetDir,
938
- payload: pending.path,
939
- }),
940
- };
941
- const autoRuntimeAction = buildAutoRuntimeAction(targetDir, recorded.execution.payload);
942
- if (autoRuntimeAction) {
943
- if (recorded.execution.archive_result?.archived_artifacts) {
944
- autoRuntimeAction.artifacts = recorded.execution.archive_result.archived_artifacts;
945
- autoRuntimeAction.skip_artifact_check = true;
946
- }
947
- recorded.runtime_action = {
948
- payload: autoRuntimeAction,
949
- source: 'runner-auto-transition',
950
- };
951
- applied = applyRuntimeMutation({
952
- targetDir,
953
- action: autoRuntimeAction.action,
954
- payload: autoRuntimeAction,
955
- payloadSource: 'runner-auto-transition',
956
- });
957
- }
958
- } else if (pending.kind === 'task-orchestrator-runtime-action') {
959
- const runtimeActionPayload = readJsonFile(pending.path, 'runtime action');
960
- recorded = {
961
- runtime_action: {
962
- payload: runtimeActionPayload,
963
- source: pending.path,
964
- },
965
- };
966
- applied = applyRuntimeMutation({
967
- targetDir,
968
- action: runtimeActionPayload.action,
969
- payload: runtimeActionPayload,
970
- payloadSource: pending.path,
971
- });
972
- } else {
973
- throw new Error(`unsupported runner input kind: ${pending.kind}`);
974
- }
975
-
976
- if (!recorded) {
977
- recorded = {};
978
- }
979
-
980
- if (applied) {
981
- const autoDispatch = maybeAutoDispatchCurrentRole(targetDir, applied);
982
- if (autoDispatch) {
983
- recorded.dispatch = autoDispatch;
984
- }
985
- }
986
-
987
- const archivedTo = archiveConsumedInput(targetDir, pending.path, pending.kind);
988
-
989
- return {
990
- kind: 'task-orchestrator-runner-advance-result',
991
- status: 'success',
992
- target: targetDir,
993
- consumed: {
994
- kind: pending.kind,
995
- producer: pending.producer,
996
- path: pending.relPath,
997
- archived_to: archivedTo,
998
- },
999
- recorded: formatAdvanceRecorded(recorded),
1000
- applied: summarizeAppliedState(applied),
1001
- next_expected: buildNextExpected(targetDir),
1002
- };
1003
- }
1004
-
1005
- function advanceRunnerWithRuntimeActionData(options = {}) {
1006
- const targetDir = path.resolve(process.cwd(), options.target || '.');
1007
- const payload = options.payloadData;
1008
- if (!payload || typeof payload !== 'object') {
1009
- throw new Error('Missing runtime-action payloadData for in-memory runner advance');
1010
- }
1011
- if (payload.kind !== 'task-orchestrator-runtime-action') {
1012
- throw new Error(`Expected kind "task-orchestrator-runtime-action" but got "${payload.kind || 'undefined'}"`);
1013
- }
1014
-
1015
- const recorded = {
1016
- runtime_action: {
1017
- payload,
1018
- source: options.source || 'memory-runtime-action',
1019
- },
1020
- };
1021
- const applied = applyRuntimeMutation({
1022
- targetDir,
1023
- action: payload.action,
1024
- payload,
1025
- payloadSource: recorded.runtime_action.source,
1026
- });
1027
-
1028
- if (applied) {
1029
- const autoDispatch = maybeAutoDispatchCurrentRole(targetDir, applied);
1030
- if (autoDispatch) {
1031
- recorded.dispatch = autoDispatch;
1032
- }
1033
- }
1034
-
1035
- return {
1036
- kind: 'task-orchestrator-runner-advance-result',
1037
- status: 'success',
1038
- target: targetDir,
1039
- consumed: null,
1040
- recorded: formatAdvanceRecorded(recorded),
1041
- applied: summarizeAppliedState(applied),
1042
- next_expected: buildNextExpected(targetDir),
1043
- };
1044
- }
1045
-
1046
- function replayReplies(options) {
1047
- const targetDir = path.resolve(process.cwd(), options.target || '.');
1048
- const steps = [];
1049
- let lastApplied = null;
1050
-
1051
- for (let index = 0; index < options.replies.length; index += 1) {
1052
- const replyPath = path.resolve(process.cwd(), options.replies[index]);
1053
- const orchestratorTurn = resolveTaskOrchestratorTurn(replyPath);
1054
- const applied = applyRuntimeMutation({
1055
- targetDir,
1056
- action: orchestratorTurn.action,
1057
- payload: orchestratorTurn.payload,
1058
- payloadSource: replyPath,
1059
- });
1060
-
1061
- lastApplied = applied;
1062
- steps.push({
1063
- index: index + 1,
1064
- reply: replyPath,
1065
- action_source: orchestratorTurn.payload.kind || null,
1066
- action: applied.adapter_action,
1067
- run_id: applied.result?.state?.run_id || null,
1068
- status: applied.result?.state?.status || null,
1069
- current_role: applied.result?.state?.current_role || null,
1070
- pending_gate: applied.result?.state?.pending_gate || null,
1071
- });
1072
- }
1073
-
1074
- const finalState = lastApplied?.result?.state || null;
1075
- return {
1076
- kind: 'task-orchestrator-runner-result',
1077
- status: 'success',
1078
- target: targetDir,
1079
- steps,
1080
- summary: {
1081
- step_count: steps.length,
1082
- run_id: finalState?.run_id || null,
1083
- status: finalState?.status || null,
1084
- current_role: finalState?.current_role || null,
1085
- pending_gate: finalState?.pending_gate || null,
1086
- },
1087
- state: finalState,
1088
- };
1089
- }
1090
-
1091
- function printPretty(result) {
1092
- if (result.kind === 'task-orchestrator-runner-status') {
1093
- console.log('task-orchestrator runner status');
1094
- console.log(` target: ${result.target}`);
1095
- console.log(` run_id: ${result.current.run_id || 'n/a'}`);
1096
- console.log(` run_status: ${result.current.run_status || 'n/a'}`);
1097
- console.log(` current_role: ${result.current.current_role || 'n/a'}`);
1098
- console.log(` pending_gate: ${result.current.pending_gate || 'n/a'}`);
1099
- console.log(` pending_inputs: ${result.pending_inputs.length}`);
1100
- for (const pending of result.pending_inputs) {
1101
- console.log(` pending -> ${pending.kind} @ ${pending.path}`);
1102
- }
1103
- console.log(` next_expected: ${result.next_expected.producer || 'none'}`);
1104
- for (const file of result.next_expected.files) {
1105
- console.log(` - ${file}`);
1106
- }
1107
- return;
1108
- }
1109
-
1110
- if (result.kind === 'task-orchestrator-runner-advance-result') {
1111
- console.log('task-orchestrator runner advanced');
1112
- console.log(` target: ${result.target}`);
1113
- console.log(` status: ${result.status}`);
1114
- if (result.consumed) {
1115
- console.log(` consumed: ${result.consumed.kind} <- ${result.consumed.path}`);
1116
- console.log(` archived_to: ${result.consumed.archived_to}`);
1117
- }
1118
- if (result.applied) {
1119
- console.log(` adapter_action: ${result.applied.adapter_action}`);
1120
- console.log(` run_id: ${result.applied.run_id || 'n/a'}`);
1121
- console.log(` run_status: ${result.applied.status || 'n/a'}`);
1122
- console.log(` current_role: ${result.applied.current_role || 'n/a'}`);
1123
- }
1124
- console.log(` next_expected: ${result.next_expected.producer || 'none'}`);
1125
- for (const file of result.next_expected.files) {
1126
- console.log(` - ${file}`);
1127
- }
1128
- return;
1129
- }
1130
-
1131
- console.log('task-orchestrator runner replayed');
1132
- console.log(` target: ${result.target}`);
1133
- console.log(` steps: ${result.summary.step_count}`);
1134
- console.log(` run_id: ${result.summary.run_id || 'n/a'}`);
1135
- console.log(` status: ${result.summary.status || 'n/a'}`);
1136
- console.log(` current_role: ${result.summary.current_role || 'n/a'}`);
1137
- console.log(` pending_gate: ${result.summary.pending_gate || 'n/a'}`);
1138
-
1139
- for (const step of result.steps) {
1140
- console.log(` [${step.index}] ${step.action} <- ${step.reply}`);
1141
- }
1142
- }
1143
-
1144
- function main(argv = process.argv.slice(2)) {
1145
- const { command, options } = parseArgs(argv);
1146
-
1147
- if (!command || options.help || command === 'help' || command === '--help' || command === '-h') {
1148
- printUsage();
1149
- return 0;
1150
- }
1151
-
1152
- if (command === 'status') {
1153
- const result = buildStatus(path.resolve(process.cwd(), options.target || '.'));
1154
- if (options.json) {
1155
- console.log(JSON.stringify(result, null, 2));
1156
- } else {
1157
- printPretty(result);
1158
- }
1159
- return 0;
1160
- }
1161
-
1162
- if (command === 'advance') {
1163
- const result = advanceRunner(options);
1164
- if (options.json) {
1165
- console.log(JSON.stringify(result, null, 2));
1166
- } else {
1167
- printPretty(result);
1168
- }
1169
- return 0;
1170
- }
1171
-
1172
- if (command !== 'replay') {
1173
- throw new Error(`Unsupported task-orchestrator-runner command: ${command}`);
1174
- }
1175
-
1176
- if (options.replies.length === 0) {
1177
- throw new Error('Missing runner input: use --reply <file> at least once');
1178
- }
1179
-
1180
- const result = replayReplies(options);
1181
-
1182
- if (options.json) {
1183
- console.log(JSON.stringify(result, null, 2));
1184
- } else {
1185
- printPretty(result);
1186
- }
1187
-
1188
- return 0;
1189
- }
1190
-
1191
- if (require.main === module) {
1192
- try {
1193
- const exitCode = main();
1194
- process.exit(exitCode);
1195
- } catch (error) {
1196
- console.error(`task-orchestrator-runner error: ${error.message}`);
1197
- process.exit(1);
1198
- }
1199
- }
1200
-
1201
- module.exports = {
1202
- main,
1203
- parseArgs,
1204
- buildStatus,
1205
- advanceRunner,
1206
- advanceRunnerWithRuntimeActionData,
1207
- replayReplies,
1208
- };
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const crypto = require('crypto');
5
+ const runtimeState = require('./runtime-state');
6
+ const extractor = require('./task-orchestrator-extractor');
7
+ const expertDispatch = require('./expert-dispatch');
8
+ const expertExecutor = require('./expert-executor');
9
+ const {
10
+ buildAutoRuntimeAction,
11
+ guardRuntimeActionForIncompleteExecution,
12
+ getRuntimeTransition,
13
+ } = require('./execution-semantics');
14
+ const {
15
+ resolveRuntimePaths,
16
+ getCandidatePaths,
17
+ shouldPersistHistory,
18
+ } = require('./runtime-paths');
19
+
20
+ const INBOX_SPECS = [
21
+ {
22
+ kind: 'task-orchestrator-turn',
23
+ pathKey: 'tmpTaskOrchestratorTurn',
24
+ producer: 'task-orchestrator',
25
+ },
26
+ {
27
+ kind: 'expert-dispatch',
28
+ pathKey: 'tmpCurrentDispatch',
29
+ producer: 'task-orchestrator',
30
+ },
31
+ {
32
+ kind: 'expert-execution',
33
+ pathKey: 'tmpCurrentExecution',
34
+ producer: 'current-expert',
35
+ },
36
+ {
37
+ kind: 'task-orchestrator-runtime-action',
38
+ pathKey: 'tmpCurrentRuntimeAction',
39
+ producer: 'task-orchestrator',
40
+ },
41
+ ];
42
+
43
+ const TERMINAL_STATUSES = new Set(['success', 'failed', 'cancelled']);
44
+ const AUTO_DISPATCH_ALLOWED_ACTIONS = new Set(['bootstrap', 'handoff', 'approve', 'resume']);
45
+ const ROLE_METADATA = {
46
+ 'requirement-analyst': {
47
+ name: '需求解析专家',
48
+ source: '.agents/roles/common/requirement-analyst.md',
49
+ },
50
+ 'frontend-implementer': {
51
+ name: '前端实现专家',
52
+ source: '.agents/roles/common/frontend-implementer.md',
53
+ },
54
+ 'code-guardian': {
55
+ name: '规范守护者',
56
+ source: '.agents/roles/common/code-guardian.md',
57
+ },
58
+ 'archive-change': {
59
+ name: '归档专家',
60
+ source: '.agents/roles/common/archive-change.md',
61
+ },
62
+ 'design-collaborator': {
63
+ name: '设计协作专家',
64
+ source: '.agents/roles/domains/demand-design/design-collaborator.md',
65
+ },
66
+ 'api-contract-specialist': {
67
+ name: 'API 契约专家',
68
+ source: '.agents/roles/domains/demand-design/api-contract-specialist.md',
69
+ },
70
+ 'unit-test-specialist': {
71
+ name: '单元测试专家',
72
+ source: '.agents/roles/domains/testing/unit-test-specialist.md',
73
+ },
74
+ 'verification-reviewer': {
75
+ name: '验证评审专家',
76
+ source: '.agents/roles/domains/testing/verification-reviewer.md',
77
+ },
78
+ 'performance-auditor': {
79
+ name: '性能审计专家',
80
+ source: '.agents/roles/domains/performance/performance-auditor.md',
81
+ },
82
+ };
83
+ const ROLE_EXPECTED_OUTPUTS = {
84
+ 'requirement-analyst': {
85
+ compact: ['完成短版 proposal.md', '完成短版 spec.md', '完成短版 tasks.md'],
86
+ full: ['完成 proposal.md', '完成 spec.md', '完成 tasks.md'],
87
+ },
88
+ 'frontend-implementer': {
89
+ compact: ['完成最小必要实现', '保持改动最小化并记录验证结果'],
90
+ full: ['完成当前范围内代码实现', '记录实现说明与验证结果'],
91
+ },
92
+ 'code-guardian': {
93
+ compact: ['完成短版 checklist.md', '完成短版 iterations.md', '给出交付结论'],
94
+ full: ['完成 checklist.md', '完成 iterations.md', '给出交付结论'],
95
+ },
96
+ 'archive-change': {
97
+ compact: ['合并当前增量规范', '完成变更归档', '结束本次运行'],
98
+ full: ['合并当前增量规范到 openspec/specs', '完成变更归档', '结束本次运行'],
99
+ },
100
+ 'design-collaborator': {
101
+ compact: ['补充最小 UI 约束与设计疑问'],
102
+ full: ['补充 UI 分析清单与设计待确认项'],
103
+ },
104
+ 'api-contract-specialist': {
105
+ compact: ['补充最小接口契约约束'],
106
+ full: ['补充接口契约说明与待确认字段'],
107
+ },
108
+ 'unit-test-specialist': {
109
+ compact: ['补充关键测试建议'],
110
+ full: ['补充单元测试策略与高风险边界场景'],
111
+ },
112
+ 'verification-reviewer': {
113
+ compact: ['补充关键验收结论'],
114
+ full: ['补充验证评审意见与验收风险'],
115
+ },
116
+ 'performance-auditor': {
117
+ compact: ['补充关键性能风险'],
118
+ full: ['补充性能审计结论与优化优先级'],
119
+ },
120
+ };
121
+
122
+ function printUsage() {
123
+ console.log(`Internal usage:
124
+ require('./task-orchestrator-runner').advanceRunner({ target })
125
+ require('./task-orchestrator-runner').buildStatus(target)
126
+ require('./task-orchestrator-runner').replayReplies({ target, replies })
127
+
128
+ Options:
129
+ --reply <file> Path to a task-orchestrator Markdown reply file; can be repeated
130
+ --target <dir> Target project directory (default: .)
131
+ --json Print JSON result
132
+ --pretty Print readable summary (default)
133
+ --help Show this help
134
+ `);
135
+ }
136
+
137
+ function parseArgs(argv) {
138
+ const args = [...argv];
139
+ const command = args.shift();
140
+ const options = {
141
+ target: '.',
142
+ replies: [],
143
+ pretty: true,
144
+ json: false,
145
+ };
146
+
147
+ while (args.length > 0) {
148
+ const arg = args.shift();
149
+ switch (arg) {
150
+ case '--reply':
151
+ options.replies.push(args.shift());
152
+ break;
153
+ case '--target':
154
+ options.target = args.shift();
155
+ break;
156
+ case '--json':
157
+ options.json = true;
158
+ options.pretty = false;
159
+ break;
160
+ case '--pretty':
161
+ options.pretty = true;
162
+ options.json = false;
163
+ break;
164
+ case '--help':
165
+ case '-h':
166
+ options.help = true;
167
+ break;
168
+ default:
169
+ throw new Error(`Unknown argument: ${arg}`);
170
+ }
171
+ }
172
+
173
+ return { command, options };
174
+ }
175
+
176
+ function readTextFile(filePath, label) {
177
+ const raw = fs.readFileSync(filePath, 'utf8');
178
+ if (!raw.trim()) {
179
+ throw new Error(`${label} is empty: ${filePath}`);
180
+ }
181
+ return raw;
182
+ }
183
+
184
+ function readJsonFile(filePath, label) {
185
+ const raw = fs.readFileSync(filePath, 'utf8');
186
+ try {
187
+ return JSON.parse(raw);
188
+ } catch (error) {
189
+ throw new Error(`${label} is not valid JSON: ${filePath}`);
190
+ }
191
+ }
192
+
193
+ function ensureDir(dirPath) {
194
+ fs.mkdirSync(dirPath, { recursive: true });
195
+ }
196
+
197
+ function loadJsonIfExists(filePath, label) {
198
+ if (!fs.existsSync(filePath)) {
199
+ return null;
200
+ }
201
+ return readJsonFile(filePath, label);
202
+ }
203
+
204
+ function parseScalar(value) {
205
+ const trimmed = value.trim();
206
+ if (trimmed === '') {
207
+ return '';
208
+ }
209
+ if (trimmed === '[]') {
210
+ return [];
211
+ }
212
+ if (
213
+ (trimmed.startsWith('"') && trimmed.endsWith('"')) ||
214
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))
215
+ ) {
216
+ return trimmed.slice(1, -1);
217
+ }
218
+ return trimmed;
219
+ }
220
+
221
+ function parseFrontmatter(fileContent) {
222
+ const lines = fileContent.split('\n');
223
+ if (lines[0] !== '---') {
224
+ return {};
225
+ }
226
+
227
+ const endIndex = lines.indexOf('---', 1);
228
+ if (endIndex === -1) {
229
+ return {};
230
+ }
231
+
232
+ const frontmatterLines = lines.slice(1, endIndex);
233
+ const data = {};
234
+ let currentKey = null;
235
+
236
+ for (const line of frontmatterLines) {
237
+ const listMatch = line.match(/^\s*-\s+(.*)$/);
238
+ if (listMatch && currentKey) {
239
+ if (!Array.isArray(data[currentKey])) {
240
+ data[currentKey] = [];
241
+ }
242
+ data[currentKey].push(parseScalar(listMatch[1]));
243
+ continue;
244
+ }
245
+
246
+ const keyMatch = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
247
+ if (!keyMatch) {
248
+ currentKey = null;
249
+ continue;
250
+ }
251
+
252
+ const [, key, rawValue] = keyMatch;
253
+ if (rawValue.trim() === '') {
254
+ data[key] = [];
255
+ currentKey = key;
256
+ continue;
257
+ }
258
+
259
+ data[key] = parseScalar(rawValue);
260
+ currentKey = null;
261
+ }
262
+
263
+ return data;
264
+ }
265
+
266
+ function loadRoleMetadata(targetDir, roleId) {
267
+ const fallback = ROLE_METADATA[roleId] || {
268
+ name: roleId,
269
+ source: null,
270
+ };
271
+
272
+ if (!fallback.source) {
273
+ return {
274
+ id: roleId,
275
+ name: fallback.name,
276
+ source: null,
277
+ preferred_skills: [],
278
+ };
279
+ }
280
+
281
+ const sourcePath = path.join(targetDir, fallback.source);
282
+ if (!fs.existsSync(sourcePath)) {
283
+ return {
284
+ id: roleId,
285
+ name: fallback.name,
286
+ source: fallback.source,
287
+ preferred_skills: [],
288
+ };
289
+ }
290
+
291
+ const frontmatter = parseFrontmatter(fs.readFileSync(sourcePath, 'utf8'));
292
+ return {
293
+ id: roleId,
294
+ name: frontmatter.name || fallback.name,
295
+ source: fallback.source,
296
+ preferred_skills: Array.isArray(frontmatter.preferred_skills) ? frontmatter.preferred_skills : [],
297
+ };
298
+ }
299
+
300
+ function inferProjectProfile(targetDir) {
301
+ const manifestCandidates = [
302
+ path.join(targetDir, '.ai-spec', 'manifest.json'),
303
+ path.join(targetDir, 'manifest.json'),
304
+ ];
305
+
306
+ for (const filePath of manifestCandidates) {
307
+ if (!fs.existsSync(filePath)) {
308
+ continue;
309
+ }
310
+ try {
311
+ const json = readJsonFile(filePath, 'manifest');
312
+ if (json.profile) {
313
+ return json.profile;
314
+ }
315
+ } catch (error) {
316
+ // ignore malformed local manifest during runtime inference
317
+ }
318
+ }
319
+
320
+ const packagePath = path.join(targetDir, 'package.json');
321
+ if (fs.existsSync(packagePath)) {
322
+ try {
323
+ const pkg = readJsonFile(packagePath, 'package.json');
324
+ const deps = {
325
+ ...(pkg.dependencies || {}),
326
+ ...(pkg.devDependencies || {}),
327
+ };
328
+ if (deps.vue) {
329
+ return 'vue';
330
+ }
331
+ if (deps.react) {
332
+ return 'react';
333
+ }
334
+ } catch (error) {
335
+ // ignore
336
+ }
337
+ }
338
+
339
+ return 'unknown';
340
+ }
341
+
342
+ function resolveExistingRuntimeEntry(entry) {
343
+ for (const candidatePath of getCandidatePaths(entry)) {
344
+ if (!fs.existsSync(candidatePath)) {
345
+ continue;
346
+ }
347
+
348
+ return {
349
+ path: candidatePath,
350
+ relPath: candidatePath === entry.path ? entry.relPath : entry.legacyRelPath,
351
+ exists: true,
352
+ };
353
+ }
354
+
355
+ return {
356
+ path: entry.path,
357
+ relPath: entry.relPath,
358
+ exists: false,
359
+ };
360
+ }
361
+
362
+ function createRunnerSnapshot(targetDir) {
363
+ const runtimePaths = resolveRuntimePaths(targetDir);
364
+ const currentDispatchEntry = resolveExistingRuntimeEntry(runtimePaths.currentDispatch);
365
+ const currentExecutionEntry = resolveExistingRuntimeEntry(runtimePaths.currentExecutionJson);
366
+ const currentRuntimeActionEntry = resolveExistingRuntimeEntry(runtimePaths.currentRuntimeActionJson);
367
+
368
+ const pendingInputs = [];
369
+ for (const spec of INBOX_SPECS) {
370
+ const entry = resolveExistingRuntimeEntry(runtimePaths[spec.pathKey]);
371
+ if (!entry.exists) {
372
+ continue;
373
+ }
374
+
375
+ pendingInputs.push({
376
+ ...spec,
377
+ path: entry.path,
378
+ relPath: entry.relPath,
379
+ exists: true,
380
+ });
381
+ }
382
+
383
+ return {
384
+ targetDir,
385
+ runtimePaths,
386
+ pendingInputs,
387
+ current: {
388
+ run: loadJsonIfExists(runtimePaths.currentRun.path, 'current run-state'),
389
+ dispatch: currentDispatchEntry.exists ? readJsonFile(currentDispatchEntry.path, 'current dispatch') : null,
390
+ execution: currentExecutionEntry.exists ? readJsonFile(currentExecutionEntry.path, 'current execution') : null,
391
+ runtimeAction: currentRuntimeActionEntry.exists ? readJsonFile(currentRuntimeActionEntry.path, 'current runtime action') : null,
392
+ },
393
+ };
394
+ }
395
+
396
+ function resolvePendingInputs(targetDir, snapshot = null) {
397
+ const activeSnapshot = snapshot || createRunnerSnapshot(targetDir);
398
+ return activeSnapshot.pendingInputs.map((item) => ({ ...item }));
399
+ }
400
+
401
+ function loadCurrentArtifacts(targetDir, snapshot = null) {
402
+ const activeSnapshot = snapshot || createRunnerSnapshot(targetDir);
403
+ return {
404
+ run: activeSnapshot.current.run,
405
+ dispatch: activeSnapshot.current.dispatch,
406
+ execution: activeSnapshot.current.execution,
407
+ runtimeAction: activeSnapshot.current.runtimeAction,
408
+ };
409
+ }
410
+
411
+ function buildNextExpectedFromSnapshot(snapshot) {
412
+ const pendingInputs = snapshot.pendingInputs;
413
+ const runtimePaths = snapshot.runtimePaths;
414
+ if (pendingInputs.length > 0) {
415
+ return {
416
+ producer: 'runner',
417
+ files: pendingInputs.map((item) => item.relPath),
418
+ reason: 'runner inbox still has pending input; consume it before requesting new AI output',
419
+ };
420
+ }
421
+
422
+ const current = snapshot.current;
423
+
424
+ if (!current.run) {
425
+ return {
426
+ producer: 'task-orchestrator',
427
+ files: [runtimePaths.tmpTaskOrchestratorTurn.relPath],
428
+ reason: 'no current run-state yet; waiting for task-orchestrator bootstrap turn',
429
+ };
430
+ }
431
+
432
+ if (TERMINAL_STATUSES.has(current.run.status)) {
433
+ return {
434
+ producer: null,
435
+ files: [],
436
+ reason: 'run is already in terminal state',
437
+ };
438
+ }
439
+
440
+ if (String(current.run.status || '').trim().toLowerCase() === 'paused') {
441
+ return {
442
+ producer: 'task-orchestrator',
443
+ files: [],
444
+ reason: 'run is paused and waiting for resume',
445
+ };
446
+ }
447
+
448
+ if (String(current.run.status || '').trim().toLowerCase() === 'waiting-confirm') {
449
+ return {
450
+ producer: 'task-orchestrator',
451
+ files: [],
452
+ reason: 'run is waiting at confirm gate before continuing',
453
+ };
454
+ }
455
+
456
+ if (current.execution) {
457
+ return {
458
+ producer: 'task-orchestrator',
459
+ files: [
460
+ runtimePaths.tmpTaskOrchestratorTurn.relPath,
461
+ runtimePaths.tmpCurrentRuntimeAction.relPath,
462
+ ],
463
+ reason: 'expert execution has been recorded; waiting for task-orchestrator runtime action',
464
+ };
465
+ }
466
+
467
+ if (current.dispatch) {
468
+ return {
469
+ producer: current.dispatch.role?.id || 'current-expert',
470
+ files: [runtimePaths.tmpCurrentExecution.relPath],
471
+ reason: 'current expert dispatch is active; waiting for expert execution output',
472
+ };
473
+ }
474
+
475
+ if (current.run.pending_gate) {
476
+ return {
477
+ producer: 'task-orchestrator',
478
+ files: [
479
+ runtimePaths.tmpTaskOrchestratorTurn.relPath,
480
+ runtimePaths.tmpCurrentRuntimeAction.relPath,
481
+ ],
482
+ reason: `run is waiting at approval gate "${current.run.pending_gate}"`,
483
+ };
484
+ }
485
+
486
+ return {
487
+ producer: 'task-orchestrator',
488
+ files: [runtimePaths.tmpCurrentDispatch.relPath],
489
+ reason: 'run-state is ready for the next expert dispatch',
490
+ };
491
+ }
492
+
493
+ function buildNextExpected(targetDir, snapshot = null) {
494
+ return buildNextExpectedFromSnapshot(snapshot || createRunnerSnapshot(targetDir));
495
+ }
496
+
497
+ function buildStatus(targetDir) {
498
+ const snapshot = createRunnerSnapshot(targetDir);
499
+ const pendingInputs = snapshot.pendingInputs;
500
+ const current = snapshot.current;
501
+ const nextExpected = buildNextExpectedFromSnapshot(snapshot);
502
+
503
+ return {
504
+ kind: 'task-orchestrator-runner-status',
505
+ status: pendingInputs.length > 1 ? 'blocked' : 'ready',
506
+ target: targetDir,
507
+ pending_inputs: pendingInputs.map((item) => ({
508
+ kind: item.kind,
509
+ producer: item.producer,
510
+ path: item.relPath,
511
+ })),
512
+ current: {
513
+ run_id: current.run?.run_id || null,
514
+ run_status: current.run?.status || null,
515
+ mode: current.run?.mode || null,
516
+ review_policy: current.run?.review_policy || null,
517
+ current_role: current.run?.current_role || null,
518
+ pending_gate: current.run?.pending_gate || null,
519
+ dispatch_role: current.dispatch?.role?.id || null,
520
+ execution_role: current.execution?.role?.id || null,
521
+ runtime_action: current.runtimeAction?.action || null,
522
+ },
523
+ next_expected: nextExpected,
524
+ };
525
+ }
526
+
527
+ function archiveConsumedInput(targetDir, filePath, kind) {
528
+ if (!fs.existsSync(filePath)) {
529
+ return null;
530
+ }
531
+
532
+ if (!shouldPersistHistory()) {
533
+ fs.unlinkSync(filePath);
534
+ return null;
535
+ }
536
+
537
+ const runtimePaths = resolveRuntimePaths(targetDir);
538
+ const consumedDir = runtimePaths.runnerConsumedDir.path;
539
+ ensureDir(consumedDir);
540
+
541
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
542
+ const archivedPath = path.join(consumedDir, `${stamp}__${kind}__${path.basename(filePath)}`);
543
+ fs.renameSync(filePath, archivedPath);
544
+
545
+ return archivedPath;
546
+ }
547
+
548
+ function summarizeAppliedState(applied) {
549
+ if (!applied || !applied.result || !applied.result.state) {
550
+ return null;
551
+ }
552
+
553
+ return {
554
+ adapter_action: applied.adapter_action,
555
+ run_id: applied.result.state.run_id || null,
556
+ status: applied.result.state.status || null,
557
+ current_role: applied.result.state.current_role || null,
558
+ pending_gate: applied.result.state.pending_gate || null,
559
+ };
560
+ }
561
+
562
+ function buildRuntimeOptionsFromPayload(payload, targetDir) {
563
+ const options = {
564
+ target: targetDir,
565
+ };
566
+ const mappings = [
567
+ ['runId', ['run_id', 'runId']],
568
+ ['toRole', ['to_role', 'toRole']],
569
+ ['nextRole', ['next_role', 'nextRole']],
570
+ ['fromRole', ['from_role', 'fromRole']],
571
+ ['gate', ['gate']],
572
+ ['pendingGate', ['pending_gate', 'pendingGate']],
573
+ ['blockedByRole', ['blocked_by_role', 'blockedByRole']],
574
+ ['resumeToRole', ['resume_to_role', 'resumeToRole']],
575
+ ['requiredUserAction', ['required_user_action', 'requiredUserAction']],
576
+ ['blockedReason', ['blocked_reason', 'blockedReason']],
577
+ ['message', ['message']],
578
+ ['error', ['error']],
579
+ ['eventType', ['event_type', 'eventType']],
580
+ ['status', ['status']],
581
+ ];
582
+
583
+ for (const [targetKey, sourceKeys] of mappings) {
584
+ for (const sourceKey of sourceKeys) {
585
+ if (Object.prototype.hasOwnProperty.call(payload, sourceKey)) {
586
+ options[targetKey] = payload[sourceKey];
587
+ break;
588
+ }
589
+ }
590
+ }
591
+
592
+ if (Object.prototype.hasOwnProperty.call(payload, 'clear_pending_gate') || Object.prototype.hasOwnProperty.call(payload, 'clearPendingGate')) {
593
+ options.clearPendingGate = Boolean(
594
+ Object.prototype.hasOwnProperty.call(payload, 'clear_pending_gate')
595
+ ? payload.clear_pending_gate
596
+ : payload.clearPendingGate,
597
+ );
598
+ }
599
+
600
+ if (payload.task_anchor || payload.taskAnchor) {
601
+ options.taskAnchorData = payload.task_anchor || payload.taskAnchor;
602
+ }
603
+ if (payload.artifacts && typeof payload.artifacts === 'object') {
604
+ options.artifactsData = payload.artifacts;
605
+ }
606
+ if (payload.verification && typeof payload.verification === 'object') {
607
+ options.verificationData = payload.verification;
608
+ }
609
+ if (payload.auto_fix && typeof payload.auto_fix === 'object') {
610
+ options.autoFixData = payload.auto_fix;
611
+ }
612
+ if (Object.prototype.hasOwnProperty.call(payload, 'skip_artifact_check') || Object.prototype.hasOwnProperty.call(payload, 'skipArtifactCheck')) {
613
+ options.skipArtifactCheck = Boolean(
614
+ Object.prototype.hasOwnProperty.call(payload, 'skip_artifact_check')
615
+ ? payload.skip_artifact_check
616
+ : payload.skipArtifactCheck
617
+ );
618
+ }
619
+
620
+ return options;
621
+ }
622
+
623
+ function clearCurrentExpertArtifacts(targetDir) {
624
+ return {
625
+ dispatch: expertDispatch.clearDispatch({ target: targetDir }),
626
+ execution: expertExecutor.clearExecution({ target: targetDir }),
627
+ runtime_action: expertExecutor.clearRuntimeAction({ target: targetDir }),
628
+ };
629
+ }
630
+
631
+ function applyRuntimeMutation({ targetDir, action, payload, payloadSource }) {
632
+ const guardedPayload = guardRuntimeActionForIncompleteExecution(targetDir, payload);
633
+ const normalizedAction = String(guardedPayload.action || action || '').toLowerCase();
634
+ let result = null;
635
+
636
+ if (normalizedAction === 'bootstrap') {
637
+ result = runtimeState.bootstrapRunState({
638
+ target: targetDir,
639
+ payloadData: guardedPayload,
640
+ });
641
+ } else {
642
+ const runtimeOptions = buildRuntimeOptionsFromPayload(guardedPayload, targetDir);
643
+ switch (normalizedAction) {
644
+ case 'handoff':
645
+ result = runtimeState.handoffRunState(runtimeOptions);
646
+ break;
647
+ case 'approve':
648
+ result = runtimeState.approveRunState(runtimeOptions);
649
+ break;
650
+ case 'resume':
651
+ result = runtimeState.resumeRunState(runtimeOptions);
652
+ break;
653
+ case 'pause':
654
+ case 'paused':
655
+ result = runtimeState.pauseRunState(runtimeOptions);
656
+ break;
657
+ case 'gate-blocked':
658
+ case 'blocked':
659
+ result = runtimeState.gateBlockedRunState(runtimeOptions);
660
+ break;
661
+ case 'status':
662
+ result = runtimeState.statusRunState(runtimeOptions);
663
+ break;
664
+ case 'complete':
665
+ case 'completed':
666
+ result = runtimeState.completeRunState(runtimeOptions);
667
+ break;
668
+ case 'fail':
669
+ case 'failed':
670
+ result = runtimeState.failRunState(runtimeOptions);
671
+ break;
672
+ case 'cancel':
673
+ case 'cancelled':
674
+ result = runtimeState.cancelRunState(runtimeOptions);
675
+ break;
676
+ default:
677
+ throw new Error(`Unsupported runtime action: ${action}`);
678
+ }
679
+ }
680
+
681
+ const applied = {
682
+ adapter_action: normalizedAction === 'completed' ? 'complete' : normalizedAction,
683
+ adapter_source: payloadSource,
684
+ result,
685
+ };
686
+
687
+ if (['bootstrap', 'handoff', 'approve', 'resume', 'pause', 'gate-blocked', 'complete', 'fail', 'cancel'].includes(applied.adapter_action)) {
688
+ return {
689
+ ...applied,
690
+ ...clearCurrentExpertArtifacts(targetDir),
691
+ };
692
+ }
693
+
694
+ return applied;
695
+ }
696
+
697
+ function tryReadJsonValue(filePath) {
698
+ try {
699
+ return readJsonFile(filePath, 'task-orchestrator turn');
700
+ } catch (error) {
701
+ return null;
702
+ }
703
+ }
704
+
705
+ function resolveTaskOrchestratorTurn(filePath) {
706
+ const parsed = tryReadJsonValue(filePath);
707
+ if (parsed && typeof parsed === 'object') {
708
+ if (parsed.kind === 'run-plan' || parsed.kind === 'task-orchestrator-bootstrap' || parsed.run_plan || parsed.runPlan) {
709
+ return {
710
+ action: 'bootstrap',
711
+ payload: parsed,
712
+ };
713
+ }
714
+
715
+ if (parsed.kind === 'task-orchestrator-runtime-action' || parsed.kind === 'task-orchestrator-runtime-event') {
716
+ return {
717
+ action: parsed.action || parsed.event,
718
+ payload: parsed,
719
+ };
720
+ }
721
+ }
722
+
723
+ const replyText = readTextFile(filePath, 'task-orchestrator turn');
724
+ const extracted = extractor.extractPayloadFromText(replyText, filePath);
725
+ return {
726
+ action: extracted.action,
727
+ payload: extracted.payload,
728
+ };
729
+ }
730
+
731
+ function readCurrentRun(targetDir) {
732
+ return createRunnerSnapshot(targetDir).current.run;
733
+ }
734
+
735
+ function buildTaskAnchorForRole(currentRun, currentRole, nextRole) {
736
+ const anchor = currentRun.anchor || {};
737
+ return {
738
+ schema_version: 1,
739
+ kind: 'task-anchor',
740
+ task: {
741
+ ...(anchor.task || {}),
742
+ raw_goal: anchor.task?.raw_goal || currentRun.trigger?.raw_input || null,
743
+ change_id: anchor.task?.change_id || currentRun.task?.change_id || null,
744
+ input_kind: anchor.task?.input_kind || currentRun.task?.input_kind || 'natural-language',
745
+ },
746
+ stage: {
747
+ ...(anchor.stage || {}),
748
+ flow_id: anchor.stage?.flow_id || currentRun.flow?.id || null,
749
+ current_role: currentRole,
750
+ next_role: nextRole,
751
+ },
752
+ constraints: anchor.constraints || null,
753
+ artifacts: anchor.artifacts || currentRun.artifacts || null,
754
+ expected_output: anchor.expected_output || [],
755
+ };
756
+ }
757
+
758
+ function buildAutoDispatch(targetDir, currentRun) {
759
+ if (!currentRun || !currentRun.current_role || TERMINAL_STATUSES.has(currentRun.status)) {
760
+ return null;
761
+ }
762
+ if (currentRun.pending_gate) {
763
+ return null;
764
+ }
765
+
766
+ const roleId = currentRun.current_role;
767
+ const transition = getRuntimeTransition(targetDir, currentRun.flow?.id || '', roleId);
768
+ const role = loadRoleMetadata(targetDir, roleId);
769
+ const artifactProfile = currentRun.artifact_profile || 'full';
770
+ const deliveryProfile = currentRun.delivery_profile || null;
771
+ const expectedOutput = ROLE_EXPECTED_OUTPUTS[roleId]?.[artifactProfile] || ROLE_EXPECTED_OUTPUTS[roleId]?.full || [];
772
+ const immediateNextRole = transition?.action === 'handoff'
773
+ ? transition.to_role || null
774
+ : transition?.next_role || null;
775
+ const nextRole = currentRun.anchor?.stage?.next_role !== undefined
776
+ ? currentRun.anchor?.stage?.next_role
777
+ : immediateNextRole;
778
+ const preferredSkills = Array.isArray(role.preferred_skills)
779
+ ? role.preferred_skills.filter((id) => {
780
+ if (deliveryProfile !== 'micro') {
781
+ return true;
782
+ }
783
+ const microAllowlist = {
784
+ 'requirement-analyst': new Set(['create-proposal', 'design-analysis']),
785
+ 'frontend-implementer': new Set(['create-view', 'create-route', 'create-api', 'theme-variables', 'create-component', 'create-store']),
786
+ 'code-guardian': new Set(['ui-verification', 'web-design-guidelines']),
787
+ };
788
+ return microAllowlist[roleId]?.has(id) ?? true;
789
+ })
790
+ : [];
791
+
792
+ return {
793
+ schema_version: 1,
794
+ kind: 'expert-dispatch',
795
+ run_id: currentRun.run_id,
796
+ status: currentRun.status === 'planned' ? 'planned' : 'running',
797
+ role,
798
+ task: {
799
+ raw_goal: currentRun.anchor?.task?.raw_goal || currentRun.trigger?.raw_input || null,
800
+ change_id: currentRun.task?.change_id || currentRun.anchor?.task?.change_id || null,
801
+ },
802
+ flow: {
803
+ id: currentRun.flow?.id || null,
804
+ },
805
+ execution: {
806
+ profile: inferProjectProfile(targetDir),
807
+ delivery_profile: deliveryProfile,
808
+ artifact_profile: currentRun.artifact_profile || null,
809
+ current_role: roleId,
810
+ next_role: nextRole,
811
+ pending_gate: currentRun.pending_gate || null,
812
+ expected_output: expectedOutput,
813
+ skills: preferredSkills.map((id) => ({ id })),
814
+ },
815
+ anchor: buildTaskAnchorForRole(currentRun, roleId, nextRole),
816
+ instructions: {
817
+ source: role.source,
818
+ markdown: `# ${roleId}`,
819
+ },
820
+ };
821
+ }
822
+
823
+ function maybeAutoDispatchCurrentRole(targetDir, applied) {
824
+ if (!applied || !AUTO_DISPATCH_ALLOWED_ACTIONS.has(applied.adapter_action)) {
825
+ return null;
826
+ }
827
+
828
+ const snapshot = createRunnerSnapshot(targetDir);
829
+ const currentRun = snapshot.current.run;
830
+ if (
831
+ !currentRun ||
832
+ !currentRun.current_role ||
833
+ currentRun.pending_gate ||
834
+ String(currentRun.status || '').trim().toLowerCase() === 'waiting-confirm' ||
835
+ TERMINAL_STATUSES.has(currentRun.status)
836
+ ) {
837
+ return null;
838
+ }
839
+
840
+ if (snapshot.current.dispatch) {
841
+ return null;
842
+ }
843
+
844
+ const payload = buildAutoDispatch(targetDir, currentRun);
845
+ if (!payload) {
846
+ return null;
847
+ }
848
+
849
+ return expertDispatch.applyDispatchData({
850
+ target: targetDir,
851
+ payloadData: payload,
852
+ source: 'runner-auto-dispatch',
853
+ });
854
+ }
855
+
856
+ function formatAdvanceRecorded(recorded) {
857
+ if (!recorded) {
858
+ return null;
859
+ }
860
+
861
+ return {
862
+ dispatch: recorded.dispatch
863
+ ? {
864
+ run_id: recorded.dispatch.payload.run_id,
865
+ role: recorded.dispatch.payload.role.id,
866
+ dispatch_id: recorded.dispatch.payload.dispatch_id,
867
+ }
868
+ : null,
869
+ execution: recorded.execution
870
+ ? {
871
+ run_id: recorded.execution.payload.run_id,
872
+ role: recorded.execution.payload.role.id,
873
+ execution_id: recorded.execution.payload.execution_id,
874
+ }
875
+ : null,
876
+ runtime_action: recorded.runtime_action
877
+ ? {
878
+ run_id: recorded.runtime_action.payload.run_id || null,
879
+ action: recorded.runtime_action.payload.action || null,
880
+ action_id: recorded.runtime_action.payload.action_id || null,
881
+ }
882
+ : null,
883
+ };
884
+ }
885
+
886
+ function advanceRunner(options) {
887
+ const targetDir = path.resolve(process.cwd(), options.target || '.');
888
+ const pendingInputs = resolvePendingInputs(targetDir);
889
+
890
+ if (pendingInputs.length === 0) {
891
+ return {
892
+ kind: 'task-orchestrator-runner-advance-result',
893
+ status: 'idle',
894
+ target: targetDir,
895
+ consumed: null,
896
+ recorded: null,
897
+ applied: null,
898
+ next_expected: buildNextExpected(targetDir),
899
+ };
900
+ }
901
+
902
+ if (pendingInputs.length > 1) {
903
+ const pendingLabels = pendingInputs.map((item) => item.relPath).join(', ');
904
+ throw new Error(`runner inbox has multiple pending inputs: ${pendingLabels}`);
905
+ }
906
+
907
+ const pending = pendingInputs[0];
908
+ let recorded = null;
909
+ let applied = null;
910
+
911
+ if (pending.kind === 'task-orchestrator-turn') {
912
+ const orchestratorTurn = resolveTaskOrchestratorTurn(pending.path);
913
+ if (orchestratorTurn.action !== 'bootstrap') {
914
+ recorded = {
915
+ runtime_action: {
916
+ payload: orchestratorTurn.payload,
917
+ source: pending.path,
918
+ },
919
+ };
920
+ }
921
+ applied = applyRuntimeMutation({
922
+ targetDir,
923
+ action: orchestratorTurn.action,
924
+ payload: orchestratorTurn.payload,
925
+ payloadSource: pending.path,
926
+ });
927
+ } else if (pending.kind === 'expert-dispatch') {
928
+ recorded = {
929
+ dispatch: expertDispatch.applyDispatch({
930
+ target: targetDir,
931
+ payload: pending.path,
932
+ }),
933
+ };
934
+ } else if (pending.kind === 'expert-execution') {
935
+ recorded = {
936
+ execution: expertExecutor.applyExecution({
937
+ target: targetDir,
938
+ payload: pending.path,
939
+ }),
940
+ };
941
+ const autoRuntimeAction = buildAutoRuntimeAction(targetDir, recorded.execution.payload);
942
+ if (autoRuntimeAction) {
943
+ if (recorded.execution.archive_result?.archived_artifacts) {
944
+ autoRuntimeAction.artifacts = recorded.execution.archive_result.archived_artifacts;
945
+ autoRuntimeAction.skip_artifact_check = true;
946
+ }
947
+ recorded.runtime_action = {
948
+ payload: autoRuntimeAction,
949
+ source: 'runner-auto-transition',
950
+ };
951
+ applied = applyRuntimeMutation({
952
+ targetDir,
953
+ action: autoRuntimeAction.action,
954
+ payload: autoRuntimeAction,
955
+ payloadSource: 'runner-auto-transition',
956
+ });
957
+ }
958
+ } else if (pending.kind === 'task-orchestrator-runtime-action') {
959
+ const runtimeActionPayload = readJsonFile(pending.path, 'runtime action');
960
+ recorded = {
961
+ runtime_action: {
962
+ payload: runtimeActionPayload,
963
+ source: pending.path,
964
+ },
965
+ };
966
+ applied = applyRuntimeMutation({
967
+ targetDir,
968
+ action: runtimeActionPayload.action,
969
+ payload: runtimeActionPayload,
970
+ payloadSource: pending.path,
971
+ });
972
+ } else {
973
+ throw new Error(`unsupported runner input kind: ${pending.kind}`);
974
+ }
975
+
976
+ if (!recorded) {
977
+ recorded = {};
978
+ }
979
+
980
+ if (applied) {
981
+ const autoDispatch = maybeAutoDispatchCurrentRole(targetDir, applied);
982
+ if (autoDispatch) {
983
+ recorded.dispatch = autoDispatch;
984
+ }
985
+ }
986
+
987
+ const archivedTo = archiveConsumedInput(targetDir, pending.path, pending.kind);
988
+
989
+ return {
990
+ kind: 'task-orchestrator-runner-advance-result',
991
+ status: 'success',
992
+ target: targetDir,
993
+ consumed: {
994
+ kind: pending.kind,
995
+ producer: pending.producer,
996
+ path: pending.relPath,
997
+ archived_to: archivedTo,
998
+ },
999
+ recorded: formatAdvanceRecorded(recorded),
1000
+ applied: summarizeAppliedState(applied),
1001
+ next_expected: buildNextExpected(targetDir),
1002
+ };
1003
+ }
1004
+
1005
+ function advanceRunnerWithRuntimeActionData(options = {}) {
1006
+ const targetDir = path.resolve(process.cwd(), options.target || '.');
1007
+ const payload = options.payloadData;
1008
+ if (!payload || typeof payload !== 'object') {
1009
+ throw new Error('Missing runtime-action payloadData for in-memory runner advance');
1010
+ }
1011
+ if (payload.kind !== 'task-orchestrator-runtime-action') {
1012
+ throw new Error(`Expected kind "task-orchestrator-runtime-action" but got "${payload.kind || 'undefined'}"`);
1013
+ }
1014
+
1015
+ const recorded = {
1016
+ runtime_action: {
1017
+ payload,
1018
+ source: options.source || 'memory-runtime-action',
1019
+ },
1020
+ };
1021
+ const applied = applyRuntimeMutation({
1022
+ targetDir,
1023
+ action: payload.action,
1024
+ payload,
1025
+ payloadSource: recorded.runtime_action.source,
1026
+ });
1027
+
1028
+ if (applied) {
1029
+ const autoDispatch = maybeAutoDispatchCurrentRole(targetDir, applied);
1030
+ if (autoDispatch) {
1031
+ recorded.dispatch = autoDispatch;
1032
+ }
1033
+ }
1034
+
1035
+ return {
1036
+ kind: 'task-orchestrator-runner-advance-result',
1037
+ status: 'success',
1038
+ target: targetDir,
1039
+ consumed: null,
1040
+ recorded: formatAdvanceRecorded(recorded),
1041
+ applied: summarizeAppliedState(applied),
1042
+ next_expected: buildNextExpected(targetDir),
1043
+ };
1044
+ }
1045
+
1046
+ function replayReplies(options) {
1047
+ const targetDir = path.resolve(process.cwd(), options.target || '.');
1048
+ const steps = [];
1049
+ let lastApplied = null;
1050
+
1051
+ for (let index = 0; index < options.replies.length; index += 1) {
1052
+ const replyPath = path.resolve(process.cwd(), options.replies[index]);
1053
+ const orchestratorTurn = resolveTaskOrchestratorTurn(replyPath);
1054
+ const applied = applyRuntimeMutation({
1055
+ targetDir,
1056
+ action: orchestratorTurn.action,
1057
+ payload: orchestratorTurn.payload,
1058
+ payloadSource: replyPath,
1059
+ });
1060
+
1061
+ lastApplied = applied;
1062
+ steps.push({
1063
+ index: index + 1,
1064
+ reply: replyPath,
1065
+ action_source: orchestratorTurn.payload.kind || null,
1066
+ action: applied.adapter_action,
1067
+ run_id: applied.result?.state?.run_id || null,
1068
+ status: applied.result?.state?.status || null,
1069
+ current_role: applied.result?.state?.current_role || null,
1070
+ pending_gate: applied.result?.state?.pending_gate || null,
1071
+ });
1072
+ }
1073
+
1074
+ const finalState = lastApplied?.result?.state || null;
1075
+ return {
1076
+ kind: 'task-orchestrator-runner-result',
1077
+ status: 'success',
1078
+ target: targetDir,
1079
+ steps,
1080
+ summary: {
1081
+ step_count: steps.length,
1082
+ run_id: finalState?.run_id || null,
1083
+ status: finalState?.status || null,
1084
+ current_role: finalState?.current_role || null,
1085
+ pending_gate: finalState?.pending_gate || null,
1086
+ },
1087
+ state: finalState,
1088
+ };
1089
+ }
1090
+
1091
+ function printPretty(result) {
1092
+ if (result.kind === 'task-orchestrator-runner-status') {
1093
+ console.log('task-orchestrator runner status');
1094
+ console.log(` target: ${result.target}`);
1095
+ console.log(` run_id: ${result.current.run_id || 'n/a'}`);
1096
+ console.log(` run_status: ${result.current.run_status || 'n/a'}`);
1097
+ console.log(` current_role: ${result.current.current_role || 'n/a'}`);
1098
+ console.log(` pending_gate: ${result.current.pending_gate || 'n/a'}`);
1099
+ console.log(` pending_inputs: ${result.pending_inputs.length}`);
1100
+ for (const pending of result.pending_inputs) {
1101
+ console.log(` pending -> ${pending.kind} @ ${pending.path}`);
1102
+ }
1103
+ console.log(` next_expected: ${result.next_expected.producer || 'none'}`);
1104
+ for (const file of result.next_expected.files) {
1105
+ console.log(` - ${file}`);
1106
+ }
1107
+ return;
1108
+ }
1109
+
1110
+ if (result.kind === 'task-orchestrator-runner-advance-result') {
1111
+ console.log('task-orchestrator runner advanced');
1112
+ console.log(` target: ${result.target}`);
1113
+ console.log(` status: ${result.status}`);
1114
+ if (result.consumed) {
1115
+ console.log(` consumed: ${result.consumed.kind} <- ${result.consumed.path}`);
1116
+ console.log(` archived_to: ${result.consumed.archived_to}`);
1117
+ }
1118
+ if (result.applied) {
1119
+ console.log(` adapter_action: ${result.applied.adapter_action}`);
1120
+ console.log(` run_id: ${result.applied.run_id || 'n/a'}`);
1121
+ console.log(` run_status: ${result.applied.status || 'n/a'}`);
1122
+ console.log(` current_role: ${result.applied.current_role || 'n/a'}`);
1123
+ }
1124
+ console.log(` next_expected: ${result.next_expected.producer || 'none'}`);
1125
+ for (const file of result.next_expected.files) {
1126
+ console.log(` - ${file}`);
1127
+ }
1128
+ return;
1129
+ }
1130
+
1131
+ console.log('task-orchestrator runner replayed');
1132
+ console.log(` target: ${result.target}`);
1133
+ console.log(` steps: ${result.summary.step_count}`);
1134
+ console.log(` run_id: ${result.summary.run_id || 'n/a'}`);
1135
+ console.log(` status: ${result.summary.status || 'n/a'}`);
1136
+ console.log(` current_role: ${result.summary.current_role || 'n/a'}`);
1137
+ console.log(` pending_gate: ${result.summary.pending_gate || 'n/a'}`);
1138
+
1139
+ for (const step of result.steps) {
1140
+ console.log(` [${step.index}] ${step.action} <- ${step.reply}`);
1141
+ }
1142
+ }
1143
+
1144
+ function main(argv = process.argv.slice(2)) {
1145
+ const { command, options } = parseArgs(argv);
1146
+
1147
+ if (!command || options.help || command === 'help' || command === '--help' || command === '-h') {
1148
+ printUsage();
1149
+ return 0;
1150
+ }
1151
+
1152
+ if (command === 'status') {
1153
+ const result = buildStatus(path.resolve(process.cwd(), options.target || '.'));
1154
+ if (options.json) {
1155
+ console.log(JSON.stringify(result, null, 2));
1156
+ } else {
1157
+ printPretty(result);
1158
+ }
1159
+ return 0;
1160
+ }
1161
+
1162
+ if (command === 'advance') {
1163
+ const result = advanceRunner(options);
1164
+ if (options.json) {
1165
+ console.log(JSON.stringify(result, null, 2));
1166
+ } else {
1167
+ printPretty(result);
1168
+ }
1169
+ return 0;
1170
+ }
1171
+
1172
+ if (command !== 'replay') {
1173
+ throw new Error(`Unsupported task-orchestrator-runner command: ${command}`);
1174
+ }
1175
+
1176
+ if (options.replies.length === 0) {
1177
+ throw new Error('Missing runner input: use --reply <file> at least once');
1178
+ }
1179
+
1180
+ const result = replayReplies(options);
1181
+
1182
+ if (options.json) {
1183
+ console.log(JSON.stringify(result, null, 2));
1184
+ } else {
1185
+ printPretty(result);
1186
+ }
1187
+
1188
+ return 0;
1189
+ }
1190
+
1191
+ if (require.main === module) {
1192
+ try {
1193
+ const exitCode = main();
1194
+ process.exit(exitCode);
1195
+ } catch (error) {
1196
+ console.error(`task-orchestrator-runner error: ${error.message}`);
1197
+ process.exit(1);
1198
+ }
1199
+ }
1200
+
1201
+ module.exports = {
1202
+ main,
1203
+ parseArgs,
1204
+ buildStatus,
1205
+ advanceRunner,
1206
+ advanceRunnerWithRuntimeActionData,
1207
+ replayReplies,
1208
+ };