voidmachine 0.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +123 -4
- package/bin/void-harness.mjs +12 -0
- package/bin/void-machine.mjs +12 -0
- package/core-assets/.claude-plugin/plugin.json +253 -0
- package/core-assets/.gitkeep +0 -0
- package/core-assets/PHILOSOPHY.md +218 -0
- package/core-assets/PROJECT-DOCTRINE.template.md +14 -0
- package/core-assets/adapters/security/manifest.yaml +96 -0
- package/core-assets/agents/.gitkeep +0 -0
- package/core-assets/agents/accessibility-specialist.md +59 -0
- package/core-assets/agents/api-integration-engineer.md +59 -0
- package/core-assets/agents/code-explorer.md +94 -0
- package/core-assets/agents/code-explorer.source +7 -0
- package/core-assets/agents/data-migration-engineer.md +59 -0
- package/core-assets/agents/devex-docs-engineer.md +57 -0
- package/core-assets/agents/doctrine-critic.md +91 -0
- package/core-assets/agents/doctrine-critic.source +11 -0
- package/core-assets/agents/domain-architect.md +56 -0
- package/core-assets/agents/experience-designer.md +59 -0
- package/core-assets/agents/frontend-engineer.md +60 -0
- package/core-assets/agents/independent-code-reviewer.md +61 -0
- package/core-assets/agents/migration-planner.md +97 -0
- package/core-assets/agents/migration-planner.source +7 -0
- package/core-assets/agents/observability-sre-engineer.md +59 -0
- package/core-assets/agents/pdf-specialist.md +58 -0
- package/core-assets/agents/performance-engineer.md +58 -0
- package/core-assets/agents/product-challenger.md +55 -0
- package/core-assets/agents/security-engineer.md +66 -0
- package/core-assets/agents/silent-failure-hunter.md +94 -0
- package/core-assets/agents/silent-failure-hunter.source +8 -0
- package/core-assets/agents/solution-architect.md +57 -0
- package/core-assets/agents/test-qa-engineer.md +60 -0
- package/core-assets/agents/type-design-analyzer.md +93 -0
- package/core-assets/agents/type-design-analyzer.source +8 -0
- package/core-assets/agents/visual-craft-director.md +62 -0
- package/core-assets/codex/hooks.json +157 -0
- package/core-assets/contract-history/visual-craft-director/v2.yaml +43 -0
- package/core-assets/data/catalog.v3.json +10479 -0
- package/core-assets/data/certification.json +1800 -0
- package/core-assets/data/identity.json +8 -0
- package/core-assets/data/model.json +4226 -0
- package/core-assets/enforce/ci-enforce.sh +183 -0
- package/core-assets/hooks/_checks.sh +145 -0
- package/core-assets/hooks/_hooklib.sh +163 -0
- package/core-assets/hooks/_syntax-worker.cjs +503 -0
- package/core-assets/hooks/_void-hook.mjs +5459 -0
- package/core-assets/hooks/activation-meter.sh +13 -0
- package/core-assets/hooks/anti-ai-slop-grep.sh +38 -0
- package/core-assets/hooks/auto-format.sh +9 -0
- package/core-assets/hooks/axe-precommit.sh +35 -0
- package/core-assets/hooks/block-dangerous-bash.sh +10 -0
- package/core-assets/hooks/block-protected-push.sh +81 -0
- package/core-assets/hooks/boundary-direction-check.sh +10 -0
- package/core-assets/hooks/control-character-grep.sh +10 -0
- package/core-assets/hooks/fowler-refactors.txt +71 -0
- package/core-assets/hooks/large-cl-grep.sh +9 -0
- package/core-assets/hooks/llm-cost-precommit.sh +55 -0
- package/core-assets/hooks/migration-lint.sh +58 -0
- package/core-assets/hooks/migration-pr-template.sh +55 -0
- package/core-assets/hooks/no-ai-design-slop.sh +10 -0
- package/core-assets/hooks/no-any-grep.sh +10 -0
- package/core-assets/hooks/no-as-cast-grep.sh +10 -0
- package/core-assets/hooks/no-console-log-grep.sh +10 -0
- package/core-assets/hooks/no-null-grep.sh +10 -0
- package/core-assets/hooks/no-only-no-skip.sh +10 -0
- package/core-assets/hooks/outcome-meter.sh +13 -0
- package/core-assets/hooks/pre-PR-review-evidence.sh +47 -0
- package/core-assets/hooks/protect-sensitive-files.sh +10 -0
- package/core-assets/hooks/refactor-named-grep.sh +49 -0
- package/core-assets/hooks/secret-in-content.sh +10 -0
- package/core-assets/hooks/sessionstart-context.sh +9 -0
- package/core-assets/hooks/stop-typecheck.sh +9 -0
- package/core-assets/hooks/tdd-guard.md +90 -0
- package/core-assets/hooks/tdd-guard.sh +10 -0
- package/core-assets/hooks/test-name-lint.sh +10 -0
- package/core-assets/hooks/tidying-commit-prefix.sh +37 -0
- package/core-assets/hooks/trim-large-output.sh +9 -0
- package/core-assets/hooks/tsc-noemit-precommit.sh +22 -0
- package/core-assets/hooks/ubiquitous-language-lint.sh +58 -0
- package/core-assets/hooks/viewport-screenshot-gate.sh +48 -0
- package/core-assets/modules/.gitkeep +0 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/SKILL.md +164 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/SKILL.md +178 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/.source +8 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/SKILL.md +209 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/SKILL.md +194 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/SKILL.md +160 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/SKILL.md +70 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/SKILL.md +122 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/.source +7 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/SKILL.md +116 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/SKILL.md +162 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/SKILL.md +161 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/SKILL.md +176 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/SKILL.md +129 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/SKILL.md +107 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/SKILL.md +153 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/SKILL.md +204 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/.source +8 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/SKILL.md +266 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/SKILL.md +178 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/.source +8 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/SKILL.md +136 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/.source +5 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/SKILL.md +116 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/.source +7 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/SKILL.md +157 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/.source +5 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/SKILL.md +160 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/SKILL.md +214 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/SKILL.md +168 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/SKILL.md +131 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/SKILL.md +149 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-server-action/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-server-action/SKILL.md +181 -0
- package/core-assets/packs/pack-server/skills/void-server-action/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/SKILL.md +73 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/SKILL.md +205 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/harness.yaml +14 -0
- package/core-assets/policies/core.yaml +95 -0
- package/core-assets/policies/ui.yaml +23 -0
- package/core-assets/profiles/base.yaml +29 -0
- package/core-assets/profiles/expo-config.yaml +36 -0
- package/core-assets/profiles/expo.yaml +35 -0
- package/core-assets/profiles/monorepo.yaml +33 -0
- package/core-assets/profiles/nextjs-config.yaml +31 -0
- package/core-assets/profiles/nextjs.yaml +31 -0
- package/core-assets/profiles/node-server.yaml +31 -0
- package/core-assets/profiles/pwa.yaml +33 -0
- package/core-assets/profiles/react.yaml +39 -0
- package/core-assets/profiles/sql.yaml +39 -0
- package/core-assets/profiles/typescript.yaml +39 -0
- package/core-assets/skills/.gitkeep +0 -0
- package/core-assets/skills/void-accessibility/.source +15 -0
- package/core-assets/skills/void-accessibility/SKILL.md +275 -0
- package/core-assets/skills/void-accessibility/harness.yaml +17 -0
- package/core-assets/skills/void-api-and-interface-design/.source +13 -0
- package/core-assets/skills/void-api-and-interface-design/SKILL.md +231 -0
- package/core-assets/skills/void-api-and-interface-design/harness.yaml +16 -0
- package/core-assets/skills/void-async-safety/.source +13 -0
- package/core-assets/skills/void-async-safety/SKILL.md +287 -0
- package/core-assets/skills/void-async-safety/harness.yaml +16 -0
- package/core-assets/skills/void-audit/.source +15 -0
- package/core-assets/skills/void-audit/SKILL.md +83 -0
- package/core-assets/skills/void-audit/harness.yaml +14 -0
- package/core-assets/skills/void-autopilot/.source +21 -0
- package/core-assets/skills/void-autopilot/SKILL.md +358 -0
- package/core-assets/skills/void-autopilot/harness.yaml +14 -0
- package/core-assets/skills/void-brainstorm/.source +14 -0
- package/core-assets/skills/void-brainstorm/SKILL.md +271 -0
- package/core-assets/skills/void-brainstorm/harness.yaml +14 -0
- package/core-assets/skills/void-checkpoint/.source +39 -0
- package/core-assets/skills/void-checkpoint/SKILL.md +227 -0
- package/core-assets/skills/void-checkpoint/harness.yaml +14 -0
- package/core-assets/skills/void-claude-md/.source +15 -0
- package/core-assets/skills/void-claude-md/SKILL.md +180 -0
- package/core-assets/skills/void-claude-md/harness.yaml +14 -0
- package/core-assets/skills/void-code-review/.source +14 -0
- package/core-assets/skills/void-code-review/SKILL.md +232 -0
- package/core-assets/skills/void-code-review/harness.yaml +15 -0
- package/core-assets/skills/void-commit-discipline/.source +9 -0
- package/core-assets/skills/void-commit-discipline/SKILL.md +211 -0
- package/core-assets/skills/void-commit-discipline/harness.yaml +15 -0
- package/core-assets/skills/void-context/.source +15 -0
- package/core-assets/skills/void-context/SKILL.md +167 -0
- package/core-assets/skills/void-context/harness.yaml +14 -0
- package/core-assets/skills/void-debug/.source +11 -0
- package/core-assets/skills/void-debug/SKILL.md +211 -0
- package/core-assets/skills/void-debug/harness.yaml +14 -0
- package/core-assets/skills/void-decide/.source +9 -0
- package/core-assets/skills/void-decide/SKILL.md +147 -0
- package/core-assets/skills/void-decide/harness.yaml +14 -0
- package/core-assets/skills/void-devex-audit/.source +8 -0
- package/core-assets/skills/void-devex-audit/SKILL.md +113 -0
- package/core-assets/skills/void-devex-audit/harness.yaml +15 -0
- package/core-assets/skills/void-doctor/.source +15 -0
- package/core-assets/skills/void-doctor/SKILL.md +83 -0
- package/core-assets/skills/void-doctor/harness.yaml +14 -0
- package/core-assets/skills/void-domain-driven-design/.source +13 -0
- package/core-assets/skills/void-domain-driven-design/SKILL.md +292 -0
- package/core-assets/skills/void-domain-driven-design/harness.yaml +15 -0
- package/core-assets/skills/void-frontend-design/.source +19 -0
- package/core-assets/skills/void-frontend-design/SKILL.md +274 -0
- package/core-assets/skills/void-frontend-design/harness.yaml +17 -0
- package/core-assets/skills/void-functional/.source +14 -0
- package/core-assets/skills/void-functional/SKILL.md +312 -0
- package/core-assets/skills/void-functional/harness.yaml +15 -0
- package/core-assets/skills/void-graph/.source +15 -0
- package/core-assets/skills/void-graph/SKILL.md +80 -0
- package/core-assets/skills/void-graph/harness.yaml +14 -0
- package/core-assets/skills/void-hexagonal-architecture/.source +12 -0
- package/core-assets/skills/void-hexagonal-architecture/SKILL.md +276 -0
- package/core-assets/skills/void-hexagonal-architecture/harness.yaml +15 -0
- package/core-assets/skills/void-implement/.source +39 -0
- package/core-assets/skills/void-implement/SKILL.md +183 -0
- package/core-assets/skills/void-implement/harness.yaml +14 -0
- package/core-assets/skills/void-learn/.source +13 -0
- package/core-assets/skills/void-learn/SKILL.md +226 -0
- package/core-assets/skills/void-learn/harness.yaml +14 -0
- package/core-assets/skills/void-llm-cost-discipline/.source +13 -0
- package/core-assets/skills/void-llm-cost-discipline/SKILL.md +299 -0
- package/core-assets/skills/void-llm-cost-discipline/harness.yaml +15 -0
- package/core-assets/skills/void-make-pdf/.source +9 -0
- package/core-assets/skills/void-make-pdf/SKILL.md +52 -0
- package/core-assets/skills/void-make-pdf/harness.yaml +15 -0
- package/core-assets/skills/void-merge/.source +8 -0
- package/core-assets/skills/void-merge/SKILL.md +111 -0
- package/core-assets/skills/void-merge/harness.yaml +14 -0
- package/core-assets/skills/void-migrations/.source +13 -0
- package/core-assets/skills/void-migrations/SKILL.md +264 -0
- package/core-assets/skills/void-migrations/harness.yaml +17 -0
- package/core-assets/skills/void-observability/.source +12 -0
- package/core-assets/skills/void-observability/SKILL.md +245 -0
- package/core-assets/skills/void-observability/harness.yaml +15 -0
- package/core-assets/skills/void-plan/.source +15 -0
- package/core-assets/skills/void-plan/SKILL.md +239 -0
- package/core-assets/skills/void-plan/harness.yaml +14 -0
- package/core-assets/skills/void-plan-review/.source +12 -0
- package/core-assets/skills/void-plan-review/SKILL.md +128 -0
- package/core-assets/skills/void-plan-review/harness.yaml +15 -0
- package/core-assets/skills/void-qa/.source +15 -0
- package/core-assets/skills/void-qa/SKILL.md +103 -0
- package/core-assets/skills/void-qa/harness.yaml +15 -0
- package/core-assets/skills/void-refactor/.source +9 -0
- package/core-assets/skills/void-refactor/SKILL.md +220 -0
- package/core-assets/skills/void-refactor/harness.yaml +15 -0
- package/core-assets/skills/void-retrospective/.source +9 -0
- package/core-assets/skills/void-retrospective/SKILL.md +71 -0
- package/core-assets/skills/void-retrospective/harness.yaml +15 -0
- package/core-assets/skills/void-security-audit/.source +12 -0
- package/core-assets/skills/void-security-audit/SKILL.md +138 -0
- package/core-assets/skills/void-security-audit/harness.yaml +15 -0
- package/core-assets/skills/void-security-guidance/.source +12 -0
- package/core-assets/skills/void-security-guidance/SKILL.md +255 -0
- package/core-assets/skills/void-security-guidance/harness.yaml +15 -0
- package/core-assets/skills/void-source-driven-development/.source +12 -0
- package/core-assets/skills/void-source-driven-development/SKILL.md +158 -0
- package/core-assets/skills/void-source-driven-development/harness.yaml +15 -0
- package/core-assets/skills/void-tdd/.source +15 -0
- package/core-assets/skills/void-tdd/SKILL.md +394 -0
- package/core-assets/skills/void-tdd/harness.yaml +15 -0
- package/core-assets/skills/void-testing/.source +19 -0
- package/core-assets/skills/void-testing/SKILL.md +301 -0
- package/core-assets/skills/void-testing/harness.yaml +17 -0
- package/core-assets/skills/void-ticket/.source +18 -0
- package/core-assets/skills/void-ticket/SKILL.md +239 -0
- package/core-assets/skills/void-ticket/harness.yaml +14 -0
- package/core-assets/skills/void-typescript-strict/.source +10 -0
- package/core-assets/skills/void-typescript-strict/SKILL.md +294 -0
- package/core-assets/skills/void-typescript-strict/harness.yaml +17 -0
- package/core-assets/skills/void-ui-review/.source +12 -0
- package/core-assets/skills/void-ui-review/SKILL.md +97 -0
- package/core-assets/skills/void-ui-review/harness.yaml +15 -0
- package/core-assets/skills/void-verify/.source +12 -0
- package/core-assets/skills/void-verify/SKILL.md +184 -0
- package/core-assets/skills/void-verify/harness.yaml +15 -0
- package/core-assets/specialists/accessibility-specialist.source +11 -0
- package/core-assets/specialists/accessibility-specialist.yaml +30 -0
- package/core-assets/specialists/api-integration-engineer.source +11 -0
- package/core-assets/specialists/api-integration-engineer.yaml +30 -0
- package/core-assets/specialists/data-migration-engineer.source +11 -0
- package/core-assets/specialists/data-migration-engineer.yaml +30 -0
- package/core-assets/specialists/devex-docs-engineer.source +11 -0
- package/core-assets/specialists/devex-docs-engineer.yaml +29 -0
- package/core-assets/specialists/domain-architect.source +11 -0
- package/core-assets/specialists/domain-architect.yaml +28 -0
- package/core-assets/specialists/experience-designer.source +15 -0
- package/core-assets/specialists/experience-designer.yaml +38 -0
- package/core-assets/specialists/frontend-engineer.source +11 -0
- package/core-assets/specialists/frontend-engineer.yaml +32 -0
- package/core-assets/specialists/independent-code-reviewer.source +10 -0
- package/core-assets/specialists/independent-code-reviewer.yaml +37 -0
- package/core-assets/specialists/migrations.json +15 -0
- package/core-assets/specialists/observability-sre-engineer.source +11 -0
- package/core-assets/specialists/observability-sre-engineer.yaml +30 -0
- package/core-assets/specialists/pdf-specialist.source +11 -0
- package/core-assets/specialists/pdf-specialist.yaml +29 -0
- package/core-assets/specialists/performance-engineer.source +11 -0
- package/core-assets/specialists/performance-engineer.yaml +29 -0
- package/core-assets/specialists/product-challenger.source +10 -0
- package/core-assets/specialists/product-challenger.yaml +27 -0
- package/core-assets/specialists/security-engineer.source +13 -0
- package/core-assets/specialists/security-engineer.yaml +41 -0
- package/core-assets/specialists/solution-architect.source +13 -0
- package/core-assets/specialists/solution-architect.yaml +32 -0
- package/core-assets/specialists/test-qa-engineer.source +14 -0
- package/core-assets/specialists/test-qa-engineer.yaml +35 -0
- package/core-assets/specialists/visual-craft-director.source +17 -0
- package/core-assets/specialists/visual-craft-director.yaml +60 -0
- package/core-assets/templates/github/dependency-audit.mjs +54 -0
- package/core-assets/templates/github/void-dependency-audit.yml +35 -0
- package/core-assets/templates/github/void-security.yml +85 -0
- package/dist/main.js +57001 -0
- package/package.json +66 -4
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Non-blocking adapter to the generated, runtime-agnostic Node event writer.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
6
|
+
RUNNER="${BASH_SOURCE[0]%/*}/_void-hook.mjs"
|
|
7
|
+
|
|
8
|
+
if command -v node >/dev/null 2>&1 && [[ -f "$RUNNER" ]]; then
|
|
9
|
+
VOID_PROJECT_ROOT="$ROOT" \
|
|
10
|
+
node "$RUNNER" activation "${VOID_AGENT_RUNTIME:-unknown}" 2>/dev/null || true
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
exit 0
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# anti-ai-slop-grep — pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Warns on banned copy patterns that signal "vibe coded" AI output.
|
|
5
|
+
# Composed with the `frontend-design` skill. WARN ONLY — false positives
|
|
6
|
+
# expected, writer is final.
|
|
7
|
+
#
|
|
8
|
+
# Allowlist:
|
|
9
|
+
# - Lines tagged `// allow-slop: <reason>` (rare, brand-justified)
|
|
10
|
+
#
|
|
11
|
+
# Exit codes: 0 allow, 2 warn.
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(tsx|jsx|ts|md|mdx)$' || true)
|
|
16
|
+
[[ -z "$STAGED" ]] && exit 0
|
|
17
|
+
|
|
18
|
+
WARNINGS=""
|
|
19
|
+
for FILE in $STAGED; do
|
|
20
|
+
[[ "$FILE" =~ \.(test|spec)\.(ts|tsx|js|jsx)$ ]] && continue
|
|
21
|
+
[[ "$FILE" =~ /__fixtures__/ ]] && continue
|
|
22
|
+
|
|
23
|
+
ADDED=$(git diff --cached -- "$FILE" | grep -E '^\+' | grep -v '^+++' | grep -vE '// *allow-slop:' || true)
|
|
24
|
+
HITS=$(printf "%s" "$ADDED" | grep -niE \
|
|
25
|
+
'Build faster.{0,20}(ship smarter|ship faster)|Ship.{0,5}(10|five|three|five).{0,3}x faster|Unlock your potential|Empower your team|Transform your workflow|Get Started Free Forever|Take your.{0,20}to the next level|Supercharge your' \
|
|
26
|
+
|| true)
|
|
27
|
+
if [[ -n "$HITS" ]]; then
|
|
28
|
+
WARNINGS="${WARNINGS}\n $FILE:\n$HITS"
|
|
29
|
+
fi
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
if [[ -n "$WARNINGS" ]]; then
|
|
33
|
+
printf "anti-ai-slop-grep (warn): generic AI copy patterns detected:" >&2
|
|
34
|
+
printf "%b\n" "$WARNINGS" >&2
|
|
35
|
+
printf "\nRewrite with specific, brand-aligned copy. See frontend-design skill.\n" >&2
|
|
36
|
+
printf "If brand justifies the pattern, tag the line '// allow-slop: <reason>'.\n" >&2
|
|
37
|
+
exit 2
|
|
38
|
+
fi
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" lifecycle format "${VOID_AGENT_RUNTIME:-unknown}"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# axe-precommit — pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Runs axe-core static analysis on staged UI changes. Blocks on WCAG AA
|
|
5
|
+
# violations. Composed with the `accessibility` skill.
|
|
6
|
+
#
|
|
7
|
+
# Requires axe-core CLI installed via pack-nextjs devDependencies.
|
|
8
|
+
# Reads the command from .void/config.json .commands.axeStatic
|
|
9
|
+
# (defaults to `npx axe-static --staged --rules wcag2a,wcag2aa`).
|
|
10
|
+
#
|
|
11
|
+
# If axe-core CLI is not available, the hook warns once and continues
|
|
12
|
+
# (does not block) so the harness install is not gated by axe.
|
|
13
|
+
#
|
|
14
|
+
# Exit codes: 0 allow, 1 block (axe-core reported violations).
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
19
|
+
CMD=$(jq -r '.commands.axeStatic // empty' "$CONFIG" 2>/dev/null || true)
|
|
20
|
+
[[ -z "$CMD" ]] && CMD="npx --yes axe-static --staged --rules wcag2a,wcag2aa"
|
|
21
|
+
|
|
22
|
+
# Bail-out if axe-static is not installed
|
|
23
|
+
if ! command -v npx >/dev/null 2>&1; then
|
|
24
|
+
printf "axe-precommit (skipped): npx not found.\n" >&2
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(tsx|jsx)$' | grep -vE '\.(test|spec)\.' || true)
|
|
29
|
+
[[ -z "$STAGED" ]] && exit 0
|
|
30
|
+
|
|
31
|
+
if ! eval "$CMD" 2>&1; then
|
|
32
|
+
printf "\naxe-precommit: WCAG AA violations detected. Commit blocked.\n" >&2
|
|
33
|
+
printf "Fix the accessibility issues above. See accessibility skill.\n" >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce dangerous-command
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# block-protected-push — l hook. Reads the agent's tool-call JSON from stdin and
|
|
3
|
+
# refuses any `git push` whose resolved target is a protected branch (main /
|
|
4
|
+
# master). This is a SECONDARY net, NOT the boundary: the real A1 boundary is
|
|
5
|
+
# server-side branch protection plus the orchestrator owning push + PR (the
|
|
6
|
+
# worker has no `git push` in its allowlist). A string-matching hook is
|
|
7
|
+
# bypassable by an agent with arbitrary code execution (node -e "git push ..."),
|
|
8
|
+
# so it backstops regressions; it does not stand alone. Runtime-agnostic: Claude
|
|
9
|
+
# "Bash" + Codex "shell" (string or argv array).
|
|
10
|
+
#
|
|
11
|
+
# Override (a deliberate, reviewed run that intends to push a protected branch):
|
|
12
|
+
# AUTO_MERGE=1. The orchestrator derives this from --auto-merge, never the
|
|
13
|
+
# ambient env (preflight fails on divergence). Exit codes: 0 allow, 2 block.
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
INPUT=$(cat)
|
|
18
|
+
# Guard the jq calls: under `set -e`, malformed JSON on stdin would otherwise
|
|
19
|
+
# exit non-0/non-2, which the hook runner treats as an error that lets the call
|
|
20
|
+
# through. Empty TOOL → the case below exits 0 (allow + no-op), a deterministic
|
|
21
|
+
# fail-safe for this secondary net (the real boundary is server-side).
|
|
22
|
+
TOOL=$(printf "%s" "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)
|
|
23
|
+
CMD=$(printf "%s" "$INPUT" | jq -r 'if (.tool_input.command? | type) == "array" then (.tool_input.command | join(" ")) else (.tool_input.command // empty) end' 2>/dev/null || true)
|
|
24
|
+
|
|
25
|
+
case "$TOOL" in Bash | shell) ;; *) exit 0 ;; esac
|
|
26
|
+
[[ -z "$CMD" ]] && exit 0
|
|
27
|
+
[[ "${AUTO_MERGE:-}" == "1" ]] && exit 0
|
|
28
|
+
printf "%s" "$CMD" | grep -qE '\bgit\b([^&|;]*\s)?push\b' || exit 0
|
|
29
|
+
|
|
30
|
+
block() {
|
|
31
|
+
printf "block-protected-push: refusing a push to a protected branch (main/master).\n" >&2
|
|
32
|
+
printf "Matched: %s\n" "$1" >&2
|
|
33
|
+
printf "The orchestrator owns protected-branch pushes; AUTO_MERGE=1 to override.\n" >&2
|
|
34
|
+
exit 2
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
is_protected() { case "$1" in main | master) return 0 ;; *) return 1 ;; esac; }
|
|
38
|
+
|
|
39
|
+
# Always-dangerous forms, independent of any refspec: --mirror / --all push every
|
|
40
|
+
# ref (main included); a `-c push.default=` override changes where a bare push
|
|
41
|
+
# lands. None are ever needed here.
|
|
42
|
+
printf "%s" "$CMD" | grep -qE '(^|[[:space:]])--mirror([[:space:]]|$)' && block "git push --mirror"
|
|
43
|
+
printf "%s" "$CMD" | grep -qE '(^|[[:space:]])--all([[:space:]]|$)' && block "git push --all"
|
|
44
|
+
printf "%s" "$CMD" | grep -qE 'push\.default' && block "git -c push.default override"
|
|
45
|
+
|
|
46
|
+
# Positional args after `push` (the remote, then refspecs), stopping at a shell
|
|
47
|
+
# chain operator so `git push && echo` is still seen as a bare push. Flags are
|
|
48
|
+
# dropped; `-c push.default=` sits before `push` so it is never captured here.
|
|
49
|
+
POSITIONALS=$(printf "%s" "$CMD" | awk '{
|
|
50
|
+
seen = 0
|
|
51
|
+
for (i = 1; i <= NF; i++) {
|
|
52
|
+
if ($i == "push") { seen = 1; continue }
|
|
53
|
+
if (!seen) continue
|
|
54
|
+
if ($i == "&&" || $i == "||" || $i == ";" || $i == "|") break
|
|
55
|
+
if ($i ~ /^-/) continue
|
|
56
|
+
print $i
|
|
57
|
+
}
|
|
58
|
+
}')
|
|
59
|
+
|
|
60
|
+
# Drop the remote (first positional); whatever remains are refspecs / branches.
|
|
61
|
+
REFSPECS=$(printf "%s\n" "$POSITIONALS" | sed '/^$/d' | tail -n +2)
|
|
62
|
+
|
|
63
|
+
if [[ -n "$REFSPECS" ]]; then
|
|
64
|
+
# Explicit destination(s): block only if one resolves to a protected branch.
|
|
65
|
+
while IFS= read -r r; do
|
|
66
|
+
[[ -z "$r" ]] && continue
|
|
67
|
+
dst="${r##*:}" # part after the last colon (delete refspec ":main" → main)
|
|
68
|
+
dst="${dst#refs/heads/}" # normalise refs/heads/main → main
|
|
69
|
+
is_protected "$dst" && block "explicit push to $dst"
|
|
70
|
+
done <<<"$REFSPECS"
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Bare push (no refspec): resolve the current branch + upstream in the cwd (the
|
|
75
|
+
# worker's worktree) and block if either is a protected branch.
|
|
76
|
+
CUR=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
|
|
77
|
+
UP=$(git rev-parse --abbrev-ref '@{u}' 2>/dev/null || true)
|
|
78
|
+
is_protected "$CUR" && block "bare push on $CUR"
|
|
79
|
+
is_protected "${UP##*/}" && block "bare push tracking $UP"
|
|
80
|
+
|
|
81
|
+
exit 0
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce boundary-direction
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce control-character
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Allowed Fowler refactor names (case-insensitive substring match).
|
|
2
|
+
# Source: Martin Fowler "Refactoring" 2nd ed. 2018, curated subset.
|
|
3
|
+
# Add a new name only with an audit-note update.
|
|
4
|
+
|
|
5
|
+
# --- basic moves ---
|
|
6
|
+
extract function
|
|
7
|
+
inline function
|
|
8
|
+
extract variable
|
|
9
|
+
inline variable
|
|
10
|
+
rename variable
|
|
11
|
+
rename function
|
|
12
|
+
rename field
|
|
13
|
+
move function
|
|
14
|
+
move field
|
|
15
|
+
move statements into function
|
|
16
|
+
move statements to callers
|
|
17
|
+
slide statements
|
|
18
|
+
|
|
19
|
+
# --- encapsulation ---
|
|
20
|
+
encapsulate variable
|
|
21
|
+
encapsulate record
|
|
22
|
+
encapsulate collection
|
|
23
|
+
hide delegate
|
|
24
|
+
remove middle man
|
|
25
|
+
|
|
26
|
+
# --- making conditions explicit ---
|
|
27
|
+
decompose conditional
|
|
28
|
+
consolidate conditional
|
|
29
|
+
replace nested conditional with guard clauses
|
|
30
|
+
replace conditional with polymorphism
|
|
31
|
+
introduce special case
|
|
32
|
+
introduce assertion
|
|
33
|
+
|
|
34
|
+
# --- removing data smell ---
|
|
35
|
+
replace magic number with symbolic constant
|
|
36
|
+
replace primitive with object
|
|
37
|
+
replace primitive with branded type
|
|
38
|
+
replace type code with subclasses
|
|
39
|
+
|
|
40
|
+
# --- functional / pipeline ---
|
|
41
|
+
replace loop with pipeline
|
|
42
|
+
combine functions into transform
|
|
43
|
+
split loop
|
|
44
|
+
|
|
45
|
+
# --- function refinement ---
|
|
46
|
+
change function declaration
|
|
47
|
+
separate query from modifier
|
|
48
|
+
parameterize function
|
|
49
|
+
remove flag argument
|
|
50
|
+
preserve whole object
|
|
51
|
+
replace parameter with query
|
|
52
|
+
replace query with parameter
|
|
53
|
+
remove dead code
|
|
54
|
+
|
|
55
|
+
# --- larger structural ---
|
|
56
|
+
split phase
|
|
57
|
+
combine functions into class
|
|
58
|
+
extract class
|
|
59
|
+
inline class
|
|
60
|
+
extract superclass
|
|
61
|
+
extract subclass
|
|
62
|
+
pull up method
|
|
63
|
+
pull up field
|
|
64
|
+
push down method
|
|
65
|
+
push down field
|
|
66
|
+
replace subclass with delegate
|
|
67
|
+
replace superclass with delegate
|
|
68
|
+
|
|
69
|
+
# --- legacy / Feathers ---
|
|
70
|
+
sprout method
|
|
71
|
+
wrap method
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; portable policy lives in @voidcorp/hook-runner.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" lifecycle large-change "${VOID_AGENT_RUNTIME:-unknown}"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# llm-cost-precommit — pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Warns on LLM cost-discipline violations in staged code:
|
|
5
|
+
# - model: 'opus' without `// using Opus because` comment in nearby line
|
|
6
|
+
# - missing max_tokens
|
|
7
|
+
# - missing cache_control on large system arrays (best-effort static check)
|
|
8
|
+
#
|
|
9
|
+
# Composed with the `llm-cost-discipline` skill.
|
|
10
|
+
#
|
|
11
|
+
# Files: TS files importing @anthropic-ai/sdk OR matching .paths.ai
|
|
12
|
+
#
|
|
13
|
+
# Exit codes: 0 allow, 2 warn.
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(ts|tsx)$' || true)
|
|
18
|
+
[[ -z "$STAGED" ]] && exit 0
|
|
19
|
+
|
|
20
|
+
WARNINGS=""
|
|
21
|
+
for FILE in $STAGED; do
|
|
22
|
+
if ! grep -q 'anthropic-ai/sdk' "$FILE" 2>/dev/null; then continue; fi
|
|
23
|
+
|
|
24
|
+
ADDED=$(git diff --cached -- "$FILE" | grep -E '^\+' | grep -v '^+++' || true)
|
|
25
|
+
|
|
26
|
+
# Opus without justifying comment
|
|
27
|
+
OPUS=$(printf "%s" "$ADDED" | grep -nE "model:\s*['\"](claude-)?opus" || true)
|
|
28
|
+
if [[ -n "$OPUS" ]]; then
|
|
29
|
+
# check if a `using Opus because` comment appears in the file near the call
|
|
30
|
+
if ! grep -qE 'using Opus because|// allow-opus' "$FILE" 2>/dev/null; then
|
|
31
|
+
WARNINGS="${WARNINGS}\n $FILE [Opus without justifying comment]:\n$OPUS"
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Missing max_tokens in messages.create call (best-effort: scan for messages.create blocks lacking max_tokens)
|
|
36
|
+
if printf "%s" "$ADDED" | grep -qE 'messages\.create\('; then
|
|
37
|
+
if ! grep -qE 'max_tokens' "$FILE" 2>/dev/null; then
|
|
38
|
+
WARNINGS="${WARNINGS}\n $FILE [missing max_tokens in messages.create]"
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Missing cache_control on long system prompt (best-effort: scan for system: with a > 100-line string ref)
|
|
43
|
+
if printf "%s" "$ADDED" | grep -qE 'system:'; then
|
|
44
|
+
if ! grep -qE 'cache_control|// allow-no-cache' "$FILE" 2>/dev/null; then
|
|
45
|
+
WARNINGS="${WARNINGS}\n $FILE [system: present but no cache_control in file — verify >1024-token threshold]"
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
if [[ -n "$WARNINGS" ]]; then
|
|
51
|
+
printf "llm-cost-precommit (warn): cost-discipline checks:" >&2
|
|
52
|
+
printf "%b\n" "$WARNINGS" >&2
|
|
53
|
+
printf "\nSee llm-cost-discipline skill. Tag '// allow-opus: <reason>' or '// allow-no-cache: <reason>' for exceptions.\n" >&2
|
|
54
|
+
exit 2
|
|
55
|
+
fi
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# migration-lint — pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Greps staged migration SQL files for banned patterns and warns the
|
|
5
|
+
# author. Composed with the `migrations` skill.
|
|
6
|
+
#
|
|
7
|
+
# Banned patterns:
|
|
8
|
+
# - NOT NULL direct add: ALTER TABLE ... ADD COLUMN ... NOT NULL
|
|
9
|
+
# - RENAME COLUMN direct
|
|
10
|
+
# - Column type change direct: ALTER COLUMN ... TYPE
|
|
11
|
+
# - DROP COLUMN
|
|
12
|
+
# - CREATE INDEX without CONCURRENTLY (warned, not blocked — small tables OK)
|
|
13
|
+
#
|
|
14
|
+
# Allowlist:
|
|
15
|
+
# - Lines tagged `-- migration-allow: <reason>`
|
|
16
|
+
#
|
|
17
|
+
# Path: read from .void/config.json .paths.migrations, defaults to
|
|
18
|
+
# **/{migrations,drizzle/migrations}/**
|
|
19
|
+
#
|
|
20
|
+
# Exit codes: 0 allow, 2 warn.
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
25
|
+
MIG_GLOB=$(jq -r '.paths.migrations // "**/{migrations,drizzle/migrations}/**"' "$CONFIG" 2>/dev/null)
|
|
26
|
+
|
|
27
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(sql|ts)$' || true)
|
|
28
|
+
[[ -z "$STAGED" ]] && exit 0
|
|
29
|
+
|
|
30
|
+
WARNINGS=""
|
|
31
|
+
for FILE in $STAGED; do
|
|
32
|
+
case "$FILE" in $MIG_GLOB) ;; *) continue ;; esac
|
|
33
|
+
ADDED=$(git diff --cached -- "$FILE" | grep -E '^\+' | grep -v '^+++' | grep -vE '-- *migration-allow:' || true)
|
|
34
|
+
|
|
35
|
+
HIT_NN=$(printf "%s" "$ADDED" | grep -niE 'ADD COLUMN[^;]*NOT NULL' || true)
|
|
36
|
+
HIT_RN=$(printf "%s" "$ADDED" | grep -niE 'RENAME COLUMN' || true)
|
|
37
|
+
HIT_TY=$(printf "%s" "$ADDED" | grep -niE 'ALTER COLUMN[^;]*TYPE' || true)
|
|
38
|
+
HIT_DR=$(printf "%s" "$ADDED" | grep -niE 'DROP COLUMN' || true)
|
|
39
|
+
HIT_CI=$(printf "%s" "$ADDED" | grep -niE 'CREATE INDEX' | grep -v 'CONCURRENTLY' || true)
|
|
40
|
+
|
|
41
|
+
for KIND_HIT in "ADD NOT NULL direct" "$HIT_NN" "RENAME COLUMN direct" "$HIT_RN" "ALTER COLUMN TYPE direct" "$HIT_TY" "DROP COLUMN" "$HIT_DR" "CREATE INDEX without CONCURRENTLY" "$HIT_CI"; do
|
|
42
|
+
:
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
if [[ -n "$HIT_NN" ]]; then WARNINGS="${WARNINGS}\n $FILE [ADD NOT NULL direct]:\n$HIT_NN"; fi
|
|
46
|
+
if [[ -n "$HIT_RN" ]]; then WARNINGS="${WARNINGS}\n $FILE [RENAME COLUMN direct]:\n$HIT_RN"; fi
|
|
47
|
+
if [[ -n "$HIT_TY" ]]; then WARNINGS="${WARNINGS}\n $FILE [ALTER COLUMN TYPE direct]:\n$HIT_TY"; fi
|
|
48
|
+
if [[ -n "$HIT_DR" ]]; then WARNINGS="${WARNINGS}\n $FILE [DROP COLUMN]:\n$HIT_DR"; fi
|
|
49
|
+
if [[ -n "$HIT_CI" ]]; then WARNINGS="${WARNINGS}\n $FILE [CREATE INDEX without CONCURRENTLY]:\n$HIT_CI"; fi
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
if [[ -n "$WARNINGS" ]]; then
|
|
53
|
+
printf "migration-lint (warn): risky DDL patterns detected:" >&2
|
|
54
|
+
printf "%b\n" "$WARNINGS" >&2
|
|
55
|
+
printf "\nApply two-phase change pattern. See migrations skill.\n" >&2
|
|
56
|
+
printf "Tag '-- migration-allow: <reason>' for surgical exceptions (small tables, etc.).\n" >&2
|
|
57
|
+
exit 2
|
|
58
|
+
fi
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# migration-pr-template — pre-push hook
|
|
3
|
+
#
|
|
4
|
+
# Warns if a PR touching migrations lacks the required body sections.
|
|
5
|
+
# Composed with the `migrations` skill.
|
|
6
|
+
#
|
|
7
|
+
# Required sections (case-insensitive substring match):
|
|
8
|
+
# - Table affected
|
|
9
|
+
# - Approximate row count
|
|
10
|
+
# - Locking impact
|
|
11
|
+
# - Backfill strategy
|
|
12
|
+
# - Rollback plan
|
|
13
|
+
# - Tested on dev branch
|
|
14
|
+
#
|
|
15
|
+
# Exit codes: 0 allow, 2 warn.
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
20
|
+
MIG_GLOB=$(jq -r '.paths.migrations // "**/{migrations,drizzle/migrations}/**"' "$CONFIG" 2>/dev/null)
|
|
21
|
+
|
|
22
|
+
# Detect if migrations were touched in the branch
|
|
23
|
+
BASE=$(gh pr view --json baseRefName --jq .baseRefName 2>/dev/null || echo "")
|
|
24
|
+
[[ -z "$BASE" ]] && exit 0
|
|
25
|
+
|
|
26
|
+
BASE_SHA=$(git merge-base "HEAD" "origin/$BASE" 2>/dev/null || echo "")
|
|
27
|
+
[[ -z "$BASE_SHA" ]] && exit 0
|
|
28
|
+
|
|
29
|
+
TOUCHED_MIGRATIONS=""
|
|
30
|
+
for FILE in $(git diff --name-only "$BASE_SHA"..HEAD); do
|
|
31
|
+
case "$FILE" in $MIG_GLOB) TOUCHED_MIGRATIONS="$FILE"; break ;; esac
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
[[ -z "$TOUCHED_MIGRATIONS" ]] && exit 0
|
|
35
|
+
|
|
36
|
+
# Inspect PR body
|
|
37
|
+
BODY=$(gh pr view --json body --jq .body 2>/dev/null || echo "")
|
|
38
|
+
if [[ -z "$BODY" ]]; then
|
|
39
|
+
printf "migration-pr-template: no open PR found, skipping.\n" >&2
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
MISSING=()
|
|
44
|
+
for SECTION in "Table affected" "row count" "Locking impact" "Backfill" "Rollback" "Tested on dev"; do
|
|
45
|
+
if ! printf "%s" "$BODY" | grep -qi "$SECTION"; then
|
|
46
|
+
MISSING+=("$SECTION")
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
|
51
|
+
printf "migration-pr-template (warn): PR touches migrations but lacks required sections:\n" >&2
|
|
52
|
+
for s in "${MISSING[@]}"; do printf " - %s\n" "$s" >&2; done
|
|
53
|
+
printf "\nSee void-migrations skill for the template.\n" >&2
|
|
54
|
+
exit 2
|
|
55
|
+
fi
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce design-slop
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce no-any
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce no-as-cast
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce no-console
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce no-null
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce no-focused-test
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Non-blocking adapter for PostToolUse and Stop canonical events.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
6
|
+
RUNNER="${BASH_SOURCE[0]%/*}/_void-hook.mjs"
|
|
7
|
+
|
|
8
|
+
if command -v node >/dev/null 2>&1 && [[ -f "$RUNNER" ]]; then
|
|
9
|
+
VOID_PROJECT_ROOT="$ROOT" \
|
|
10
|
+
node "$RUNNER" outcome "${VOID_AGENT_RUNTIME:-unknown}" 2>/dev/null || true
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
exit 0
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pre-PR-review-evidence — pre-push hook
|
|
3
|
+
#
|
|
4
|
+
# Warns (does NOT block) if the PR body lacks a Review Evidence block, in
|
|
5
|
+
# strict mode. Reads the PR body via `gh pr view --json body` for the
|
|
6
|
+
# current branch.
|
|
7
|
+
#
|
|
8
|
+
# Composed with the `code-review` skill.
|
|
9
|
+
#
|
|
10
|
+
# Strict mode trigger: pushing to a branch tracked as `main` / `develop` /
|
|
11
|
+
# `release/*`, OR `.void/config.json` modes.codeReview = strict.
|
|
12
|
+
#
|
|
13
|
+
# Exit codes: 0 allow, 2 warn.
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
18
|
+
MODE=$(jq -r '.modes.codeReview // "auto"' "$CONFIG" 2>/dev/null || echo "auto")
|
|
19
|
+
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
|
|
20
|
+
|
|
21
|
+
# Only warn in strict (auto mode warns only on protected base branches)
|
|
22
|
+
case "$MODE" in
|
|
23
|
+
strict) ;;
|
|
24
|
+
auto)
|
|
25
|
+
BASE=$(gh pr view --json baseRefName --jq .baseRefName 2>/dev/null || echo "")
|
|
26
|
+
case "$BASE" in main|develop|release/*) ;; *) exit 0 ;; esac
|
|
27
|
+
;;
|
|
28
|
+
*) exit 0 ;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
# Need an open PR to inspect
|
|
32
|
+
BODY=$(gh pr view --json body --jq .body 2>/dev/null || true)
|
|
33
|
+
if [[ -z "$BODY" ]]; then
|
|
34
|
+
printf "pre-PR-review-evidence: no open PR for branch '%s', skipping.\n" "$BRANCH" >&2
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if ! printf "%s" "$BODY" | grep -qiE '##\s*Review\s*Evidence'; then
|
|
39
|
+
cat >&2 <<EOF
|
|
40
|
+
pre-PR-review-evidence (warn): PR body lacks a '## Review Evidence' block.
|
|
41
|
+
|
|
42
|
+
In strict mode, the PR body must include the review evidence (dimensions
|
|
43
|
+
covered, blockers, nits, composed agents). See the 'void-code-review' skill for
|
|
44
|
+
the template.
|
|
45
|
+
EOF
|
|
46
|
+
exit 2
|
|
47
|
+
fi
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility adapter; native manifests invoke the same Node bundle directly.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
HOOK_DIR="${BASH_SOURCE[0]%/*}"
|
|
5
|
+
NODE_BIN=$(command -v node 2>/dev/null || true)
|
|
6
|
+
if [[ -z "$NODE_BIN" ]]; then
|
|
7
|
+
printf 'HOOK_RUNNER_FAILED: Node.js is required for enforcement\n' >&2
|
|
8
|
+
exit 2
|
|
9
|
+
fi
|
|
10
|
+
exec "$NODE_BIN" "$HOOK_DIR/_void-hook.mjs" enforce protected-file
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# refactor-named-grep — commit-msg hook
|
|
3
|
+
#
|
|
4
|
+
# Warns (does NOT block) on `refactor:` commit subjects that do not name a
|
|
5
|
+
# recognized Fowler refactor from the allowlist (../fowler-refactors.txt).
|
|
6
|
+
# Encourages clear vocabulary in git log.
|
|
7
|
+
#
|
|
8
|
+
# Composed with the `refactor` skill.
|
|
9
|
+
#
|
|
10
|
+
# Inputs: $1 = path to the commit message file.
|
|
11
|
+
# Exit codes: 0 allow, 2 warn.
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
MSG_FILE="${1:-}"
|
|
16
|
+
[[ -z "$MSG_FILE" || ! -f "$MSG_FILE" ]] && exit 0
|
|
17
|
+
|
|
18
|
+
SUBJECT=$(head -1 "$MSG_FILE")
|
|
19
|
+
echo "$SUBJECT" | grep -qE '^refactor[(:]' || exit 0
|
|
20
|
+
|
|
21
|
+
# Locate the allowlist
|
|
22
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
ALLOWLIST="$HOOK_DIR/fowler-refactors.txt"
|
|
24
|
+
[[ ! -f "$ALLOWLIST" ]] && exit 0 # no allowlist available, skip silently
|
|
25
|
+
|
|
26
|
+
# Lowercase the subject for matching
|
|
27
|
+
SUBJECT_LOWER=$(printf "%s" "$SUBJECT" | tr '[:upper:]' '[:lower:]')
|
|
28
|
+
|
|
29
|
+
MATCHED=0
|
|
30
|
+
while IFS= read -r NAME; do
|
|
31
|
+
[[ -z "$NAME" || "$NAME" =~ ^# ]] && continue
|
|
32
|
+
NAME_LOWER=$(printf "%s" "$NAME" | tr '[:upper:]' '[:lower:]')
|
|
33
|
+
if printf "%s" "$SUBJECT_LOWER" | grep -qF "$NAME_LOWER"; then
|
|
34
|
+
MATCHED=1
|
|
35
|
+
break
|
|
36
|
+
fi
|
|
37
|
+
done < "$ALLOWLIST"
|
|
38
|
+
|
|
39
|
+
if [[ "$MATCHED" -eq 0 ]]; then
|
|
40
|
+
cat >&2 <<EOF
|
|
41
|
+
refactor-named-grep (warn): 'refactor:' subject does not name a recognized Fowler refactor.
|
|
42
|
+
|
|
43
|
+
Examples: "refactor: extract validateEmail helper", "refactor: rename userQty to userCount",
|
|
44
|
+
"refactor: replace magic number 0.21 with TAX_RATE".
|
|
45
|
+
|
|
46
|
+
See ${ALLOWLIST} for the allowed names.
|
|
47
|
+
EOF
|
|
48
|
+
exit 2
|
|
49
|
+
fi
|