@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,469 +1,469 @@
1
- /**
2
- * Visual Inbox Consumer
3
- *
4
- * 在 CLI 命令边界(protocol-step / -advance / -update / -status)以同步、超时短的方式
5
- * 扫描 .ai-spec/inbox/ 下的控制指令文件并应用到本地 runtime-state,再把结果
6
- * 通过 receipt-pusher 反向回报给 visual。
7
- *
8
- * 设计约束(见 plan):
9
- * - 仅使用 Node 内置模块(fs / path / crypto / os),零 npm 依赖
10
- * - 所有失败必须静默降级,永不抛出阻断主流程
11
- * - 超时硬限(默认 ≤ 50ms),保证不影响命令启动时延
12
- * - 处理过的文件移入 .ai-spec/inbox/.processed/,带结果后缀
13
- */
14
-
15
- const fs = require('fs');
16
- const path = require('path');
17
- const crypto = require('crypto');
18
-
19
- const INBOX_DIR_REL = '.ai-spec/inbox';
20
- const PROCESSED_SUBDIR = '.processed';
21
- const APPLIED_SUBDIR = '.applied';
22
- const FAILED_SUBDIR = '.failed';
23
-
24
- const SUPPORTED_COMMANDS = new Set([
25
- 'approve_gate',
26
- 'reject_gate',
27
- 'resume_run',
28
- 'cancel_run',
29
- ]);
30
-
31
- function safeReadJson(filePath) {
32
- try {
33
- const text = fs.readFileSync(filePath, 'utf-8');
34
- return JSON.parse(text);
35
- } catch (_err) {
36
- return null;
37
- }
38
- }
39
-
40
- function ensureDir(dir) {
41
- try {
42
- fs.mkdirSync(dir, { recursive: true });
43
- } catch (_err) {
44
- // noop
45
- }
46
- }
47
-
48
- function loadBridgeConfig(targetDir) {
49
- const candidates = [
50
- path.join(targetDir, '.ai-spec/visual-bridge.json'),
51
- path.join(targetDir, '.ai-spec/visual-config.json'),
52
- ];
53
- for (const file of candidates) {
54
- const data = safeReadJson(file);
55
- if (data && typeof data === 'object') {
56
- return { source: file, data };
57
- }
58
- }
59
- return null;
60
- }
61
-
62
- function verifySignature(message, signature, secret) {
63
- if (!secret) {
64
- return true; // 未配置 token 视为本地受信任环境,跳过校验
65
- }
66
- if (!signature || typeof signature !== 'string') {
67
- return false;
68
- }
69
- try {
70
- const expected = crypto
71
- .createHmac('sha256', String(secret))
72
- .update(typeof message === 'string' ? message : JSON.stringify(message))
73
- .digest('hex');
74
- if (expected.length !== signature.length) {
75
- return false;
76
- }
77
- return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
78
- } catch (_err) {
79
- return false;
80
- }
81
- }
82
-
83
- function loadRuntimeState(targetDir) {
84
- try {
85
- const runtimeState = require('../../bin/runtime-state');
86
- return runtimeState;
87
- } catch (_err) {
88
- return null;
89
- }
90
- }
91
-
92
- /**
93
- * 切面式写入:当 Visual 侧审批被成功应用后,往项目根 .ai-spec/next-step.md
94
- * 追加一条人类可读的提示,供 IDE 里的 AI / 用户感知"已批准、请继续"。
95
- *
96
- * 设计原则:
97
- * - 纯 additive,失败 silent 吞,绝不影响主 apply 链路
98
- * - 只追加,不清空;保留审批历史
99
- * - 通过结构化 marker 方便 AGENTS.md / Cursor slash 读取
100
- */
101
- function appendNextStepHint(targetDir, command, payload, snapshot) {
102
- try {
103
- const file = path.join(targetDir, '.ai-spec', 'next-step.md');
104
- ensureDir(path.dirname(file));
105
- const ts = new Date().toISOString();
106
- const gate = payload?.gate || snapshot?.pending_gate || 'unknown';
107
- const runId = payload?.run_id || snapshot?.run_id || 'unknown';
108
- const nextRole = snapshot?.current_role || payload?.next_role || 'unknown';
109
- const recommend =
110
- command === 'approve_gate' || command === 'resume_run'
111
- ? '请在 IDE (Cursor / Claude Code) 执行 `/spec-continue` 继续下一步开发。'
112
- : command === 'request_changes'
113
- ? '请补齐资产后重新提交审批。'
114
- : '请查看 visual 审批结果并在 IDE 按提示操作。';
115
- const block = [
116
- '',
117
- `## [${ts}] ${command} applied`,
118
- '',
119
- `- run_id: \`${runId}\``,
120
- `- gate: \`${gate}\``,
121
- `- next_role: \`${nextRole}\``,
122
- `- action: ${recommend}`,
123
- '',
124
- '<!-- visual-next-step:end -->',
125
- '',
126
- ].join('\n');
127
-
128
- const header = fs.existsSync(file)
129
- ? ''
130
- : [
131
- '# Visual 审批 → 下一步提示',
132
- '',
133
- '> 本文件由 `br-ai-spec` 的 visual-hooks 自动追加写入。',
134
- '> 每当 visual 侧审批(approve_gate / resume_run)被成功应用到本地',
135
- '> runtime-state 后,会在下方 append 一条记录。IDE 中的 AI 可读取',
136
- '> 该文件作为"继续开发"的信号。本地手动推进或清理可直接删除此文件。',
137
- '',
138
- ].join('\n');
139
-
140
- fs.appendFileSync(file, `${header}${block}`, 'utf-8');
141
- } catch (_err) {
142
- // silent — 这条提示是增值能力,失败绝不影响主链路
143
- }
144
- }
145
-
146
- /**
147
- * 切面式写入 gate-signal.json:为 IDE 侧 AI 轮询提供"审批已到达"的结构化信号。
148
- * 所有失败静默吞掉,绝不影响 apply 主链路。
149
- */
150
- function emitGateSignal(targetDir, command, payload, snapshot) {
151
- try {
152
- const normalizedDecision = String(payload?.decision || '').trim().toLowerCase();
153
- const decision =
154
- command === 'approve_gate'
155
- ? 'approved'
156
- : command === 'resume_run'
157
- ? 'resumed'
158
- : command === 'reject_gate'
159
- ? normalizedDecision === 'request_changes' || normalizedDecision === 'request-changes'
160
- ? 'request_changes'
161
- : 'rejected'
162
- : null;
163
- if (!decision) return;
164
- const { writeGateSignal } = require('./gate-signal');
165
- writeGateSignal({
166
- targetDir,
167
- runId: payload?.run_id || snapshot?.run_id || null,
168
- gate: payload?.gate || snapshot?.pending_gate || 'unknown',
169
- decision,
170
- reason: payload?.reason || payload?.decision || null,
171
- actorId: payload?.requested_by || payload?.actor_id || null,
172
- });
173
- } catch (_err) {
174
- // silent — 切面能力,任何异常都不允许冒泡影响 receipt 结果
175
- }
176
- }
177
-
178
- function applyControl(targetDir, command, payload) {
179
- const runtimeState = loadRuntimeState(targetDir);
180
- if (!runtimeState) {
181
- return { result: 'rejected', reason: 'runtime-state module unavailable' };
182
- }
183
-
184
- try {
185
- if (command === 'approve_gate') {
186
- const result = runtimeState.approveRunState({
187
- target: targetDir,
188
- gate: payload?.gate || null,
189
- runId: payload?.run_id || null,
190
- nextRole: payload?.next_role || null,
191
- status: payload?.status || 'running',
192
- });
193
- const snapshot = {
194
- status: result?.state?.status,
195
- current_role: result?.state?.current_role,
196
- run_id: result?.state?.run_id,
197
- };
198
- appendNextStepHint(targetDir, 'approve_gate', payload, snapshot);
199
- emitGateSignal(targetDir, 'approve_gate', payload, snapshot);
200
- return { result: 'applied', snapshot };
201
- }
202
-
203
- if (command === 'reject_gate') {
204
- const state = safeReadJson(path.join(targetDir, '.ai-spec', 'current-run.json'));
205
- if (!state?.run_id) {
206
- return { result: 'conflict', reason: 'current run-state unavailable' };
207
- }
208
- const activeGate = state.pending_gate || null;
209
- const requestedGate = payload?.gate || activeGate;
210
- if (!activeGate) {
211
- return { result: 'conflict', reason: 'No pending approval gate found' };
212
- }
213
- if (requestedGate && activeGate !== requestedGate) {
214
- return {
215
- result: 'conflict',
216
- reason: `Pending gate mismatch: current is "${activeGate}", requested "${requestedGate}"`,
217
- };
218
- }
219
- const decision = String(payload?.decision || '').trim().toLowerCase();
220
- const isRequestChanges =
221
- decision === 'request_changes' || decision === 'request-changes';
222
- const reason = payload?.reason || payload?.decision || 'rejected by visual gate';
223
- const result = runtimeState.gateBlockedRunState({
224
- target: targetDir,
225
- runId: payload?.run_id || state.run_id,
226
- gate: activeGate,
227
- pendingGate: activeGate,
228
- status: 'waiting-approval',
229
- fromRole: state.current_role || null,
230
- toRole: state.current_role || null,
231
- blockedByRole: state.current_role || state.gate_context?.blocked_by_role || null,
232
- resumeToRole: state.gate_context?.resume_to_role || null,
233
- requiredUserAction: isRequestChanges
234
- ? `请先补齐资产或说明后重新提交审批。${reason ? ` 当前要求:${reason}` : ''}`.trim()
235
- : state.gate_context?.required_user_action || '当前门禁已被拒绝,请修正后重新请求审批。',
236
- blockedReason: isRequestChanges
237
- ? `gate request_changes: ${reason}`
238
- : `gate rejected: ${reason}`,
239
- message: isRequestChanges
240
- ? `gate request_changes: ${reason}`
241
- : `gate rejected: ${reason}`,
242
- eventType: isRequestChanges ? 'gate-request-changes' : 'gate-rejected',
243
- });
244
- const rejectSnapshot = {
245
- status: result?.state?.status,
246
- current_role: result?.state?.current_role,
247
- pending_gate: result?.state?.pending_gate,
248
- run_id: result?.state?.run_id,
249
- };
250
- if (isRequestChanges) {
251
- appendNextStepHint(targetDir, 'request_changes', payload, rejectSnapshot);
252
- }
253
- emitGateSignal(targetDir, 'reject_gate', payload, rejectSnapshot);
254
- return {
255
- result: 'rejected',
256
- reason,
257
- snapshot: rejectSnapshot,
258
- };
259
- }
260
-
261
- if (command === 'resume_run') {
262
- const result = runtimeState.approveRunState({
263
- target: targetDir,
264
- gate: payload?.gate || null,
265
- runId: payload?.run_id || null,
266
- nextRole: payload?.next_role || payload?.resume_to_role || null,
267
- status: 'running',
268
- });
269
- const snapshot = {
270
- status: result?.state?.status,
271
- current_role: result?.state?.current_role,
272
- run_id: result?.state?.run_id,
273
- };
274
- appendNextStepHint(targetDir, 'resume_run', payload, snapshot);
275
- emitGateSignal(targetDir, 'resume_run', payload, snapshot);
276
- return { result: 'applied', snapshot };
277
- }
278
-
279
- if (command === 'cancel_run') {
280
- // cancel_run 走轻量路径:只生成回执,不强制改写状态以避免与协议推进竞争。
281
- return {
282
- result: 'applied',
283
- snapshot: { decision: 'cancel_requested', reason: payload?.reason || null },
284
- };
285
- }
286
-
287
- return { result: 'rejected', reason: `unsupported command: ${command}` };
288
- } catch (err) {
289
- const msg = String(err?.message || err);
290
- if (/No pending approval gate/.test(msg) || /Pending gate mismatch/.test(msg)) {
291
- return { result: 'conflict', reason: msg };
292
- }
293
- return { result: 'rejected', reason: msg };
294
- }
295
- }
296
-
297
- function moveFile(srcPath, destDir) {
298
- ensureDir(destDir);
299
- const base = path.basename(srcPath);
300
- const dest = path.join(destDir, `${Date.now()}_${base}`);
301
- try {
302
- fs.renameSync(srcPath, dest);
303
- return dest;
304
- } catch (_err) {
305
- try {
306
- fs.copyFileSync(srcPath, dest);
307
- fs.unlinkSync(srcPath);
308
- return dest;
309
- } catch (_err2) {
310
- return null;
311
- }
312
- }
313
- }
314
-
315
- function listInboxFiles(inboxDir) {
316
- if (!fs.existsSync(inboxDir)) return [];
317
- let entries;
318
- try {
319
- entries = fs.readdirSync(inboxDir, { withFileTypes: true });
320
- } catch (_err) {
321
- return [];
322
- }
323
- return entries
324
- .filter((entry) => entry.isFile() && /^control-.*\.json$/.test(entry.name))
325
- .map((entry) => path.join(inboxDir, entry.name))
326
- .sort();
327
- }
328
-
329
- /**
330
- * 消费 inbox 控制指令并产生 receipt 列表
331
- *
332
- * 完整生命周期(按顺序,每步都是 best-effort 静默失败):
333
- * 1. 可选 HTTP pull:从 visual 拉 pending 控制指令落盘到 inbox
334
- * 2. 扫描 inbox 文件并应用到本地 runtime-state
335
- * 3. 可选 HTTP push:把 receipts 回灌给 visual
336
- *
337
- * @param {{ targetDir: string, timeoutMs?: number, secret?: string, skipPull?: boolean, skipPush?: boolean }} opts
338
- * @returns {Promise<{ processed: number, receipts: Array<object>, pulled?: number }>}
339
- */
340
- async function consumeInbox(opts = {}) {
341
- const targetDir = opts.targetDir || process.cwd();
342
- const timeoutMs = Number.isFinite(opts.timeoutMs) ? opts.timeoutMs : 50;
343
- const startedAt = Date.now();
344
-
345
- const bridge = loadBridgeConfig(targetDir);
346
- const secret =
347
- opts.secret ||
348
- bridge?.data?.control_secret ||
349
- bridge?.data?.controlSecret ||
350
- null;
351
-
352
- let pulled = 0;
353
- if (!opts.skipPull && bridge?.data?.enabled !== false) {
354
- try {
355
- const { pullPendingControls } = require('./control-puller');
356
- const pullResult = await pullPendingControls({
357
- targetDir,
358
- timeoutMs: Math.max(50, Math.floor(timeoutMs * 4)),
359
- });
360
- pulled = pullResult?.written || 0;
361
- } catch (_err) {
362
- // pull 阶段失败不影响后续 inbox 消费
363
- }
364
- }
365
-
366
- const inboxDir = path.join(targetDir, INBOX_DIR_REL);
367
- if (!fs.existsSync(inboxDir)) {
368
- return { processed: 0, receipts: [], pulled };
369
- }
370
-
371
- const files = listInboxFiles(inboxDir);
372
- if (files.length === 0) {
373
- return { processed: 0, receipts: [] };
374
- }
375
-
376
- const receipts = [];
377
- let processed = 0;
378
- const seenOutboxIds = new Set();
379
-
380
- for (const file of files) {
381
- if (Date.now() - startedAt > timeoutMs) {
382
- break; // 超时优雅退出,剩余文件留待下一次命令边界处理
383
- }
384
-
385
- const envelope = safeReadJson(file);
386
- if (!envelope || typeof envelope !== 'object') {
387
- moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
388
- continue;
389
- }
390
-
391
- const {
392
- outbox_id: outboxId,
393
- command,
394
- payload,
395
- signature,
396
- } = envelope;
397
- const receiptKey = outboxId || path.basename(file);
398
-
399
- if (seenOutboxIds.has(receiptKey)) {
400
- moveFile(file, path.join(inboxDir, PROCESSED_SUBDIR));
401
- continue;
402
- }
403
- seenOutboxIds.add(receiptKey);
404
-
405
- let receipt = {
406
- eventType: 'control.receipt',
407
- outbox_id: receiptKey,
408
- command: command || null,
409
- result: 'rejected',
410
- reason: null,
411
- applied_state_snapshot: null,
412
- received_at: new Date().toISOString(),
413
- };
414
-
415
- if (!command || !SUPPORTED_COMMANDS.has(command)) {
416
- receipt.reason = `unsupported command: ${command}`;
417
- moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
418
- receipts.push(receipt);
419
- processed += 1;
420
- continue;
421
- }
422
-
423
- const signed = verifySignature(
424
- { outbox_id: outboxId, command, payload },
425
- signature,
426
- secret,
427
- );
428
- if (!signed) {
429
- receipt.reason = 'signature verification failed';
430
- moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
431
- receipts.push(receipt);
432
- processed += 1;
433
- continue;
434
- }
435
-
436
- const applyResult = applyControl(targetDir, command, payload || {});
437
- receipt.result = applyResult.result;
438
- receipt.reason = applyResult.reason || null;
439
- receipt.applied_state_snapshot = applyResult.snapshot || null;
440
-
441
- const destDir = applyResult.result === 'applied'
442
- ? path.join(inboxDir, APPLIED_SUBDIR)
443
- : path.join(inboxDir, PROCESSED_SUBDIR);
444
- moveFile(file, destDir);
445
-
446
- receipts.push(receipt);
447
- processed += 1;
448
- }
449
-
450
- if (!opts.skipPush && receipts.length > 0 && bridge?.data?.enabled !== false) {
451
- try {
452
- const { pushReceipts } = require('./receipt-pusher');
453
- await pushReceipts({
454
- targetDir,
455
- receipts,
456
- timeoutMs: Math.max(200, Math.floor(timeoutMs * 8)),
457
- });
458
- } catch (_err) {
459
- // 推送失败不影响本地 inbox 已正常处理的事实
460
- }
461
- }
462
-
463
- return { processed, receipts, pulled };
464
- }
465
-
466
- module.exports = {
467
- consumeInbox,
468
- INBOX_DIR_REL,
469
- };
1
+ /**
2
+ * Visual Inbox Consumer
3
+ *
4
+ * 在 CLI 命令边界(protocol-step / -advance / -update / -status)以同步、超时短的方式
5
+ * 扫描 .ai-spec/inbox/ 下的控制指令文件并应用到本地 runtime-state,再把结果
6
+ * 通过 receipt-pusher 反向回报给 visual。
7
+ *
8
+ * 设计约束(见 plan):
9
+ * - 仅使用 Node 内置模块(fs / path / crypto / os),零 npm 依赖
10
+ * - 所有失败必须静默降级,永不抛出阻断主流程
11
+ * - 超时硬限(默认 ≤ 50ms),保证不影响命令启动时延
12
+ * - 处理过的文件移入 .ai-spec/inbox/.processed/,带结果后缀
13
+ */
14
+
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+ const crypto = require('crypto');
18
+
19
+ const INBOX_DIR_REL = '.ai-spec/inbox';
20
+ const PROCESSED_SUBDIR = '.processed';
21
+ const APPLIED_SUBDIR = '.applied';
22
+ const FAILED_SUBDIR = '.failed';
23
+
24
+ const SUPPORTED_COMMANDS = new Set([
25
+ 'approve_gate',
26
+ 'reject_gate',
27
+ 'resume_run',
28
+ 'cancel_run',
29
+ ]);
30
+
31
+ function safeReadJson(filePath) {
32
+ try {
33
+ const text = fs.readFileSync(filePath, 'utf-8');
34
+ return JSON.parse(text);
35
+ } catch (_err) {
36
+ return null;
37
+ }
38
+ }
39
+
40
+ function ensureDir(dir) {
41
+ try {
42
+ fs.mkdirSync(dir, { recursive: true });
43
+ } catch (_err) {
44
+ // noop
45
+ }
46
+ }
47
+
48
+ function loadBridgeConfig(targetDir) {
49
+ const candidates = [
50
+ path.join(targetDir, '.ai-spec/visual-bridge.json'),
51
+ path.join(targetDir, '.ai-spec/visual-config.json'),
52
+ ];
53
+ for (const file of candidates) {
54
+ const data = safeReadJson(file);
55
+ if (data && typeof data === 'object') {
56
+ return { source: file, data };
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function verifySignature(message, signature, secret) {
63
+ if (!secret) {
64
+ return true; // 未配置 token 视为本地受信任环境,跳过校验
65
+ }
66
+ if (!signature || typeof signature !== 'string') {
67
+ return false;
68
+ }
69
+ try {
70
+ const expected = crypto
71
+ .createHmac('sha256', String(secret))
72
+ .update(typeof message === 'string' ? message : JSON.stringify(message))
73
+ .digest('hex');
74
+ if (expected.length !== signature.length) {
75
+ return false;
76
+ }
77
+ return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
78
+ } catch (_err) {
79
+ return false;
80
+ }
81
+ }
82
+
83
+ function loadRuntimeState(targetDir) {
84
+ try {
85
+ const runtimeState = require('../../bin/runtime-state');
86
+ return runtimeState;
87
+ } catch (_err) {
88
+ return null;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * 切面式写入:当 Visual 侧审批被成功应用后,往项目根 .ai-spec/next-step.md
94
+ * 追加一条人类可读的提示,供 IDE 里的 AI / 用户感知"已批准、请继续"。
95
+ *
96
+ * 设计原则:
97
+ * - 纯 additive,失败 silent 吞,绝不影响主 apply 链路
98
+ * - 只追加,不清空;保留审批历史
99
+ * - 通过结构化 marker 方便 AGENTS.md / Cursor slash 读取
100
+ */
101
+ function appendNextStepHint(targetDir, command, payload, snapshot) {
102
+ try {
103
+ const file = path.join(targetDir, '.ai-spec', 'next-step.md');
104
+ ensureDir(path.dirname(file));
105
+ const ts = new Date().toISOString();
106
+ const gate = payload?.gate || snapshot?.pending_gate || 'unknown';
107
+ const runId = payload?.run_id || snapshot?.run_id || 'unknown';
108
+ const nextRole = snapshot?.current_role || payload?.next_role || 'unknown';
109
+ const recommend =
110
+ command === 'approve_gate' || command === 'resume_run'
111
+ ? '请在 IDE (Cursor / Claude Code) 执行 `/spec-continue` 继续下一步开发。'
112
+ : command === 'request_changes'
113
+ ? '请补齐资产后重新提交审批。'
114
+ : '请查看 visual 审批结果并在 IDE 按提示操作。';
115
+ const block = [
116
+ '',
117
+ `## [${ts}] ${command} applied`,
118
+ '',
119
+ `- run_id: \`${runId}\``,
120
+ `- gate: \`${gate}\``,
121
+ `- next_role: \`${nextRole}\``,
122
+ `- action: ${recommend}`,
123
+ '',
124
+ '<!-- visual-next-step:end -->',
125
+ '',
126
+ ].join('\n');
127
+
128
+ const header = fs.existsSync(file)
129
+ ? ''
130
+ : [
131
+ '# Visual 审批 → 下一步提示',
132
+ '',
133
+ '> 本文件由 `br-ai-spec` 的 visual-hooks 自动追加写入。',
134
+ '> 每当 visual 侧审批(approve_gate / resume_run)被成功应用到本地',
135
+ '> runtime-state 后,会在下方 append 一条记录。IDE 中的 AI 可读取',
136
+ '> 该文件作为"继续开发"的信号。本地手动推进或清理可直接删除此文件。',
137
+ '',
138
+ ].join('\n');
139
+
140
+ fs.appendFileSync(file, `${header}${block}`, 'utf-8');
141
+ } catch (_err) {
142
+ // silent — 这条提示是增值能力,失败绝不影响主链路
143
+ }
144
+ }
145
+
146
+ /**
147
+ * 切面式写入 gate-signal.json:为 IDE 侧 AI 轮询提供"审批已到达"的结构化信号。
148
+ * 所有失败静默吞掉,绝不影响 apply 主链路。
149
+ */
150
+ function emitGateSignal(targetDir, command, payload, snapshot) {
151
+ try {
152
+ const normalizedDecision = String(payload?.decision || '').trim().toLowerCase();
153
+ const decision =
154
+ command === 'approve_gate'
155
+ ? 'approved'
156
+ : command === 'resume_run'
157
+ ? 'resumed'
158
+ : command === 'reject_gate'
159
+ ? normalizedDecision === 'request_changes' || normalizedDecision === 'request-changes'
160
+ ? 'request_changes'
161
+ : 'rejected'
162
+ : null;
163
+ if (!decision) return;
164
+ const { writeGateSignal } = require('./gate-signal');
165
+ writeGateSignal({
166
+ targetDir,
167
+ runId: payload?.run_id || snapshot?.run_id || null,
168
+ gate: payload?.gate || snapshot?.pending_gate || 'unknown',
169
+ decision,
170
+ reason: payload?.reason || payload?.decision || null,
171
+ actorId: payload?.requested_by || payload?.actor_id || null,
172
+ });
173
+ } catch (_err) {
174
+ // silent — 切面能力,任何异常都不允许冒泡影响 receipt 结果
175
+ }
176
+ }
177
+
178
+ function applyControl(targetDir, command, payload) {
179
+ const runtimeState = loadRuntimeState(targetDir);
180
+ if (!runtimeState) {
181
+ return { result: 'rejected', reason: 'runtime-state module unavailable' };
182
+ }
183
+
184
+ try {
185
+ if (command === 'approve_gate') {
186
+ const result = runtimeState.approveRunState({
187
+ target: targetDir,
188
+ gate: payload?.gate || null,
189
+ runId: payload?.run_id || null,
190
+ nextRole: payload?.next_role || null,
191
+ status: payload?.status || 'running',
192
+ });
193
+ const snapshot = {
194
+ status: result?.state?.status,
195
+ current_role: result?.state?.current_role,
196
+ run_id: result?.state?.run_id,
197
+ };
198
+ appendNextStepHint(targetDir, 'approve_gate', payload, snapshot);
199
+ emitGateSignal(targetDir, 'approve_gate', payload, snapshot);
200
+ return { result: 'applied', snapshot };
201
+ }
202
+
203
+ if (command === 'reject_gate') {
204
+ const state = safeReadJson(path.join(targetDir, '.ai-spec', 'current-run.json'));
205
+ if (!state?.run_id) {
206
+ return { result: 'conflict', reason: 'current run-state unavailable' };
207
+ }
208
+ const activeGate = state.pending_gate || null;
209
+ const requestedGate = payload?.gate || activeGate;
210
+ if (!activeGate) {
211
+ return { result: 'conflict', reason: 'No pending approval gate found' };
212
+ }
213
+ if (requestedGate && activeGate !== requestedGate) {
214
+ return {
215
+ result: 'conflict',
216
+ reason: `Pending gate mismatch: current is "${activeGate}", requested "${requestedGate}"`,
217
+ };
218
+ }
219
+ const decision = String(payload?.decision || '').trim().toLowerCase();
220
+ const isRequestChanges =
221
+ decision === 'request_changes' || decision === 'request-changes';
222
+ const reason = payload?.reason || payload?.decision || 'rejected by visual gate';
223
+ const result = runtimeState.gateBlockedRunState({
224
+ target: targetDir,
225
+ runId: payload?.run_id || state.run_id,
226
+ gate: activeGate,
227
+ pendingGate: activeGate,
228
+ status: 'waiting-approval',
229
+ fromRole: state.current_role || null,
230
+ toRole: state.current_role || null,
231
+ blockedByRole: state.current_role || state.gate_context?.blocked_by_role || null,
232
+ resumeToRole: state.gate_context?.resume_to_role || null,
233
+ requiredUserAction: isRequestChanges
234
+ ? `请先补齐资产或说明后重新提交审批。${reason ? ` 当前要求:${reason}` : ''}`.trim()
235
+ : state.gate_context?.required_user_action || '当前门禁已被拒绝,请修正后重新请求审批。',
236
+ blockedReason: isRequestChanges
237
+ ? `gate request_changes: ${reason}`
238
+ : `gate rejected: ${reason}`,
239
+ message: isRequestChanges
240
+ ? `gate request_changes: ${reason}`
241
+ : `gate rejected: ${reason}`,
242
+ eventType: isRequestChanges ? 'gate-request-changes' : 'gate-rejected',
243
+ });
244
+ const rejectSnapshot = {
245
+ status: result?.state?.status,
246
+ current_role: result?.state?.current_role,
247
+ pending_gate: result?.state?.pending_gate,
248
+ run_id: result?.state?.run_id,
249
+ };
250
+ if (isRequestChanges) {
251
+ appendNextStepHint(targetDir, 'request_changes', payload, rejectSnapshot);
252
+ }
253
+ emitGateSignal(targetDir, 'reject_gate', payload, rejectSnapshot);
254
+ return {
255
+ result: 'rejected',
256
+ reason,
257
+ snapshot: rejectSnapshot,
258
+ };
259
+ }
260
+
261
+ if (command === 'resume_run') {
262
+ const result = runtimeState.approveRunState({
263
+ target: targetDir,
264
+ gate: payload?.gate || null,
265
+ runId: payload?.run_id || null,
266
+ nextRole: payload?.next_role || payload?.resume_to_role || null,
267
+ status: 'running',
268
+ });
269
+ const snapshot = {
270
+ status: result?.state?.status,
271
+ current_role: result?.state?.current_role,
272
+ run_id: result?.state?.run_id,
273
+ };
274
+ appendNextStepHint(targetDir, 'resume_run', payload, snapshot);
275
+ emitGateSignal(targetDir, 'resume_run', payload, snapshot);
276
+ return { result: 'applied', snapshot };
277
+ }
278
+
279
+ if (command === 'cancel_run') {
280
+ // cancel_run 走轻量路径:只生成回执,不强制改写状态以避免与协议推进竞争。
281
+ return {
282
+ result: 'applied',
283
+ snapshot: { decision: 'cancel_requested', reason: payload?.reason || null },
284
+ };
285
+ }
286
+
287
+ return { result: 'rejected', reason: `unsupported command: ${command}` };
288
+ } catch (err) {
289
+ const msg = String(err?.message || err);
290
+ if (/No pending approval gate/.test(msg) || /Pending gate mismatch/.test(msg)) {
291
+ return { result: 'conflict', reason: msg };
292
+ }
293
+ return { result: 'rejected', reason: msg };
294
+ }
295
+ }
296
+
297
+ function moveFile(srcPath, destDir) {
298
+ ensureDir(destDir);
299
+ const base = path.basename(srcPath);
300
+ const dest = path.join(destDir, `${Date.now()}_${base}`);
301
+ try {
302
+ fs.renameSync(srcPath, dest);
303
+ return dest;
304
+ } catch (_err) {
305
+ try {
306
+ fs.copyFileSync(srcPath, dest);
307
+ fs.unlinkSync(srcPath);
308
+ return dest;
309
+ } catch (_err2) {
310
+ return null;
311
+ }
312
+ }
313
+ }
314
+
315
+ function listInboxFiles(inboxDir) {
316
+ if (!fs.existsSync(inboxDir)) return [];
317
+ let entries;
318
+ try {
319
+ entries = fs.readdirSync(inboxDir, { withFileTypes: true });
320
+ } catch (_err) {
321
+ return [];
322
+ }
323
+ return entries
324
+ .filter((entry) => entry.isFile() && /^control-.*\.json$/.test(entry.name))
325
+ .map((entry) => path.join(inboxDir, entry.name))
326
+ .sort();
327
+ }
328
+
329
+ /**
330
+ * 消费 inbox 控制指令并产生 receipt 列表
331
+ *
332
+ * 完整生命周期(按顺序,每步都是 best-effort 静默失败):
333
+ * 1. 可选 HTTP pull:从 visual 拉 pending 控制指令落盘到 inbox
334
+ * 2. 扫描 inbox 文件并应用到本地 runtime-state
335
+ * 3. 可选 HTTP push:把 receipts 回灌给 visual
336
+ *
337
+ * @param {{ targetDir: string, timeoutMs?: number, secret?: string, skipPull?: boolean, skipPush?: boolean }} opts
338
+ * @returns {Promise<{ processed: number, receipts: Array<object>, pulled?: number }>}
339
+ */
340
+ async function consumeInbox(opts = {}) {
341
+ const targetDir = opts.targetDir || process.cwd();
342
+ const timeoutMs = Number.isFinite(opts.timeoutMs) ? opts.timeoutMs : 50;
343
+ const startedAt = Date.now();
344
+
345
+ const bridge = loadBridgeConfig(targetDir);
346
+ const secret =
347
+ opts.secret ||
348
+ bridge?.data?.control_secret ||
349
+ bridge?.data?.controlSecret ||
350
+ null;
351
+
352
+ let pulled = 0;
353
+ if (!opts.skipPull && bridge?.data?.enabled !== false) {
354
+ try {
355
+ const { pullPendingControls } = require('./control-puller');
356
+ const pullResult = await pullPendingControls({
357
+ targetDir,
358
+ timeoutMs: Math.max(50, Math.floor(timeoutMs * 4)),
359
+ });
360
+ pulled = pullResult?.written || 0;
361
+ } catch (_err) {
362
+ // pull 阶段失败不影响后续 inbox 消费
363
+ }
364
+ }
365
+
366
+ const inboxDir = path.join(targetDir, INBOX_DIR_REL);
367
+ if (!fs.existsSync(inboxDir)) {
368
+ return { processed: 0, receipts: [], pulled };
369
+ }
370
+
371
+ const files = listInboxFiles(inboxDir);
372
+ if (files.length === 0) {
373
+ return { processed: 0, receipts: [] };
374
+ }
375
+
376
+ const receipts = [];
377
+ let processed = 0;
378
+ const seenOutboxIds = new Set();
379
+
380
+ for (const file of files) {
381
+ if (Date.now() - startedAt > timeoutMs) {
382
+ break; // 超时优雅退出,剩余文件留待下一次命令边界处理
383
+ }
384
+
385
+ const envelope = safeReadJson(file);
386
+ if (!envelope || typeof envelope !== 'object') {
387
+ moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
388
+ continue;
389
+ }
390
+
391
+ const {
392
+ outbox_id: outboxId,
393
+ command,
394
+ payload,
395
+ signature,
396
+ } = envelope;
397
+ const receiptKey = outboxId || path.basename(file);
398
+
399
+ if (seenOutboxIds.has(receiptKey)) {
400
+ moveFile(file, path.join(inboxDir, PROCESSED_SUBDIR));
401
+ continue;
402
+ }
403
+ seenOutboxIds.add(receiptKey);
404
+
405
+ let receipt = {
406
+ eventType: 'control.receipt',
407
+ outbox_id: receiptKey,
408
+ command: command || null,
409
+ result: 'rejected',
410
+ reason: null,
411
+ applied_state_snapshot: null,
412
+ received_at: new Date().toISOString(),
413
+ };
414
+
415
+ if (!command || !SUPPORTED_COMMANDS.has(command)) {
416
+ receipt.reason = `unsupported command: ${command}`;
417
+ moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
418
+ receipts.push(receipt);
419
+ processed += 1;
420
+ continue;
421
+ }
422
+
423
+ const signed = verifySignature(
424
+ { outbox_id: outboxId, command, payload },
425
+ signature,
426
+ secret,
427
+ );
428
+ if (!signed) {
429
+ receipt.reason = 'signature verification failed';
430
+ moveFile(file, path.join(inboxDir, FAILED_SUBDIR));
431
+ receipts.push(receipt);
432
+ processed += 1;
433
+ continue;
434
+ }
435
+
436
+ const applyResult = applyControl(targetDir, command, payload || {});
437
+ receipt.result = applyResult.result;
438
+ receipt.reason = applyResult.reason || null;
439
+ receipt.applied_state_snapshot = applyResult.snapshot || null;
440
+
441
+ const destDir = applyResult.result === 'applied'
442
+ ? path.join(inboxDir, APPLIED_SUBDIR)
443
+ : path.join(inboxDir, PROCESSED_SUBDIR);
444
+ moveFile(file, destDir);
445
+
446
+ receipts.push(receipt);
447
+ processed += 1;
448
+ }
449
+
450
+ if (!opts.skipPush && receipts.length > 0 && bridge?.data?.enabled !== false) {
451
+ try {
452
+ const { pushReceipts } = require('./receipt-pusher');
453
+ await pushReceipts({
454
+ targetDir,
455
+ receipts,
456
+ timeoutMs: Math.max(200, Math.floor(timeoutMs * 8)),
457
+ });
458
+ } catch (_err) {
459
+ // 推送失败不影响本地 inbox 已正常处理的事实
460
+ }
461
+ }
462
+
463
+ return { processed, receipts, pulled };
464
+ }
465
+
466
+ module.exports = {
467
+ consumeInbox,
468
+ INBOX_DIR_REL,
469
+ };