forgecraft-mcp 1.4.0 → 1.7.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/LICENSE +67 -0
- package/README.md +527 -525
- package/dist/analyzers/anchors/anchor-loader.d.ts +47 -0
- package/dist/analyzers/anchors/anchor-loader.d.ts.map +1 -0
- package/dist/analyzers/anchors/anchor-loader.js +113 -0
- package/dist/analyzers/anchors/anchor-loader.js.map +1 -0
- package/dist/analyzers/anti-pattern.d.ts.map +1 -1
- package/dist/analyzers/anti-pattern.js +38 -26
- package/dist/analyzers/anti-pattern.js.map +1 -1
- package/dist/analyzers/completeness-helpers.d.ts +5 -0
- package/dist/analyzers/completeness-helpers.d.ts.map +1 -1
- package/dist/analyzers/completeness-helpers.js +17 -0
- package/dist/analyzers/completeness-helpers.js.map +1 -1
- package/dist/analyzers/completeness.d.ts.map +1 -1
- package/dist/analyzers/completeness.js +4 -4
- package/dist/analyzers/completeness.js.map +1 -1
- package/dist/analyzers/gs-scorer.d.ts +3 -1
- package/dist/analyzers/gs-scorer.d.ts.map +1 -1
- package/dist/analyzers/gs-scorer.js +5 -2
- package/dist/analyzers/gs-scorer.js.map +1 -1
- package/dist/analyzers/package-json.d.ts.map +1 -1
- package/dist/analyzers/package-json.js +194 -34
- package/dist/analyzers/package-json.js.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.d.ts +4 -2
- package/dist/analyzers/scorers/composable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.js +50 -2
- package/dist/analyzers/scorers/composable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.d.ts +3 -2
- package/dist/analyzers/scorers/executable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.js +64 -4
- package/dist/analyzers/scorers/executable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.d.ts +5 -3
- package/dist/analyzers/scorers/scorer-utils.d.ts.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.js +34 -9
- package/dist/analyzers/scorers/scorer-utils.js.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.d.ts +7 -4
- package/dist/analyzers/scorers/self-describing-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.js +17 -18
- package/dist/analyzers/scorers/self-describing-scorer.js.map +1 -1
- package/dist/cli/help.js +51 -51
- package/dist/disciplines/catalog.d.ts +16 -0
- package/dist/disciplines/catalog.d.ts.map +1 -0
- package/dist/disciplines/catalog.js +196 -0
- package/dist/disciplines/catalog.js.map +1 -0
- package/dist/disciplines/runner.d.ts +13 -0
- package/dist/disciplines/runner.d.ts.map +1 -0
- package/dist/disciplines/runner.js +35 -0
- package/dist/disciplines/runner.js.map +1 -0
- package/dist/registry/composer.d.ts.map +1 -1
- package/dist/registry/composer.js +9 -4
- package/dist/registry/composer.js.map +1 -1
- package/dist/registry/loader-tag.d.ts.map +1 -1
- package/dist/registry/loader-tag.js +1 -0
- package/dist/registry/loader-tag.js.map +1 -1
- package/dist/registry/remote-gates.js +1 -1
- package/dist/registry/remote-gates.js.map +1 -1
- package/dist/registry/renderer-skeletons.js +92 -92
- package/dist/registry/sentinel-renderer.js +299 -20
- package/dist/registry/sentinel-renderer.js.map +1 -1
- package/dist/sentinel/detect.d.ts +41 -0
- package/dist/sentinel/detect.d.ts.map +1 -0
- package/dist/sentinel/detect.js +122 -0
- package/dist/sentinel/detect.js.map +1 -0
- package/dist/sentinel/write.d.ts +54 -0
- package/dist/sentinel/write.d.ts.map +1 -0
- package/dist/sentinel/write.js +75 -0
- package/dist/sentinel/write.js.map +1 -0
- package/dist/shared/cnt-health.d.ts +16 -0
- package/dist/shared/cnt-health.d.ts.map +1 -1
- package/dist/shared/cnt-health.js +55 -8
- package/dist/shared/cnt-health.js.map +1 -1
- package/dist/shared/config.d.ts +14 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +45 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/gs-score-logger.js +6 -6
- package/dist/shared/hook-installer.d.ts +58 -0
- package/dist/shared/hook-installer.d.ts.map +1 -0
- package/dist/shared/hook-installer.js +316 -0
- package/dist/shared/hook-installer.js.map +1 -0
- package/dist/shared/project-gates-helpers.d.ts +9 -0
- package/dist/shared/project-gates-helpers.d.ts.map +1 -1
- package/dist/shared/project-gates-helpers.js +35 -0
- package/dist/shared/project-gates-helpers.js.map +1 -1
- package/dist/shared/types/config.d.ts +7 -1
- package/dist/shared/types/config.d.ts.map +1 -1
- package/dist/shared/types/gates.d.ts +34 -0
- package/dist/shared/types/gates.d.ts.map +1 -1
- package/dist/shared/types/project.d.ts +68 -2
- package/dist/shared/types/project.d.ts.map +1 -1
- package/dist/shared/types/project.js +1 -0
- package/dist/shared/types/project.js.map +1 -1
- package/dist/shared/types/templates.d.ts +8 -1
- package/dist/shared/types/templates.d.ts.map +1 -1
- package/dist/shared/types/verify.d.ts +51 -1
- package/dist/shared/types/verify.d.ts.map +1 -1
- package/dist/shared/types/verify.js +37 -1
- package/dist/shared/types/verify.js.map +1 -1
- package/dist/tools/add-hook.d.ts.map +1 -1
- package/dist/tools/add-hook.js +8 -1
- package/dist/tools/add-hook.js.map +1 -1
- package/dist/tools/add-module.js +123 -123
- package/dist/tools/advice-registry.d.ts.map +1 -1
- package/dist/tools/advice-registry.js +108 -18
- package/dist/tools/advice-registry.js.map +1 -1
- package/dist/tools/advise-session-advisor.d.ts +16 -0
- package/dist/tools/advise-session-advisor.d.ts.map +1 -0
- package/dist/tools/advise-session-advisor.js +89 -0
- package/dist/tools/advise-session-advisor.js.map +1 -0
- package/dist/tools/advise-session-signals.d.ts +21 -0
- package/dist/tools/advise-session-signals.d.ts.map +1 -0
- package/dist/tools/advise-session-signals.js +113 -0
- package/dist/tools/advise-session-signals.js.map +1 -0
- package/dist/tools/advise-session.d.ts +22 -0
- package/dist/tools/advise-session.d.ts.map +1 -0
- package/dist/tools/advise-session.js +31 -0
- package/dist/tools/advise-session.js.map +1 -0
- package/dist/tools/analyze-harness.d.ts +18 -0
- package/dist/tools/analyze-harness.d.ts.map +1 -0
- package/dist/tools/analyze-harness.js +298 -0
- package/dist/tools/analyze-harness.js.map +1 -0
- package/dist/tools/audit.d.ts.map +1 -1
- package/dist/tools/audit.js +19 -0
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/change-request.d.ts +53 -0
- package/dist/tools/change-request.d.ts.map +1 -0
- package/dist/tools/change-request.js +395 -0
- package/dist/tools/change-request.js.map +1 -0
- package/dist/tools/check-cascade-contracts.d.ts +13 -0
- package/dist/tools/check-cascade-contracts.d.ts.map +1 -1
- package/dist/tools/check-cascade-contracts.js +73 -2
- package/dist/tools/check-cascade-contracts.js.map +1 -1
- package/dist/tools/check-cascade-report.js +64 -64
- package/dist/tools/check-cascade-steps.d.ts +3 -0
- package/dist/tools/check-cascade-steps.d.ts.map +1 -1
- package/dist/tools/check-cascade-steps.js +104 -15
- package/dist/tools/check-cascade-steps.js.map +1 -1
- package/dist/tools/check-cascade.d.ts +4 -3
- package/dist/tools/check-cascade.d.ts.map +1 -1
- package/dist/tools/check-cascade.js +30 -12
- package/dist/tools/check-cascade.js.map +1 -1
- package/dist/tools/check-derivation-chain.d.ts +37 -0
- package/dist/tools/check-derivation-chain.d.ts.map +1 -0
- package/dist/tools/check-derivation-chain.js +418 -0
- package/dist/tools/check-derivation-chain.js.map +1 -0
- package/dist/tools/check-spec-consistency.d.ts +25 -0
- package/dist/tools/check-spec-consistency.d.ts.map +1 -0
- package/dist/tools/check-spec-consistency.js +339 -0
- package/dist/tools/check-spec-consistency.js.map +1 -0
- package/dist/tools/check-t4.d.ts +54 -0
- package/dist/tools/check-t4.d.ts.map +1 -0
- package/dist/tools/check-t4.js +305 -0
- package/dist/tools/check-t4.js.map +1 -0
- package/dist/tools/close-cycle.d.ts +11 -0
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +364 -4
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/cnt-add-routing.d.ts +31 -0
- package/dist/tools/cnt-add-routing.d.ts.map +1 -0
- package/dist/tools/cnt-add-routing.js +99 -0
- package/dist/tools/cnt-add-routing.js.map +1 -0
- package/dist/tools/configure-mcp.d.ts.map +1 -1
- package/dist/tools/configure-mcp.js +52 -2
- package/dist/tools/configure-mcp.js.map +1 -1
- package/dist/tools/consolidate-status.d.ts +31 -0
- package/dist/tools/consolidate-status.d.ts.map +1 -1
- package/dist/tools/consolidate-status.js +105 -0
- package/dist/tools/consolidate-status.js.map +1 -1
- package/dist/tools/executable-gates.d.ts +52 -0
- package/dist/tools/executable-gates.d.ts.map +1 -0
- package/dist/tools/executable-gates.js +333 -0
- package/dist/tools/executable-gates.js.map +1 -0
- package/dist/tools/extract-adrs-from-spec.d.ts +33 -0
- package/dist/tools/extract-adrs-from-spec.d.ts.map +1 -0
- package/dist/tools/extract-adrs-from-spec.js +410 -0
- package/dist/tools/extract-adrs-from-spec.js.map +1 -0
- package/dist/tools/extract-adrs-history.d.ts +47 -0
- package/dist/tools/extract-adrs-history.d.ts.map +1 -0
- package/dist/tools/extract-adrs-history.js +265 -0
- package/dist/tools/extract-adrs-history.js.map +1 -0
- package/dist/tools/forgecraft-dispatch-extended.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch-extended.js +137 -0
- package/dist/tools/forgecraft-dispatch-extended.js.map +1 -1
- package/dist/tools/forgecraft-dispatch.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch.js +16 -0
- package/dist/tools/forgecraft-dispatch.js.map +1 -1
- package/dist/tools/forgecraft-schema-params.d.ts +174 -2
- package/dist/tools/forgecraft-schema-params.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema-params.js +197 -0
- package/dist/tools/forgecraft-schema-params.js.map +1 -1
- package/dist/tools/forgecraft-schema.d.ts +179 -7
- package/dist/tools/forgecraft-schema.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema.js +37 -0
- package/dist/tools/forgecraft-schema.js.map +1 -1
- package/dist/tools/generate-adr.js +6 -6
- package/dist/tools/generate-adr.js.map +1 -1
- package/dist/tools/generate-decision.d.ts +77 -0
- package/dist/tools/generate-decision.d.ts.map +1 -0
- package/dist/tools/generate-decision.js +162 -0
- package/dist/tools/generate-decision.js.map +1 -0
- package/dist/tools/generate-env-probe.d.ts +49 -0
- package/dist/tools/generate-env-probe.d.ts.map +1 -0
- package/dist/tools/generate-env-probe.js +365 -0
- package/dist/tools/generate-env-probe.js.map +1 -0
- package/dist/tools/generate-harness.d.ts +53 -0
- package/dist/tools/generate-harness.d.ts.map +1 -0
- package/dist/tools/generate-harness.js +395 -0
- package/dist/tools/generate-harness.js.map +1 -0
- package/dist/tools/generate-roadmap.d.ts +1 -1
- package/dist/tools/generate-roadmap.d.ts.map +1 -1
- package/dist/tools/generate-roadmap.js +38 -4
- package/dist/tools/generate-roadmap.js.map +1 -1
- package/dist/tools/generate-session-prompt.d.ts +3 -3
- package/dist/tools/generate-session-prompt.d.ts.map +1 -1
- package/dist/tools/generate-session-prompt.js +9 -1
- package/dist/tools/generate-session-prompt.js.map +1 -1
- package/dist/tools/generate-slo-probe.d.ts +53 -0
- package/dist/tools/generate-slo-probe.d.ts.map +1 -0
- package/dist/tools/generate-slo-probe.js +366 -0
- package/dist/tools/generate-slo-probe.js.map +1 -0
- package/dist/tools/layer-status-gates.d.ts +24 -0
- package/dist/tools/layer-status-gates.d.ts.map +1 -0
- package/dist/tools/layer-status-gates.js +151 -0
- package/dist/tools/layer-status-gates.js.map +1 -0
- package/dist/tools/layer-status.d.ts +126 -0
- package/dist/tools/layer-status.d.ts.map +1 -0
- package/dist/tools/layer-status.js +647 -0
- package/dist/tools/layer-status.js.map +1 -0
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/list.js +9 -5
- package/dist/tools/list.js.map +1 -1
- package/dist/tools/postcondition-coverage.d.ts +57 -0
- package/dist/tools/postcondition-coverage.d.ts.map +1 -0
- package/dist/tools/postcondition-coverage.js +256 -0
- package/dist/tools/postcondition-coverage.js.map +1 -0
- package/dist/tools/probe-runners.d.ts +21 -0
- package/dist/tools/probe-runners.d.ts.map +1 -0
- package/dist/tools/probe-runners.js +246 -0
- package/dist/tools/probe-runners.js.map +1 -0
- package/dist/tools/probe-templates.d.ts +27 -0
- package/dist/tools/probe-templates.d.ts.map +1 -0
- package/dist/tools/probe-templates.js +279 -0
- package/dist/tools/probe-templates.js.map +1 -0
- package/dist/tools/propose-session.d.ts +28 -0
- package/dist/tools/propose-session.d.ts.map +1 -0
- package/dist/tools/propose-session.js +333 -0
- package/dist/tools/propose-session.js.map +1 -0
- package/dist/tools/refresh-output.js +14 -14
- package/dist/tools/review-stubs.d.ts +29 -0
- package/dist/tools/review-stubs.d.ts.map +1 -0
- package/dist/tools/review-stubs.js +173 -0
- package/dist/tools/review-stubs.js.map +1 -0
- package/dist/tools/roadmap-builder.d.ts +49 -1
- package/dist/tools/roadmap-builder.d.ts.map +1 -1
- package/dist/tools/roadmap-builder.js +210 -5
- package/dist/tools/roadmap-builder.js.map +1 -1
- package/dist/tools/run-env-probe.d.ts +57 -0
- package/dist/tools/run-env-probe.d.ts.map +1 -0
- package/dist/tools/run-env-probe.js +270 -0
- package/dist/tools/run-env-probe.js.map +1 -0
- package/dist/tools/run-harness.d.ts +52 -0
- package/dist/tools/run-harness.d.ts.map +1 -0
- package/dist/tools/run-harness.js +279 -0
- package/dist/tools/run-harness.js.map +1 -0
- package/dist/tools/run-slo-probe.d.ts +50 -0
- package/dist/tools/run-slo-probe.d.ts.map +1 -0
- package/dist/tools/run-slo-probe.js +281 -0
- package/dist/tools/run-slo-probe.js.map +1 -0
- package/dist/tools/scaffold-spec-stubs.js +115 -115
- package/dist/tools/scaffold-templates.js +62 -62
- package/dist/tools/scaffold-writer.d.ts.map +1 -1
- package/dist/tools/scaffold-writer.js +9 -0
- package/dist/tools/scaffold-writer.js.map +1 -1
- package/dist/tools/score-rubric.d.ts +19 -0
- package/dist/tools/score-rubric.d.ts.map +1 -0
- package/dist/tools/score-rubric.js +411 -0
- package/dist/tools/score-rubric.js.map +1 -0
- package/dist/tools/session-prompt-builders.d.ts +20 -0
- package/dist/tools/session-prompt-builders.d.ts.map +1 -1
- package/dist/tools/session-prompt-builders.js +78 -5
- package/dist/tools/session-prompt-builders.js.map +1 -1
- package/dist/tools/session-prompt-sections.d.ts +4 -2
- package/dist/tools/session-prompt-sections.d.ts.map +1 -1
- package/dist/tools/session-prompt-sections.js +22 -10
- package/dist/tools/session-prompt-sections.js.map +1 -1
- package/dist/tools/setup-artifact-writers.d.ts +69 -4
- package/dist/tools/setup-artifact-writers.d.ts.map +1 -1
- package/dist/tools/setup-artifact-writers.js +681 -5
- package/dist/tools/setup-artifact-writers.js.map +1 -1
- package/dist/tools/setup-cnt-builders.d.ts.map +1 -1
- package/dist/tools/setup-cnt-builders.js +162 -34
- package/dist/tools/setup-cnt-builders.js.map +1 -1
- package/dist/tools/setup-monitoring.d.ts +41 -0
- package/dist/tools/setup-monitoring.d.ts.map +1 -0
- package/dist/tools/setup-monitoring.js +364 -0
- package/dist/tools/setup-monitoring.js.map +1 -0
- package/dist/tools/setup-phase1.d.ts.map +1 -1
- package/dist/tools/setup-phase1.js +14 -1
- package/dist/tools/setup-phase1.js.map +1 -1
- package/dist/tools/setup-phase2.d.ts +14 -0
- package/dist/tools/setup-phase2.d.ts.map +1 -1
- package/dist/tools/setup-phase2.js +130 -3
- package/dist/tools/setup-phase2.js.map +1 -1
- package/dist/tools/setup-project.d.ts +8 -0
- package/dist/tools/setup-project.d.ts.map +1 -1
- package/dist/tools/setup-project.js +52 -2
- package/dist/tools/setup-project.js.map +1 -1
- package/dist/tools/spec-parser-tags.d.ts.map +1 -1
- package/dist/tools/spec-parser-tags.js +1 -0
- package/dist/tools/spec-parser-tags.js.map +1 -1
- package/dist/tools/verify-formatter.d.ts.map +1 -1
- package/dist/tools/verify-formatter.js +15 -1
- package/dist/tools/verify-formatter.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +3 -0
- package/dist/tools/verify.js.map +1 -1
- package/package.json +98 -89
- package/templates/analytics/instructions.yaml +37 -37
- package/templates/analytics/mcp-servers.yaml +11 -11
- package/templates/analytics/structure.yaml +25 -25
- package/templates/api/harness/uc-template.hurl +20 -0
- package/templates/api/instructions.yaml +231 -231
- package/templates/api/mcp-servers.yaml +22 -22
- package/templates/api/nfr.yaml +23 -23
- package/templates/api/review.yaml +103 -103
- package/templates/api/structure.yaml +34 -34
- package/templates/api/verification.yaml +132 -132
- package/templates/cli/instructions.yaml +31 -31
- package/templates/cli/mcp-servers.yaml +11 -11
- package/templates/cli/review.yaml +53 -53
- package/templates/cli/structure.yaml +16 -16
- package/templates/data-lineage/instructions.yaml +28 -28
- package/templates/data-lineage/mcp-servers.yaml +22 -22
- package/templates/data-pipeline/instructions.yaml +84 -84
- package/templates/data-pipeline/mcp-servers.yaml +13 -13
- package/templates/data-pipeline/nfr.yaml +39 -39
- package/templates/data-pipeline/structure.yaml +23 -23
- package/templates/docs-manifest.yaml +227 -0
- package/templates/fintech/hooks.yaml +55 -55
- package/templates/fintech/instructions.yaml +112 -112
- package/templates/fintech/mcp-servers.yaml +13 -13
- package/templates/fintech/nfr.yaml +46 -46
- package/templates/fintech/playbook.yaml +210 -210
- package/templates/fintech/verification.yaml +239 -239
- package/templates/game/harness/uc-template.sim.ts +29 -0
- package/templates/game/instructions.yaml +289 -289
- package/templates/game/mcp-servers.yaml +38 -38
- package/templates/game/nfr.yaml +64 -64
- package/templates/game/playbook.yaml +214 -214
- package/templates/game/review.yaml +97 -97
- package/templates/game/structure.yaml +67 -67
- package/templates/game/verification.yaml +174 -174
- package/templates/healthcare/instructions.yaml +42 -42
- package/templates/healthcare/mcp-servers.yaml +13 -13
- package/templates/healthcare/nfr.yaml +47 -47
- package/templates/hipaa/instructions.yaml +41 -41
- package/templates/hipaa/mcp-servers.yaml +13 -13
- package/templates/infra/instructions.yaml +104 -104
- package/templates/infra/mcp-servers.yaml +20 -20
- package/templates/infra/nfr.yaml +46 -46
- package/templates/infra/review.yaml +65 -65
- package/templates/infra/structure.yaml +25 -25
- package/templates/library/instructions.yaml +36 -36
- package/templates/library/mcp-servers.yaml +20 -20
- package/templates/library/review.yaml +56 -56
- package/templates/library/structure.yaml +19 -19
- package/templates/medallion-architecture/instructions.yaml +41 -41
- package/templates/medallion-architecture/mcp-servers.yaml +22 -22
- package/templates/ml/instructions.yaml +85 -85
- package/templates/ml/mcp-servers.yaml +11 -11
- package/templates/ml/nfr.yaml +39 -39
- package/templates/ml/structure.yaml +25 -25
- package/templates/ml/verification.yaml +156 -156
- package/templates/mobile/instructions.yaml +44 -44
- package/templates/mobile/mcp-servers.yaml +11 -11
- package/templates/mobile/nfr.yaml +49 -49
- package/templates/mobile/structure.yaml +27 -27
- package/templates/mobile/verification.yaml +121 -121
- package/templates/observability-xray/instructions.yaml +40 -40
- package/templates/observability-xray/mcp-servers.yaml +15 -15
- package/templates/realtime/instructions.yaml +42 -42
- package/templates/realtime/mcp-servers.yaml +13 -13
- package/templates/soc2/instructions.yaml +41 -41
- package/templates/soc2/mcp-servers.yaml +24 -24
- package/templates/social/instructions.yaml +43 -43
- package/templates/social/mcp-servers.yaml +24 -24
- package/templates/state-machine/instructions.yaml +42 -42
- package/templates/state-machine/mcp-servers.yaml +11 -11
- package/templates/tools-registry.yaml +164 -164
- package/templates/universal/claude-md-blocks/layer-navigation.md +20 -0
- package/templates/universal/claude-md-blocks/nfr-contracts.md +22 -0
- package/templates/universal/hooks.yaml +879 -723
- package/templates/universal/instructions.yaml +1692 -1692
- package/templates/universal/mcp-servers.yaml +50 -50
- package/templates/universal/nfr.yaml +197 -197
- package/templates/universal/reference.yaml +326 -326
- package/templates/universal/review.yaml +204 -204
- package/templates/universal/skills.yaml +262 -262
- package/templates/universal/structure.yaml +67 -67
- package/templates/universal/verification.yaml +416 -416
- package/templates/web-next/hooks.yaml +114 -0
- package/templates/web-next/instructions.yaml +106 -0
- package/templates/web-react/harness/uc-template.spec.ts +35 -0
- package/templates/web-react/hooks.yaml +156 -44
- package/templates/web-react/instructions.yaml +296 -207
- package/templates/web-react/mcp-servers.yaml +20 -20
- package/templates/web-react/nfr.yaml +27 -27
- package/templates/web-react/review.yaml +94 -94
- package/templates/web-react/structure.yaml +46 -46
- package/templates/web-react/verification.yaml +126 -126
- package/templates/web-static/hooks.yaml +85 -0
- package/templates/web-static/instructions.yaml +204 -115
- package/templates/web-static/mcp-servers.yaml +20 -20
- package/templates/web3/instructions.yaml +44 -44
- package/templates/web3/mcp-servers.yaml +11 -11
- package/templates/web3/verification.yaml +159 -159
- package/templates/zero-trust/instructions.yaml +41 -41
- package/templates/zero-trust/mcp-servers.yaml +15 -15
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
tag: WEB-NEXT
|
|
2
|
+
section: hooks
|
|
3
|
+
hooks:
|
|
4
|
+
- name: design-token-enforcement
|
|
5
|
+
trigger: pre-commit
|
|
6
|
+
description: "Block raw hex/rgb color literals in component and style files"
|
|
7
|
+
filename: pre-commit-design-tokens.sh
|
|
8
|
+
script: |
|
|
9
|
+
#!/bin/bash
|
|
10
|
+
# Block raw hex/rgb/hsl color literals — use design tokens instead.
|
|
11
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx|css|scss|less)$')
|
|
12
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
13
|
+
VIOLATIONS=0
|
|
14
|
+
for file in $STAGED; do
|
|
15
|
+
# Skip token definition files and test/story files
|
|
16
|
+
if echo "$file" | grep -qiE '(tokens\.|variables\.|theme\.|_vars\.|\.test\.|\.spec\.|\.stories\.)'; then
|
|
17
|
+
continue
|
|
18
|
+
fi
|
|
19
|
+
COUNT=$(grep -cE '#[0-9A-Fa-f]{3,8}\b|rgb\s*\(|rgba\s*\(|hsl\s*\(' "$file" 2>/dev/null || echo 0)
|
|
20
|
+
if [ "$COUNT" -gt 0 ]; then
|
|
21
|
+
echo " ❌ $file — $COUNT raw color literal(s). Use var(--color-*) design tokens:"
|
|
22
|
+
grep -nE '#[0-9A-Fa-f]{3,8}\b|rgb\s*\(|rgba\s*\(|hsl\s*\(' "$file" | head -3 | sed 's/^/ /'
|
|
23
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
24
|
+
fi
|
|
25
|
+
done
|
|
26
|
+
if [ $VIOLATIONS -gt 0 ]; then
|
|
27
|
+
echo ""
|
|
28
|
+
echo "❌ Design token gate failed. Replace raw colors with CSS custom property tokens."
|
|
29
|
+
echo " Token reference: src/styles/tokens.css"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
- name: atomic-structure-enforcement
|
|
34
|
+
trigger: pre-commit
|
|
35
|
+
description: "Enforce atomic design placement (atoms/molecules/organisms/templates/pages)"
|
|
36
|
+
filename: pre-commit-atomic-structure.sh
|
|
37
|
+
script: |
|
|
38
|
+
#!/bin/bash
|
|
39
|
+
# Enforce atomic component placement in components/ directories.
|
|
40
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
41
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
42
|
+
VIOLATIONS=0
|
|
43
|
+
for file in $STAGED; do
|
|
44
|
+
# Only check files inside a components/ directory
|
|
45
|
+
if echo "$file" | grep -qE '/components/'; then
|
|
46
|
+
# Skip if in a valid atomic subdirectory
|
|
47
|
+
if ! echo "$file" | grep -qE '/components/(atoms|molecules|organisms|templates|pages)/'; then
|
|
48
|
+
echo " ❌ $file — not in atomic directory. Move to atoms/, molecules/, organisms/, templates/, or pages/"
|
|
49
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
done
|
|
53
|
+
if [ $VIOLATIONS -gt 0 ]; then
|
|
54
|
+
echo ""
|
|
55
|
+
echo "❌ Atomic structure gate failed: components/ files must be in atomic subdirectories."
|
|
56
|
+
echo " Use: src/components/{atoms|molecules|organisms|templates|pages}/"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
- name: responsive-adr-enforcement
|
|
61
|
+
trigger: pre-commit
|
|
62
|
+
description: "Require a responsive strategy ADR before committing responsive layout code"
|
|
63
|
+
filename: pre-commit-responsive-adr.sh
|
|
64
|
+
script: |
|
|
65
|
+
#!/bin/bash
|
|
66
|
+
# Require a responsive strategy ADR before any responsive layout code is committed.
|
|
67
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx|css|scss|less)$')
|
|
68
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
69
|
+
HAS_RESPONSIVE=0
|
|
70
|
+
for file in $STAGED; do
|
|
71
|
+
if grep -qE '@media|sm:|md:|lg:|xl:|2xl:|breakpoint' "$file" 2>/dev/null; then
|
|
72
|
+
HAS_RESPONSIVE=1
|
|
73
|
+
break
|
|
74
|
+
fi
|
|
75
|
+
done
|
|
76
|
+
if [ $HAS_RESPONSIVE -eq 0 ]; then exit 0; fi
|
|
77
|
+
# Check for a responsive strategy ADR
|
|
78
|
+
ADR_EXISTS=$(find docs/adrs -name "*.md" 2>/dev/null | \
|
|
79
|
+
xargs grep -l -iE '(responsive|breakpoint|mobile.first|viewport)' 2>/dev/null | \
|
|
80
|
+
wc -l | tr -d ' ')
|
|
81
|
+
if [ "$ADR_EXISTS" -eq 0 ]; then
|
|
82
|
+
echo "❌ Responsive layout code added but no responsive strategy ADR found."
|
|
83
|
+
echo " Create docs/adrs/active/responsive-strategy.md before adding responsive code."
|
|
84
|
+
echo " The ADR must document: breakpoints, approach (mobile-first/desktop-first),"
|
|
85
|
+
echo " CSS framework choice, and target viewport range."
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
- name: ux-pattern-docs-check
|
|
90
|
+
trigger: pre-commit
|
|
91
|
+
description: "Require docs/patterns/error.md and loading.md before page/modal/table components"
|
|
92
|
+
filename: pre-commit-ux-patterns.sh
|
|
93
|
+
script: |
|
|
94
|
+
#!/bin/bash
|
|
95
|
+
# Require UX pattern docs before page, modal, or table components are committed.
|
|
96
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
97
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
98
|
+
HAS_PATTERN_COMPONENT=0
|
|
99
|
+
for file in $STAGED; do
|
|
100
|
+
if echo "$file" | grep -qiE '(page|screen|modal|dialog|table|drawer)\.(tsx|jsx)$'; then
|
|
101
|
+
HAS_PATTERN_COMPONENT=1
|
|
102
|
+
break
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
if [ $HAS_PATTERN_COMPONENT -eq 0 ]; then exit 0; fi
|
|
106
|
+
MISSING=""
|
|
107
|
+
[ ! -f "docs/patterns/error.md" ] && MISSING="$MISSING error.md"
|
|
108
|
+
[ ! -f "docs/patterns/loading.md" ] && MISSING="$MISSING loading.md"
|
|
109
|
+
if [ -n "$MISSING" ]; then
|
|
110
|
+
echo "❌ UX pattern docs missing:$MISSING"
|
|
111
|
+
echo " Create docs/patterns/{error,loading,empty,modals,tables}.md before adding"
|
|
112
|
+
echo " page, modal, or table components. These are the source of truth for common UI patterns."
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
tag: WEB-NEXT
|
|
2
|
+
section: instructions
|
|
3
|
+
blocks:
|
|
4
|
+
- id: nextjs-app-router-conventions
|
|
5
|
+
tier: recommended
|
|
6
|
+
title: "Next.js App Router Conventions"
|
|
7
|
+
content: |
|
|
8
|
+
## Next.js App Router Conventions
|
|
9
|
+
|
|
10
|
+
- Use the App Router (`app/`) as the default. Pages Router (`pages/`) is legacy — do not mix unless migrating.
|
|
11
|
+
- Every route segment is a directory with a `page.tsx` file. Layout nesting via `layout.tsx`.
|
|
12
|
+
- Mark components as `"use client"` only when they use browser APIs, event handlers, or React hooks that require the browser. Server Components are the default.
|
|
13
|
+
- Server Actions (`"use server"`) replace API routes for mutations. Use `next-safe-action` or Zod for validation.
|
|
14
|
+
- Data fetching: fetch in Server Components using async/await directly. Use `unstable_cache` or `revalidatePath` for ISR.
|
|
15
|
+
- Route handlers (`route.ts`) for REST endpoints that must be publicly accessible.
|
|
16
|
+
- `<Image>` from `next/image` for all images — never raw `<img>` tags.
|
|
17
|
+
- `<Link>` from `next/link` for all internal navigation.
|
|
18
|
+
|
|
19
|
+
- id: ui-design-token-enforcement
|
|
20
|
+
tier: core
|
|
21
|
+
title: "Design Token Enforcement"
|
|
22
|
+
content: |
|
|
23
|
+
## Design Token Enforcement — Non-Negotiable
|
|
24
|
+
|
|
25
|
+
**Before writing any visual code**, read `src/styles/tokens.css` (or `src/tokens/` if split by domain).
|
|
26
|
+
|
|
27
|
+
- NEVER use raw hex (`#1a2b3c`), `rgb()`, `rgba()`, or `hsl()` values in component or style files.
|
|
28
|
+
- ALL colors: `var(--color-primary)`, `var(--color-text-muted)`, `var(--color-surface-elevated)`.
|
|
29
|
+
- ALL spacing: `var(--spacing-4)`, `var(--spacing-8)` (or Tailwind theme tokens — never arbitrary px values).
|
|
30
|
+
- ALL typography: `var(--font-size-lg)`, `var(--font-weight-semibold)`.
|
|
31
|
+
- If a token for the intended value doesn't exist, **add it to the token file** — don't hardcode the value.
|
|
32
|
+
- Token definition files (tokens.css, variables.css, theme.ts) are the ONLY exception to this rule.
|
|
33
|
+
- A pre-commit hook blocks commits containing raw color literals in component or style files.
|
|
34
|
+
|
|
35
|
+
- id: ui-atomic-component-structure
|
|
36
|
+
tier: core
|
|
37
|
+
title: "Atomic Component Structure"
|
|
38
|
+
content: |
|
|
39
|
+
## Atomic Component Structure — Mandatory First-Check
|
|
40
|
+
|
|
41
|
+
**Before creating any new component**, search the component library:
|
|
42
|
+
1. `src/components/atoms/` — does the primitive already exist?
|
|
43
|
+
2. `src/components/molecules/` — does the composition already exist?
|
|
44
|
+
3. `src/components/organisms/` — does the full UI section already exist?
|
|
45
|
+
|
|
46
|
+
Create a new component only if nothing suitable exists.
|
|
47
|
+
|
|
48
|
+
### Placement Rules
|
|
49
|
+
| Level | Scope | Examples |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **atoms/** | Indivisible UI elements | Button, Input, Badge, Icon, Label, Spinner, Avatar |
|
|
52
|
+
| **molecules/** | Compositions of 2–5 atoms | SearchField, FormField, Card, MenuItem, Tooltip |
|
|
53
|
+
| **organisms/** | Complex UI sections | Header, DataTable, Sidebar, Modal, Wizard |
|
|
54
|
+
| **templates/** | Page-level layout shells | DashboardLayout, AuthLayout, SettingsLayout |
|
|
55
|
+
| **pages/** | Route-bound page components | one per route |
|
|
56
|
+
|
|
57
|
+
A pre-commit hook blocks component files placed directly in `components/` without an atomic subdirectory.
|
|
58
|
+
|
|
59
|
+
- id: ui-ux-pattern-wiring
|
|
60
|
+
tier: core
|
|
61
|
+
title: "UX Pattern Wiring"
|
|
62
|
+
content: |
|
|
63
|
+
## UX Pattern Wiring — Read Before Implementing
|
|
64
|
+
|
|
65
|
+
**Before implementing any common interaction**, read the relevant pattern from `docs/patterns/`:
|
|
66
|
+
|
|
67
|
+
| Interaction | Pattern doc | What it defines |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| Error state | `docs/patterns/error.md` | Error boundaries, API failure UI, validation |
|
|
70
|
+
| Loading / skeleton | `docs/patterns/loading.md` | Spinners vs. skeletons, delay thresholds |
|
|
71
|
+
| Empty state | `docs/patterns/empty.md` | Zero-data UI, onboarding prompts |
|
|
72
|
+
| Modal / dialog | `docs/patterns/modals.md` | Focus trap, close behaviour, stacking |
|
|
73
|
+
| Data table | `docs/patterns/tables.md` | Sorting, pagination, row selection |
|
|
74
|
+
|
|
75
|
+
If a pattern doc does not exist, **create it before implementing the component**.
|
|
76
|
+
Never implement an error, loading, empty, modal, or table pattern without the `docs/patterns/` file as source of truth.
|
|
77
|
+
|
|
78
|
+
- id: ui-responsive-strategy-adr
|
|
79
|
+
tier: core
|
|
80
|
+
title: "Responsive Strategy ADR"
|
|
81
|
+
content: |
|
|
82
|
+
## Responsive Strategy — ADR Required Before Any Responsive Code
|
|
83
|
+
|
|
84
|
+
Before writing any `@media` query, Tailwind responsive prefix (`sm:`, `md:`, `lg:`), or breakpoint variable, verify that `docs/adrs/active/responsive-strategy.md` exists.
|
|
85
|
+
|
|
86
|
+
If it doesn't exist, create it:
|
|
87
|
+
```markdown
|
|
88
|
+
# ADR: Responsive Strategy
|
|
89
|
+
|
|
90
|
+
## Status: Accepted
|
|
91
|
+
|
|
92
|
+
## Context
|
|
93
|
+
[Device/viewport range this app must support]
|
|
94
|
+
|
|
95
|
+
## Decision
|
|
96
|
+
- **Breakpoints**: mobile < 640px | tablet 640–1024px | desktop > 1024px
|
|
97
|
+
- **Approach**: mobile-first (min-width media queries)
|
|
98
|
+
- **Framework**: [Tailwind CSS / CSS custom properties / CSS Grid]
|
|
99
|
+
- **Target devices**: iOS Safari 16+, Chrome 110+, minimum viewport 320px
|
|
100
|
+
|
|
101
|
+
## Consequences
|
|
102
|
+
All responsive layout code uses these breakpoints exclusively. No component-local
|
|
103
|
+
breakpoint values. Deviations require an amendment to this ADR.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
A pre-commit hook blocks responsive code when no responsive strategy ADR is present.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* L2 Harness: {{uc_id}} — {{uc_title}}
|
|
5
|
+
*
|
|
6
|
+
* Actor: {{actor}}
|
|
7
|
+
* Precondition: {{precondition}}
|
|
8
|
+
* Postcondition: {{postcondition}}
|
|
9
|
+
*
|
|
10
|
+
* Behavioral harness probe — verifies use case postconditions in the running UI.
|
|
11
|
+
* Failure = specification violation. Regenerate from spec; don't patch the code.
|
|
12
|
+
*/
|
|
13
|
+
test.describe("{{uc_id}}: {{uc_title}}", () => {
|
|
14
|
+
test.beforeEach(async ({ page }) => {
|
|
15
|
+
// Set up precondition: {{precondition}}
|
|
16
|
+
await page.goto("http://localhost:3000");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("postcondition: {{postcondition}}", async ({ page }) => {
|
|
20
|
+
// TODO: implement UC main flow
|
|
21
|
+
// {{step_1}}
|
|
22
|
+
// {{step_2}}
|
|
23
|
+
|
|
24
|
+
// Assert postcondition
|
|
25
|
+
// await expect(page.locator('...')).toBeVisible();
|
|
26
|
+
throw new Error(
|
|
27
|
+
"Not implemented: add UI interactions following {{uc_id}} main flow",
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("error case: [fill in error case]", async ({ page }) => {
|
|
32
|
+
// TODO: test error paths from use case
|
|
33
|
+
throw new Error("Not implemented: add error path for {{uc_id}}");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -1,44 +1,156 @@
|
|
|
1
|
-
tag: WEB-REACT
|
|
2
|
-
section: hooks
|
|
3
|
-
hooks:
|
|
4
|
-
- name: i18n-enforcement
|
|
5
|
-
trigger: pre-commit
|
|
6
|
-
description: "Scan JSX/TSX for hardcoded user-facing strings not wrapped in t()"
|
|
7
|
-
filename: pre-commit-i18n.sh
|
|
8
|
-
script: |
|
|
9
|
-
#!/bin/bash
|
|
10
|
-
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
11
|
-
if [ -z "$STAGED" ]; then exit 0; fi
|
|
12
|
-
VIOLATIONS=0
|
|
13
|
-
for file in $STAGED; do
|
|
14
|
-
# Find string literals in JSX that aren't in t() calls, className, data-testid, etc.
|
|
15
|
-
if grep -nE '>\s*[A-Z][a-z]+(\s+[a-z]+)+\s*<' "$file" | grep -vE '(className|data-testid|aria-|console\.)' > /tmp/i18n_violations 2>/dev/null; then
|
|
16
|
-
if [ -s /tmp/i18n_violations ]; then
|
|
17
|
-
echo " ⚠️ $file — possible untranslated string:"
|
|
18
|
-
cat /tmp/i18n_violations | head -3
|
|
19
|
-
VIOLATIONS=$((VIOLATIONS + 1))
|
|
20
|
-
fi
|
|
21
|
-
fi
|
|
22
|
-
done
|
|
23
|
-
rm -f /tmp/i18n_violations
|
|
24
|
-
if [ $VIOLATIONS -gt 0 ]; then
|
|
25
|
-
echo "⚠️ $VIOLATIONS file(s) may have untranslated strings. Use t() wrapper."
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
- name: a11y-lint
|
|
29
|
-
trigger: pre-commit
|
|
30
|
-
description: "Run accessibility checks on staged JSX/TSX files"
|
|
31
|
-
filename: pre-commit-a11y.sh
|
|
32
|
-
script: |
|
|
33
|
-
#!/bin/bash
|
|
34
|
-
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
35
|
-
if [ -z "$STAGED" ]; then exit 0; fi
|
|
36
|
-
# Check for div used as button without role
|
|
37
|
-
for file in $STAGED; do
|
|
38
|
-
if grep -nE '<div\s+onClick' "$file" | grep -v 'role=' > /tmp/a11y_violations 2>/dev/null; then
|
|
39
|
-
if [ -s /tmp/a11y_violations ]; then
|
|
40
|
-
echo " ⚠️ $file — clickable div without role attribute. Use <button> or add role=\"button\""
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
done
|
|
44
|
-
rm -f /tmp/a11y_violations
|
|
1
|
+
tag: WEB-REACT
|
|
2
|
+
section: hooks
|
|
3
|
+
hooks:
|
|
4
|
+
- name: i18n-enforcement
|
|
5
|
+
trigger: pre-commit
|
|
6
|
+
description: "Scan JSX/TSX for hardcoded user-facing strings not wrapped in t()"
|
|
7
|
+
filename: pre-commit-i18n.sh
|
|
8
|
+
script: |
|
|
9
|
+
#!/bin/bash
|
|
10
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
11
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
12
|
+
VIOLATIONS=0
|
|
13
|
+
for file in $STAGED; do
|
|
14
|
+
# Find string literals in JSX that aren't in t() calls, className, data-testid, etc.
|
|
15
|
+
if grep -nE '>\s*[A-Z][a-z]+(\s+[a-z]+)+\s*<' "$file" | grep -vE '(className|data-testid|aria-|console\.)' > /tmp/i18n_violations 2>/dev/null; then
|
|
16
|
+
if [ -s /tmp/i18n_violations ]; then
|
|
17
|
+
echo " ⚠️ $file — possible untranslated string:"
|
|
18
|
+
cat /tmp/i18n_violations | head -3
|
|
19
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
20
|
+
fi
|
|
21
|
+
fi
|
|
22
|
+
done
|
|
23
|
+
rm -f /tmp/i18n_violations
|
|
24
|
+
if [ $VIOLATIONS -gt 0 ]; then
|
|
25
|
+
echo "⚠️ $VIOLATIONS file(s) may have untranslated strings. Use t() wrapper."
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
- name: a11y-lint
|
|
29
|
+
trigger: pre-commit
|
|
30
|
+
description: "Run accessibility checks on staged JSX/TSX files"
|
|
31
|
+
filename: pre-commit-a11y.sh
|
|
32
|
+
script: |
|
|
33
|
+
#!/bin/bash
|
|
34
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
35
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
36
|
+
# Check for div used as button without role
|
|
37
|
+
for file in $STAGED; do
|
|
38
|
+
if grep -nE '<div\s+onClick' "$file" | grep -v 'role=' > /tmp/a11y_violations 2>/dev/null; then
|
|
39
|
+
if [ -s /tmp/a11y_violations ]; then
|
|
40
|
+
echo " ⚠️ $file — clickable div without role attribute. Use <button> or add role=\"button\""
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
done
|
|
44
|
+
rm -f /tmp/a11y_violations
|
|
45
|
+
|
|
46
|
+
- name: design-token-enforcement
|
|
47
|
+
trigger: pre-commit
|
|
48
|
+
description: "Block raw hex/rgb color literals in component and style files"
|
|
49
|
+
filename: pre-commit-design-tokens.sh
|
|
50
|
+
script: |
|
|
51
|
+
#!/bin/bash
|
|
52
|
+
# Block raw hex/rgb/hsl color literals — use design tokens instead.
|
|
53
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx|css|scss|less)$')
|
|
54
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
55
|
+
VIOLATIONS=0
|
|
56
|
+
for file in $STAGED; do
|
|
57
|
+
# Skip token definition files and test/story files
|
|
58
|
+
if echo "$file" | grep -qiE '(tokens\.|variables\.|theme\.|_vars\.|\.test\.|\.spec\.|\.stories\.)'; then
|
|
59
|
+
continue
|
|
60
|
+
fi
|
|
61
|
+
COUNT=$(grep -cE '#[0-9A-Fa-f]{3,8}\b|rgb\s*\(|rgba\s*\(|hsl\s*\(' "$file" 2>/dev/null || echo 0)
|
|
62
|
+
if [ "$COUNT" -gt 0 ]; then
|
|
63
|
+
echo " ❌ $file — $COUNT raw color literal(s). Use var(--color-*) design tokens:"
|
|
64
|
+
grep -nE '#[0-9A-Fa-f]{3,8}\b|rgb\s*\(|rgba\s*\(|hsl\s*\(' "$file" | head -3 | sed 's/^/ /'
|
|
65
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
66
|
+
fi
|
|
67
|
+
done
|
|
68
|
+
if [ $VIOLATIONS -gt 0 ]; then
|
|
69
|
+
echo ""
|
|
70
|
+
echo "❌ Design token gate failed. Replace raw colors with CSS custom property tokens."
|
|
71
|
+
echo " Token reference: src/styles/tokens.css"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
- name: atomic-structure-enforcement
|
|
76
|
+
trigger: pre-commit
|
|
77
|
+
description: "Enforce atomic design placement (atoms/molecules/organisms/templates/pages)"
|
|
78
|
+
filename: pre-commit-atomic-structure.sh
|
|
79
|
+
script: |
|
|
80
|
+
#!/bin/bash
|
|
81
|
+
# Enforce atomic component placement in components/ directories.
|
|
82
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
83
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
84
|
+
VIOLATIONS=0
|
|
85
|
+
for file in $STAGED; do
|
|
86
|
+
# Only check files inside a components/ directory
|
|
87
|
+
if echo "$file" | grep -qE '/components/'; then
|
|
88
|
+
# Skip if in a valid atomic subdirectory
|
|
89
|
+
if ! echo "$file" | grep -qE '/components/(atoms|molecules|organisms|templates|pages)/'; then
|
|
90
|
+
echo " ❌ $file — not in atomic directory. Move to atoms/, molecules/, organisms/, templates/, or pages/"
|
|
91
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
92
|
+
fi
|
|
93
|
+
fi
|
|
94
|
+
done
|
|
95
|
+
if [ $VIOLATIONS -gt 0 ]; then
|
|
96
|
+
echo ""
|
|
97
|
+
echo "❌ Atomic structure gate failed: components/ files must be in atomic subdirectories."
|
|
98
|
+
echo " Use: src/components/{atoms|molecules|organisms|templates|pages}/"
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
- name: responsive-adr-enforcement
|
|
103
|
+
trigger: pre-commit
|
|
104
|
+
description: "Require a responsive strategy ADR before committing responsive layout code"
|
|
105
|
+
filename: pre-commit-responsive-adr.sh
|
|
106
|
+
script: |
|
|
107
|
+
#!/bin/bash
|
|
108
|
+
# Require a responsive strategy ADR before any responsive layout code is committed.
|
|
109
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx|css|scss|less)$')
|
|
110
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
111
|
+
HAS_RESPONSIVE=0
|
|
112
|
+
for file in $STAGED; do
|
|
113
|
+
if grep -qE '@media|sm:|md:|lg:|xl:|2xl:|breakpoint' "$file" 2>/dev/null; then
|
|
114
|
+
HAS_RESPONSIVE=1
|
|
115
|
+
break
|
|
116
|
+
fi
|
|
117
|
+
done
|
|
118
|
+
if [ $HAS_RESPONSIVE -eq 0 ]; then exit 0; fi
|
|
119
|
+
# Check for a responsive strategy ADR
|
|
120
|
+
ADR_EXISTS=$(find docs/adrs -name "*.md" 2>/dev/null | \
|
|
121
|
+
xargs grep -l -iE '(responsive|breakpoint|mobile.first|viewport)' 2>/dev/null | \
|
|
122
|
+
wc -l | tr -d ' ')
|
|
123
|
+
if [ "$ADR_EXISTS" -eq 0 ]; then
|
|
124
|
+
echo "❌ Responsive layout code added but no responsive strategy ADR found."
|
|
125
|
+
echo " Create docs/adrs/active/responsive-strategy.md before adding responsive code."
|
|
126
|
+
echo " The ADR must document: breakpoints, approach (mobile-first/desktop-first),"
|
|
127
|
+
echo " CSS framework choice, and target viewport range."
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
- name: ux-pattern-docs-check
|
|
132
|
+
trigger: pre-commit
|
|
133
|
+
description: "Require docs/patterns/error.md and loading.md before page/modal/table components"
|
|
134
|
+
filename: pre-commit-ux-patterns.sh
|
|
135
|
+
script: |
|
|
136
|
+
#!/bin/bash
|
|
137
|
+
# Require UX pattern docs before page, modal, or table components are committed.
|
|
138
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx|jsx)$')
|
|
139
|
+
if [ -z "$STAGED" ]; then exit 0; fi
|
|
140
|
+
HAS_PATTERN_COMPONENT=0
|
|
141
|
+
for file in $STAGED; do
|
|
142
|
+
if echo "$file" | grep -qiE '(page|screen|modal|dialog|table|drawer)\.(tsx|jsx)$'; then
|
|
143
|
+
HAS_PATTERN_COMPONENT=1
|
|
144
|
+
break
|
|
145
|
+
fi
|
|
146
|
+
done
|
|
147
|
+
if [ $HAS_PATTERN_COMPONENT -eq 0 ]; then exit 0; fi
|
|
148
|
+
MISSING=""
|
|
149
|
+
[ ! -f "docs/patterns/error.md" ] && MISSING="$MISSING error.md"
|
|
150
|
+
[ ! -f "docs/patterns/loading.md" ] && MISSING="$MISSING loading.md"
|
|
151
|
+
if [ -n "$MISSING" ]; then
|
|
152
|
+
echo "❌ UX pattern docs missing:$MISSING"
|
|
153
|
+
echo " Create docs/patterns/{error,loading,empty,modals,tables}.md before adding"
|
|
154
|
+
echo " page, modal, or table components. These are the source of truth for common UI patterns."
|
|
155
|
+
exit 1
|
|
156
|
+
fi
|