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,241 @@
1
+ #!/usr/bin/env tsx
2
+ /*
3
+ * buildanything runtime — entrypoint loaded by Claude Code plugin
4
+ * when SDK mode is enabled.
5
+ *
6
+ * Responsibilities:
7
+ * - schema_version forward-compat check on docs/plans/.build-state.json
8
+ * - --resume stale-edge recovery (Task 4.3.4)
9
+ * - SDK/host compat probe (sdkActive = state file + CLAUDE_CODE_VERSION ok)
10
+ * - logging
11
+ *
12
+ * Orchestrator MCP tools (state_save, write_lease, cycle_counter, scribe) are
13
+ * served over stdio by bin/mcp-servers/orchestrator-mcp.ts — registered via
14
+ * .claude-plugin/plugin.json's mcpServers block and auto-started by Claude
15
+ * Code. This runtime no longer registers them in-process.
16
+ */
17
+
18
+ import process from "node:process";
19
+ import { readFile } from "node:fs/promises";
20
+ import { dirname, resolve } from "node:path";
21
+ import semver from "semver";
22
+
23
+ interface PluginConfig {
24
+ config?: {
25
+ sdkStateFile?: string;
26
+ claudeCodeHostRange?: string;
27
+ sdkVersion?: string;
28
+ maxSupportedSchemaVersion?: number;
29
+ };
30
+ }
31
+
32
+ const RUNTIME_VERSION = "0.1.0";
33
+ // Hardcoded fallback if plugin.json lacks maxSupportedSchemaVersion. Keep this
34
+ // in sync with the `schema_version` table in protocols/state-schema.md.
35
+ const MAX_SUPPORTED_SCHEMA_VERSION_FALLBACK = 2;
36
+ // EX_CONFIG — configuration/state mismatch.
37
+ const EXIT_SCHEMA_VERSION_REJECT = 78;
38
+ const BUILD_STATE_PATH_REL = "docs/plans/.build-state.json";
39
+
40
+ export interface SchemaVersionCheck {
41
+ accepted: boolean;
42
+ reason?: "too_new";
43
+ detected?: number;
44
+ max?: number;
45
+ message?: string;
46
+ }
47
+
48
+ // Pure: evaluate whether a parsed state file's schema_version is forward-
49
+ // compatible with this runtime. Missing / non-numeric / ≤ max → accepted.
50
+ // Only `> max` triggers a reject. Upgrade/migration for LOWER versions is
51
+ // explicitly out of scope here (task 4.5.2 scope note).
52
+ export function checkSchemaVersion(
53
+ state: unknown,
54
+ maxSupported: number,
55
+ stateFilePath: string,
56
+ ): SchemaVersionCheck {
57
+ if (!state || typeof state !== "object") return { accepted: true };
58
+ const raw = (state as Record<string, unknown>).schema_version;
59
+ if (typeof raw !== "number" || !Number.isFinite(raw)) return { accepted: true };
60
+ if (raw <= maxSupported) return { accepted: true };
61
+ return {
62
+ accepted: false,
63
+ reason: "too_new",
64
+ detected: raw,
65
+ max: maxSupported,
66
+ message:
67
+ `buildanything: state file schema_version=${raw} exceeds supported maximum ${maxSupported} ` +
68
+ `(${stateFilePath}). Upgrade plugin to >=v${raw} or delete the state file. ` +
69
+ `See docs/migration/sdk-host-compat.md.`,
70
+ };
71
+ }
72
+
73
+ async function loadPluginConfig(): Promise<PluginConfig> {
74
+ const scriptPath = process.argv[1] ?? "";
75
+ const here = scriptPath ? dirname(scriptPath) : process.cwd();
76
+ const pluginJsonPath = resolve(here, "..", ".claude-plugin", "plugin.json");
77
+ const raw = await readFile(pluginJsonPath, "utf8");
78
+ return JSON.parse(raw) as PluginConfig;
79
+ }
80
+
81
+ async function main(): Promise<void> {
82
+ const argv = process.argv.slice(2);
83
+ const resumeRequested = argv.includes("--resume");
84
+
85
+ let pinned = "unknown";
86
+ let hostRange = "unknown";
87
+ let sdkStateFile = ".buildanything/sdk-state";
88
+ let maxSupportedSchemaVersion = MAX_SUPPORTED_SCHEMA_VERSION_FALLBACK;
89
+ try {
90
+ const plugin = await loadPluginConfig();
91
+ if (plugin.config?.sdkVersion) pinned = plugin.config.sdkVersion;
92
+ if (plugin.config?.claudeCodeHostRange) hostRange = plugin.config.claudeCodeHostRange;
93
+ if (plugin.config?.sdkStateFile) sdkStateFile = plugin.config.sdkStateFile;
94
+ if (
95
+ typeof plugin.config?.maxSupportedSchemaVersion === "number" &&
96
+ Number.isFinite(plugin.config.maxSupportedSchemaVersion)
97
+ ) {
98
+ maxSupportedSchemaVersion = plugin.config.maxSupportedSchemaVersion;
99
+ }
100
+ if (!plugin.config) {
101
+ console.warn("[buildanything-runtime] warning: plugin.json has no 'config' block; using unknown defaults");
102
+ }
103
+ } catch (err) {
104
+ console.warn(`[buildanything-runtime] warning: could not load plugin.json config (${(err as Error).message}); using unknown defaults`);
105
+ }
106
+
107
+ // [Task 4.5.2] Forward-reject state files with schema_version > max.
108
+ // Runs before any SDK/MCP wiring so an incompatible state file halts the
109
+ // whole session instead of silently stripping fields on next write.
110
+ const buildStatePath = resolve(process.cwd(), BUILD_STATE_PATH_REL);
111
+ try {
112
+ const raw = await readFile(buildStatePath, "utf8");
113
+ let parsed: unknown;
114
+ try {
115
+ parsed = JSON.parse(raw);
116
+ } catch (err) {
117
+ // Malformed JSON is NOT our concern here — other handlers surface it.
118
+ // Log for visibility and continue.
119
+ console.warn(
120
+ `[buildanything-runtime] warning: could not parse ${buildStatePath} for schema check (${(err as Error).message}); continuing`,
121
+ );
122
+ parsed = null;
123
+ }
124
+ const check = checkSchemaVersion(parsed, maxSupportedSchemaVersion, buildStatePath);
125
+ if (!check.accepted) {
126
+ process.stderr.write(`${check.message}\n`);
127
+ process.exit(EXIT_SCHEMA_VERSION_REJECT);
128
+ }
129
+ } catch (err) {
130
+ const code = (err as NodeJS.ErrnoException).code;
131
+ if (code !== "ENOENT") {
132
+ console.warn(
133
+ `[buildanything-runtime] warning: could not read ${buildStatePath} for schema check (${(err as Error).message}); continuing`,
134
+ );
135
+ }
136
+ // ENOENT → no state file yet (fresh project); nothing to reject.
137
+ }
138
+
139
+ console.log(`buildanything-runtime v${RUNTIME_VERSION} starting (sdk=${pinned}, hostRange=${hostRange})`);
140
+
141
+ if (resumeRequested) {
142
+ console.log("[buildanything-runtime] resume requested");
143
+ // [Task 4.3.4] --resume staleness decrement — clears a crashed
144
+ // backward edge (>60s old) by decrementing counters, so the retry
145
+ // isn't double-counted toward the escalate-to-user cap.
146
+ try {
147
+ const cycleCounter = await import("../src/orchestrator/mcp/cycle-counter.js");
148
+ const stateSaveModule = await import("../src/orchestrator/mcp/state-save.js");
149
+ let parsed: Record<string, unknown> | null = null;
150
+ try {
151
+ const raw = await readFile(buildStatePath, "utf8");
152
+ parsed = JSON.parse(raw) as Record<string, unknown>;
153
+ } catch (err) {
154
+ const code = (err as NodeJS.ErrnoException).code;
155
+ if (code === "ENOENT") {
156
+ process.stderr.write("buildanything: no active backward edge; --resume is a no-op.\n");
157
+ } else {
158
+ console.warn(
159
+ `[buildanything-runtime] warning: could not read ${buildStatePath} for --resume stale-edge check (${(err as Error).message}); continuing`,
160
+ );
161
+ }
162
+ }
163
+ if (parsed) {
164
+ if (!parsed.in_flight_backward_edge) {
165
+ process.stderr.write("buildanything: no active backward edge; --resume is a no-op.\n");
166
+ } else {
167
+ const cleared = cycleCounter.handleStaleEdge(parsed as unknown as import("../src/orchestrator/mcp/cycle-counter.js").CounterState);
168
+ if (cleared) {
169
+ stateSaveModule.stateSave(buildStatePath, parsed);
170
+ process.stderr.write(
171
+ "buildanything: cleared stale in_flight_backward_edge (>60s old); counters decremented. Resuming from last known good phase.\n",
172
+ );
173
+ } else {
174
+ process.stderr.write(
175
+ "buildanything: --resume requested but no stale edge detected; proceeding normally.\n",
176
+ );
177
+ }
178
+ }
179
+ }
180
+ } catch (err) {
181
+ console.warn(
182
+ `[buildanything-runtime] warning: --resume stale-edge check failed (${(err as Error).message}); continuing`,
183
+ );
184
+ }
185
+ }
186
+
187
+ const hostVersion = process.env.CLAUDE_CODE_VERSION;
188
+ let hostCompat = true;
189
+ if (!hostVersion) {
190
+ console.log("[buildanything-runtime] host version unavailable (CLAUDE_CODE_VERSION not set); skipping compat check");
191
+ } else if (semver.satisfies(hostVersion, hostRange)) {
192
+ console.log(`[buildanything-runtime] host version ${hostVersion} satisfies compat range ${hostRange}`);
193
+ } else {
194
+ hostCompat = false;
195
+ }
196
+
197
+ if (!hostCompat) {
198
+ console.warn(`[buildanything-runtime] host version ${hostVersion} outside compat range ${hostRange} — falling back to markdown mode.`);
199
+ }
200
+
201
+ const stateFilePath = resolve(process.cwd(), sdkStateFile);
202
+ let stateFileActive = false;
203
+ try {
204
+ const contents = (await readFile(stateFilePath, "utf8")).trim();
205
+ stateFileActive = contents === "on";
206
+ } catch (err) {
207
+ const code = (err as NodeJS.ErrnoException).code;
208
+ if (code === "ENOENT") {
209
+ console.log(`[buildanything-runtime] debug: sdk state file missing at ${stateFilePath}; treating as off`);
210
+ } else {
211
+ console.warn(`[buildanything-runtime] warning: could not read sdk state file (${(err as Error).message}); treating as off`);
212
+ }
213
+ }
214
+ const sdkActive = stateFileActive && hostCompat;
215
+ console.log(`[buildanything-runtime] sdkActive=${sdkActive} (stateFile=${stateFileActive}, hostCompat=${hostCompat})`);
216
+
217
+ // Orchestrator MCP tools (scribe_decision [Task 1.2.4], acquire/release/list
218
+ // write-lease [Task 2.3.4], state_save/state_read/verify_integrity [Task
219
+ // 3.2.4], cycle_counter_check/clear_in_flight_edge/handle_stale_edge [Task
220
+ // 4.2.4]) are served over stdio by bin/mcp-servers/orchestrator-mcp.ts,
221
+ // registered through .claude-plugin/plugin.json's mcpServers block. The
222
+ // Agent SDK path no longer owns these tools — stdio is the single source.
223
+ // The adapters in bin/adapters/*.ts remain for any future in-process SDK
224
+ // path that wants to share the zod shapes.
225
+ void sdkActive;
226
+ }
227
+
228
+ function isCliEntry(): boolean {
229
+ // Run main() only when invoked as the CLI, not when imported by tests.
230
+ const entry = process.argv[1] ?? "";
231
+ return entry.endsWith("buildanything-runtime.ts") || entry.endsWith("buildanything-runtime.js");
232
+ }
233
+
234
+ if (isCliEntry()) {
235
+ main()
236
+ .then(() => process.exit(0))
237
+ .catch((err) => {
238
+ console.error("[buildanything-runtime] fatal:", err instanceof Error ? err.stack ?? err.message : err);
239
+ process.exit(1);
240
+ });
241
+ }
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Thin shim: delegates to the graph indexer TypeScript entry via tsx.
5
+ const { spawn } = require('child_process');
6
+ const path = require('path');
7
+
8
+ const tsEntry = path.join(__dirname, 'graph-index.ts');
9
+ const child = spawn('npx', ['--no-install', 'tsx', tsEntry, ...process.argv.slice(2)], {
10
+ stdio: 'inherit',
11
+ });
12
+
13
+ child.on('exit', (code, signal) => {
14
+ if (signal) {
15
+ process.kill(process.pid, signal);
16
+ return;
17
+ }
18
+ process.exit(code ?? 0);
19
+ });
20
+
21
+ child.on('error', (err) => {
22
+ process.stderr.write(`[graph-index shim] failed to spawn tsx: ${err.message}\n`);
23
+ process.exit(1);
24
+ });
@@ -0,0 +1,340 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import { readFileSync, statSync, readdirSync, existsSync, unlinkSync } from "node:fs";
4
+ import { basename, resolve, join, relative, extname } from "node:path";
5
+ import { createHash } from "node:crypto";
6
+ import process from "node:process";
7
+ import { extractProductSpec, extractDesignMd, extractDesignMdTokens, extractComponentManifest, extractPageSpec, extractArchitecture, extractSprintTasks, extractDecisionsJsonl, extractScreenshot, saveGraph } from "../src/graph/index.js";
8
+ import type { GraphFragment } from "../src/graph/types.js";
9
+
10
+ type ImageClass = "reference" | "brand_drift" | "dogfood";
11
+
12
+ const VALID_IMAGE_CLASSES: ReadonlySet<string> = new Set(["reference", "brand_drift", "dogfood"]);
13
+ const IMAGE_EXTENSIONS: ReadonlySet<string> = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]);
14
+
15
+ function parseArgs(argv: string[]): { positional: string[]; imageClass: string | undefined } {
16
+ const positional: string[] = [];
17
+ let imageClass: string | undefined;
18
+ for (const arg of argv) {
19
+ if (arg.startsWith("--image-class=")) {
20
+ imageClass = arg.slice("--image-class=".length);
21
+ } else if (arg === "--image-class") {
22
+ // peek-ahead style not supported; require =VALUE form
23
+ process.stderr.write("[graph-index] error: --image-class requires =VALUE form (e.g. --image-class=reference)\n");
24
+ process.exit(64);
25
+ } else {
26
+ positional.push(arg);
27
+ }
28
+ }
29
+ return { positional, imageClass };
30
+ }
31
+
32
+ function inferImageClassFromPath(absPath: string): ImageClass | null {
33
+ // Normalize trailing slash + lower-case scan against known suffixes.
34
+ const normalized = absPath.replace(/\/+$/, "");
35
+ if (normalized.endsWith("/design-references") || normalized.includes("/design-references/")) {
36
+ return "reference";
37
+ }
38
+ if (normalized.endsWith("/evidence/brand-drift") || normalized.includes("/evidence/brand-drift/")) {
39
+ return "brand_drift";
40
+ }
41
+ if (normalized.endsWith("/evidence/dogfood") || normalized.includes("/evidence/dogfood/")) {
42
+ return "dogfood";
43
+ }
44
+ return null;
45
+ }
46
+
47
+ function targetFileForClass(c: ImageClass): string {
48
+ switch (c) {
49
+ case "reference": return "slice-5-references.json";
50
+ case "brand_drift": return "slice-5-brand-drift.json";
51
+ case "dogfood": return "slice-5-dogfood.json";
52
+ }
53
+ }
54
+
55
+ function collectImageFiles(dir: string): string[] {
56
+ const files: string[] = [];
57
+ // Recurse one level — competitors/, inspiration/, screenshots/ subdirs are common.
58
+ const entries = readdirSync(dir, { withFileTypes: true });
59
+ for (const entry of entries) {
60
+ const full = join(dir, entry.name);
61
+ if (entry.isDirectory()) {
62
+ try {
63
+ for (const sub of readdirSync(full, { withFileTypes: true })) {
64
+ if (sub.isFile() && IMAGE_EXTENSIONS.has(extname(sub.name).toLowerCase())) {
65
+ files.push(join(full, sub.name));
66
+ }
67
+ }
68
+ } catch { /* unreadable subdir */ }
69
+ } else if (entry.isFile() && IMAGE_EXTENSIONS.has(extname(entry.name).toLowerCase())) {
70
+ files.push(full);
71
+ }
72
+ }
73
+ return files.sort();
74
+ }
75
+
76
+ function indexImageDirectory(absPath: string, imageClass: ImageClass): void {
77
+ // TODO Slice 5 production: when imageClass === 'dogfood', read evidence/dogfood/findings.json side-channel to populate linked_finding_id per screenshot.
78
+ const imageFiles = collectImageFiles(absPath);
79
+
80
+ if (imageFiles.length === 0) {
81
+ // Per Slice 5 schema §11 scenario 1: empty directory writes empty fragment, does NOT fail.
82
+ process.stdout.write(`[graph-index] info — no images in ${absPath}, writing empty fragment\n`);
83
+ }
84
+
85
+ const allNodes: GraphFragment["nodes"] = [];
86
+ const allEdges: GraphFragment["edges"] = [];
87
+ const hashChunks: Buffer[] = [];
88
+ const warnings: string[] = [];
89
+ let successCount = 0;
90
+
91
+ for (const filePath of imageFiles) {
92
+ let bytes: Buffer;
93
+ try {
94
+ bytes = readFileSync(filePath);
95
+ } catch (err) {
96
+ const msg = `failed to read ${filePath}: ${err instanceof Error ? err.message : String(err)}`;
97
+ process.stderr.write(`[graph-index] warning: ${msg}\n`);
98
+ warnings.push(msg);
99
+ continue;
100
+ }
101
+ hashChunks.push(bytes);
102
+
103
+ try {
104
+ const result = extractScreenshot({
105
+ imagePath: relative(process.cwd(), filePath),
106
+ imageClass,
107
+ imageBytes: new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength),
108
+ });
109
+
110
+ if (!result.ok) {
111
+ const msg = `${filePath}: ${result.errors.map((e) => e.message).join("; ")}`;
112
+ warnings.push(msg);
113
+ continue;
114
+ }
115
+ allNodes.push(...result.nodes);
116
+ allEdges.push(...result.edges);
117
+ successCount++;
118
+ } catch (err) {
119
+ const msg = `${filePath}: ${err instanceof Error ? err.message : String(err)}`;
120
+ warnings.push(msg);
121
+ continue;
122
+ }
123
+ }
124
+
125
+ if (imageFiles.length > 0 && successCount === 0) {
126
+ for (const w of warnings) {
127
+ process.stderr.write(`[graph-index] warning: ${w}\n`);
128
+ }
129
+ process.exit(1);
130
+ }
131
+
132
+ const combined = Buffer.concat(hashChunks);
133
+ const combinedHash = combined.length > 0
134
+ ? createHash("sha256").update(combined).digest("hex")
135
+ : "0".repeat(64);
136
+
137
+ const relDir = relative(process.cwd(), absPath) + "/";
138
+
139
+ const fragment: GraphFragment = {
140
+ source_file: relDir,
141
+ source_sha: combinedHash,
142
+ produced_at: new Date().toISOString(),
143
+ version: 1,
144
+ schema: "buildanything-slice-5",
145
+ nodes: allNodes,
146
+ edges: allEdges,
147
+ };
148
+
149
+ const targetFile = targetFileForClass(imageClass);
150
+ saveGraph(process.cwd(), fragment, targetFile);
151
+ process.stdout.write(
152
+ `[graph-index] ok — ${fragment.nodes.length} nodes, ${fragment.edges.length} edges → .buildanything/graph/${targetFile}\n`,
153
+ );
154
+
155
+ if (imageFiles.length > 0) {
156
+ for (const w of warnings) {
157
+ process.stdout.write(`[graph-index] warning: ${w}\n`);
158
+ }
159
+ process.stdout.write(`[graph-index] indexed ${successCount}/${imageFiles.length} images; ${warnings.length} warnings\n`);
160
+ }
161
+ }
162
+
163
+ const { positional, imageClass: explicitImageClass } = parseArgs(process.argv.slice(2));
164
+ const target = positional[0];
165
+
166
+ if (!target) {
167
+ process.stderr.write(
168
+ "Usage: graph-index <path> [--image-class=reference|brand_drift|dogfood]\n" +
169
+ " Recognized basenames: product-spec.md, DESIGN.md, component-manifest.md, architecture.md, sprint-tasks.md, decisions.jsonl\n" +
170
+ " Directory mode: page-specs/ → indexes all *.md files inside\n" +
171
+ " Image directory mode: design-references/ | evidence/brand-drift/ | evidence/dogfood/ → indexes all images\n" +
172
+ " DESIGN.md produces both slice-2-dna.json (Pass 1) and slice-3-tokens.json (Pass 2, if tokens found)\n",
173
+ );
174
+ process.exit(64);
175
+ }
176
+
177
+ if (explicitImageClass !== undefined && !VALID_IMAGE_CLASSES.has(explicitImageClass)) {
178
+ process.stderr.write(`[graph-index] error: --image-class must be one of: reference, brand_drift, dogfood (got: ${explicitImageClass})\n`);
179
+ process.exit(64);
180
+ }
181
+
182
+ try {
183
+ const absPath = resolve(target);
184
+
185
+ // ── Directory mode ──────────────────────────────────────────────────
186
+ let isDir = false;
187
+ try { isDir = statSync(absPath).isDirectory(); } catch { /* not a dir */ }
188
+
189
+ if (isDir) {
190
+ // page-specs/ — Slice 3 markdown directory mode
191
+ if (basename(absPath) === "page-specs") {
192
+ const mdFiles = readdirSync(absPath)
193
+ .filter((f) => f.endsWith(".md"))
194
+ .sort();
195
+
196
+ if (mdFiles.length === 0) {
197
+ process.stderr.write(`[graph-index] error: no .md files found in directory: ${absPath}\n`);
198
+ process.exit(1);
199
+ }
200
+
201
+ const allNodes: GraphFragment["nodes"] = [];
202
+ const allEdges: GraphFragment["edges"] = [];
203
+ const contents: string[] = [];
204
+
205
+ for (const file of mdFiles) {
206
+ const filePath = join(absPath, file);
207
+ const content = readFileSync(filePath, "utf-8");
208
+ contents.push(content);
209
+ const result = extractPageSpec({ mdPath: filePath, mdContent: content });
210
+ if (!result.ok) {
211
+ for (const err of result.errors) {
212
+ process.stderr.write(`[graph-index] ${file} L${err.line}: ${err.message}\n`);
213
+ }
214
+ process.stderr.write(`[graph-index] fatal: page-spec parse failed for ${file}\n`);
215
+ process.exit(1);
216
+ }
217
+ allNodes.push(...result.fragment!.nodes);
218
+ allEdges.push(...result.fragment!.edges);
219
+ }
220
+
221
+ const combinedHash = createHash("sha256").update(contents.join("")).digest("hex");
222
+ const relDir = relative(process.cwd(), absPath) + "/";
223
+
224
+ const fragment: GraphFragment = {
225
+ source_file: relDir,
226
+ source_sha: combinedHash,
227
+ produced_at: new Date().toISOString(),
228
+ version: 1,
229
+ schema: "buildanything-slice-3",
230
+ nodes: allNodes,
231
+ edges: allEdges,
232
+ };
233
+
234
+ saveGraph(process.cwd(), fragment, "slice-3-pages.json");
235
+ process.stdout.write(
236
+ `[graph-index] ok — ${fragment.nodes.length} nodes, ${fragment.edges.length} edges → .buildanything/graph/slice-3-pages.json\n`,
237
+ );
238
+ process.exit(0);
239
+ }
240
+
241
+ // Slice 5 image-directory mode — explicit override OR path inference
242
+ const inferred = inferImageClassFromPath(absPath);
243
+ const resolvedClass = (explicitImageClass ?? inferred) as ImageClass | null;
244
+
245
+ if (resolvedClass !== null) {
246
+ indexImageDirectory(absPath, resolvedClass);
247
+ process.exit(0);
248
+ }
249
+
250
+ process.stderr.write(
251
+ `[graph-index] error: directory ${absPath} is not a recognized indexer target.\n` +
252
+ ` Markdown directory: page-specs/\n` +
253
+ ` Image directories (auto-detected): design-references/, evidence/brand-drift/, evidence/dogfood/\n` +
254
+ ` Or pass --image-class=reference|brand_drift|dogfood to force.\n`,
255
+ );
256
+ process.exit(64);
257
+ }
258
+
259
+ // ── File mode ───────────────────────────────────────────────────────
260
+ if (!(() => { try { readFileSync(absPath); return true; } catch { return false; } })()) {
261
+ process.stderr.write(
262
+ "Usage: graph-index <path>\n" +
263
+ " Recognized basenames: product-spec.md, DESIGN.md, component-manifest.md, architecture.md, sprint-tasks.md, decisions.jsonl\n" +
264
+ " Directory mode: pass a page-specs/ directory to index all *.md files inside\n",
265
+ );
266
+ process.exit(64);
267
+ }
268
+
269
+ const mdContent = readFileSync(absPath, "utf-8");
270
+ const base = basename(absPath);
271
+
272
+ let result;
273
+ let targetFile: string;
274
+ if (base === "product-spec.md") {
275
+ result = extractProductSpec({ mdPath: absPath, mdContent });
276
+ targetFile = "slice-1.json";
277
+ } else if (base === "DESIGN.md") {
278
+ result = extractDesignMd({ mdPath: absPath, mdContent });
279
+ targetFile = "slice-2-dna.json";
280
+ } else if (base === "component-manifest.md") {
281
+ result = extractComponentManifest({ mdPath: absPath, mdContent });
282
+ targetFile = "slice-2-manifest.json";
283
+ } else if (base === "architecture.md") {
284
+ result = extractArchitecture({ mdPath: absPath, mdContent });
285
+ targetFile = "slice-4-architecture.json";
286
+ } else if (base === "sprint-tasks.md") {
287
+ result = extractSprintTasks({ mdPath: absPath, mdContent });
288
+ targetFile = "slice-4-tasks.json";
289
+ } else if (base === "decisions.jsonl") {
290
+ result = extractDecisionsJsonl({ mdPath: absPath, mdContent });
291
+ targetFile = "slice-4-decisions.json";
292
+ } else {
293
+ process.stderr.write(
294
+ `Usage: graph-index <path>\n Recognized basenames: product-spec.md, DESIGN.md, component-manifest.md, architecture.md, sprint-tasks.md, decisions.jsonl\n Directory mode: pass a page-specs/ directory to index all *.md files inside\n Got: ${base}\n`,
295
+ );
296
+ process.exit(64);
297
+ }
298
+
299
+ if (result.ok) {
300
+ const fragment = result.fragment!;
301
+ saveGraph(process.cwd(), fragment, targetFile);
302
+ process.stdout.write(
303
+ `[graph-index] ok — ${fragment.nodes.length} nodes, ${fragment.edges.length} edges → .buildanything/graph/${targetFile}\n`,
304
+ );
305
+ } else {
306
+ for (const err of result.errors) {
307
+ process.stderr.write(`[graph-index] L${err.line}: ${err.message}\n`);
308
+ }
309
+ process.exit(1);
310
+ }
311
+
312
+ // ── DESIGN.md Pass 2: tokens ────────────────────────────────────────
313
+ if (base === "DESIGN.md") {
314
+ const pass2 = extractDesignMdTokens({ mdPath: absPath, mdContent });
315
+ if (pass2.ok && pass2.fragment!.nodes.length > 0) {
316
+ saveGraph(process.cwd(), pass2.fragment!, "slice-3-tokens.json");
317
+ process.stdout.write(
318
+ `[graph-index] ok — ${pass2.fragment!.nodes.length} nodes, ${pass2.fragment!.edges.length} edges → .buildanything/graph/slice-3-tokens.json\n`,
319
+ );
320
+ } else if (!pass2.ok) {
321
+ for (const err of pass2.errors) {
322
+ process.stderr.write(`[graph-index] warning (Pass 2): L${err.line}: ${err.message}\n`);
323
+ }
324
+ }
325
+
326
+ if ((pass2.ok && pass2.fragment!.nodes.length === 0) || !pass2.ok) {
327
+ const stalePath = join(process.cwd(), ".buildanything", "graph", "slice-3-tokens.json");
328
+ try {
329
+ if (existsSync(stalePath)) {
330
+ unlinkSync(stalePath);
331
+ process.stdout.write("[graph-index] Pass 2 empty — removed stale slice-3-tokens.json\n");
332
+ }
333
+ } catch { /* best-effort */ }
334
+ }
335
+ }
336
+ } catch (e: unknown) {
337
+ const msg = e instanceof Error ? e.message : String(e);
338
+ process.stderr.write(`[graph-index] fatal: ${msg}\n`);
339
+ process.exit(2);
340
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Thin shim: delegates to the TypeScript entry via tsx.
5
+ // Mirrors bin/buildanything-runtime.js and the hooks pattern so Claude Code
6
+ // can launch this stdio MCP server without tsx installed globally.
7
+ const { spawn } = require('child_process');
8
+ const path = require('path');
9
+
10
+ const tsEntry = path.join(__dirname, 'graph-mcp.ts');
11
+ const child = spawn('npx', ['--no-install', 'tsx', tsEntry, ...process.argv.slice(2)], {
12
+ stdio: 'inherit',
13
+ });
14
+
15
+ child.on('exit', (code, signal) => {
16
+ if (signal) {
17
+ process.kill(process.pid, signal);
18
+ return;
19
+ }
20
+ process.exit(code ?? 0);
21
+ });
22
+
23
+ child.on('error', (err) => {
24
+ process.stderr.write(`[graph-mcp shim] failed to spawn tsx: ${err.message}\n`);
25
+ process.exit(1);
26
+ });