buildanything 1.8.0 → 2.0.0
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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +9 -3
- package/CHANGELOG.md +57 -0
- package/README.md +2 -2
- package/agents/a11y-architect.md +166 -0
- package/agents/business-model.md +80 -29
- package/agents/code-architect.md +75 -0
- package/agents/code-reviewer.md +255 -0
- package/agents/code-simplifier.md +64 -0
- package/agents/design-brand-guardian.md +293 -53
- package/agents/design-critic.md +139 -0
- package/agents/design-inclusive-visuals-specialist.md +6 -19
- package/agents/design-ui-designer.md +335 -56
- package/agents/design-ux-architect.md +403 -55
- package/agents/design-ux-researcher.md +264 -49
- package/agents/engineering-ai-engineer.md +26 -36
- package/agents/engineering-backend-architect.md +185 -36
- package/agents/engineering-data-engineer.md +225 -43
- package/agents/engineering-devops-automator.md +227 -74
- package/agents/engineering-frontend-developer.md +210 -34
- package/agents/engineering-mobile-app-builder.md +6 -1
- package/agents/engineering-rapid-prototyper.md +30 -9
- package/agents/engineering-security-engineer.md +263 -61
- package/agents/engineering-senior-developer.md +128 -19
- package/agents/engineering-sre.md +84 -0
- package/agents/engineering-technical-writer.md +285 -41
- package/agents/feature-intel.md +110 -0
- package/agents/ios-app-review-guardian.md +19 -2
- package/agents/ios-foundation-models-specialist.md +20 -2
- package/agents/ios-storekit-specialist.md +9 -2
- package/agents/ios-swift-architect.md +28 -1
- package/agents/ios-swift-search.md +8 -1
- package/agents/ios-swift-ui-design.md +33 -1
- package/agents/marketing-app-store-optimizer.md +246 -64
- package/agents/planner.md +216 -0
- package/agents/pr-test-analyzer.md +63 -0
- package/agents/product-feedback-synthesizer.md +8 -2
- package/agents/refactor-cleaner.md +102 -0
- package/agents/security-reviewer.md +128 -0
- package/agents/silent-failure-hunter.md +54 -0
- package/agents/swift-build-resolver.md +119 -0
- package/agents/swift-reviewer.md +112 -0
- package/agents/tech-feasibility.md +21 -1
- package/agents/testing-api-tester.md +236 -59
- package/agents/testing-evidence-collector.md +26 -1
- package/agents/testing-performance-benchmarker.md +21 -1
- package/agents/testing-reality-checker.md +6 -1
- package/agents/visual-research.md +116 -0
- package/bin/adapters/cycle-counter-tool.ts +155 -0
- package/bin/adapters/scribe-tool.ts +71 -0
- package/bin/adapters/state-save-tool.ts +130 -0
- package/bin/adapters/write-lease-tool.ts +127 -0
- package/bin/buildanything-runtime.js +15 -0
- package/bin/buildanything-runtime.ts +328 -0
- package/bin/setup.js +83 -8
- package/commands/add-feature.md +2 -0
- package/commands/build.md +782 -266
- package/commands/fix.md +1 -1
- package/commands/self-check.md +121 -0
- package/commands/setup.md +50 -9
- package/commands/ux-review.md +2 -2
- package/commands/verify.md +6 -9
- package/docs/migration/agents.yaml +729 -0
- package/docs/migration/phase-graph.yaml +1088 -0
- package/docs/migration/sdk-host-compat.md +18 -0
- package/hooks/compile-writer-owner-cache.ts +171 -0
- package/hooks/hooks.json +36 -0
- package/hooks/pre-tool-use +19 -0
- package/hooks/pre-tool-use.ts +776 -0
- package/hooks/record-mode-transitions.ts +178 -0
- package/hooks/session-start +71 -1
- package/hooks/subagent-start +17 -0
- package/hooks/subagent-start.ts +471 -0
- package/hooks/subagent-stop +17 -0
- package/hooks/subagent-stop.ts +153 -0
- package/package.json +24 -4
- package/protocols/architecture-schema.md +171 -0
- package/protocols/decision-log.md +131 -0
- package/protocols/ios-context.md +10 -11
- package/protocols/ios-phase-branches.md +208 -33
- package/protocols/launch-readiness.md +258 -0
- package/protocols/metric-loop.md +62 -2
- package/protocols/smoke-test.md +9 -1
- package/protocols/state-schema.json +388 -0
- package/protocols/state-schema.md +172 -0
- package/protocols/verify.md +62 -2
- package/protocols/visual-dna.md +185 -0
- package/protocols/web-phase-branches.md +222 -72
- package/skills/ios/_VENDORED.md +2 -0
- package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
- package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
- package/skills/ios/hig-components-content/SKILL.md +86 -0
- package/skills/ios/hig-components-content/references/activity-views.md +79 -0
- package/skills/ios/hig-components-content/references/charts.md +180 -0
- package/skills/ios/hig-components-content/references/collections.md +48 -0
- package/skills/ios/hig-components-content/references/color-wells.md +42 -0
- package/skills/ios/hig-components-content/references/image-views.md +82 -0
- package/skills/ios/hig-components-content/references/image-wells.md +34 -0
- package/skills/ios/hig-components-content/references/lockups.md +78 -0
- package/skills/ios/hig-components-content/references/web-views.md +36 -0
- package/skills/ios/hig-components-controls/SKILL.md +88 -0
- package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
- package/skills/ios/hig-components-controls/references/controls.md +112 -0
- package/skills/ios/hig-components-controls/references/gauges.md +74 -0
- package/skills/ios/hig-components-controls/references/labels.md +92 -0
- package/skills/ios/hig-components-controls/references/pickers.md +128 -0
- package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
- package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
- package/skills/ios/hig-components-controls/references/sliders.md +92 -0
- package/skills/ios/hig-components-controls/references/steppers.md +40 -0
- package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
- package/skills/ios/hig-components-controls/references/text-views.md +56 -0
- package/skills/ios/hig-components-controls/references/toggles.md +127 -0
- package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
- package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
- package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
- package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
- package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
- package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
- package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
- package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
- package/skills/ios/hig-components-layout/SKILL.md +99 -0
- package/skills/ios/hig-components-layout/references/boxes.md +48 -0
- package/skills/ios/hig-components-layout/references/column-views.md +44 -0
- package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
- package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
- package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
- package/skills/ios/hig-components-layout/references/panels.md +75 -0
- package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
- package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
- package/skills/ios/hig-components-layout/references/split-views.md +110 -0
- package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
- package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
- package/skills/ios/hig-components-layout/references/windows.md +188 -0
- package/skills/ios/hig-components-menus/SKILL.md +81 -0
- package/skills/ios/hig-components-menus/references/action-button.md +61 -0
- package/skills/ios/hig-components-menus/references/buttons.md +261 -0
- package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
- package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
- package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
- package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
- package/skills/ios/hig-components-menus/references/menus.md +171 -0
- package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
- package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
- package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
- package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
- package/skills/ios/hig-components-search/SKILL.md +68 -0
- package/skills/ios/hig-components-search/references/page-controls.md +120 -0
- package/skills/ios/hig-components-search/references/path-controls.md +40 -0
- package/skills/ios/hig-components-search/references/search-fields.md +189 -0
- package/skills/ios/hig-components-status/SKILL.md +80 -0
- package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
- package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
- package/skills/ios/hig-components-status/references/status-bars.md +38 -0
- package/skills/ios/hig-components-system/SKILL.md +88 -0
- package/skills/ios/hig-components-system/references/app-clips.md +387 -0
- package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
- package/skills/ios/hig-components-system/references/complications.md +425 -0
- package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
- package/skills/ios/hig-components-system/references/live-activities.md +442 -0
- package/skills/ios/hig-components-system/references/notifications.md +153 -0
- package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
- package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
- package/skills/ios/hig-components-system/references/widgets.md +517 -0
- package/skills/ios/hig-foundations/SKILL.md +98 -0
- package/skills/ios/hig-foundations/references/accessibility.md +291 -0
- package/skills/ios/hig-foundations/references/app-icons.md +210 -0
- package/skills/ios/hig-foundations/references/branding.md +44 -0
- package/skills/ios/hig-foundations/references/color.md +274 -0
- package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
- package/skills/ios/hig-foundations/references/icons.md +263 -0
- package/skills/ios/hig-foundations/references/images.md +176 -0
- package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
- package/skills/ios/hig-foundations/references/inclusion.md +189 -0
- package/skills/ios/hig-foundations/references/layout.md +425 -0
- package/skills/ios/hig-foundations/references/materials.md +238 -0
- package/skills/ios/hig-foundations/references/motion.md +103 -0
- package/skills/ios/hig-foundations/references/privacy.md +231 -0
- package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
- package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
- package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
- package/skills/ios/hig-foundations/references/typography.md +1146 -0
- package/skills/ios/hig-foundations/references/writing.md +91 -0
- package/skills/ios/hig-inputs/SKILL.md +94 -0
- package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
- package/skills/ios/hig-inputs/references/camera-control.md +107 -0
- package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
- package/skills/ios/hig-inputs/references/eyes.md +120 -0
- package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
- package/skills/ios/hig-inputs/references/game-controls.md +156 -0
- package/skills/ios/hig-inputs/references/gestures.md +208 -0
- package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
- package/skills/ios/hig-inputs/references/keyboards.md +234 -0
- package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
- package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
- package/skills/ios/hig-inputs/references/remotes.md +67 -0
- package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
- package/skills/ios/hig-patterns/SKILL.md +104 -0
- package/skills/ios/hig-patterns/references/charting-data.md +81 -0
- package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
- package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
- package/skills/ios/hig-patterns/references/entering-data.md +69 -0
- package/skills/ios/hig-patterns/references/feedback.md +67 -0
- package/skills/ios/hig-patterns/references/file-management.md +135 -0
- package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
- package/skills/ios/hig-patterns/references/launching.md +81 -0
- package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
- package/skills/ios/hig-patterns/references/loading.md +59 -0
- package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
- package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
- package/skills/ios/hig-patterns/references/modality.md +82 -0
- package/skills/ios/hig-patterns/references/multitasking.md +131 -0
- package/skills/ios/hig-patterns/references/offering-help.md +117 -0
- package/skills/ios/hig-patterns/references/onboarding.md +69 -0
- package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
- package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
- package/skills/ios/hig-patterns/references/playing-video.md +180 -0
- package/skills/ios/hig-patterns/references/printing.md +50 -0
- package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
- package/skills/ios/hig-patterns/references/searching.md +70 -0
- package/skills/ios/hig-patterns/references/settings.md +84 -0
- package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
- package/skills/ios/hig-patterns/references/workouts.md +76 -0
- package/skills/ios/hig-platforms/SKILL.md +84 -0
- package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
- package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
- package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
- package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
- package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
- package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
- package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
- package/skills/ios/hig-project-context/SKILL.md +133 -0
- package/skills/ios/hig-technologies/SKILL.md +107 -0
- package/skills/ios/hig-technologies/references/airplay.md +125 -0
- package/skills/ios/hig-technologies/references/always-on.md +62 -0
- package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
- package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
- package/skills/ios/hig-technologies/references/carekit.md +224 -0
- package/skills/ios/hig-technologies/references/carplay.md +119 -0
- package/skills/ios/hig-technologies/references/game-center.md +343 -0
- package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
- package/skills/ios/hig-technologies/references/healthkit.md +120 -0
- package/skills/ios/hig-technologies/references/homekit.md +343 -0
- package/skills/ios/hig-technologies/references/icloud.md +52 -0
- package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
- package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
- package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
- package/skills/ios/hig-technologies/references/live-photos.md +54 -0
- package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
- package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
- package/skills/ios/hig-technologies/references/maps.md +221 -0
- package/skills/ios/hig-technologies/references/nfc.md +51 -0
- package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
- package/skills/ios/hig-technologies/references/researchkit.md +134 -0
- package/skills/ios/hig-technologies/references/shareplay.md +142 -0
- package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
- package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
- package/skills/ios/hig-technologies/references/siri.md +523 -0
- package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
- package/skills/ios/hig-technologies/references/voiceover.md +90 -0
- package/skills/ios/hig-technologies/references/wallet.md +420 -0
- package/skills/ios/ios-bootstrap/SKILL.md +16 -7
- package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
- package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
- package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
- package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
- package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
- package/skills/web/accessibility/SKILL.md +146 -0
- package/skills/web/aceternity-ui/SKILL.md +719 -0
- package/skills/web/aceternity-ui/metadata.json +10 -0
- package/skills/web/api-design/SKILL.md +523 -0
- package/skills/web/chart-accessibility/SKILL.md +332 -0
- package/skills/web/composition-patterns/AGENTS.md +946 -0
- package/skills/web/composition-patterns/README.md +60 -0
- package/skills/web/composition-patterns/SKILL.md +89 -0
- package/skills/web/composition-patterns/metadata.json +11 -0
- package/skills/web/composition-patterns/rules/_sections.md +29 -0
- package/skills/web/composition-patterns/rules/_template.md +24 -0
- package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/skills/web/database-migrations/SKILL.md +429 -0
- package/skills/web/deployment-patterns/SKILL.md +427 -0
- package/skills/web/docker-patterns/SKILL.md +364 -0
- package/skills/web/e2e-testing/SKILL.md +326 -0
- package/skills/web/lighthouse-ci/SKILL.md +361 -0
- package/skills/web/mcp-server-patterns/SKILL.md +69 -0
- package/skills/web/next-best-practices/SKILL.md +153 -0
- package/skills/web/next-best-practices/async-patterns.md +87 -0
- package/skills/web/next-best-practices/bundling.md +180 -0
- package/skills/web/next-best-practices/data-patterns.md +297 -0
- package/skills/web/next-best-practices/debug-tricks.md +105 -0
- package/skills/web/next-best-practices/directives.md +73 -0
- package/skills/web/next-best-practices/error-handling.md +227 -0
- package/skills/web/next-best-practices/file-conventions.md +140 -0
- package/skills/web/next-best-practices/font.md +245 -0
- package/skills/web/next-best-practices/functions.md +108 -0
- package/skills/web/next-best-practices/hydration-error.md +91 -0
- package/skills/web/next-best-practices/image.md +173 -0
- package/skills/web/next-best-practices/metadata.md +301 -0
- package/skills/web/next-best-practices/parallel-routes.md +287 -0
- package/skills/web/next-best-practices/route-handlers.md +146 -0
- package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
- package/skills/web/next-best-practices/runtime-selection.md +39 -0
- package/skills/web/next-best-practices/scripts.md +141 -0
- package/skills/web/next-best-practices/self-hosting.md +371 -0
- package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
- package/skills/web/next-cache-components/SKILL.md +411 -0
- package/skills/web/postgres-best-practices/SKILL.md +14 -0
- package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
- package/skills/web/react-best-practices/AGENTS.md +3810 -0
- package/skills/web/react-best-practices/README.md +123 -0
- package/skills/web/react-best-practices/SKILL.md +149 -0
- package/skills/web/react-best-practices/metadata.json +15 -0
- package/skills/web/react-best-practices/rules/_sections.md +46 -0
- package/skills/web/react-best-practices/rules/_template.md +28 -0
- package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
- package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/web/seo/SKILL.md +154 -0
- package/skills/web/web-design-guidelines/SKILL.md +39 -0
- package/skills/web/zap-scan-config/SKILL.md +444 -0
- package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
- package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
- package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
- package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
- package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
- package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
- package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
- package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
- package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
- package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
- package/src/lrr/aggregator.ts +80 -0
- package/src/orchestrator/hooks/context-header.ts +95 -0
- package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
- package/src/orchestrator/hooks/token-accounting.ts +101 -0
- package/src/orchestrator/mcp/cycle-counter.ts +129 -0
- package/src/orchestrator/mcp/scribe.ts +283 -0
- package/src/orchestrator/mcp/state-save.ts +149 -0
- package/src/orchestrator/mcp/write-lease.ts +167 -0
- package/src/orchestrator/phase4-shared-context.ts +41 -0
- package/src/orchestrator/schemas/backward-edge.ts +46 -0
- package/agents/agentic-identity-trust.md +0 -121
- package/agents/data-consolidation-agent.md +0 -39
- package/agents/design-image-prompt-engineer.md +0 -105
- package/agents/design-visual-storyteller.md +0 -147
- package/agents/design-whimsy-injector.md +0 -89
- package/agents/engineering-autonomous-optimization-architect.md +0 -105
- package/agents/market-intel.md +0 -35
- package/agents/marketing-instagram-curator.md +0 -111
- package/agents/marketing-reddit-community-builder.md +0 -121
- package/agents/marketing-social-media-strategist.md +0 -74
- package/agents/marketing-tiktok-strategist.md +0 -123
- package/agents/marketing-twitter-engager.md +0 -124
- package/agents/marketing-wechat-official-account.md +0 -143
- package/agents/marketing-xiaohongshu-specialist.md +0 -136
- package/agents/marketing-zhihu-strategist.md +0 -160
- package/agents/product-behavioral-nudge-engine.md +0 -78
- package/agents/project-management-experiment-tracker.md +0 -102
- package/agents/report-distribution-agent.md +0 -43
- package/agents/risk-analysis.md +0 -45
- package/agents/sales-data-extraction-agent.md +0 -46
- package/agents/specialized-cultural-intelligence-strategist.md +0 -65
- package/agents/specialized-developer-advocate.md +0 -146
- package/agents/support-analytics-reporter.md +0 -133
- package/agents/support-executive-summary-generator.md +0 -64
- package/agents/support-finance-tracker.md +0 -145
- package/agents/support-legal-compliance-checker.md +0 -129
- package/agents/support-support-responder.md +0 -91
- package/agents/testing-accessibility-auditor.md +0 -110
- package/agents/testing-test-results-analyzer.md +0 -97
- package/agents/testing-tool-evaluator.md +0 -76
- package/agents/testing-workflow-optimizer.md +0 -99
- package/agents/user-research.md +0 -40
- package/protocols/brainstorm.md +0 -99
- package/protocols/design.md +0 -269
- package/protocols/planning.md +0 -87
- package/skills/ios/ios-hig/SKILL.md +0 -41
- package/skills/ios/ios-hig/references/accessibility.md +0 -81
- package/skills/ios/ios-hig/references/content.md +0 -142
- package/skills/ios/ios-hig/references/feedback.md +0 -123
- package/skills/ios/ios-hig/references/interaction.md +0 -199
- package/skills/ios/ios-hig/references/performance-platform.md +0 -129
- package/skills/ios/ios-hig/references/privacy-permissions.md +0 -181
- package/skills/ios/ios-hig/references/visual-design.md +0 -84
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/*
|
|
3
|
+
* buildanything: SubagentStart hook handler (tasks 3.1.1 + 3.1.3 + 6.2.1).
|
|
4
|
+
*
|
|
5
|
+
* Stage 3 + Stage 6. Reads the Claude Code SubagentStart stdin payload plus
|
|
6
|
+
* docs/plans/.build-state.json from process.cwd() and does three things:
|
|
7
|
+
*
|
|
8
|
+
* 1) Stages the subset of state fields the CONTEXT header needs to
|
|
9
|
+
* .buildanything/subagent-start-cache/<id>.json
|
|
10
|
+
* (task 3.1.1 — keyed by parent_tool_use_id or session_id).
|
|
11
|
+
* 2) Renders the CONTEXT header via src/orchestrator/hooks/context-header
|
|
12
|
+
* and emits it on stdout as
|
|
13
|
+
* {"additional_context": "<rendered header>"}
|
|
14
|
+
* which Claude Code injects into the spawned subagent's prompt
|
|
15
|
+
* (task 3.1.3 — same envelope shape as session-start).
|
|
16
|
+
* 3) When state.current_phase === 4 (Phase 4 — implementation sprint),
|
|
17
|
+
* additionally renders the sprint-scoped shared-context block via
|
|
18
|
+
* src/orchestrator/phase4-shared-context and APPENDS it to the
|
|
19
|
+
* additional_context string (task 6.2.1). This hoists the per-sprint
|
|
20
|
+
* refs/architecture/quality-targets block into the subagent prompt
|
|
21
|
+
* once per dispatch, so Phase 4 implementer/reviewer/critic prompts
|
|
22
|
+
* in commands/build.md can drop the inline refs block (cost lever).
|
|
23
|
+
*
|
|
24
|
+
* Render is best-effort on BOTH renderers: if a generator module fails to
|
|
25
|
+
* load (SDK off, module moved) or the inputs aren't sufficient (missing
|
|
26
|
+
* project_type, non-numeric phase, state absent), we skip that envelope
|
|
27
|
+
* and log to stderr rather than crash the subagent spawn. A sprint-context
|
|
28
|
+
* failure does not suppress a successful header — we emit header alone.
|
|
29
|
+
*
|
|
30
|
+
* Rollback flags (per MIGRATION-PLAN-FINAL.md §Stage 6):
|
|
31
|
+
* BUILDANYTHING_SDK_SPRINT_CONTEXT=off|false|0 — disables sprint-context
|
|
32
|
+
* injection entirely (restore 3.1.3 behavior: header only).
|
|
33
|
+
* BUILDANYTHING_SDK_SPRINT_CONTEXT_IOS=off|false|0 — for iOS project_type,
|
|
34
|
+
* suppresses the iOS-features sub-section within sprint context while
|
|
35
|
+
* keeping the rest. Web projects are unaffected by this flag.
|
|
36
|
+
* Default (no env var set) = both ON. Case-insensitive.
|
|
37
|
+
*
|
|
38
|
+
* Output protocol: SubagentStart hooks default exit 0 = allow. This handler
|
|
39
|
+
* exits 0 on every path; rendering failures never block the subagent.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
43
|
+
import { resolve } from "node:path";
|
|
44
|
+
import process from "node:process";
|
|
45
|
+
|
|
46
|
+
const CACHE_DIR_REL = ".buildanything/subagent-start-cache";
|
|
47
|
+
const STATE_PATH_REL = "docs/plans/.build-state.json";
|
|
48
|
+
const VISUAL_DNA_PATH_REL = "docs/plans/visual-dna.md";
|
|
49
|
+
const REFS_PATH_REL = "docs/plans/refs.json";
|
|
50
|
+
const ARCHITECTURE_PATH_REL = "docs/plans/architecture.md";
|
|
51
|
+
const SPRINT_CONTEXT_MARKER = "\n\n--- SPRINT CONTEXT ---\n\n";
|
|
52
|
+
|
|
53
|
+
// Minimal structural type for the renderer's return value. Kept local so
|
|
54
|
+
// this hook file does not statically depend on src/ (hooks/ is not in the
|
|
55
|
+
// tsconfig include set). The generator is loaded via dynamic import() at
|
|
56
|
+
// runtime under tsx.
|
|
57
|
+
interface RenderedHeaderLike {
|
|
58
|
+
content: string;
|
|
59
|
+
hash: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Same-shape structural type for phase4-shared-context's return. Local
|
|
63
|
+
// duplication keeps the hook off the src/ type graph; the runtime import
|
|
64
|
+
// returns the real object.
|
|
65
|
+
interface SprintContextBlockLike {
|
|
66
|
+
content: string;
|
|
67
|
+
hash: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Claude Code SubagentStart stdin shape — only the fields we consume. Anything
|
|
71
|
+
// else is ignored. We do a best-effort parse; malformed stdin exits 0.
|
|
72
|
+
interface SubagentStartPayload {
|
|
73
|
+
session_id?: string;
|
|
74
|
+
parent_tool_use_id?: string;
|
|
75
|
+
subagent_type?: string;
|
|
76
|
+
prompt?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The .build-state.json shape is defined authoritatively in
|
|
80
|
+
// protocols/state-schema.json. We read a narrow subset here — the fields the
|
|
81
|
+
// CONTEXT header is "likely to need." If the state schema grows new fields
|
|
82
|
+
// the header wants, add them here and in 3.1.2's renderer together.
|
|
83
|
+
interface BuildState {
|
|
84
|
+
schema_version?: number;
|
|
85
|
+
phase?: number | string;
|
|
86
|
+
// Some state writes use `current_phase` alongside/instead of `phase` —
|
|
87
|
+
// matches hooks/pre-tool-use.ts's `state.current_phase ?? state.phase`
|
|
88
|
+
// tolerance. Read both; prefer current_phase when present.
|
|
89
|
+
current_phase?: number | string;
|
|
90
|
+
step?: string;
|
|
91
|
+
project_type?: string;
|
|
92
|
+
session_id?: string;
|
|
93
|
+
build_request?: string;
|
|
94
|
+
context_level?: string;
|
|
95
|
+
git_branch?: string;
|
|
96
|
+
autonomous?: boolean;
|
|
97
|
+
mode?: string;
|
|
98
|
+
phase_artifacts?: Record<string, unknown>;
|
|
99
|
+
// "if present" per task 3.1.1 spec — not in the base schema yet but may
|
|
100
|
+
// arrive via phase_artifacts or a future schema bump. Read defensively.
|
|
101
|
+
current_phase_refs?: unknown;
|
|
102
|
+
architecture_ref?: unknown;
|
|
103
|
+
[k: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface StagedContext {
|
|
107
|
+
// Correlation keys for 3.1.3 injection.
|
|
108
|
+
cache_key: string;
|
|
109
|
+
session_id: string | null;
|
|
110
|
+
parent_tool_use_id: string | null;
|
|
111
|
+
subagent_type: string | null;
|
|
112
|
+
// Selected state fields — the CONTEXT header's input set.
|
|
113
|
+
state: {
|
|
114
|
+
schema_version: number | null;
|
|
115
|
+
phase: number | string | null;
|
|
116
|
+
step: string | null;
|
|
117
|
+
project_type: string | null;
|
|
118
|
+
build_request: string | null;
|
|
119
|
+
context_level: string | null;
|
|
120
|
+
git_branch: string | null;
|
|
121
|
+
autonomous: boolean | null;
|
|
122
|
+
mode: string | null;
|
|
123
|
+
phase_artifacts: Record<string, unknown> | null;
|
|
124
|
+
current_phase_refs: unknown;
|
|
125
|
+
architecture_ref: unknown;
|
|
126
|
+
};
|
|
127
|
+
staged_at: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function readStdin(): string {
|
|
131
|
+
try {
|
|
132
|
+
return readFileSync(0, "utf8");
|
|
133
|
+
} catch {
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function parsePayload(raw: string): SubagentStartPayload | null {
|
|
139
|
+
const text = raw.trim();
|
|
140
|
+
if (!text) return {};
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(text);
|
|
143
|
+
if (parsed && typeof parsed === "object") {
|
|
144
|
+
return parsed as SubagentStartPayload;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
} catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function loadBuildState(projectDir: string): BuildState | null {
|
|
153
|
+
const path = resolve(projectDir, STATE_PATH_REL);
|
|
154
|
+
let text: string;
|
|
155
|
+
try {
|
|
156
|
+
text = readFileSync(path, "utf8");
|
|
157
|
+
} catch {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const parsed = JSON.parse(text);
|
|
162
|
+
if (parsed && typeof parsed === "object") {
|
|
163
|
+
return parsed as BuildState;
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
} catch {
|
|
167
|
+
process.stderr.write(
|
|
168
|
+
"buildanything: subagent-start could not parse .build-state.json; skipping stage\n",
|
|
169
|
+
);
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function pickString(v: unknown): string | null {
|
|
175
|
+
return typeof v === "string" && v.length > 0 ? v : null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function pickPhaseArtifacts(
|
|
179
|
+
v: unknown,
|
|
180
|
+
): Record<string, unknown> | null {
|
|
181
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
182
|
+
return v as Record<string, unknown>;
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function selectCacheKey(payload: SubagentStartPayload): string | null {
|
|
188
|
+
const parent = pickString(payload.parent_tool_use_id);
|
|
189
|
+
if (parent) return parent;
|
|
190
|
+
const session = pickString(payload.session_id);
|
|
191
|
+
if (session) return session;
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function buildStagedContext(
|
|
196
|
+
key: string,
|
|
197
|
+
payload: SubagentStartPayload,
|
|
198
|
+
state: BuildState,
|
|
199
|
+
): StagedContext {
|
|
200
|
+
return {
|
|
201
|
+
cache_key: key,
|
|
202
|
+
session_id: pickString(payload.session_id),
|
|
203
|
+
parent_tool_use_id: pickString(payload.parent_tool_use_id),
|
|
204
|
+
subagent_type: pickString(payload.subagent_type),
|
|
205
|
+
state: {
|
|
206
|
+
schema_version:
|
|
207
|
+
typeof state.schema_version === "number" ? state.schema_version : null,
|
|
208
|
+
phase:
|
|
209
|
+
typeof state.phase === "number" || typeof state.phase === "string"
|
|
210
|
+
? state.phase
|
|
211
|
+
: null,
|
|
212
|
+
step: pickString(state.step),
|
|
213
|
+
project_type: pickString(state.project_type),
|
|
214
|
+
build_request: pickString(state.build_request),
|
|
215
|
+
context_level: pickString(state.context_level),
|
|
216
|
+
git_branch: pickString(state.git_branch),
|
|
217
|
+
autonomous:
|
|
218
|
+
typeof state.autonomous === "boolean" ? state.autonomous : null,
|
|
219
|
+
mode: pickString(state.mode),
|
|
220
|
+
phase_artifacts: pickPhaseArtifacts(state.phase_artifacts),
|
|
221
|
+
current_phase_refs: state.current_phase_refs ?? null,
|
|
222
|
+
architecture_ref: state.architecture_ref ?? null,
|
|
223
|
+
},
|
|
224
|
+
staged_at: new Date().toISOString(),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function writeStaged(projectDir: string, staged: StagedContext): void {
|
|
229
|
+
const dir = resolve(projectDir, CACHE_DIR_REL);
|
|
230
|
+
mkdirSync(dir, { recursive: true });
|
|
231
|
+
const file = resolve(dir, `${staged.cache_key}.json`);
|
|
232
|
+
// Overwrite-on-conflict is the documented behavior — most recent wins per
|
|
233
|
+
// scenario (g). Atomic write-and-rename is task 3.2.2, out of scope here.
|
|
234
|
+
writeFileSync(file, `${JSON.stringify(staged, null, 2)}\n`, "utf8");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function coercePhase(v: unknown): number | null {
|
|
238
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
239
|
+
if (typeof v === "string" && v.trim() !== "") {
|
|
240
|
+
const n = Number(v);
|
|
241
|
+
if (Number.isFinite(n)) return n;
|
|
242
|
+
}
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function pickIosFeatures(v: unknown): Record<string, boolean> | undefined {
|
|
247
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return undefined;
|
|
248
|
+
const out: Record<string, boolean> = {};
|
|
249
|
+
for (const [k, raw] of Object.entries(v as Record<string, unknown>)) {
|
|
250
|
+
if (typeof raw === "boolean") out[k] = raw;
|
|
251
|
+
}
|
|
252
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function renderHeader(
|
|
256
|
+
projectDir: string,
|
|
257
|
+
state: BuildState,
|
|
258
|
+
): Promise<RenderedHeaderLike | null> {
|
|
259
|
+
const projectType = pickString(state.project_type);
|
|
260
|
+
if (projectType !== "web" && projectType !== "ios") return null;
|
|
261
|
+
|
|
262
|
+
const phase = coercePhase(state.phase);
|
|
263
|
+
if (phase === null) return null;
|
|
264
|
+
|
|
265
|
+
let mod: typeof import("../src/orchestrator/hooks/context-header.js");
|
|
266
|
+
try {
|
|
267
|
+
mod = await import("../src/orchestrator/hooks/context-header.js");
|
|
268
|
+
} catch (err) {
|
|
269
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
270
|
+
process.stderr.write(
|
|
271
|
+
`buildanything: subagent-start could not load context-header renderer (${msg}); skipping injection\n`,
|
|
272
|
+
);
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
return mod.renderContextHeader({
|
|
278
|
+
projectType,
|
|
279
|
+
phase,
|
|
280
|
+
iosFeatures: pickIosFeatures(state.ios_features),
|
|
281
|
+
visualDnaPath: resolve(projectDir, VISUAL_DNA_PATH_REL),
|
|
282
|
+
});
|
|
283
|
+
} catch (err) {
|
|
284
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
285
|
+
process.stderr.write(
|
|
286
|
+
`buildanything: subagent-start context-header render failed (${msg}); skipping injection\n`,
|
|
287
|
+
);
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function isFlagDisabled(value: string | undefined): boolean {
|
|
293
|
+
if (value === undefined) return false;
|
|
294
|
+
const normalized = value.trim().toLowerCase();
|
|
295
|
+
return normalized === "off" || normalized === "false" || normalized === "0";
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function readJsonFile(path: string): Record<string, unknown> | null {
|
|
299
|
+
let text: string;
|
|
300
|
+
try {
|
|
301
|
+
text = readFileSync(path, "utf8");
|
|
302
|
+
} catch {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
const parsed = JSON.parse(text);
|
|
307
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
308
|
+
return parsed as Record<string, unknown>;
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
} catch {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function readTextFile(path: string): string | null {
|
|
317
|
+
try {
|
|
318
|
+
return readFileSync(path, "utf8");
|
|
319
|
+
} catch {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function extractQualityTargets(state: BuildState): Record<string, unknown> {
|
|
325
|
+
// Quality targets live under phase_artifacts.quality_targets by convention
|
|
326
|
+
// (docs/plans/quality-targets.json or similar). If absent, pass an empty
|
|
327
|
+
// object — the generator handles it (JSON.stringify({}) is "{}"). Best
|
|
328
|
+
// effort only; no cross-read of non-canonical paths.
|
|
329
|
+
const artifacts = pickPhaseArtifacts(state.phase_artifacts);
|
|
330
|
+
if (!artifacts) return {};
|
|
331
|
+
const qt = artifacts["quality_targets"];
|
|
332
|
+
if (qt && typeof qt === "object" && !Array.isArray(qt)) {
|
|
333
|
+
return qt as Record<string, unknown>;
|
|
334
|
+
}
|
|
335
|
+
return {};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function extractIosFeatureNames(v: unknown): string[] {
|
|
339
|
+
// state.ios_features is Record<string, boolean> (16 flags). The
|
|
340
|
+
// sprint-context generator expects the enabled feature NAMES as string[].
|
|
341
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return [];
|
|
342
|
+
const out: string[] = [];
|
|
343
|
+
for (const [k, raw] of Object.entries(v as Record<string, unknown>)) {
|
|
344
|
+
if (raw === true) out.push(k);
|
|
345
|
+
}
|
|
346
|
+
return out;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async function renderSprintContextBlock(
|
|
350
|
+
projectDir: string,
|
|
351
|
+
state: BuildState,
|
|
352
|
+
): Promise<SprintContextBlockLike | null> {
|
|
353
|
+
if (isFlagDisabled(process.env.BUILDANYTHING_SDK_SPRINT_CONTEXT)) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const projectType = pickString(state.project_type);
|
|
358
|
+
const iosFlagDisabled = isFlagDisabled(
|
|
359
|
+
process.env.BUILDANYTHING_SDK_SPRINT_CONTEXT_IOS,
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
let mod: typeof import("../src/orchestrator/phase4-shared-context.js");
|
|
363
|
+
try {
|
|
364
|
+
mod = await import("../src/orchestrator/phase4-shared-context.js");
|
|
365
|
+
} catch (err) {
|
|
366
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
367
|
+
process.stderr.write(
|
|
368
|
+
`buildanything: subagent-start could not load phase4-shared-context (${msg}); skipping sprint context\n`,
|
|
369
|
+
);
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const refs = readJsonFile(resolve(projectDir, REFS_PATH_REL)) ?? {};
|
|
374
|
+
const architecture =
|
|
375
|
+
readTextFile(resolve(projectDir, ARCHITECTURE_PATH_REL)) ?? "";
|
|
376
|
+
const qualityTargets = extractQualityTargets(state);
|
|
377
|
+
|
|
378
|
+
// iOS features: only pass when project is iOS AND the iOS parity flag is
|
|
379
|
+
// not off. Web project_type never receives the iosFeatures param regardless
|
|
380
|
+
// of the iOS flag. Unknown project_type defers to the generator default
|
|
381
|
+
// (no iOS section).
|
|
382
|
+
let iosFeatures: string[] | undefined;
|
|
383
|
+
if (projectType === "ios" && !iosFlagDisabled) {
|
|
384
|
+
const names = extractIosFeatureNames(state.ios_features);
|
|
385
|
+
if (names.length > 0) iosFeatures = names;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
return mod.renderSprintContext({
|
|
390
|
+
buildState: state as Record<string, unknown>,
|
|
391
|
+
refs,
|
|
392
|
+
architecture,
|
|
393
|
+
qualityTargets,
|
|
394
|
+
iosFeatures,
|
|
395
|
+
});
|
|
396
|
+
} catch (err) {
|
|
397
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
398
|
+
process.stderr.write(
|
|
399
|
+
`buildanything: subagent-start sprint-context render failed (${msg}); skipping sprint context\n`,
|
|
400
|
+
);
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function emitAdditionalContext(content: string): void {
|
|
406
|
+
process.stdout.write(`${JSON.stringify({ additional_context: content })}\n`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async function main(): Promise<number> {
|
|
410
|
+
const raw = readStdin();
|
|
411
|
+
const payload = parsePayload(raw);
|
|
412
|
+
if (!payload) {
|
|
413
|
+
// Malformed stdin — observational hook, exit 0.
|
|
414
|
+
return 0;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const key = selectCacheKey(payload);
|
|
418
|
+
if (!key) {
|
|
419
|
+
// No correlation id at all — cannot key the staging file. Exit 0.
|
|
420
|
+
return 0;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const state = loadBuildState(process.cwd());
|
|
424
|
+
if (!state) {
|
|
425
|
+
// No state (build not started) or unparseable — nothing to stage and
|
|
426
|
+
// no header to inject. Subagent spawns with its normal prompt.
|
|
427
|
+
return 0;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const staged = buildStagedContext(key, payload, state);
|
|
431
|
+
|
|
432
|
+
try {
|
|
433
|
+
writeStaged(process.cwd(), staged);
|
|
434
|
+
} catch (err) {
|
|
435
|
+
// Staging is best-effort. Log once and continue — we never block subagent
|
|
436
|
+
// spawn on a cache write failure, and header injection is independent.
|
|
437
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
438
|
+
process.stderr.write(
|
|
439
|
+
`buildanything: subagent-start could not write cache (${msg}); skipping\n`,
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const rendered = await renderHeader(process.cwd(), state);
|
|
444
|
+
if (rendered) {
|
|
445
|
+
// Phase 4 sprint-context hoist (task 6.2.1). Mirrors pre-tool-use.ts's
|
|
446
|
+
// `current_phase ?? phase` precedence, since state writers on the
|
|
447
|
+
// upgrade path may populate either field.
|
|
448
|
+
const effectivePhase = coercePhase(state.current_phase ?? state.phase);
|
|
449
|
+
let combined = rendered.content;
|
|
450
|
+
if (effectivePhase === 4) {
|
|
451
|
+
const sprint = await renderSprintContextBlock(process.cwd(), state);
|
|
452
|
+
if (sprint) {
|
|
453
|
+
combined = `${rendered.content}${SPRINT_CONTEXT_MARKER}${sprint.content}`;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
emitAdditionalContext(combined);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return 0;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
main().then(
|
|
463
|
+
(code) => process.exit(code),
|
|
464
|
+
(err) => {
|
|
465
|
+
// Last-resort guard: render path uses try/catch internally, but if
|
|
466
|
+
// anything slips through, log and exit 0 so the subagent still spawns.
|
|
467
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
468
|
+
process.stderr.write(`buildanything: subagent-start crashed (${msg})\n`);
|
|
469
|
+
process.exit(0);
|
|
470
|
+
},
|
|
471
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# buildanything: SubagentStop lease-release hook (task 2.5.1)
|
|
3
|
+
# Reads the SubagentStop stdin payload and scrubs any entries in
|
|
4
|
+
# docs/plans/.build-state.json.active_write_leases[] whose task_id matches
|
|
5
|
+
# the stopping subagent's task_id (parent_tool_use_id). Best-effort —
|
|
6
|
+
# always exit 0 so Stop events are never blocked.
|
|
7
|
+
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
HANDLER="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}/hooks/subagent-stop.ts"
|
|
11
|
+
|
|
12
|
+
if [ ! -f "$HANDLER" ]; then
|
|
13
|
+
echo "buildanything: subagent-stop handler missing at $HANDLER — skipping" >&2
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
exec npx --no-install tsx "$HANDLER"
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/*
|
|
3
|
+
* buildanything: SubagentStop lease-release hook handler (task 2.5.1).
|
|
4
|
+
*
|
|
5
|
+
* When a subagent terminates, Claude Code fires a SubagentStop event. This
|
|
6
|
+
* handler reads that payload, derives the stopping subagent's task_id
|
|
7
|
+
* strictly from parent_tool_use_id (matching the 2.4.2 semantic), and
|
|
8
|
+
* removes every entry from docs/plans/.build-state.json.active_write_leases[]
|
|
9
|
+
* whose task_id matches. Writes back via atomic write-to-.tmp + rename.
|
|
10
|
+
*
|
|
11
|
+
* This mirrors the contract of src/orchestrator/mcp/write-lease.ts's
|
|
12
|
+
* releaseLease(taskId) without importing it — subagents running in Claude
|
|
13
|
+
* Code do not have that module loaded.
|
|
14
|
+
*
|
|
15
|
+
* Best-effort semantics:
|
|
16
|
+
* - No parent_tool_use_id → no-op
|
|
17
|
+
* - Missing / corrupt state file → stderr log, exit 0
|
|
18
|
+
* - Write failure → stderr log, exit 0
|
|
19
|
+
* - ANY error → stderr log, exit 0. Never block the Stop event.
|
|
20
|
+
*
|
|
21
|
+
* Unknown keys on lease entries are preserved when filtering.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
25
|
+
import { resolve } from "node:path";
|
|
26
|
+
import process from "node:process";
|
|
27
|
+
|
|
28
|
+
const STATE_PATH_REL = "docs/plans/.build-state.json";
|
|
29
|
+
|
|
30
|
+
interface SubagentStopPayload {
|
|
31
|
+
session_id?: string;
|
|
32
|
+
parent_tool_use_id?: string;
|
|
33
|
+
tool_use_id?: string;
|
|
34
|
+
subagent_type?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Lease entries are `{task_id, file_paths[]}` plus possibly extra fields.
|
|
38
|
+
// We preserve unknown keys when filtering, so treat the entry shape opaquely
|
|
39
|
+
// except for the task_id we need to compare on.
|
|
40
|
+
interface LeaseEntry {
|
|
41
|
+
task_id?: unknown;
|
|
42
|
+
[k: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface BuildState {
|
|
46
|
+
active_write_leases?: LeaseEntry[];
|
|
47
|
+
[k: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function readStdin(): string {
|
|
51
|
+
try {
|
|
52
|
+
return readFileSync(0, "utf8");
|
|
53
|
+
} catch {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parsePayload(raw: string): SubagentStopPayload | null {
|
|
59
|
+
const text = raw.trim();
|
|
60
|
+
if (!text) return {};
|
|
61
|
+
try {
|
|
62
|
+
const parsed = JSON.parse(text);
|
|
63
|
+
if (parsed && typeof parsed === "object") {
|
|
64
|
+
return parsed as SubagentStopPayload;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function deriveTaskId(payload: SubagentStopPayload): string | null {
|
|
73
|
+
// STRICT: only parent_tool_use_id, matching the 2.4.2 acquisition semantic.
|
|
74
|
+
const raw = payload.parent_tool_use_id;
|
|
75
|
+
if (typeof raw !== "string") return null;
|
|
76
|
+
const trimmed = raw.trim();
|
|
77
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function atomicWriteJson(path: string, value: unknown): void {
|
|
81
|
+
const tmp = `${path}.tmp`;
|
|
82
|
+
writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
83
|
+
renameSync(tmp, path);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main(): number {
|
|
87
|
+
const raw = readStdin();
|
|
88
|
+
const payload = parsePayload(raw);
|
|
89
|
+
if (!payload) {
|
|
90
|
+
process.stderr.write(
|
|
91
|
+
"buildanything: subagent-stop could not parse stdin payload; skipping\n",
|
|
92
|
+
);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const taskId = deriveTaskId(payload);
|
|
97
|
+
if (!taskId) {
|
|
98
|
+
// No parent_tool_use_id → nothing to release. Silent no-op.
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const statePath = resolve(process.cwd(), STATE_PATH_REL);
|
|
103
|
+
|
|
104
|
+
let text: string;
|
|
105
|
+
try {
|
|
106
|
+
text = readFileSync(statePath, "utf8");
|
|
107
|
+
} catch {
|
|
108
|
+
// No state file (build not started) — nothing to release.
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let state: BuildState;
|
|
113
|
+
try {
|
|
114
|
+
state = JSON.parse(text) as BuildState;
|
|
115
|
+
} catch (err) {
|
|
116
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
117
|
+
process.stderr.write(
|
|
118
|
+
`buildanything: subagent-stop could not parse .build-state.json (${msg}); skipping\n`,
|
|
119
|
+
);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const existing = Array.isArray(state.active_write_leases)
|
|
124
|
+
? state.active_write_leases
|
|
125
|
+
: [];
|
|
126
|
+
|
|
127
|
+
const filtered = existing.filter((l) => l?.task_id !== taskId);
|
|
128
|
+
const releasedCount = existing.length - filtered.length;
|
|
129
|
+
|
|
130
|
+
if (releasedCount === 0) {
|
|
131
|
+
// No leases owned by this task_id — nothing to write.
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const next: BuildState = { ...state, active_write_leases: filtered };
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
atomicWriteJson(statePath, next);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
141
|
+
process.stderr.write(
|
|
142
|
+
`buildanything: subagent-stop could not write .build-state.json (${msg}); leases NOT released for task '${taskId}'\n`,
|
|
143
|
+
);
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
process.stderr.write(
|
|
148
|
+
`buildanything: subagent-stop released ${releasedCount} lease(s) for task '${taskId}'\n`,
|
|
149
|
+
);
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
process.exit(main());
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "buildanything",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "One command to build an entire product.
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "One command to build an entire product. 44 specialist agents orchestrated into a full engineering pipeline for Claude Code.",
|
|
5
5
|
"bin": {
|
|
6
|
-
"buildanything": "./bin/setup.js"
|
|
6
|
+
"buildanything": "./bin/setup.js",
|
|
7
|
+
"buildanything-runtime": "./bin/buildanything-runtime.js"
|
|
7
8
|
},
|
|
8
9
|
"scripts": {
|
|
9
10
|
"version": "node bin/sync-version.js && git add .claude-plugin/plugin.json .claude-plugin/marketplace.json"
|
|
@@ -20,6 +21,9 @@
|
|
|
20
21
|
"one-shot"
|
|
21
22
|
],
|
|
22
23
|
"author": "Sujit Meka",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22"
|
|
26
|
+
},
|
|
23
27
|
"license": "MIT",
|
|
24
28
|
"repository": {
|
|
25
29
|
"type": "git",
|
|
@@ -37,7 +41,23 @@
|
|
|
37
41
|
"hooks/",
|
|
38
42
|
"protocols/",
|
|
39
43
|
"skills/",
|
|
44
|
+
"src/",
|
|
45
|
+
"docs/migration/phase-graph.yaml",
|
|
46
|
+
"docs/migration/agents.yaml",
|
|
47
|
+
"docs/migration/sdk-host-compat.md",
|
|
40
48
|
"README.md",
|
|
41
49
|
"CHANGELOG.md"
|
|
42
|
-
]
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.114",
|
|
53
|
+
"semver": "^7.7.4",
|
|
54
|
+
"tsx": "^4.21.0",
|
|
55
|
+
"yaml": "^2.8.0",
|
|
56
|
+
"zod": "^4.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^22",
|
|
60
|
+
"@types/semver": "^7.7.1",
|
|
61
|
+
"typescript": "^6.0.3"
|
|
62
|
+
}
|
|
43
63
|
}
|