@bonesofspring/ai-rules 0.2.31 → 0.2.32
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/CHANGELOG.md +11 -0
- package/docs/LOCAL-OVERLAY.md +14 -0
- package/package.json +1 -1
- package/presets/claude/android-kotlin/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/go/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/java/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/next/REPO_AGENTS.md +11 -1
- package/presets/claude/next/agents/build-verifier.md +1 -0
- package/presets/claude/next/agents/code-reviewer.md +1 -0
- package/presets/claude/next/agents/feature-developer.md +1 -0
- package/presets/claude/next/agents/openspec-author.md +2 -0
- package/presets/claude/next/agents/task-analyst.md +7 -0
- package/presets/claude/next/agents/task-router.md +1 -0
- package/presets/claude/next/rules/README.md +3 -0
- package/presets/claude/next/rules/anti-hallucination/react-next-anti-hallucination.md +10 -0
- package/presets/claude/next/rules/api-and-data/store-rtk.md +6 -0
- package/presets/claude/next/rules/architecture/feature-delivery-workflow.md +5 -1
- package/presets/claude/next/rules/architecture/product-specs-authoring.md +1 -0
- package/presets/claude/next/rules/architecture/product-specs.md +1 -0
- package/presets/claude/next/rules/architecture/reference-features.md +5 -0
- package/presets/claude/next/rules/stack/next-app-core.md +3 -0
- package/presets/claude/next/rules/stack/next-static-export.md +36 -0
- package/presets/claude/next/rules/testing/tests-e2e-structure.md +1 -0
- package/presets/claude/next/rules/testing/tests-unit.md +1 -0
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +16 -2
- package/presets/claude/next/rules/tooling-and-review/code-review-mr.md +4 -0
- package/presets/claude/next/rules/tooling-and-review/mcp-usage.md +1 -0
- package/presets/claude/next/rules/tooling-and-review/post-change-lint.md +4 -0
- package/presets/claude/next/rules/tooling-and-review/security-next.md +13 -0
- package/presets/claude/next/rules/ui-and-accessibility/component-catalog-gate.md +39 -0
- package/presets/claude/next/rules/ui-and-accessibility/design-tokens-binding.md +1 -1
- package/presets/claude/next/rules/ui-and-accessibility/forms-validation.md +35 -0
- package/presets/claude/next/rules/ui-and-accessibility/react-ui.md +19 -1
- package/presets/claude/next/team/fixtures/feature-with-ux-no-figma.json +3 -4
- package/presets/claude/nuxt/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/php-hexagonal/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/php-laravel/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/claude/svelte/rules/tooling-and-review/agent-team-orchestrator.md +1 -2
- package/presets/cursor/android-kotlin/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/go/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/java/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/mcp-ts/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/next/REPO_AGENTS.md +11 -1
- package/presets/cursor/next/agents/build-verifier.md +1 -0
- package/presets/cursor/next/agents/code-reviewer.md +1 -0
- package/presets/cursor/next/agents/feature-developer.md +1 -0
- package/presets/cursor/next/agents/openspec-author.md +2 -0
- package/presets/cursor/next/agents/task-analyst.md +7 -0
- package/presets/cursor/next/agents/task-router.md +1 -0
- package/presets/cursor/next/ai-local/rules-library/agent-artifacts-no-local-paths.md +41 -8
- package/presets/cursor/next/ai-local/rules-library/agent-pipeline-gates.md +19 -0
- package/presets/cursor/next/ai-local/rules-library/analytics-events.md +18 -0
- package/presets/cursor/next/ai-local/rules-library/api-contract-source.md +14 -0
- package/presets/cursor/next/ai-local/rules-library/artifact-lifecycle.md +17 -0
- package/presets/cursor/next/ai-local/rules-library/code-style.md +68 -0
- package/presets/cursor/next/ai-local/rules-library/component-child-decomposition.md +81 -0
- package/presets/cursor/next/ai-local/rules-library/feature-flags-experiments.md +15 -0
- package/presets/cursor/next/ai-local/rules-library/mcp-required-for-ui-layout.md +1 -1
- package/presets/cursor/next/ai-local/rules-library/no-react-fc.md +46 -0
- package/presets/cursor/next/ai-local/rules-library/no-test-driven-behavior-change.md +1 -1
- package/presets/cursor/next/ai-local/rules-library/pwa-service-worker.md +15 -0
- package/presets/cursor/next/ai-local/rules-library/qa-test-cases.md +14 -0
- package/presets/cursor/next/ai-local/rules-library/router-pages.md +4 -2
- package/presets/cursor/next/ai-local/rules-library/single-source-copy-constants.md +3 -1
- package/presets/cursor/next/ai-local/rules-library/storybook-catalog-structure.md +62 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-cleanup-temp-screenshots.md +40 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-csf-authoring.md +100 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-dev-compare-figma.md +67 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-keep-tests-current.md +75 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-modals.md +64 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-no-app-node-modules.md +40 -0
- package/presets/cursor/next/ai-local/rules-library/storybook-ui-quality-gate.md +38 -0
- package/presets/cursor/next/ai-local/rules-library/task-levels.md +28 -0
- package/presets/cursor/next/ai-local/rules-library/ui-change-review-gate.md +14 -0
- package/presets/cursor/next/rules/README.md +4 -1
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/next/rules/ai-local-overlay.mdc +16 -2
- package/presets/cursor/next/rules/code-review-mr.mdc +4 -0
- package/presets/cursor/next/rules/component-catalog-gate.mdc +38 -0
- package/presets/cursor/next/rules/design-tokens-binding.mdc +1 -1
- package/presets/cursor/next/rules/feature-delivery-workflow.mdc +5 -1
- package/presets/cursor/next/rules/forms-validation.mdc +33 -0
- package/presets/cursor/next/rules/mcp-usage.mdc +1 -0
- package/presets/cursor/next/rules/next-app-core.mdc +3 -0
- package/presets/cursor/next/rules/next-static-export.mdc +35 -0
- package/presets/cursor/next/rules/post-change-lint.mdc +4 -0
- package/presets/cursor/next/rules/product-specs-authoring.mdc +1 -0
- package/presets/cursor/next/rules/product-specs.mdc +1 -0
- package/presets/cursor/next/rules/react-next-anti-hallucination.mdc +10 -0
- package/presets/cursor/next/rules/react-ui.mdc +19 -1
- package/presets/cursor/next/rules/reference-features.mdc +5 -0
- package/presets/cursor/next/rules/security-next.mdc +12 -0
- package/presets/cursor/next/rules/store-rtk.mdc +6 -0
- package/presets/cursor/next/rules/tests-e2e-structure.mdc +1 -0
- package/presets/cursor/next/rules/tests-unit.mdc +1 -0
- package/presets/cursor/next/team/fixtures/feature-with-ux-no-figma.json +3 -4
- package/presets/cursor/nuxt/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/php-hexagonal/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/php-laravel/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/cursor/svelte/rules/agent-team-orchestrator.mdc +1 -1
- package/presets/mavis/android-kotlin/adapter-map.json +1 -1
- package/presets/mavis/android-kotlin/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/android-kotlin/rules/code-review-mr.md +6 -6
- package/presets/mavis/go/adapter-map.json +1 -1
- package/presets/mavis/go/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/go/rules/code-quality-and-refactoring.md +1 -1
- package/presets/mavis/ios-swift/adapter-map.json +1 -1
- package/presets/mavis/ios-swift/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/ios-swift/rules/code-quality-and-refactoring.md +1 -1
- package/presets/mavis/ios-swift/rules/code-review-mr.md +6 -6
- package/presets/mavis/ios-swift/rules/feature-delivery-workflow.md +14 -14
- package/presets/mavis/ios-swift/rules/reference-features.md +3 -3
- package/presets/mavis/java/adapter-map.json +1 -1
- package/presets/mavis/java/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/java/rules/code-quality-and-refactoring.md +1 -1
- package/presets/mavis/mcp-ts/adapter-map.json +1 -1
- package/presets/mavis/mcp-ts/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/next/REPO_AGENTS.md +11 -1
- package/presets/mavis/next/adapter-map.json +192 -8
- package/presets/mavis/next/agents/build-verifier.md +1 -0
- package/presets/mavis/next/agents/code-reviewer.md +1 -0
- package/presets/mavis/next/agents/feature-developer.md +1 -0
- package/presets/mavis/next/agents/openspec-author.md +2 -0
- package/presets/mavis/next/agents/task-analyst.md +7 -0
- package/presets/mavis/next/agents/task-router.md +1 -0
- package/presets/mavis/next/ai-local/rules-library/agent-artifacts-no-local-paths.md +41 -8
- package/presets/mavis/next/ai-local/rules-library/agent-pipeline-gates.md +19 -0
- package/presets/mavis/next/ai-local/rules-library/analytics-events.md +18 -0
- package/presets/mavis/next/ai-local/rules-library/api-contract-source.md +14 -0
- package/presets/mavis/next/ai-local/rules-library/artifact-lifecycle.md +17 -0
- package/presets/mavis/next/ai-local/rules-library/code-style.md +68 -0
- package/presets/mavis/next/ai-local/rules-library/component-child-decomposition.md +81 -0
- package/presets/mavis/next/ai-local/rules-library/feature-flags-experiments.md +15 -0
- package/presets/mavis/next/ai-local/rules-library/mcp-required-for-ui-layout.md +1 -1
- package/presets/mavis/next/ai-local/rules-library/no-react-fc.md +46 -0
- package/presets/mavis/next/ai-local/rules-library/no-test-driven-behavior-change.md +1 -1
- package/presets/mavis/next/ai-local/rules-library/pwa-service-worker.md +15 -0
- package/presets/mavis/next/ai-local/rules-library/qa-test-cases.md +14 -0
- package/presets/mavis/next/ai-local/rules-library/router-pages.md +4 -2
- package/presets/mavis/next/ai-local/rules-library/single-source-copy-constants.md +3 -1
- package/presets/mavis/next/ai-local/rules-library/storybook-catalog-structure.md +62 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-cleanup-temp-screenshots.md +40 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-csf-authoring.md +100 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-dev-compare-figma.md +67 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-keep-tests-current.md +75 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-modals.md +64 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-no-app-node-modules.md +40 -0
- package/presets/mavis/next/ai-local/rules-library/storybook-ui-quality-gate.md +38 -0
- package/presets/mavis/next/ai-local/rules-library/task-levels.md +28 -0
- package/presets/mavis/next/ai-local/rules-library/ui-change-review-gate.md +14 -0
- package/presets/mavis/next/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/next/rules/ai-local-overlay.md +16 -2
- package/presets/mavis/next/rules/code-quality-and-refactoring.md +2 -2
- package/presets/mavis/next/rules/code-review-mr.md +11 -7
- package/presets/mavis/next/rules/component-catalog-gate.md +31 -0
- package/presets/mavis/next/rules/design-tokens-binding.md +1 -1
- package/presets/mavis/next/rules/feature-delivery-workflow.md +22 -18
- package/presets/mavis/next/rules/forms-validation.md +26 -0
- package/presets/mavis/next/rules/mcp-usage.md +1 -0
- package/presets/mavis/next/rules/mockup-review.md +1 -1
- package/presets/mavis/next/rules/next-app-core.md +3 -0
- package/presets/mavis/next/rules/next-static-export.md +28 -0
- package/presets/mavis/next/rules/post-change-lint.md +4 -0
- package/presets/mavis/next/rules/product-specs-authoring.md +1 -0
- package/presets/mavis/next/rules/product-specs.md +1 -0
- package/presets/mavis/next/rules/react-next-anti-hallucination.md +10 -0
- package/presets/mavis/next/rules/react-ui.md +19 -1
- package/presets/mavis/next/rules/reference-features.md +7 -2
- package/presets/mavis/next/rules/security-next.md +12 -0
- package/presets/mavis/next/rules/store-rtk.md +6 -0
- package/presets/mavis/next/rules/tests-e2e-structure.md +2 -1
- package/presets/mavis/next/rules/tests-unit.md +1 -0
- package/presets/mavis/next/team/fixtures/feature-with-ux-no-figma.json +3 -4
- package/presets/mavis/nuxt/adapter-map.json +1 -1
- package/presets/mavis/nuxt/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/nuxt/rules/code-review-mr.md +6 -6
- package/presets/mavis/nuxt/rules/feature-delivery-workflow.md +15 -15
- package/presets/mavis/nuxt/rules/reference-features.md +2 -2
- package/presets/mavis/nuxt/rules/tests-e2e-structure.md +1 -1
- package/presets/mavis/php-hexagonal/adapter-map.json +1 -1
- package/presets/mavis/php-hexagonal/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/php-hexagonal/rules/code-quality-and-refactoring.md +1 -1
- package/presets/mavis/php-laravel/adapter-map.json +1 -1
- package/presets/mavis/php-laravel/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/php-laravel/rules/code-quality-and-refactoring.md +1 -1
- package/presets/mavis/svelte/adapter-map.json +1 -1
- package/presets/mavis/svelte/rules/agent-team-orchestrator.md +1 -2
- package/presets/mavis/svelte/rules/code-review-mr.md +6 -6
- package/presets/mavis/svelte/rules/feature-delivery-workflow.md +1 -1
- package/presets/mavis/svelte/rules/reference-features.md +2 -2
- package/presets/mavis/svelte/rules/tests-e2e-structure.md +1 -1
- package/presets/opencode/android-kotlin/adapter-map.json +1 -1
- package/presets/opencode/android-kotlin/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/android-kotlin/rules/code-review-mr.md +6 -6
- package/presets/opencode/go/adapter-map.json +1 -1
- package/presets/opencode/go/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/go/rules/code-quality-and-refactoring.md +1 -1
- package/presets/opencode/ios-swift/adapter-map.json +1 -1
- package/presets/opencode/ios-swift/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/ios-swift/rules/code-quality-and-refactoring.md +1 -1
- package/presets/opencode/ios-swift/rules/code-review-mr.md +6 -6
- package/presets/opencode/ios-swift/rules/feature-delivery-workflow.md +14 -14
- package/presets/opencode/ios-swift/rules/reference-features.md +3 -3
- package/presets/opencode/java/adapter-map.json +1 -1
- package/presets/opencode/java/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/java/rules/code-quality-and-refactoring.md +1 -1
- package/presets/opencode/mcp-ts/adapter-map.json +1 -1
- package/presets/opencode/mcp-ts/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/next/REPO_AGENTS.md +11 -1
- package/presets/opencode/next/adapter-map.json +192 -8
- package/presets/opencode/next/agents/build-verifier.md +1 -0
- package/presets/opencode/next/agents/code-reviewer.md +1 -0
- package/presets/opencode/next/agents/feature-developer.md +1 -0
- package/presets/opencode/next/agents/openspec-author.md +2 -0
- package/presets/opencode/next/agents/task-analyst.md +7 -0
- package/presets/opencode/next/agents/task-router.md +1 -0
- package/presets/opencode/next/ai-local/rules-library/agent-artifacts-no-local-paths.md +41 -8
- package/presets/opencode/next/ai-local/rules-library/agent-pipeline-gates.md +19 -0
- package/presets/opencode/next/ai-local/rules-library/analytics-events.md +18 -0
- package/presets/opencode/next/ai-local/rules-library/api-contract-source.md +14 -0
- package/presets/opencode/next/ai-local/rules-library/artifact-lifecycle.md +17 -0
- package/presets/opencode/next/ai-local/rules-library/code-style.md +68 -0
- package/presets/opencode/next/ai-local/rules-library/component-child-decomposition.md +81 -0
- package/presets/opencode/next/ai-local/rules-library/feature-flags-experiments.md +15 -0
- package/presets/opencode/next/ai-local/rules-library/mcp-required-for-ui-layout.md +1 -1
- package/presets/opencode/next/ai-local/rules-library/no-react-fc.md +46 -0
- package/presets/opencode/next/ai-local/rules-library/no-test-driven-behavior-change.md +1 -1
- package/presets/opencode/next/ai-local/rules-library/pwa-service-worker.md +15 -0
- package/presets/opencode/next/ai-local/rules-library/qa-test-cases.md +14 -0
- package/presets/opencode/next/ai-local/rules-library/router-pages.md +4 -2
- package/presets/opencode/next/ai-local/rules-library/single-source-copy-constants.md +3 -1
- package/presets/opencode/next/ai-local/rules-library/storybook-catalog-structure.md +62 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-cleanup-temp-screenshots.md +40 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-csf-authoring.md +100 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-dev-compare-figma.md +67 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-keep-tests-current.md +75 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-modals.md +64 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-no-app-node-modules.md +40 -0
- package/presets/opencode/next/ai-local/rules-library/storybook-ui-quality-gate.md +38 -0
- package/presets/opencode/next/ai-local/rules-library/task-levels.md +28 -0
- package/presets/opencode/next/ai-local/rules-library/ui-change-review-gate.md +14 -0
- package/presets/opencode/next/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/next/rules/ai-local-overlay.md +16 -2
- package/presets/opencode/next/rules/code-quality-and-refactoring.md +2 -2
- package/presets/opencode/next/rules/code-review-mr.md +11 -7
- package/presets/opencode/next/rules/component-catalog-gate.md +31 -0
- package/presets/opencode/next/rules/design-tokens-binding.md +1 -1
- package/presets/opencode/next/rules/feature-delivery-workflow.md +22 -18
- package/presets/opencode/next/rules/forms-validation.md +26 -0
- package/presets/opencode/next/rules/mcp-usage.md +1 -0
- package/presets/opencode/next/rules/mockup-review.md +1 -1
- package/presets/opencode/next/rules/next-app-core.md +3 -0
- package/presets/opencode/next/rules/next-static-export.md +28 -0
- package/presets/opencode/next/rules/post-change-lint.md +4 -0
- package/presets/opencode/next/rules/product-specs-authoring.md +1 -0
- package/presets/opencode/next/rules/product-specs.md +1 -0
- package/presets/opencode/next/rules/react-next-anti-hallucination.md +10 -0
- package/presets/opencode/next/rules/react-ui.md +19 -1
- package/presets/opencode/next/rules/reference-features.md +7 -2
- package/presets/opencode/next/rules/security-next.md +12 -0
- package/presets/opencode/next/rules/store-rtk.md +6 -0
- package/presets/opencode/next/rules/tests-e2e-structure.md +2 -1
- package/presets/opencode/next/rules/tests-unit.md +1 -0
- package/presets/opencode/next/team/fixtures/feature-with-ux-no-figma.json +3 -4
- package/presets/opencode/nuxt/adapter-map.json +1 -1
- package/presets/opencode/nuxt/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/nuxt/rules/code-review-mr.md +6 -6
- package/presets/opencode/nuxt/rules/feature-delivery-workflow.md +15 -15
- package/presets/opencode/nuxt/rules/reference-features.md +2 -2
- package/presets/opencode/nuxt/rules/tests-e2e-structure.md +1 -1
- package/presets/opencode/php-hexagonal/adapter-map.json +1 -1
- package/presets/opencode/php-hexagonal/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/php-hexagonal/rules/code-quality-and-refactoring.md +1 -1
- package/presets/opencode/php-laravel/adapter-map.json +1 -1
- package/presets/opencode/php-laravel/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/php-laravel/rules/code-quality-and-refactoring.md +1 -1
- package/presets/opencode/svelte/adapter-map.json +1 -1
- package/presets/opencode/svelte/rules/agent-team-orchestrator.md +1 -2
- package/presets/opencode/svelte/rules/code-review-mr.md +6 -6
- package/presets/opencode/svelte/rules/feature-delivery-workflow.md +1 -1
- package/presets/opencode/svelte/rules/reference-features.md +2 -2
- package/presets/opencode/svelte/rules/tests-e2e-structure.md +1 -1
- package/scripts/check-generated-drift.mjs +42 -2
- package/scripts/check-local-overlay.sh +39 -0
- package/scripts/fixtures/cli-golden/claude/next.json +44 -41
- package/scripts/fixtures/cli-golden/cursor/next.json +69 -46
- package/scripts/fixtures/cli-golden/mavis/android-kotlin.json +21 -21
- package/scripts/fixtures/cli-golden/mavis/go.json +8 -8
- package/scripts/fixtures/cli-golden/mavis/ios-swift.json +12 -12
- package/scripts/fixtures/cli-golden/mavis/java.json +8 -8
- package/scripts/fixtures/cli-golden/mavis/mcp-ts.json +5 -5
- package/scripts/fixtures/cli-golden/mavis/next.json +70 -47
- package/scripts/fixtures/cli-golden/mavis/nuxt.json +25 -25
- package/scripts/fixtures/cli-golden/mavis/php-hexagonal.json +8 -8
- package/scripts/fixtures/cli-golden/mavis/php-laravel.json +8 -8
- package/scripts/fixtures/cli-golden/mavis/svelte.json +25 -25
- package/scripts/fixtures/cli-golden/opencode/android-kotlin.json +21 -21
- package/scripts/fixtures/cli-golden/opencode/go.json +8 -8
- package/scripts/fixtures/cli-golden/opencode/ios-swift.json +12 -12
- package/scripts/fixtures/cli-golden/opencode/java.json +8 -8
- package/scripts/fixtures/cli-golden/opencode/mcp-ts.json +5 -5
- package/scripts/fixtures/cli-golden/opencode/next.json +70 -47
- package/scripts/fixtures/cli-golden/opencode/nuxt.json +25 -25
- package/scripts/fixtures/cli-golden/opencode/php-hexagonal.json +8 -8
- package/scripts/fixtures/cli-golden/opencode/php-laravel.json +8 -8
- package/scripts/fixtures/cli-golden/opencode/svelte.json +25 -25
- package/scripts/lib/generate-adapter-common.mjs +17 -0
- package/scripts/lib/generate-mavis-adapter.mjs +9 -3
- package/scripts/lib/generate-opencode-adapter.mjs +9 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
globs: storybook/**/*.stories.tsx, storybook/**/*.fixtures.ts, storybook/**/*.fixtures.data.ts, storybook/**/*.stories.meta.ts
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook CSF authoring
|
|
6
|
+
|
|
7
|
+
When editing CSF/fixtures, acknowledge: `Using .ai.local: storybook-csf-authoring(, …)*`.
|
|
8
|
+
|
|
9
|
+
## CSF3 skeleton
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
13
|
+
|
|
14
|
+
const meta = {
|
|
15
|
+
title: 'UI/Pages/ExamplePage',
|
|
16
|
+
component: ExamplePage,
|
|
17
|
+
tags: ['test', 'snapshot'],
|
|
18
|
+
decorators: [withStoreProvider({ preloadedState })],
|
|
19
|
+
parameters: { layout: 'fullscreen', viewport: { defaultViewport: 'desktop' } },
|
|
20
|
+
} satisfies Meta<typeof ExamplePage>;
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
type TStory = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
/** S01 — default loaded state */
|
|
26
|
+
export const Default: TStory = { /* … */ };
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Imports
|
|
30
|
+
|
|
31
|
+
- Production: `@/ui/...`, `@/store/...`, `@/types/...`.
|
|
32
|
+
- Storybook: the project's shared decorators/helpers (`withStoreProvider`, `withGreyCanvas`, `withStorybookSearchParams`, `withDocumentReferrer`), the shared MSW helper, and the test utilities (`expect`, `within`, `userEvent`, `fn`, `waitFor`).
|
|
33
|
+
- Play helpers: co-locate in `*.stories.meta.ts` or `*.fixtures.ts` — do not duplicate selectors.
|
|
34
|
+
|
|
35
|
+
## Data & decorators
|
|
36
|
+
|
|
37
|
+
- MSW: `parameters: { ...storyMsw(handlers) }` from the shared MSW helper.
|
|
38
|
+
- Store: `decorators: [withStoreProvider({ preloadedState })]` — use fixture builders.
|
|
39
|
+
- Search params: `withStorybookSearchParams({ key: 'value' })`.
|
|
40
|
+
- Browser globals (render-time): `withDocumentReferrer('')` — `document.referrer` and in-app list session signals are **story fixtures**, not play-only setup. Reset session keys when production reads them at render.
|
|
41
|
+
- White-card isolated blocks **only** (a solid white surface token): `withGreyCanvas`. Do not use on grey primary/secondary roots.
|
|
42
|
+
- **Never** `parameters.nextjs.appDirectory`. Do not null-guard production `useSearchParams`.
|
|
43
|
+
|
|
44
|
+
## Fixtures
|
|
45
|
+
|
|
46
|
+
Split: handlers/ids (`*.fixtures.ts`), static data (`*.fixtures.data.ts`), play constants (`*.stories.meta.ts`).
|
|
47
|
+
Reuse page fixtures before inventing ids. Document story-local id ranges in the README.
|
|
48
|
+
|
|
49
|
+
## One CSF file per `title` (strict)
|
|
50
|
+
|
|
51
|
+
Allowed: `PageName.stories.tsx`, `Components/<Block>.stories.tsx`, `modals/<Domain>/<Modal>.stories.tsx`.
|
|
52
|
+
|
|
53
|
+
**Forbidden:**
|
|
54
|
+
|
|
55
|
+
- New `*.p1.stories.tsx`, `*.p2.stories.tsx`, or any `*.pN.stories.tsx`.
|
|
56
|
+
- Adding exports to existing p1/p2 files.
|
|
57
|
+
- Numbered overflow siblings sharing the same `title`.
|
|
58
|
+
|
|
59
|
+
Existing p1/p2 in a repo are **legacy — do not copy or extend**. If the main file is large, extract a page block into `Components/` (new `title`).
|
|
60
|
+
|
|
61
|
+
## No mobile/viewport duplicates (strict)
|
|
62
|
+
|
|
63
|
+
One desktop canvas per logical state; reviewers use the Storybook viewport toolbar.
|
|
64
|
+
|
|
65
|
+
**Ban:** `export const Mobile*`, `Mobile_*`, `defaultViewport: 'mobile1'` / `'mobile2'`, `isMobile: true` preloads, `*MobileMediaPreload` fixtures, dedicated `*Mobile*.stories.tsx` for viewport variants.
|
|
66
|
+
|
|
67
|
+
**Keep only** product UI whose name is Mobile (a distinct component, not a second viewport of a page).
|
|
68
|
+
|
|
69
|
+
## Play vs visual
|
|
70
|
+
|
|
71
|
+
- Every snapshot story has a `play` asserting primary `data-testid`s or visible copy.
|
|
72
|
+
- Call the visual-settle helper after icon/header paint (~300ms) when flaking — use it on isolated blocks/modals with masked icons before vis.
|
|
73
|
+
- Portals: assert `within(canvasElement.ownerDocument.body)`.
|
|
74
|
+
- **Loading / spinner vis:** preload the store slice (`loadingStatus: 'loading'`) or MSW `delay('infinite')`. **Forbidden:** click download/submit then vis the in-flight frame without pinning the request.
|
|
75
|
+
- Freeze animations only on spinner/QR/skeleton stories, as the last line of `play`; then `--update -t` that story only.
|
|
76
|
+
- **Intentional** `LoadFailed` export (MSW 500) ≠ an accidental "failed to load the page" (missing API mocking).
|
|
77
|
+
|
|
78
|
+
## Tags & layout
|
|
79
|
+
|
|
80
|
+
- `tags: ['test', 'snapshot']` on visual catalog entries.
|
|
81
|
+
- Page: `layout: 'fullscreen'`, `viewport.defaultViewport: 'desktop'`.
|
|
82
|
+
- Isolated block: `layout: 'centered'` unless the block needs width.
|
|
83
|
+
|
|
84
|
+
## Grey canvas (white cards only)
|
|
85
|
+
|
|
86
|
+
Apply the grey-canvas decorator **only** when the production root is a solid white surface. Use the project's grey-surface token. Never hex.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { withGreyCanvas } from '<shared-decorators>' // adjust depth
|
|
90
|
+
|
|
91
|
+
decorators: [withGreyCanvas], // outer; width shells stay inside
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Do not apply** when the root is already grey, transparent, a fullscreen page, or a modal. Grey-on-grey hides radius and rest/hover fills.
|
|
95
|
+
|
|
96
|
+
**Forbidden:** `parameters.backgrounds` hex lists; a grey wrapper the same size as the card (edge still invisible).
|
|
97
|
+
|
|
98
|
+
## After batch
|
|
99
|
+
|
|
100
|
+
Mandatory: **`storybook-ui-quality-gate`** — preview stories, compare canvas vs mockup, then run story tests. Then **`storybook-keep-tests-current`**: fix play/fixtures, targeted vitest, `--update` vis after intentional visual changes, re-run green. Then **`storybook-cleanup-temp-screenshots`** — delete dump PNGs from this turn; do not commit them.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
globs: app/src/ui/**/*.tsx, app/src/ui/**/*.ts, storybook/stories/**/*.stories.tsx
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook dev-time Figma visual compare (mandatory)
|
|
6
|
+
|
|
7
|
+
When this rule applies, acknowledge: `Using .ai.local: storybook-dev-compare-figma(, …)*`.
|
|
8
|
+
|
|
9
|
+
While implementing or refactoring `app/src/ui/**` (new component, visual/interaction change, layout, styles, copy, hover/open), the **source of visual truth is Figma** — not Storybook vis-baselines. Vis-baselines are a **regression detector** (they catch "you broke what was working"), not a design spec (they do not validate "this matches the Figma mockup"). They can lock in a wrong implementation as the baseline if `--update` is run before the implementation is correct.
|
|
10
|
+
|
|
11
|
+
This rule makes the dev-loop **mandatory** and forbids the failure mode where an agent captures a `--update` baseline against a wrong implementation, the wrong implementation becomes the "correct" baseline, and the next round of changes is compared against the wrong baseline — drift is hidden forever.
|
|
12
|
+
|
|
13
|
+
## The required loop (every visual change)
|
|
14
|
+
|
|
15
|
+
1. **Read Figma first** — `figma_get_metadata` for the node structure, `figma_get_design_context` for the actual styles/tokens, `figma_get_variable_defs` for design tokens, `figma_get_screenshot` for the visual reference. Do not pick the wrong reference node (e.g. a wrapper frame instead of the card component). Pick the **innermost** matching node.
|
|
16
|
+
2. **Implement to spec** — every token (color, padding, gap, font, radius) must come from `figma_get_design_context` / `figma_get_variable_defs`, not from memory or from guessing. If a style is not in the Figma spec, the implementation is wrong; do not invent.
|
|
17
|
+
3. **Open the story in a browser** — navigate to the story URL (e.g. `http://localhost:6006/?path=/story/<story-id>`). If Storybook is not running, start it with `yarn storybook` from `storybook/`.
|
|
18
|
+
4. **Take a screenshot** — of the **opened dialog / visible state**, not the Storybook iframe placeholder.
|
|
19
|
+
5. **Visual compare with Figma** — open the Figma screenshot in the same view (saved PNG of the Figma node). Compare element-by-element:
|
|
20
|
+
- Title (font, size, weight, color, line-height, letter-spacing)
|
|
21
|
+
- Subtitle / supporting text (same)
|
|
22
|
+
- Container (background, border, radius, padding, gap)
|
|
23
|
+
- Icon (image content, size, container styling)
|
|
24
|
+
- Status / state (text + color)
|
|
25
|
+
- Disclosure / actions (icon, size, position)
|
|
26
|
+
- Hover state (compare in both the Figma "Hover" variant AND Storybook hover)
|
|
27
|
+
6. **Diff and fix** — if the Storybook render does not match the Figma, fix the production code (or fixture, if the data was wrong) and re-screenshot. Do not `--update` the baseline until the Figma match is confirmed by a human-readable visual side-by-side.
|
|
28
|
+
7. **Only then `--update`** — `yarn vitest run --project=storybook <path> --update` records the now-correct baseline. After the rewrite, run **without** `--update` once to confirm the new baseline is stable.
|
|
29
|
+
|
|
30
|
+
## Why baselines are NOT enough
|
|
31
|
+
|
|
32
|
+
A baseline is a pixel diff against an existing image. If the existing image is wrong, the baseline silently approves future wrongness.
|
|
33
|
+
|
|
34
|
+
The failure mode this guards against: an agent implements UI with wrong border, wrong icon, wrong font, and wrong background; captures a `--update` baseline; vis-tests go green. The next round tightens tokens but keeps the wrong icon; `--update` again; still green. An operator later opens the story and it looks nothing like Figma. The "green" vis-tests had been comparing to a wrong baseline for two rounds.
|
|
35
|
+
|
|
36
|
+
The fix is not "more `--update` discipline". The fix is a **mandatory dev-time visual compare with Figma** before any `--update`.
|
|
37
|
+
|
|
38
|
+
## Forbidden
|
|
39
|
+
|
|
40
|
+
- Running `yarn vitest -u` against a story that has not been visually compared with Figma in the current session.
|
|
41
|
+
- "Vis-tests are green" used as evidence the UI matches Figma.
|
|
42
|
+
- Comparing only via a single Figma screenshot and then trusting memory for the rest of the change.
|
|
43
|
+
- Using a Figma screenshot of a **different node** as the reference (e.g. the outer modal instead of the card component, the empty state instead of the loaded state, the desktop variant instead of the mobile variant).
|
|
44
|
+
- Skipping the dev-time compare and relying on the operator to spot drift after the fact.
|
|
45
|
+
|
|
46
|
+
## Required when
|
|
47
|
+
|
|
48
|
+
Mandatory for any change under `app/src/ui/**` that affects:
|
|
49
|
+
|
|
50
|
+
- Layout, padding, gap, alignment
|
|
51
|
+
- Typography (font, size, weight, color)
|
|
52
|
+
- Color, background, border, radius, shadow
|
|
53
|
+
- Icon / image / illustration
|
|
54
|
+
- Hover / open / focused / error / empty / loading visual states
|
|
55
|
+
- Storybook vis-baseline first capture (`--update`) or any intentional change to baselines
|
|
56
|
+
|
|
57
|
+
## MCP wiring
|
|
58
|
+
|
|
59
|
+
- `chrome-devtools_*` (in the session MCP catalog) is the preferred browser navigation / screenshot tool for the dev-time compare. If it is `error` / `needsAuth` / `loading`, **stop** and report the block, do not approximate.
|
|
60
|
+
- `playwright` MCP can be used as a substitute **only if** `chrome-devtools` is unavailable — but `chrome-devtools` is preferred because it gives a real DOM + screenshot of the running app.
|
|
61
|
+
- A `localhost:6006` reached via a browser MCP is the right way; a screenshot of the production Next.js route is **not** an acceptable substitute (per `mcp-required-for-ui-layout.md`).
|
|
62
|
+
|
|
63
|
+
## Reference
|
|
64
|
+
|
|
65
|
+
- `storybook-ui-quality-gate.md` — this rule makes its "compare with mockup" step mandatory and dev-time, not at-the-end.
|
|
66
|
+
- `storybook-keep-tests-current.md` — the post-change half (play + baseline refresh); this rule is the pre-`--update` half.
|
|
67
|
+
- `mcp-required-for-ui-layout.md` — Figma + Storybook MCP gate.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
globs: storybook/**/*.stories.tsx, storybook/**/*.fixtures.ts, storybook/**/*.fixtures.data.ts, storybook/**/*.stories.meta.ts, storybook/stories/**/README.md, app/src/ui/**/*.tsx, app/src/ui/**/*.ts
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook keep tests current
|
|
6
|
+
|
|
7
|
+
When this rule applies, acknowledge: `Using .ai.local: storybook-keep-tests-current(, …)*`.
|
|
8
|
+
|
|
9
|
+
## When (mandatory)
|
|
10
|
+
|
|
11
|
+
Storybook tests and vis baselines are **part of the change**. Do not finish with red or stale snapshots.
|
|
12
|
+
|
|
13
|
+
Triggers:
|
|
14
|
+
|
|
15
|
+
1. Add or edit a story, fixture, `*.stories.meta.ts`, or page Storybook README.
|
|
16
|
+
2. Change production UI a story imports (`app/src/ui/**`) — layout, styles, copy, `data-testid`, states. New/refactored UI must already have stories via **`storybook-ui-quality-gate`** (preview vs mockup); this rule is the test/baseline half.
|
|
17
|
+
3. Change mocks / domain / store fields that stories preload — grep `storybook/stories` and apply this gate.
|
|
18
|
+
|
|
19
|
+
Leaving play broken or skipping `--update` after an intentional visual change is incomplete work.
|
|
20
|
+
|
|
21
|
+
## Find related stories
|
|
22
|
+
|
|
23
|
+
Grep `storybook/stories` for the component name and its import. Cover **all** hits: page, `Components/<Block>`, cards, modals — not only the file you opened. Check the page `README.md` state map.
|
|
24
|
+
|
|
25
|
+
## Keep working
|
|
26
|
+
|
|
27
|
+
- **Play:** selectors, copy, `data-testid`s, settle/portal helpers must match the new UI.
|
|
28
|
+
- **Fixtures / MSW / preloadedState:** match domain after mapper or store changes.
|
|
29
|
+
- New production visual state → new story export (catalog structure). Removed UI → delete or retarget the story.
|
|
30
|
+
- Page `README.md`: state → export → fixture id.
|
|
31
|
+
|
|
32
|
+
**Forbidden:** commenting out `play`; dropping `test` / `snapshot` tags to silence failures; ignoring vis drift.
|
|
33
|
+
|
|
34
|
+
## Computed copy & browser fixtures
|
|
35
|
+
|
|
36
|
+
When play asserts **visible copy** that production derives from `document.referrer`, sessionStorage, in-app signals, or i18n: stub those inputs in a **decorator** (sync before mount). Play is too late.
|
|
37
|
+
|
|
38
|
+
- Do not treat a hard-coded label as a stable selector when the same `data-testid` can show two production strings. Assert the variant's **inputs** first, then the copy.
|
|
39
|
+
- After adding/changing a story that depends on browser document state, grep production for `document.referrer` / session keys used at render.
|
|
40
|
+
|
|
41
|
+
## Play queries & timeouts
|
|
42
|
+
|
|
43
|
+
- Static shells (no fetch): prefer `getByTestId` / `getByRole` so a missing node fails immediately, not `Test timed out in 30000ms`.
|
|
44
|
+
- `findBy*` / `waitFor` only when UI is actually async (MSW, loader). Cap timeout (e.g. 3–5s). Never wait for a testid that production does not mount without mocks.
|
|
45
|
+
- Vitest `testTimeout` includes the vis auto-snapshot `afterEach`. A 30s timeout on a story with a tiny `play` is often vis (icon masks, large SVG, full header/footer), not a missing node. Isolated green + full-suite 30s timeout → cap the wait, do not raise `testTimeout`.
|
|
46
|
+
- Any `new Image()` / mask-URL wait **must** have a 3–5s cap. Unbounded `Image()` → full-suite hang while isolated still passes.
|
|
47
|
+
- **Vis loading race:** a `userEvent.click` that dispatches an unmocked thunk (download, fetch) → vis captures spinner **or** idle. Pin the frame: preload the store slice (`loadingStatus: 'loading'`) or MSW `delay('infinite')`. **Forbidden:** click-then-snapshot an in-flight request.
|
|
48
|
+
|
|
49
|
+
## Run (from `storybook/`)
|
|
50
|
+
|
|
51
|
+
Targeted path only — do not `--update` the whole catalog.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
yarn vitest run --project=storybook <path>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Play / fixture failures: **fix CSF**, then re-run. Do not `--update` to hide a broken `play`.
|
|
58
|
+
|
|
59
|
+
After an **intentional** visual change, refresh baselines (`--update` **after** the path):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
yarn vitest run --project=storybook <path> --update
|
|
63
|
+
yarn vitest run --project=storybook <path> -t '<Story name>' --update
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`--update` on a **file path** rewrites **every** export in that file. A spinner/animation-freeze story can recapture siblings not yet painted. Use `-t '<Story name>'` for one snapshot. Review each rewritten PNG; do not blind-accept.
|
|
67
|
+
|
|
68
|
+
Re-run **without** `--update` until exit 0. After a vis/timeout flake: re-run the **originally failing files together** (isolated green ≠ full-suite green).
|
|
69
|
+
|
|
70
|
+
## Baselines
|
|
71
|
+
|
|
72
|
+
- Local: `storybook/__vis__/local` (gitignored) — still refresh so the next local run is green.
|
|
73
|
+
- CI: `storybook/__vis__/<platform>/__baselines__` — add when those files exist in git.
|
|
74
|
+
- Done only when targeted vitest is green **without** `--update`.
|
|
75
|
+
- Done only after **`storybook-cleanup-temp-screenshots`**: no leftover dump PNGs from this turn.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
globs: storybook/stories/modals/**
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook modals catalog
|
|
6
|
+
|
|
7
|
+
When editing modal stories, acknowledge: `Using .ai.local: storybook-modals(, …)*`.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Isolated modal components only — no page underlay.
|
|
12
|
+
- No "card wrapper" stories when `UI/Modals/...` already covers the trigger (see the modals README reuse table).
|
|
13
|
+
- A component-catalog open-by-default `ConfirmModal` is a component-catalog exception — **do not copy** that pattern here.
|
|
14
|
+
|
|
15
|
+
## Title & path
|
|
16
|
+
|
|
17
|
+
- Title: `UI/Modals/<Domain>/<ModalName>` matching `storybook/stories/modals/<Domain>/`.
|
|
18
|
+
- Never place modal titles under `UI/Pages/` or `UI/Components/`.
|
|
19
|
+
|
|
20
|
+
## Closed by default
|
|
21
|
+
|
|
22
|
+
First paint shows a labeled trigger (`BasicButton`), not an open dialog.
|
|
23
|
+
|
|
24
|
+
- Trigger: a stable `data-testid` (e.g. `modal-story__open-trigger`).
|
|
25
|
+
- **Forbidden:** always-open default export; snapshot variants that skip the closed state unless separately named + justified in README.
|
|
26
|
+
|
|
27
|
+
## Render helpers
|
|
28
|
+
|
|
29
|
+
From the shared modal decorators module:
|
|
30
|
+
|
|
31
|
+
- `createReduxModalStoryRender` — dispatch prod open actions from a closed `preloadedState`.
|
|
32
|
+
- `createLocalModalStoryRender` — `useState(isOpen)` harness.
|
|
33
|
+
- A `ModalStoryShell` wrapper; pass `isMounted` when prod conditionally mounts the modal.
|
|
34
|
+
|
|
35
|
+
## Play sequence
|
|
36
|
+
|
|
37
|
+
1. `expectNoModalDialog`
|
|
38
|
+
2. `clickModalStoryTrigger`
|
|
39
|
+
3. `expectVisibleTextInModal` / `expectVisibleTestIdInModal`
|
|
40
|
+
4. Close via prod affordances (overlay, cancel/confirm) — no story-only close button.
|
|
41
|
+
|
|
42
|
+
Portals: assert `within(canvasElement.ownerDocument.body)`.
|
|
43
|
+
|
|
44
|
+
## Visual
|
|
45
|
+
|
|
46
|
+
Vis addon snapshots **after** play (opened dialog + trigger). Document per-modal exceptions (e.g. a modal that closes after confirm).
|
|
47
|
+
|
|
48
|
+
- After open + copy assertions: call the visual-settle helper when the dialog has masked icons. Isolated green + full-suite `Test timed out in 30000ms` → vis afterEach / unbounded icon wait, not a missing node.
|
|
49
|
+
- Do not add `new Image()` / mask waits without a 3–5s cap.
|
|
50
|
+
- Do not raise story `testTimeout` to hide a CDN hang.
|
|
51
|
+
|
|
52
|
+
After add/edit/UI refactor: **`storybook-ui-quality-gate`** (preview vs mockup) then **`storybook-keep-tests-current`** — play + `--update` + re-run green.
|
|
53
|
+
|
|
54
|
+
## MSW / store / query-open
|
|
55
|
+
|
|
56
|
+
- Fetch-on-mount: shared MSW helper + store provider (same as pages).
|
|
57
|
+
- Postpayment / query-open modals: shell-controlled `isOpen` + `withStorybookSearchParams` when prod uses query params.
|
|
58
|
+
|
|
59
|
+
## Forbidden
|
|
60
|
+
|
|
61
|
+
- Always-open default export.
|
|
62
|
+
- Duplicate card modals under `modals/` when listed in the modals README reuse table.
|
|
63
|
+
- Viewport-duplicate modal stories (`Mobile*`, `defaultViewport: 'mobile*'`).
|
|
64
|
+
- New `*.pN.stories.tsx` overflow files — one CSF per modal `title`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
glob: always
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook must not resolve packages from app/node_modules
|
|
6
|
+
|
|
7
|
+
When this rule applies, acknowledge: `Using .ai.local: storybook-no-app-node-modules`.
|
|
8
|
+
|
|
9
|
+
## Rule
|
|
10
|
+
|
|
11
|
+
When Storybook lives in its own package (`storybook/package.json`, `storybook/yarn.lock`, `storybook/node_modules`), it **must not** load npm dependencies from the app's `node_modules`.
|
|
12
|
+
|
|
13
|
+
Categorical. Missing a design-system package, "versions match `app/`", ESLint plugin lookup, a Vite alias, or a Docker `COPY` of `app/node_modules` do not waive it. Do not cite an existing violation as a pattern to copy.
|
|
14
|
+
|
|
15
|
+
## Forbidden
|
|
16
|
+
|
|
17
|
+
Any mechanism that makes Storybook (dev, build, test, lint, typecheck, Docker) import an installed package from `app/node_modules`:
|
|
18
|
+
|
|
19
|
+
- Vite/webpack `resolve.alias`, `resolve.modules`, `optimizeDeps`, `dedupe`, or a plugin `resolveId` aimed at `app/node_modules` / `../app/node_modules`.
|
|
20
|
+
- `paths` in any `storybook/**/tsconfig*.json` that point at `../app/node_modules/**`.
|
|
21
|
+
- `NODE_PATH`, yarn/npm/pnpm link, workspace hoisting, or a symlink from `storybook/node_modules` into `app/node_modules`.
|
|
22
|
+
- Docker `COPY`, volume, or bind-mount of `app/node_modules` into a Storybook stage or image.
|
|
23
|
+
- ESLint, Stylelint, Vitest, or another Storybook tool resolving plugins or packages from `app/node_modules`.
|
|
24
|
+
|
|
25
|
+
## Allowed
|
|
26
|
+
|
|
27
|
+
Application **source and static files**, not installed packages:
|
|
28
|
+
|
|
29
|
+
- `@/` → `app/src/**`
|
|
30
|
+
- `app/next.config.ts`, `app/environment.d.ts`, `app/public/**`, `app/src/assets/**`
|
|
31
|
+
|
|
32
|
+
`server.fs.allow` may include `app/` so Vite can read that source. It must not be used to import from `app/node_modules`.
|
|
33
|
+
|
|
34
|
+
## If a package is missing
|
|
35
|
+
|
|
36
|
+
Add it to `storybook/package.json`, install it into `storybook/node_modules`, and align the version with `app/package.json`. Do not alias it into `app/node_modules`.
|
|
37
|
+
|
|
38
|
+
## Known violations — do not extend
|
|
39
|
+
|
|
40
|
+
Existing aliases, `paths`, and Docker `COPY` sites that resolve through `app/node_modules` today are violations, not a pattern. A change that edits one of those sites removes that `app/node_modules` binding in the same change.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
glob: always
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Storybook UI quality gate
|
|
6
|
+
|
|
7
|
+
When this rule applies, acknowledge: `Using .ai.local: storybook-ui-quality-gate(, …)*`.
|
|
8
|
+
|
|
9
|
+
Storybook is the **mandatory** surface for developing and refactoring UI. Use it to compare the canvas with the mockup and to control visual/interaction quality. A Next.js route screenshot, source-only review, or unit tests without stories is **not** enough.
|
|
10
|
+
|
|
11
|
+
## When (mandatory)
|
|
12
|
+
|
|
13
|
+
Triggers:
|
|
14
|
+
|
|
15
|
+
1. New page, block, modal, or reusable component (`app/src/ui/**`).
|
|
16
|
+
2. Visual or interaction refactor — layout, styles, tokens, copy, hover/open, empty/error/loading.
|
|
17
|
+
3. Existing UI that already has stories (then also **`storybook-keep-tests-current`**).
|
|
18
|
+
|
|
19
|
+
**Skip:** types / API / store / mocks with **no** render or style change.
|
|
20
|
+
|
|
21
|
+
## Loop (do not skip steps)
|
|
22
|
+
|
|
23
|
+
1. **Before UI code:** read the Storybook story instructions (Storybook MCP) if available. Copy the nearest analog CSF. If the brief has a `figma.com` URL, keep that node as the visual SoT.
|
|
24
|
+
2. **Stories with the UI — not after.** Cover **every implemented visual state** (see `storybook-catalog-structure`). New state without an export is incomplete work.
|
|
25
|
+
3. **Compare with mockup:** preview the stories and open **every** returned URL. Side-by-side story canvas vs Figma (or vs AC / `ux-design.md` when there is no Figma). Check spacing, tokens, typography, empty/error/loading, hover/open. Use the viewport **toolbar** — no `Mobile*` duplicate stories.
|
|
26
|
+
4. **Quality:** run the story tests, then **`storybook-keep-tests-current`** (play + vis green without `--update`). Then **`storybook-cleanup-temp-screenshots`**.
|
|
27
|
+
|
|
28
|
+
Mismatch with the mockup → fix **production** (or the fixture if data was wrong), then preview again. Do not "accept" drift.
|
|
29
|
+
|
|
30
|
+
MCP down: `yarn storybook` + folder README analog; still visually review the canvas and run vitest from `storybook/`.
|
|
31
|
+
|
|
32
|
+
## Forbidden
|
|
33
|
+
|
|
34
|
+
- Shipping UI without stories for new/changed visual states.
|
|
35
|
+
- "Looks fine on the Next.js page" without Storybook preview.
|
|
36
|
+
- Skipping preview / story tests when MCP is up.
|
|
37
|
+
- Treating Storybook as post-hoc docs after the feature is "done".
|
|
38
|
+
- Closing the task while canvas ≠ mockup for a state that was in scope.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
glob: always
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# Task artifact levels (L0–L3)
|
|
6
|
+
|
|
7
|
+
When sizing a task before starting, acknowledge: `Using .ai.local: task-levels(, …)*`.
|
|
8
|
+
|
|
9
|
+
Every non-trivial task must live as a file artifact, never only in chat. Pick one level by size and impact; when unsure, pick the higher level.
|
|
10
|
+
|
|
11
|
+
## Levels
|
|
12
|
+
|
|
13
|
+
| Level | When | Where | Required files |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| **L0 — note** | 1 file, < 30 min, no plan needed | chat todos + `git diff` | none |
|
|
16
|
+
| **L1 — team task** | 2–10 files, one feature/fix with discrete steps | `.ai.local/team/tasks/<slug>/` | `pipeline.json` + `status.json` + `brief.md` + `decomposition.md` + `.memlog.md` (+ per-agent artifacts) |
|
|
17
|
+
| **L2 — change spec** | architecture / boundary change, compliance boundary touched, > 10 files, or multi-role review | `openspec/changes/<YYYY-MM-DD>-<slug>/` | `proposal.md` + `design.md` + `tasks.md` |
|
|
18
|
+
| **L3 — hybrid** | formal change that also needs an execution pipeline | L2 (contract) + L1 (execution), cross-referenced | all of L2 + L1 |
|
|
19
|
+
|
|
20
|
+
## Selection order (apply in order)
|
|
21
|
+
|
|
22
|
+
1. Touches PD / medical data / analytics / third-party scripts / SSR-cookie shape → **L2 minimum** (with a compliance block).
|
|
23
|
+
2. Changes the data flow or a module boundary → **L2**.
|
|
24
|
+
3. > 10 files or > 1 subsystem → **L2**.
|
|
25
|
+
4. Otherwise multi-step (planning + implementation + verification) → **L1**.
|
|
26
|
+
5. Otherwise → **L0**.
|
|
27
|
+
|
|
28
|
+
Never demote a task to keep the artifact small.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
globs: app/src/ui/**/*.{ts,tsx}
|
|
2
|
+
|
|
3
|
+
## Body
|
|
4
|
+
|
|
5
|
+
# UI change review gate
|
|
6
|
+
|
|
7
|
+
Before a UI change is considered complete, acknowledge: `Using .ai.local: ui-change-review-gate(, …)*`.
|
|
8
|
+
|
|
9
|
+
## Required before completion
|
|
10
|
+
|
|
11
|
+
1. **Mockup review artifact.** If the task scope contains `app/src/ui/**`, a terminal `mockup-review.md` with verdict `PASS`/`PASS_WITH_NOTES` exists — even when no `figma.com` URL was supplied (then review against AC / `ux-design.md`). Missing artifact = incomplete work, not a warning.
|
|
12
|
+
2. **Composed frame.** For a page or block, the review node set includes the **composed page frame**, not only isolated component sets. A node id claimed by another task must be declared in `## Scope`.
|
|
13
|
+
3. **Same-day rewrite.** Do not rewrite a block shipped the same day without a new review artifact and an owner (single-writer rule).
|
|
14
|
+
4. **Storybook tests run.** Targeted storybook tests green without `--update`.
|
|
@@ -109,8 +109,7 @@ Each slug has one `artifact-manifest.json` at `.ai.local/team/tasks/<slug>/`. Th
|
|
|
109
109
|
|
|
110
110
|
- Read the manifest before broad prior-artifact discovery. Each step receives authoritative input entry IDs, owns named output entry IDs, and finishes with one terminal receipt linked to AC/task IDs.
|
|
111
111
|
- Markdown remains detailed evidence; the manifest points to authoritative paths and records producer, status, timestamps, outcome, and evidence paths.
|
|
112
|
-
-
|
|
113
|
-
Agents upsert only the items in `manifest.artifacts[]` they own and preserve foreign items. Parallel agents use distinct IDs; the parent/orchestrator serializes manifest merges.
|
|
112
|
+
- Agents upsert only the items they own in `manifest.artifacts[]` and preserve all foreign items in that array. Parallel agents use distinct IDs; the parent/orchestrator serializes manifest merges. The top-level array key is `artifacts` — not `entries`; see `agent-artifact-contracts.md` for the schema callout.
|
|
114
113
|
- The orchestration runtime/hook is the single writer for `status.json` lifecycle fields and `metrics.json`. Agents read status for eligibility but never rewrite unrelated state, gate, retry, attempt, timestamp, or metrics fields.
|
|
115
114
|
- Missing/stale manifests are reported as a handoff gap; fall back to `brief.md`, `decomposition.md`, and `pipeline.json` rather than inventing authority.
|
|
116
115
|
|
|
@@ -7,8 +7,9 @@ This rule is mandatory. **You MUST** obey it on every turn, without exception.
|
|
|
7
7
|
1. **Probe** — before answering, run `ls -la .ai.local` from the repository root.
|
|
8
8
|
2. **Walk** — if `.ai.local/` exists at multiple levels (monorepo), read every level from root to leaf. **Deeper wins** in practice: more specific rules appear later in the assembled context and take precedence.
|
|
9
9
|
3. **Apply** — treat every `.ai.local/rules/*.md` and `.ai.local/conventions.md` as a higher-priority rule for this repo. Do **not** load `.ai.local/team/**` as rules (shared pipeline artifacts). The block below ("Authoring `.ai.local/rules/*.md`") defines the conventions.
|
|
10
|
-
4. **
|
|
11
|
-
5. **
|
|
10
|
+
4. **Activate seeds** — if `.ai.local/rules-library/<seed>.md` exists and matches the current task scope, treat it as the applicable local rule and tell the owner to move it into `.ai.local/rules/`. Seeds are **staged-inactive** templates shipped by `init` (e.g. `router-pages`, `no-react-fc`, `storybook-ui-quality-gate`, `component-child-decomposition`); they do **not** apply until moved.
|
|
11
|
+
5. **Conflict** — if a local rule conflicts with a preset rule, **the local rule wins**. If a local rule body contains `override: kill <preset-rule-name>`, drop that preset rule from your context window entirely.
|
|
12
|
+
6. **Acknowledge** — when answering a user question, briefly state which `.ai.local/` rules apply to the current task (one line is enough). Format: `Using .ai.local: <rule-name>(, <rule-name>)*`. If no `.ai.local/` exists, do NOT mention this rule.
|
|
12
13
|
|
|
13
14
|
If `.ai.local/` does not exist → **no-op**, do not error. Do not produce any log line about its absence.
|
|
14
15
|
|
|
@@ -24,6 +25,18 @@ Each `.ai.local/rules/<name>.md` is a plain-markdown rule body. The model parses
|
|
|
24
25
|
|
|
25
26
|
Keep files ≤ 120 lines. Match the style of preset rules (short sections, bullets, code examples).
|
|
26
27
|
|
|
28
|
+
## What `init` overwrites vs preserves
|
|
29
|
+
|
|
30
|
+
`init` manages the tool trees; they are **not** the home of durable project config.
|
|
31
|
+
|
|
32
|
+
| Overwritten / merged by `init` | Preserved |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `.cursor/**`, `.claude/**`, `.mavis/**`, `.opencode/**` (rules, agents, skills, commands, hooks) | `.ai.local/**` |
|
|
35
|
+
| root `AGENTS.md` (from `REPO_AGENTS.md`) | `docs/specs/**`, `openspec/**` |
|
|
36
|
+
| tool MCP config (`.cursor/mcp.json`; `opencode.json` — `mcp` merged, other blocks may be rewritten) | repo-root `.mcp.json`, `.ai/context/**`, `.ai.local/rules/**` |
|
|
37
|
+
|
|
38
|
+
Put durable project-owned agent config and authoritative specs **outside** the tool trees (`.ai.local/`, `.ai/context/`, repo-root `.mcp.json`). After any re-init, verify consumer-owned blocks you added to a managed file (e.g. `opencode.json` `instructions` / `permission.bash`) survived.
|
|
39
|
+
|
|
27
40
|
## Limitations (read this)
|
|
28
41
|
|
|
29
42
|
- Cursor, Claude, Mavis, and OpenCode do **not** natively read `.ai.local/`. This rule is a **prompt-only** mechanism: it asks you, the model, to read and apply the files. Reliability is high but not 100%.
|
|
@@ -34,4 +47,5 @@ Keep files ≤ 120 lines. Match the style of preset rules (short sections, bulle
|
|
|
34
47
|
|
|
35
48
|
- Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package.
|
|
36
49
|
- Living gotchas: `.ai.local/conventions.md`. Pipeline artifacts: `.ai.local/team/` (do not load as rules).
|
|
50
|
+
- Staged seeds: `.ai.local/rules-library/**` (move a matching seed into `.ai.local/rules/` to activate).
|
|
37
51
|
- Root `AGENTS.md` reinforces this rule with a `MANDATORY` section.
|
|
@@ -48,6 +48,6 @@ Style enforcement (formatter / linter / post-change gate) lives in the **stack t
|
|
|
48
48
|
## Stack notes
|
|
49
49
|
|
|
50
50
|
- Before adding a new UI control, check existing UI code and project packages.
|
|
51
|
-
- Public API: index/barrel files and explicitly exported entities (`public-imports.
|
|
51
|
+
- Public API: index/barrel files and explicitly exported entities (`public-imports.md`, `layer-barrel-exports.md`).
|
|
52
52
|
- Allowed examples: shared hook/utility; typing `any`/`unknown`; splitting a large component; CSS tokens instead of “magic” values.
|
|
53
|
-
- Lint/stylelint — only **`post-change-lint.
|
|
53
|
+
- Lint/stylelint — only **`post-change-lint.md`**; ESLint config: `app/eslint.config.mjs`. Disabling a rule (`eslint-disable`) — only **locally** (line/small block) with a short “why” comment. Style prose in domain rules stays thin — prefer ESLint/Stylelint over duplicating formatter recipes.
|
|
@@ -45,19 +45,23 @@ On-demand rule for review flows. **Procedure and output format:** skill `code-re
|
|
|
45
45
|
|
|
46
46
|
### Checklist references
|
|
47
47
|
|
|
48
|
-
- Architecture layers: `architecture-boundaries.
|
|
49
|
-
- Imports: `public-imports.
|
|
50
|
-
- UI: `react-ui.
|
|
51
|
-
- Security: `security-next.
|
|
52
|
-
- Tests: `tests-unit.
|
|
53
|
-
- Lint gate before final report: `post-change-lint.
|
|
48
|
+
- Architecture layers: `architecture-boundaries.md`, `next-app-core.md`; network: `http-client.md`
|
|
49
|
+
- Imports: `public-imports.md`, `layer-barrel-exports.md`
|
|
50
|
+
- UI: `react-ui.md`
|
|
51
|
+
- Security: `security-next.md`
|
|
52
|
+
- Tests: `tests-unit.md`, `playwright-agents.md`, `tests-e2e-structure.md`
|
|
53
|
+
- Lint gate before final report: `post-change-lint.md`
|
|
54
54
|
|
|
55
55
|
### UI / Figma parity (web)
|
|
56
56
|
|
|
57
57
|
When the diff touches UI / layout / styling (paths under `app/src/ui/**`, global layout/CSS/tokens) AND a Figma mockup is referenced in `brief.md` / `decomposition.md` (URL, fileKey, or node id) **or** `mockup-review.md` is present:
|
|
58
58
|
|
|
59
59
|
- The `code-reviewer` agent must perform a **detailed, pixel-accurate** comparison of the implementation against the mockup, **across every viewport the project uses** (the `mockup-review` AC-8 / Stack notes set — web buckets ~375 / ~768 / ~1280 small/medium/large — and the Storybook viewport toolbar in this repo). Figma frames via Figma MCP `get_screenshot`; the running app via Playwright MCP / Chrome DevTools MCP at the matching width.
|
|
60
|
-
- The comparison is a **per-element parity check** (typography / color / spacing / imagery / states / structure / auto-layout intent) per the `code-reviewer` UI / Figma parity gate. Bind to the `mockup-review.md` `## Design contract` and the **`design-tokens-binding.
|
|
60
|
+
- The comparison is a **per-element parity check** (typography / color / spacing / imagery / states / structure / auto-layout intent) per the `code-reviewer` UI / Figma parity gate. Bind to the `mockup-review.md` `## Design contract` and the **`design-tokens-binding.md`** discipline (`@sds/tokens-*` / DS components, no raw `#…` / `px` where a token exists).
|
|
61
61
|
- Findings: `path:line` + Figma node id + viewport + severity. Emit a `## Figma parity (UI)` section in `review.md`.
|
|
62
62
|
- **Storybook visual baselines are not a substitute.** Approving a UI MR on Storybook baselines alone is not acceptable when a Figma reference exists.
|
|
63
63
|
- Missing or `unable_to_compare` parity section on a UI-touching MR with a Figma reference → `REQUEST_CHANGES`. Unbound raw values where a token exists (typography / color / spacing / imagery) → `blocker` / `important`. The full gate lives in the `code-reviewer` agent prompt; this rule cross-references it.
|
|
64
|
+
|
|
65
|
+
### Spec / docs sync (behaviour change)
|
|
66
|
+
|
|
67
|
+
When the diff changes documented `app/src/**` behaviour and the repo carries a spec tree (`docs/specs/**`, `openspec/specs/**`, `docs/qa/**`, or `*.cases.md`), the same changeset must update the linked page / spec / QA case (or record an explicit open-question gap). A missing update on an **AC-named** surface → `REQUEST_CHANGES`; on a non-AC surface → `important`. Do not treat `docs/specs` and `openspec` as substitutes for each other — keep both in sync.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Component catalog gate (UI quality)
|
|
2
|
+
|
|
3
|
+
When the repo ships a **component catalog** (Storybook, Ladle, Chromatic, or a `stories/` tree), it is the required surface for developing and reviewing UI. A route screenshot, a source-only review, or unit tests without stories is **not** enough.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
- Triggers: a new `app/src/ui/**` component / page / block / modal, or a visual/interaction refactor (layout, styles, tokens, copy, hover/open, empty / error / loading).
|
|
8
|
+
- Skip: types / API / store / mocks with no render or style change.
|
|
9
|
+
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- **Stories ship with the UI**, in the same change — not after.
|
|
13
|
+
- **Compare against the design source** (Figma, else the AC): the catalog is the canvas, the design is the truth. Visual baselines are a **regression detector**, not a design spec — fix the implementation first, then update the baseline.
|
|
14
|
+
- **Package isolation:** when the catalog is its own package (own `package.json` / lockfile / `node_modules`), it resolves dependencies from **its own** `node_modules` — never the app's. Missing package ⇒ add it to the catalog manifest; never alias into the app.
|
|
15
|
+
- **Clean up** temp screenshots you created this turn; keep only intentional baselines and product assets.
|
|
16
|
+
- Keep catalog tests green — do not finish with red or stale baselines.
|
|
17
|
+
|
|
18
|
+
## Stack notes
|
|
19
|
+
|
|
20
|
+
- Catalog: Storybook. Developer loop: read Figma → implement → preview the story → screenshot → compare → fix → **update baselines last**.
|
|
21
|
+
- Run the catalog runner from the catalog directory (e.g. its own Vitest project), not the app's unit runner.
|
|
22
|
+
|
|
23
|
+
## Handoff
|
|
24
|
+
|
|
25
|
+
- `feature-developer`: a UI work package in a catalog repo is **not done** without a story and a green catalog test run.
|
|
26
|
+
- `code-reviewer`: a UI-touching MR with a catalog present and no story → `REQUEST_CHANGES`.
|
|
27
|
+
|
|
28
|
+
## Related
|
|
29
|
+
|
|
30
|
+
- `design-tokens-binding.md` — Figma → repo token binding for the implementation.
|
|
31
|
+
- `mockup-review.md` — the reviewer-side parity gate.
|
|
@@ -22,7 +22,7 @@ The implementation must mirror the Figma mockup token-for-token. Raw design valu
|
|
|
22
22
|
|
|
23
23
|
## Imagery & icons
|
|
24
24
|
|
|
25
|
-
- **Images:** use the Figma asset source from `get_design_context` / the node’s image fill. Repo: `next/image`
|
|
25
|
+
- **Images:** use the Figma asset source from `get_design_context` / the node’s image fill. Repo: **the project’s image primitive** — check the nearest component in the same layer (often a plain `<img>` or a DS image component; `next/image` only where the config keeps the optimizer enabled). Derive `src`, `width`, `height` from Figma. Do not use a placeholder, do not invent a URL, do not change aspect ratio.
|
|
26
26
|
- **Icons:** use the `@sds/icon` (or project DS) symbol name from the Figma component instance / metadata. Do not invent icon names. The Figma node’s component name (e.g. `Icon / chevron-right`) maps to the DS symbol.
|
|
27
27
|
- `alt` text from the Figma node name when meaningful; otherwise from the design context copy.
|
|
28
28
|
|