buildanything 1.8.0 → 2.1.1

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 (494) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +17 -3
  3. package/CHANGELOG.md +57 -0
  4. package/README.md +57 -61
  5. package/agents/a11y-architect.md +168 -0
  6. package/agents/briefing-officer.md +172 -0
  7. package/agents/business-model.md +82 -29
  8. package/agents/code-architect.md +80 -0
  9. package/agents/code-reviewer.md +256 -0
  10. package/agents/code-simplifier.md +72 -0
  11. package/agents/design-brand-guardian.md +312 -53
  12. package/agents/design-critic.md +144 -0
  13. package/agents/design-inclusive-visuals-specialist.md +8 -19
  14. package/agents/design-ui-designer.md +352 -56
  15. package/agents/design-ux-architect.md +418 -55
  16. package/agents/design-ux-researcher.md +359 -49
  17. package/agents/engineering-ai-engineer.md +28 -36
  18. package/agents/engineering-backend-architect.md +187 -36
  19. package/agents/engineering-data-engineer.md +227 -43
  20. package/agents/engineering-devops-automator.md +229 -74
  21. package/agents/engineering-frontend-developer.md +223 -34
  22. package/agents/engineering-mobile-app-builder.md +8 -1
  23. package/agents/engineering-rapid-prototyper.md +45 -11
  24. package/agents/engineering-security-engineer.md +265 -61
  25. package/agents/engineering-senior-developer.md +141 -19
  26. package/agents/engineering-sre.md +86 -0
  27. package/agents/engineering-technical-writer.md +287 -41
  28. package/agents/feature-intel.md +111 -0
  29. package/agents/ios-app-review-guardian.md +21 -2
  30. package/agents/ios-foundation-models-specialist.md +22 -2
  31. package/agents/ios-product-reality-auditor.md +292 -0
  32. package/agents/ios-storekit-specialist.md +11 -2
  33. package/agents/ios-swift-architect.md +29 -1
  34. package/agents/ios-swift-search.md +9 -1
  35. package/agents/ios-swift-ui-design.md +40 -5
  36. package/agents/marketing-app-store-optimizer.md +248 -64
  37. package/agents/planner.md +221 -0
  38. package/agents/pr-test-analyzer.md +64 -0
  39. package/agents/product-feedback-synthesizer.md +70 -2
  40. package/agents/product-owner.md +163 -0
  41. package/agents/product-reality-auditor.md +216 -0
  42. package/agents/product-spec-writer.md +176 -0
  43. package/agents/refactor-cleaner.md +110 -0
  44. package/agents/security-reviewer.md +129 -0
  45. package/agents/silent-failure-hunter.md +55 -0
  46. package/agents/swift-build-resolver.md +121 -0
  47. package/agents/swift-reviewer.md +113 -0
  48. package/agents/tech-feasibility.md +26 -4
  49. package/agents/testing-api-tester.md +238 -59
  50. package/agents/testing-evidence-collector.md +50 -1
  51. package/agents/testing-performance-benchmarker.md +23 -1
  52. package/agents/testing-reality-checker.md +7 -1
  53. package/agents/visual-research.md +118 -0
  54. package/bin/adapters/cycle-counter-tool.ts +155 -0
  55. package/bin/adapters/scribe-tool.ts +73 -0
  56. package/bin/adapters/state-save-tool.ts +130 -0
  57. package/bin/adapters/write-lease-tool.ts +127 -0
  58. package/bin/buildanything-runtime.js +15 -0
  59. package/bin/buildanything-runtime.ts +241 -0
  60. package/bin/graph-index.js +24 -0
  61. package/bin/graph-index.ts +340 -0
  62. package/bin/mcp-servers/graph-mcp.js +26 -0
  63. package/bin/mcp-servers/graph-mcp.ts +481 -0
  64. package/bin/mcp-servers/orchestrator-mcp.js +26 -0
  65. package/bin/mcp-servers/orchestrator-mcp.ts +361 -0
  66. package/bin/setup.js +312 -76
  67. package/commands/add-feature.md +2 -0
  68. package/commands/build.md +994 -265
  69. package/commands/fix.md +1 -1
  70. package/commands/idea-sweep.md +2 -2
  71. package/commands/self-check.md +121 -0
  72. package/commands/setup.md +61 -9
  73. package/commands/ux-review.md +5 -5
  74. package/commands/verify.md +9 -9
  75. package/docs/migration/agents.yaml +729 -0
  76. package/docs/migration/phase-graph.yaml +1504 -0
  77. package/docs/migration/sdk-host-compat.md +18 -0
  78. package/hooks/compile-writer-owner-cache.ts +171 -0
  79. package/hooks/design-md-lint +4 -0
  80. package/hooks/design-md-lint.ts +295 -0
  81. package/hooks/hooks.json +36 -0
  82. package/hooks/pre-tool-use +19 -0
  83. package/hooks/pre-tool-use.ts +807 -0
  84. package/hooks/record-mode-transitions.ts +235 -0
  85. package/hooks/session-start +71 -1
  86. package/hooks/subagent-start +17 -0
  87. package/hooks/subagent-start.ts +472 -0
  88. package/hooks/subagent-stop +17 -0
  89. package/hooks/subagent-stop.ts +153 -0
  90. package/package.json +26 -4
  91. package/protocols/agent-prompt-authoring.md +165 -0
  92. package/protocols/architecture-schema.md +178 -0
  93. package/protocols/cleanup.md +4 -0
  94. package/protocols/decision-log.md +135 -0
  95. package/protocols/design-md-authoring.md +520 -0
  96. package/protocols/design-md-spec.md +362 -0
  97. package/protocols/fake-data-detector.md +1 -1
  98. package/protocols/ios-context.md +10 -11
  99. package/protocols/ios-fake-data-detector.md +65 -0
  100. package/protocols/ios-phase-branches.md +299 -39
  101. package/protocols/launch-readiness.md +262 -0
  102. package/protocols/metric-loop.md +62 -2
  103. package/protocols/page-spec-schema.md +234 -0
  104. package/protocols/product-spec-schema.md +354 -0
  105. package/protocols/smoke-test.md +9 -1
  106. package/protocols/sprint-tasks-schema.md +53 -0
  107. package/protocols/state-schema.json +423 -0
  108. package/protocols/state-schema.md +202 -0
  109. package/protocols/verify.md +91 -3
  110. package/protocols/web-phase-branches.md +395 -75
  111. package/skills/ios/_VENDORED.md +2 -0
  112. package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
  113. package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
  114. package/skills/ios/hig-components-content/SKILL.md +86 -0
  115. package/skills/ios/hig-components-content/references/activity-views.md +79 -0
  116. package/skills/ios/hig-components-content/references/charts.md +180 -0
  117. package/skills/ios/hig-components-content/references/collections.md +48 -0
  118. package/skills/ios/hig-components-content/references/color-wells.md +42 -0
  119. package/skills/ios/hig-components-content/references/image-views.md +82 -0
  120. package/skills/ios/hig-components-content/references/image-wells.md +34 -0
  121. package/skills/ios/hig-components-content/references/lockups.md +78 -0
  122. package/skills/ios/hig-components-content/references/web-views.md +36 -0
  123. package/skills/ios/hig-components-controls/SKILL.md +88 -0
  124. package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
  125. package/skills/ios/hig-components-controls/references/controls.md +112 -0
  126. package/skills/ios/hig-components-controls/references/gauges.md +74 -0
  127. package/skills/ios/hig-components-controls/references/labels.md +92 -0
  128. package/skills/ios/hig-components-controls/references/pickers.md +128 -0
  129. package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
  130. package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
  131. package/skills/ios/hig-components-controls/references/sliders.md +92 -0
  132. package/skills/ios/hig-components-controls/references/steppers.md +40 -0
  133. package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
  134. package/skills/ios/hig-components-controls/references/text-views.md +56 -0
  135. package/skills/ios/hig-components-controls/references/toggles.md +127 -0
  136. package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
  137. package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
  138. package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
  139. package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
  140. package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
  141. package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
  142. package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
  143. package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
  144. package/skills/ios/hig-components-layout/SKILL.md +99 -0
  145. package/skills/ios/hig-components-layout/references/boxes.md +48 -0
  146. package/skills/ios/hig-components-layout/references/column-views.md +44 -0
  147. package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
  148. package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
  149. package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
  150. package/skills/ios/hig-components-layout/references/panels.md +75 -0
  151. package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
  152. package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
  153. package/skills/ios/hig-components-layout/references/split-views.md +110 -0
  154. package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
  155. package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
  156. package/skills/ios/hig-components-layout/references/windows.md +188 -0
  157. package/skills/ios/hig-components-menus/SKILL.md +81 -0
  158. package/skills/ios/hig-components-menus/references/action-button.md +61 -0
  159. package/skills/ios/hig-components-menus/references/buttons.md +261 -0
  160. package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
  161. package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
  162. package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
  163. package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
  164. package/skills/ios/hig-components-menus/references/menus.md +171 -0
  165. package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
  166. package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
  167. package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
  168. package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
  169. package/skills/ios/hig-components-search/SKILL.md +68 -0
  170. package/skills/ios/hig-components-search/references/page-controls.md +120 -0
  171. package/skills/ios/hig-components-search/references/path-controls.md +40 -0
  172. package/skills/ios/hig-components-search/references/search-fields.md +189 -0
  173. package/skills/ios/hig-components-status/SKILL.md +80 -0
  174. package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
  175. package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
  176. package/skills/ios/hig-components-status/references/status-bars.md +38 -0
  177. package/skills/ios/hig-components-system/SKILL.md +88 -0
  178. package/skills/ios/hig-components-system/references/app-clips.md +387 -0
  179. package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
  180. package/skills/ios/hig-components-system/references/complications.md +425 -0
  181. package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
  182. package/skills/ios/hig-components-system/references/live-activities.md +442 -0
  183. package/skills/ios/hig-components-system/references/notifications.md +153 -0
  184. package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
  185. package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
  186. package/skills/ios/hig-components-system/references/widgets.md +517 -0
  187. package/skills/ios/hig-foundations/SKILL.md +98 -0
  188. package/skills/ios/hig-foundations/references/accessibility.md +291 -0
  189. package/skills/ios/hig-foundations/references/app-icons.md +210 -0
  190. package/skills/ios/hig-foundations/references/branding.md +44 -0
  191. package/skills/ios/hig-foundations/references/color.md +274 -0
  192. package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
  193. package/skills/ios/hig-foundations/references/icons.md +263 -0
  194. package/skills/ios/hig-foundations/references/images.md +176 -0
  195. package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
  196. package/skills/ios/hig-foundations/references/inclusion.md +189 -0
  197. package/skills/ios/hig-foundations/references/layout.md +425 -0
  198. package/skills/ios/hig-foundations/references/materials.md +238 -0
  199. package/skills/ios/hig-foundations/references/motion.md +103 -0
  200. package/skills/ios/hig-foundations/references/privacy.md +231 -0
  201. package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
  202. package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
  203. package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
  204. package/skills/ios/hig-foundations/references/typography.md +1146 -0
  205. package/skills/ios/hig-foundations/references/writing.md +91 -0
  206. package/skills/ios/hig-inputs/SKILL.md +94 -0
  207. package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
  208. package/skills/ios/hig-inputs/references/camera-control.md +107 -0
  209. package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
  210. package/skills/ios/hig-inputs/references/eyes.md +120 -0
  211. package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
  212. package/skills/ios/hig-inputs/references/game-controls.md +156 -0
  213. package/skills/ios/hig-inputs/references/gestures.md +208 -0
  214. package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
  215. package/skills/ios/hig-inputs/references/keyboards.md +234 -0
  216. package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
  217. package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
  218. package/skills/ios/hig-inputs/references/remotes.md +67 -0
  219. package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
  220. package/skills/ios/hig-patterns/SKILL.md +104 -0
  221. package/skills/ios/hig-patterns/references/charting-data.md +81 -0
  222. package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
  223. package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
  224. package/skills/ios/hig-patterns/references/entering-data.md +69 -0
  225. package/skills/ios/hig-patterns/references/feedback.md +67 -0
  226. package/skills/ios/hig-patterns/references/file-management.md +135 -0
  227. package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
  228. package/skills/ios/hig-patterns/references/launching.md +81 -0
  229. package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
  230. package/skills/ios/hig-patterns/references/loading.md +59 -0
  231. package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
  232. package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
  233. package/skills/ios/hig-patterns/references/modality.md +82 -0
  234. package/skills/ios/hig-patterns/references/multitasking.md +131 -0
  235. package/skills/ios/hig-patterns/references/offering-help.md +117 -0
  236. package/skills/ios/hig-patterns/references/onboarding.md +69 -0
  237. package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
  238. package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
  239. package/skills/ios/hig-patterns/references/playing-video.md +180 -0
  240. package/skills/ios/hig-patterns/references/printing.md +50 -0
  241. package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
  242. package/skills/ios/hig-patterns/references/searching.md +70 -0
  243. package/skills/ios/hig-patterns/references/settings.md +84 -0
  244. package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
  245. package/skills/ios/hig-patterns/references/workouts.md +76 -0
  246. package/skills/ios/hig-platforms/SKILL.md +84 -0
  247. package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
  248. package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
  249. package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
  250. package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
  251. package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
  252. package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
  253. package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
  254. package/skills/ios/hig-project-context/SKILL.md +133 -0
  255. package/skills/ios/hig-technologies/SKILL.md +107 -0
  256. package/skills/ios/hig-technologies/references/airplay.md +125 -0
  257. package/skills/ios/hig-technologies/references/always-on.md +62 -0
  258. package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
  259. package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
  260. package/skills/ios/hig-technologies/references/carekit.md +224 -0
  261. package/skills/ios/hig-technologies/references/carplay.md +119 -0
  262. package/skills/ios/hig-technologies/references/game-center.md +343 -0
  263. package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
  264. package/skills/ios/hig-technologies/references/healthkit.md +120 -0
  265. package/skills/ios/hig-technologies/references/homekit.md +343 -0
  266. package/skills/ios/hig-technologies/references/icloud.md +52 -0
  267. package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
  268. package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
  269. package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
  270. package/skills/ios/hig-technologies/references/live-photos.md +54 -0
  271. package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
  272. package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
  273. package/skills/ios/hig-technologies/references/maps.md +221 -0
  274. package/skills/ios/hig-technologies/references/nfc.md +51 -0
  275. package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
  276. package/skills/ios/hig-technologies/references/researchkit.md +134 -0
  277. package/skills/ios/hig-technologies/references/shareplay.md +142 -0
  278. package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
  279. package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
  280. package/skills/ios/hig-technologies/references/siri.md +523 -0
  281. package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
  282. package/skills/ios/hig-technologies/references/voiceover.md +90 -0
  283. package/skills/ios/hig-technologies/references/wallet.md +420 -0
  284. package/skills/ios/ios-bootstrap/SKILL.md +17 -8
  285. package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
  286. package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
  287. package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
  288. package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
  289. package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
  290. package/skills/web/accessibility/SKILL.md +146 -0
  291. package/skills/web/aceternity-ui/SKILL.md +719 -0
  292. package/skills/web/aceternity-ui/metadata.json +10 -0
  293. package/skills/web/api-design/SKILL.md +523 -0
  294. package/skills/web/chart-accessibility/SKILL.md +332 -0
  295. package/skills/web/composition-patterns/AGENTS.md +946 -0
  296. package/skills/web/composition-patterns/README.md +60 -0
  297. package/skills/web/composition-patterns/SKILL.md +89 -0
  298. package/skills/web/composition-patterns/metadata.json +11 -0
  299. package/skills/web/composition-patterns/rules/_sections.md +29 -0
  300. package/skills/web/composition-patterns/rules/_template.md +24 -0
  301. package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  302. package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
  303. package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  304. package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
  305. package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
  306. package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
  307. package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
  308. package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
  309. package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
  310. package/skills/web/database-migrations/SKILL.md +429 -0
  311. package/skills/web/deployment-patterns/SKILL.md +427 -0
  312. package/skills/web/docker-patterns/SKILL.md +364 -0
  313. package/skills/web/e2e-testing/SKILL.md +326 -0
  314. package/skills/web/lighthouse-ci/SKILL.md +361 -0
  315. package/skills/web/mcp-server-patterns/SKILL.md +69 -0
  316. package/skills/web/next-best-practices/SKILL.md +153 -0
  317. package/skills/web/next-best-practices/async-patterns.md +87 -0
  318. package/skills/web/next-best-practices/bundling.md +180 -0
  319. package/skills/web/next-best-practices/data-patterns.md +297 -0
  320. package/skills/web/next-best-practices/debug-tricks.md +105 -0
  321. package/skills/web/next-best-practices/directives.md +73 -0
  322. package/skills/web/next-best-practices/error-handling.md +227 -0
  323. package/skills/web/next-best-practices/file-conventions.md +140 -0
  324. package/skills/web/next-best-practices/font.md +245 -0
  325. package/skills/web/next-best-practices/functions.md +108 -0
  326. package/skills/web/next-best-practices/hydration-error.md +91 -0
  327. package/skills/web/next-best-practices/image.md +173 -0
  328. package/skills/web/next-best-practices/metadata.md +301 -0
  329. package/skills/web/next-best-practices/parallel-routes.md +287 -0
  330. package/skills/web/next-best-practices/route-handlers.md +146 -0
  331. package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
  332. package/skills/web/next-best-practices/runtime-selection.md +39 -0
  333. package/skills/web/next-best-practices/scripts.md +141 -0
  334. package/skills/web/next-best-practices/self-hosting.md +371 -0
  335. package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
  336. package/skills/web/next-cache-components/SKILL.md +411 -0
  337. package/skills/web/postgres-best-practices/SKILL.md +14 -0
  338. package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
  339. package/skills/web/react-best-practices/AGENTS.md +3810 -0
  340. package/skills/web/react-best-practices/README.md +123 -0
  341. package/skills/web/react-best-practices/SKILL.md +149 -0
  342. package/skills/web/react-best-practices/metadata.json +15 -0
  343. package/skills/web/react-best-practices/rules/_sections.md +46 -0
  344. package/skills/web/react-best-practices/rules/_template.md +28 -0
  345. package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
  346. package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  347. package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
  348. package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
  349. package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
  350. package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  351. package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
  352. package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
  353. package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
  354. package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  355. package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
  356. package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
  357. package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
  358. package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  359. package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  360. package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
  361. package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
  362. package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
  363. package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  364. package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
  365. package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
  366. package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
  367. package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
  368. package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
  369. package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
  370. package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
  371. package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
  372. package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
  373. package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
  374. package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
  375. package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
  376. package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
  377. package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
  378. package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  379. package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
  380. package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  381. package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
  382. package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
  383. package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  384. package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  385. package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  386. package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
  387. package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
  388. package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
  389. package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  390. package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
  391. package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
  392. package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  393. package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
  394. package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  395. package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  396. package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  397. package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
  398. package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  399. package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
  400. package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  401. package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  402. package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
  403. package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  404. package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  405. package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
  406. package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
  407. package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
  408. package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
  409. package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
  410. package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
  411. package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
  412. package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
  413. package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
  414. package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
  415. package/skills/web/seo/SKILL.md +154 -0
  416. package/skills/web/web-design-guidelines/SKILL.md +39 -0
  417. package/skills/web/zap-scan-config/SKILL.md +444 -0
  418. package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
  419. package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
  420. package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
  421. package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
  422. package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
  423. package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
  424. package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
  425. package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
  426. package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
  427. package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
  428. package/src/graph/ids.ts +86 -0
  429. package/src/graph/index.ts +32 -0
  430. package/src/graph/parser/architecture.ts +603 -0
  431. package/src/graph/parser/component-manifest.ts +268 -0
  432. package/src/graph/parser/decisions-jsonl.ts +407 -0
  433. package/src/graph/parser/design-md-pass2.ts +253 -0
  434. package/src/graph/parser/design-md.ts +477 -0
  435. package/src/graph/parser/page-spec.ts +496 -0
  436. package/src/graph/parser/product-spec.ts +930 -0
  437. package/src/graph/parser/screenshot.ts +342 -0
  438. package/src/graph/parser/sprint-tasks.ts +317 -0
  439. package/src/graph/storage/index.ts +1154 -0
  440. package/src/graph/types.ts +432 -0
  441. package/src/graph/util/dhash.ts +84 -0
  442. package/src/lrr/aggregator.ts +175 -0
  443. package/src/orchestrator/hooks/context-header.ts +119 -0
  444. package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
  445. package/src/orchestrator/hooks/token-accounting.ts +112 -0
  446. package/src/orchestrator/mcp/cycle-counter.ts +130 -0
  447. package/src/orchestrator/mcp/scribe.ts +294 -0
  448. package/src/orchestrator/mcp/state-save.ts +149 -0
  449. package/src/orchestrator/mcp/write-lease.ts +184 -0
  450. package/src/orchestrator/phase4-shared-context.ts +57 -0
  451. package/src/orchestrator/schemas/backward-edge.ts +46 -0
  452. package/agents/agentic-identity-trust.md +0 -121
  453. package/agents/data-consolidation-agent.md +0 -39
  454. package/agents/design-image-prompt-engineer.md +0 -105
  455. package/agents/design-visual-storyteller.md +0 -147
  456. package/agents/design-whimsy-injector.md +0 -89
  457. package/agents/engineering-autonomous-optimization-architect.md +0 -105
  458. package/agents/market-intel.md +0 -35
  459. package/agents/marketing-instagram-curator.md +0 -111
  460. package/agents/marketing-reddit-community-builder.md +0 -121
  461. package/agents/marketing-social-media-strategist.md +0 -74
  462. package/agents/marketing-tiktok-strategist.md +0 -123
  463. package/agents/marketing-twitter-engager.md +0 -124
  464. package/agents/marketing-wechat-official-account.md +0 -143
  465. package/agents/marketing-xiaohongshu-specialist.md +0 -136
  466. package/agents/marketing-zhihu-strategist.md +0 -160
  467. package/agents/product-behavioral-nudge-engine.md +0 -78
  468. package/agents/project-management-experiment-tracker.md +0 -102
  469. package/agents/report-distribution-agent.md +0 -43
  470. package/agents/risk-analysis.md +0 -45
  471. package/agents/sales-data-extraction-agent.md +0 -46
  472. package/agents/specialized-cultural-intelligence-strategist.md +0 -65
  473. package/agents/specialized-developer-advocate.md +0 -146
  474. package/agents/support-analytics-reporter.md +0 -133
  475. package/agents/support-executive-summary-generator.md +0 -64
  476. package/agents/support-finance-tracker.md +0 -145
  477. package/agents/support-legal-compliance-checker.md +0 -129
  478. package/agents/support-support-responder.md +0 -91
  479. package/agents/testing-accessibility-auditor.md +0 -110
  480. package/agents/testing-test-results-analyzer.md +0 -97
  481. package/agents/testing-tool-evaluator.md +0 -76
  482. package/agents/testing-workflow-optimizer.md +0 -99
  483. package/agents/user-research.md +0 -40
  484. package/protocols/brainstorm.md +0 -99
  485. package/protocols/design.md +0 -269
  486. package/protocols/planning.md +0 -87
  487. package/skills/ios/ios-hig/SKILL.md +0 -41
  488. package/skills/ios/ios-hig/references/accessibility.md +0 -81
  489. package/skills/ios/ios-hig/references/content.md +0 -142
  490. package/skills/ios/ios-hig/references/feedback.md +0 -123
  491. package/skills/ios/ios-hig/references/interaction.md +0 -199
  492. package/skills/ios/ios-hig/references/performance-platform.md +0 -129
  493. package/skills/ios/ios-hig/references/privacy-permissions.md +0 -181
  494. package/skills/ios/ios-hig/references/visual-design.md +0 -84
@@ -0,0 +1,119 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync, existsSync } from 'node:fs';
3
+
4
+ export interface ContextHeaderInput {
5
+ projectType: 'web' | 'ios';
6
+ phase: number;
7
+ iosFeatures?: Record<string, boolean>;
8
+ visualDnaPath?: string; // path to DESIGN.md (repo root) — DNA lives in `## Overview > ### Brand DNA` block
9
+ }
10
+
11
+ export interface RenderedHeader {
12
+ content: string;
13
+ hash: string;
14
+ }
15
+
16
+ /** Cache: rendered header keyed by buildId + phase + input hash for automatic invalidation */
17
+ let cachedHeader: RenderedHeader | null = null;
18
+ let cachedBuildId: string | null = null;
19
+ let cachedPhase: number | null = null;
20
+ let cachedInputHash: string | null = null;
21
+
22
+ /**
23
+ * Compute a hash of the variable inputs that affect the rendered header.
24
+ * Used to detect mid-phase mutations (e.g., ios_features changing within a phase).
25
+ */
26
+ /**
27
+ * Extract the 7 DNA axis values from DESIGN.md `## Overview > ### Brand DNA` block.
28
+ * The block is a bullet list of 7 axes; we capture the bullets (one per axis)
29
+ * and join them with newlines. Falls back to first 5 non-frontmatter lines if
30
+ * the block is missing (legacy/partial files).
31
+ */
32
+ function extractBrandDnaBlock(content: string): string {
33
+ const dnaMatch = content.match(/###\s+Brand DNA\s*\n([\s\S]*?)(?=\n###\s|\n##\s|$)/);
34
+ if (dnaMatch) return dnaMatch[1].trim().split('\n').slice(0, 7).join('\n');
35
+ const stripped = content.replace(/^---\n[\s\S]*?\n---\n/, '');
36
+ return stripped.split('\n').slice(0, 5).join('\n').trim();
37
+ }
38
+
39
+ function inputHash(input: ContextHeaderInput): string {
40
+ const key = JSON.stringify({
41
+ projectType: input.projectType,
42
+ phase: input.phase,
43
+ iosFeatures: input.iosFeatures ?? null,
44
+ visualDnaPath: input.visualDnaPath ?? null,
45
+ });
46
+ return createHash('sha256').update(key).digest('hex').slice(0, 16);
47
+ }
48
+
49
+ /**
50
+ * Render the CONTEXT header for a phase.
51
+ * Called once at phase boundary; result reused for all dispatches in that phase.
52
+ * Automatically invalidates if inputs change within the same phase
53
+ * (e.g., ios_features mutating mid-build per spec pass criteria).
54
+ */
55
+ export function renderContextHeader(input: ContextHeaderInput, buildId: string): RenderedHeader {
56
+ const currentInputHash = inputHash(input);
57
+ // Return cached if same build, same phase, AND same inputs
58
+ if (
59
+ cachedBuildId === buildId &&
60
+ cachedPhase === input.phase &&
61
+ cachedInputHash === currentInputHash &&
62
+ cachedHeader
63
+ ) return cachedHeader;
64
+
65
+ const lines: string[] = ['CONTEXT:'];
66
+ lines.push(` project_type: ${input.projectType}`);
67
+ lines.push(` phase: ${input.phase}`);
68
+
69
+ // DNA: only for web, phase >= 4. Extract the 7 axis values from
70
+ // DESIGN.md `## Overview > ### Brand DNA` h3 block — NOT the full file.
71
+ // Falls back to first 5 lines if the block is absent (legacy/partial files).
72
+ if (input.projectType === 'web' && input.phase >= 4 && input.visualDnaPath) {
73
+ if (existsSync(input.visualDnaPath)) {
74
+ const content = readFileSync(input.visualDnaPath, 'utf-8');
75
+ const summary = extractBrandDnaBlock(content);
76
+ lines.push(` dna: ${summary}`);
77
+ }
78
+ }
79
+
80
+ // iOS features: only for ios
81
+ if (input.projectType === 'ios' && input.iosFeatures) {
82
+ const enabled = Object.entries(input.iosFeatures)
83
+ .filter(([, v]) => v)
84
+ .map(([k]) => k);
85
+ if (enabled.length > 0) {
86
+ lines.push(` ios_features: [${enabled.join(', ')}]`);
87
+ }
88
+ }
89
+
90
+ lines.push('');
91
+ lines.push('TASK:');
92
+
93
+ const content = lines.join('\n');
94
+ const hash = createHash('sha256').update(content).digest('hex').slice(0, 16);
95
+
96
+ cachedBuildId = buildId;
97
+ cachedHeader = { content, hash };
98
+ cachedPhase = input.phase;
99
+ cachedInputHash = currentInputHash;
100
+ return cachedHeader;
101
+ }
102
+
103
+ /**
104
+ * Invalidate the cache (call on phase boundary or state mutation).
105
+ */
106
+ export function invalidateCache(): void {
107
+ cachedHeader = null;
108
+ cachedBuildId = null;
109
+ cachedPhase = null;
110
+ cachedInputHash = null;
111
+ }
112
+
113
+ /**
114
+ * Check if the cache is valid for a given build + phase.
115
+ */
116
+ export function isCacheValid(phase: number, buildId?: string): boolean {
117
+ if (buildId !== undefined && cachedBuildId !== buildId) return false;
118
+ return cachedPhase === phase && cachedHeader !== null;
119
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Phase-boundary + Task-completion token accounting emitter (task 3.4.2).
3
+ *
4
+ * Subscribes to SDK assistant+result message `usage` fields.
5
+ * At every phase boundary and Task tool call completion, calls
6
+ * recordUsage() to append a cost line to docs/plans/build-log.md.
7
+ *
8
+ * Spec: MIGRATION-PLAN-FINAL.md §4 Stage 3 G3
9
+ * Depends on: src/orchestrator/hooks/token-accounting.ts (task 3.4.1)
10
+ */
11
+
12
+ import { recordUsage, type TokenUsage, type AccountingEntry } from './token-accounting';
13
+
14
+ const DEFAULT_BUILD_LOG = 'docs/plans/build-log.md';
15
+
16
+ export interface SdkUsageMessage {
17
+ input_tokens?: number;
18
+ output_tokens?: number;
19
+ cache_creation_input_tokens?: number;
20
+ cache_read_input_tokens?: number;
21
+ }
22
+
23
+ export interface PhaseContext {
24
+ phase: number;
25
+ step: string;
26
+ buildLogPath?: string;
27
+ }
28
+
29
+ export interface TaskContext extends PhaseContext {
30
+ task: string;
31
+ subagent_type: string;
32
+ }
33
+
34
+ /**
35
+ * Extract TokenUsage from an SDK usage message.
36
+ * SDK field names differ slightly from our internal format.
37
+ */
38
+ export function extractUsage(msg: SdkUsageMessage): TokenUsage {
39
+ return {
40
+ input_tokens: msg.input_tokens ?? 0,
41
+ output_tokens: msg.output_tokens ?? 0,
42
+ cache_read: msg.cache_read_input_tokens ?? 0,
43
+ cache_create: msg.cache_creation_input_tokens ?? 0,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Emit a cost line at a phase boundary.
49
+ * Called by the orchestrator after each phase completes.
50
+ */
51
+ export function emitPhaseBoundary(
52
+ ctx: PhaseContext,
53
+ usage: SdkUsageMessage,
54
+ ): AccountingEntry {
55
+ return recordUsage(ctx.buildLogPath ?? DEFAULT_BUILD_LOG, {
56
+ phase: ctx.phase,
57
+ step: ctx.step,
58
+ usage: extractUsage(usage),
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Emit a cost line at task completion.
64
+ * Called after each Task tool call returns from a subagent dispatch.
65
+ */
66
+ export function emitTaskCompletion(
67
+ ctx: TaskContext,
68
+ usage: SdkUsageMessage,
69
+ ): AccountingEntry {
70
+ return recordUsage(ctx.buildLogPath ?? DEFAULT_BUILD_LOG, {
71
+ phase: ctx.phase,
72
+ step: ctx.step,
73
+ task: ctx.task,
74
+ subagent_type: ctx.subagent_type,
75
+ usage: extractUsage(usage),
76
+ });
77
+ }
@@ -0,0 +1,112 @@
1
+ import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+
4
+ export interface TokenUsage {
5
+ input_tokens: number;
6
+ output_tokens: number;
7
+ cache_read?: number;
8
+ cache_create?: number;
9
+ }
10
+
11
+ export interface AccountingEntry {
12
+ timestamp: string;
13
+ phase: number;
14
+ step: string;
15
+ task?: string;
16
+ subagent_type?: string;
17
+ model?: string;
18
+ usage: TokenUsage;
19
+ cost_usd: number;
20
+ cumulative_usd: number;
21
+ }
22
+
23
+ /** Running cumulative cost across the build */
24
+ let cumulativeCost = 0;
25
+
26
+ /** Per-model pricing per million tokens */
27
+ export const PRICING_TABLE: Record<string, { input: number; output: number; cache_read: number; cache_create: number }> = {
28
+ 'claude-sonnet-4-5': { input: 3.0, output: 15.0, cache_read: 0.30, cache_create: 3.75 },
29
+ 'claude-haiku-3-5': { input: 0.80, output: 4.0, cache_read: 0.08, cache_create: 1.00 },
30
+ 'claude-opus-4-5': { input: 15.0, output: 75.0, cache_read: 1.50, cache_create: 18.75 },
31
+ };
32
+ const DEFAULT_PRICING = PRICING_TABLE['claude-sonnet-4-5'];
33
+
34
+ /**
35
+ * Calculate cost from token usage.
36
+ * When `model` is omitted or unrecognised, Sonnet pricing is used.
37
+ */
38
+ export function calculateCost(usage: TokenUsage, model?: string): number {
39
+ const pricing = (model ? PRICING_TABLE[model] : undefined) ?? DEFAULT_PRICING;
40
+ const inputCost = (usage.input_tokens / 1_000_000) * pricing.input;
41
+ const outputCost = (usage.output_tokens / 1_000_000) * pricing.output;
42
+ const cacheReadCost = ((usage.cache_read ?? 0) / 1_000_000) * pricing.cache_read;
43
+ const cacheCreateCost = ((usage.cache_create ?? 0) / 1_000_000) * pricing.cache_create;
44
+ return Math.round((inputCost + outputCost + cacheReadCost + cacheCreateCost) * 10000) / 10000;
45
+ }
46
+
47
+ /**
48
+ * Record a token usage entry and append to build-log.md.
49
+ *
50
+ * @param startingCost — optional seed value so callers can restore
51
+ * cumulative cost from a persisted build-log at build start.
52
+ * Defaults to the current in-memory cumulative cost.
53
+ */
54
+ export function recordUsage(
55
+ buildLogPath: string,
56
+ entry: Omit<AccountingEntry, 'cost_usd' | 'cumulative_usd' | 'timestamp'>,
57
+ startingCost = cumulativeCost,
58
+ ): AccountingEntry {
59
+ const cost = calculateCost(entry.usage, entry.model);
60
+ cumulativeCost = startingCost + cost;
61
+
62
+ const record: AccountingEntry = {
63
+ timestamp: new Date().toISOString(),
64
+ ...entry,
65
+ cost_usd: cost,
66
+ cumulative_usd: Math.round(cumulativeCost * 10000) / 10000,
67
+ };
68
+
69
+ const line = formatLogLine(record);
70
+ const dir = dirname(buildLogPath);
71
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
72
+ writeFileSync(buildLogPath, line + '\n', { flag: 'a' });
73
+
74
+ return record;
75
+ }
76
+
77
+ /**
78
+ * Format an accounting entry as a build-log line.
79
+ */
80
+ export function formatLogLine(entry: AccountingEntry): string {
81
+ const meta = [`phase=${entry.phase}`, `step=${entry.step}`];
82
+ if (entry.task) meta.push(`task=${entry.task}`);
83
+ if (entry.subagent_type) meta.push(`subagent_type=${entry.subagent_type}`);
84
+ if (entry.model) meta.push(`model=${entry.model}`);
85
+
86
+ const tokens = [
87
+ `input_tokens=${entry.usage.input_tokens}`,
88
+ `output_tokens=${entry.usage.output_tokens}`,
89
+ ];
90
+ if (entry.usage.cache_read) tokens.push(`cache_read=${entry.usage.cache_read}`);
91
+ if (entry.usage.cache_create) tokens.push(`cache_create=${entry.usage.cache_create}`);
92
+ tokens.push(`cost_usd=${entry.cost_usd}`);
93
+ tokens.push(`cumulative_usd=${entry.cumulative_usd}`);
94
+
95
+ return `[${entry.timestamp}] ${meta.join(' ')}\n${tokens.join(' ')}`;
96
+ }
97
+
98
+ /**
99
+ * Get current cumulative cost.
100
+ */
101
+ export function getCumulativeCost(): number {
102
+ return cumulativeCost;
103
+ }
104
+
105
+ /**
106
+ * Reset cumulative cost to zero.
107
+ * Call at build initialisation to prevent cross-build drift
108
+ * when the process is long-lived.
109
+ */
110
+ export function reset(): void {
111
+ cumulativeCost = 0;
112
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * cycle_counter_check MCP handler (Stage 4, A6 semantic).
3
+ *
4
+ * Authoritative semantic: escalation fires when NEW counter value > max_cycles.
5
+ * max_cycles = 2 → first two attempts allow, third escalates.
6
+ *
7
+ * Dual counter: per-decision AND per-target-phase. Escalation when EITHER exceeds cap.
8
+ */
9
+
10
+ import type { InFlightBackwardEdge, BackwardRoutingCounters } from '../schemas/backward-edge';
11
+ import { STALE_EDGE_THRESHOLD_MS } from '../schemas/backward-edge';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Types
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface CycleCheckInput {
18
+ decision_id: string;
19
+ target_phase: string;
20
+ }
21
+
22
+ export interface CycleCheckResult {
23
+ action: 'allow' | 'escalate_to_user';
24
+ decision_count: number;
25
+ phase_count: number;
26
+ }
27
+
28
+ export interface CounterState extends BackwardRoutingCounters {}
29
+
30
+ const DEFAULT_MAX_CYCLES = 2;
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Core handler (tasks 4.2.1, 4.2.2, 4.2.3)
34
+ // ---------------------------------------------------------------------------
35
+
36
+ /**
37
+ * Check and increment the cycle counter for a backward-routing edge.
38
+ * Returns allow for the first max_cycles attempts, escalate_to_user after.
39
+ *
40
+ * Mutates the state object in place — caller must persist via a single
41
+ * atomic state_save combining counter increment + in_flight_backward_edge
42
+ * write (A3 crash-seam protocol).
43
+ */
44
+ export function cycleCounterCheck(
45
+ state: CounterState,
46
+ input: CycleCheckInput,
47
+ maxCycles: number = DEFAULT_MAX_CYCLES,
48
+ ): CycleCheckResult {
49
+ if (!input.decision_id) throw new Error('decision_id is required');
50
+ if (!input.target_phase) throw new Error('target_phase is required');
51
+
52
+ // Initialize counters if missing
53
+ state.backward_routing_count ??= {};
54
+ state.backward_routing_count_by_target_phase ??= {};
55
+
56
+ // Atomically increment both counters
57
+ const decisionCount = (state.backward_routing_count[input.decision_id] ?? 0) + 1;
58
+ const phaseCount = (state.backward_routing_count_by_target_phase[input.target_phase] ?? 0) + 1;
59
+
60
+ state.backward_routing_count[input.decision_id] = decisionCount;
61
+ state.backward_routing_count_by_target_phase[input.target_phase] = phaseCount;
62
+
63
+ // Write in_flight_backward_edge (A3 crash-seam) — single atomic state_save
64
+ state.in_flight_backward_edge = {
65
+ decision_id: input.decision_id,
66
+ target_phase: input.target_phase,
67
+ counter_value: decisionCount,
68
+ started_at: new Date().toISOString(),
69
+ };
70
+
71
+ // Escalation: EITHER counter exceeds cap → escalate
72
+ const action: CycleCheckResult['action'] =
73
+ (decisionCount > maxCycles || phaseCount > maxCycles)
74
+ ? 'escalate_to_user'
75
+ : 'allow';
76
+
77
+ return { action, decision_count: decisionCount, phase_count: phaseCount };
78
+ }
79
+
80
+ // ---------------------------------------------------------------------------
81
+ // Edge lifecycle helpers
82
+ // ---------------------------------------------------------------------------
83
+
84
+ /**
85
+ * Clear the in-flight backward edge (called by target phase on re-entry).
86
+ * Caller must persist via state_save.
87
+ */
88
+ export function clearInFlightEdge(state: CounterState): void {
89
+ delete state.in_flight_backward_edge;
90
+ }
91
+
92
+ /**
93
+ * Handle stale edge on --resume (A3 crash recovery).
94
+ * If edge is older than threshold, decrement both counters and clear the edge.
95
+ * Returns true if a stale edge was cleaned up.
96
+ */
97
+ export function handleStaleEdge(state: CounterState, thresholdMs: number = STALE_EDGE_THRESHOLD_MS): boolean {
98
+ const edge = state.in_flight_backward_edge;
99
+ if (!edge) return false;
100
+
101
+ const age = Date.now() - new Date(edge.started_at).getTime();
102
+ if (age <= thresholdMs) return false; // edge is fresh, standard resume
103
+
104
+ // Edge never completed — decrement per-decision counter
105
+ const decCurrent = state.backward_routing_count[edge.decision_id] ?? 0;
106
+ if (decCurrent > 0) {
107
+ state.backward_routing_count[edge.decision_id] = decCurrent - 1;
108
+ }
109
+
110
+ // Decrement per-target-phase counter
111
+ const phaseCurrent = state.backward_routing_count_by_target_phase[edge.target_phase] ?? 0;
112
+ if (phaseCurrent > 0) {
113
+ state.backward_routing_count_by_target_phase[edge.target_phase] = phaseCurrent - 1;
114
+ }
115
+
116
+ delete state.in_flight_backward_edge;
117
+ return true; // stale edge handled
118
+ }
119
+
120
+ // ---------------------------------------------------------------------------
121
+ // Test helpers
122
+ // ---------------------------------------------------------------------------
123
+
124
+ /** Create a fresh empty CounterState. For testing only. */
125
+ export function createEmptyState(): CounterState {
126
+ return {
127
+ backward_routing_count: {},
128
+ backward_routing_count_by_target_phase: {},
129
+ };
130
+ }