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,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 secret-content
|
|
@@ -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 context-continuity "${VOID_AGENT_RUNTIME:-unknown}"
|
|
@@ -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 typecheck "${VOID_AGENT_RUNTIME:-unknown}"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# `tdd-guard` hook
|
|
2
|
+
|
|
3
|
+
PreToolUse hook on `Edit` / `Write`. Materializes the `void-tdd` skill's Iron Law mechanically: blocks edits to production paths that add behavior without a corresponding test change in the same staged change set, unless a legitimate bypass applies.
|
|
4
|
+
|
|
5
|
+
In `strict` mode: blocks (exit 1).
|
|
6
|
+
In `souple` mode: warns (exit 2).
|
|
7
|
+
In `exploratory` mode: no-op (exit 0).
|
|
8
|
+
|
|
9
|
+
See `docs/plans/skill-audits/void-tdd.md` for the Iron Law and the bypass rationale. See Section 0bis.3 of `docs/plans/2026-05-29-void-harness-design.md` for the list of legitimate bypasses.
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Read from `.void/config.json` of the consumer project:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"modes": { "tdd": "auto" },
|
|
18
|
+
"paths": {
|
|
19
|
+
"business": "apps/*/src/**",
|
|
20
|
+
"tests": "apps/*/src/**/*.test.{ts,tsx}",
|
|
21
|
+
"spikes": "apps/*/scripts/spike-*"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If `.void/config.json` is absent, sensible defaults are used (see hook source).
|
|
27
|
+
|
|
28
|
+
## Bypasses applied (in order)
|
|
29
|
+
|
|
30
|
+
1. Doc-only changes (`.md`, `.mdx`, `.txt`, files under `docs/`)
|
|
31
|
+
2. Config and build files (`package.json`, `tsconfig.json`, `vitest.config.*`, `next.config.*`, `tailwind.config.*`, `drizzle.config.*`, `biome.json`, `eslint.config.*`)
|
|
32
|
+
3. Test fixtures and seed data (`tests/fixtures/**`, `**/__tests__/fixtures/**`, `**/seed/**`)
|
|
33
|
+
4. DB migrations (`**/migrations/**`, `drizzle/meta/**`) — covered by `void-migrations` skill
|
|
34
|
+
5. Spike paths (consumer-defined; default `apps/*/scripts/spike-*`)
|
|
35
|
+
6. Codemods (`**/codemods/**`)
|
|
36
|
+
7. Type-only changes (`*.d.ts`)
|
|
37
|
+
8. Generated code (`**/__generated__/**` or `@generated` marker in the first 3 lines)
|
|
38
|
+
9. The test file itself (`*.test.ts`, `*.test.tsx`, `*.spec.ts`, `*.spec.tsx`)
|
|
39
|
+
10. Per-file exploratory marker (`// tdd-mode: exploratory` in the first 5 lines)
|
|
40
|
+
|
|
41
|
+
## Content bypass: a module that only re-exports
|
|
42
|
+
|
|
43
|
+
The ten bypasses above are properties of the **path**. One is a property of the **content**: a module whose every top-level statement is a re-export (`export … from`, `export *`, `export {}`) carries no behaviour, so the test one would write for it would assert that an export exists, which the compiler already proves. A comment, a `'use client'` directive and a type-only import do not break the detection; anything else does.
|
|
44
|
+
|
|
45
|
+
Both the file as it stands and the fragment being written must hold, so a barrel that gains one line of logic is covered again on that same edit. Malformed content (an unterminated string or block comment) is undecidable and stays covered.
|
|
46
|
+
|
|
47
|
+
Without it the hook blocked a one-line barrel in a consumer where 51 barrels out of 51 have no sibling test by convention, and the edit went out through `sed`, outside the traced tools: the guard did not protect, and it pushed the work out of its own field of vision.
|
|
48
|
+
|
|
49
|
+
## Pure-deletion bypass
|
|
50
|
+
|
|
51
|
+
If the staged diff for the file contains only deletions (no `+` non-marker lines), the hook allows. Pure deletion does not require a new failing test.
|
|
52
|
+
|
|
53
|
+
## Override
|
|
54
|
+
|
|
55
|
+
- Per-file: add `// tdd-mode: exploratory` (or `strict` / `souple`) at the top of the file.
|
|
56
|
+
- Per-repo: set `.void/config.json` `modes.tdd` to `strict` / `souple` / `exploratory`.
|
|
57
|
+
- Per-session: set env `VOIDCORP_MODE_TDD=souple` (not yet wired — open question).
|
|
58
|
+
|
|
59
|
+
## Inputs (env vars set by the runner)
|
|
60
|
+
|
|
61
|
+
- `VOIDCORP_HOOK_FILE` — absolute path of the file
|
|
62
|
+
- `VOIDCORP_HOOK_TOOL` — `Edit` / `Write`
|
|
63
|
+
- `VOIDCORP_HOOK_PHASE` — `pre` / `post` (this hook only runs on `pre`)
|
|
64
|
+
- `VOIDCORP_HOOK_DIFF` — optional, the staged diff content
|
|
65
|
+
- `VOIDCORP_CONFIG` — optional, defaults to `.void/config.json`
|
|
66
|
+
|
|
67
|
+
## Exit codes
|
|
68
|
+
|
|
69
|
+
- `0` — allow
|
|
70
|
+
- `1` — block (message on stderr)
|
|
71
|
+
- `2` — warn (allow, message on stderr)
|
|
72
|
+
|
|
73
|
+
## Test fixtures (for `test/tdd-guard/`)
|
|
74
|
+
|
|
75
|
+
The skill test suite must cover at least:
|
|
76
|
+
|
|
77
|
+
- `strict` mode + production edit without sibling test → block
|
|
78
|
+
- `strict` mode + production edit WITH sibling test in same staged set → allow
|
|
79
|
+
- `souple` mode + production edit without sibling test → warn
|
|
80
|
+
- `exploratory` mode + any edit → allow
|
|
81
|
+
- Each of the 10 bypasses → allow
|
|
82
|
+
- Pure deletion → allow
|
|
83
|
+
- Override marker `// tdd-mode: exploratory` in file → allow
|
|
84
|
+
|
|
85
|
+
## Open questions
|
|
86
|
+
|
|
87
|
+
- Per-session env override (`VOIDCORP_MODE_TDD`) — wire it up in the hook or rely on `.void/config.json` only? Lean wire (faster iteration during work).
|
|
88
|
+
- Glob matching for `paths.business` — current `case` statement is shell glob, fine for simple patterns but not full minimatch. Defer until a consumer needs `**` patterns more complex than `apps/*/src/**`.
|
|
89
|
+
- Auto-detection of the test runner (vitest vs jest) for the sibling-test naming convention. Currently assumes `.test.ts(x)`. Make configurable in Phase D.
|
|
90
|
+
- Performance — `git diff --cached --name-only` runs every edit. Cache for the duration of a session? Defer; measure first.
|
|
@@ -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 tdd-order
|
|
@@ -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 test-name
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tidying-commit-prefix — commit-msg hook
|
|
3
|
+
#
|
|
4
|
+
# Warns (does NOT block) when a `refactor:` commit subject is paired with
|
|
5
|
+
# behavior-change keywords in the body (feat, fix, implement, add). The
|
|
6
|
+
# Two-Hat principle says: Tidyings and Behavior Changes never share a commit.
|
|
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
|
+
BODY=$(tail -n +2 "$MSG_FILE")
|
|
20
|
+
|
|
21
|
+
# Only check refactor: commits
|
|
22
|
+
echo "$SUBJECT" | grep -qE '^refactor[(:]' || exit 0
|
|
23
|
+
|
|
24
|
+
# Look for behavior-change keywords in body
|
|
25
|
+
if printf "%s" "$BODY" | grep -qiE '\b(feat|feature|fix|bug|implement|add a new|adds a new)\b'; then
|
|
26
|
+
cat >&2 <<EOF
|
|
27
|
+
tidying-commit-prefix (warn): 'refactor:' subject paired with behavior-change keywords in body.
|
|
28
|
+
|
|
29
|
+
The Two-Hat principle (Beck "Tidy First?" 2023) says Tidyings and Behavior Changes
|
|
30
|
+
never share a commit. If this commit does both, split it:
|
|
31
|
+
refactor: <named Fowler move>
|
|
32
|
+
feat: <new behavior>
|
|
33
|
+
|
|
34
|
+
If the body is descriptive of the structural change only, ignore this warning.
|
|
35
|
+
EOF
|
|
36
|
+
exit 2
|
|
37
|
+
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 trim "${VOID_AGENT_RUNTIME:-unknown}"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tsc-noemit-precommit — pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Runs `tsc --noEmit` (or pack-configured equivalent) and blocks the commit on
|
|
5
|
+
# any type error. Composed with the `typescript-strict` skill.
|
|
6
|
+
#
|
|
7
|
+
# Reads command from .void/config.json -> commands.typecheck, defaults to
|
|
8
|
+
# the local tsconfig via npx tsc --noEmit.
|
|
9
|
+
#
|
|
10
|
+
# Exit codes: 0 allow, 1 block (type errors printed).
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
15
|
+
CMD=$(jq -r '.commands.typecheck // empty' "$CONFIG" 2>/dev/null || true)
|
|
16
|
+
[[ -z "$CMD" ]] && CMD="npx tsc --noEmit"
|
|
17
|
+
|
|
18
|
+
if ! eval "$CMD" 2>&1; then
|
|
19
|
+
printf "\ntsc-noemit-precommit: type errors detected. Commit blocked.\n" >&2
|
|
20
|
+
printf "Fix the type errors above, or run '%s' manually to iterate.\n" "$CMD" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ubiquitous-language-lint — informational pre-commit hook
|
|
3
|
+
#
|
|
4
|
+
# Composed with the `domain-driven-design` skill. Maintains a per-context
|
|
5
|
+
# glossary at docs/DOMAIN.md (or per-context docs/<context>/DOMAIN.md).
|
|
6
|
+
# Flags drift between code identifiers and glossary terms.
|
|
7
|
+
#
|
|
8
|
+
# This hook is INFORMATIONAL. It never blocks. The user decides whether
|
|
9
|
+
# to update the glossary or rename the code.
|
|
10
|
+
#
|
|
11
|
+
# Output: a summary report of terms present in code but missing from
|
|
12
|
+
# DOMAIN.md, and vice versa.
|
|
13
|
+
#
|
|
14
|
+
# Exit codes: always 0 (informational only).
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
GLOSSARY_PATHS=()
|
|
19
|
+
[[ -f docs/DOMAIN.md ]] && GLOSSARY_PATHS+=(docs/DOMAIN.md)
|
|
20
|
+
while IFS= read -r f; do
|
|
21
|
+
[[ -n "$f" ]] && GLOSSARY_PATHS+=("$f")
|
|
22
|
+
done < <(find docs -path 'docs/*/DOMAIN.md' -type f 2>/dev/null || true)
|
|
23
|
+
|
|
24
|
+
[[ ${#GLOSSARY_PATHS[@]} -eq 0 ]] && exit 0 # no glossary, skip silently
|
|
25
|
+
|
|
26
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(ts|tsx)$' || true)
|
|
27
|
+
[[ -z "$STAGED" ]] && exit 0
|
|
28
|
+
|
|
29
|
+
# Extract glossary terms (lines starting with `- ` or `## ` followed by a noun)
|
|
30
|
+
GLOSSARY_TERMS=$(cat "${GLOSSARY_PATHS[@]}" 2>/dev/null \
|
|
31
|
+
| grep -oE '^(- |## )[A-Z][A-Za-z]+' \
|
|
32
|
+
| sed -E 's/^(- |## )//' \
|
|
33
|
+
| sort -u || true)
|
|
34
|
+
|
|
35
|
+
# Extract identifier terms from staged TS files
|
|
36
|
+
CODE_TERMS=""
|
|
37
|
+
for FILE in $STAGED; do
|
|
38
|
+
CODE_TERMS+=$'\n'$(git show ":$FILE" 2>/dev/null \
|
|
39
|
+
| grep -oE '\b[A-Z][A-Za-z]{3,}\b' \
|
|
40
|
+
| sort -u || true)
|
|
41
|
+
done
|
|
42
|
+
CODE_TERMS=$(printf "%s" "$CODE_TERMS" | sort -u)
|
|
43
|
+
|
|
44
|
+
# Set diff: terms in glossary but not in code, and vice versa
|
|
45
|
+
MISSING_IN_CODE=$(comm -23 <(printf "%s\n" "$GLOSSARY_TERMS") <(printf "%s\n" "$CODE_TERMS"))
|
|
46
|
+
MISSING_IN_GLOSSARY=$(comm -13 <(printf "%s\n" "$GLOSSARY_TERMS") <(printf "%s\n" "$CODE_TERMS") | head -20)
|
|
47
|
+
|
|
48
|
+
if [[ -n "$MISSING_IN_CODE" || -n "$MISSING_IN_GLOSSARY" ]]; then
|
|
49
|
+
printf "ubiquitous-language-lint (informational):\n" >&2
|
|
50
|
+
[[ -n "$MISSING_IN_GLOSSARY" ]] && {
|
|
51
|
+
printf " Code identifiers not in DOMAIN.md (top 20):\n%s\n" "$MISSING_IN_GLOSSARY" >&2
|
|
52
|
+
}
|
|
53
|
+
[[ -n "$MISSING_IN_CODE" ]] && {
|
|
54
|
+
printf " DOMAIN.md terms not used in code:\n%s\n" "$MISSING_IN_CODE" >&2
|
|
55
|
+
}
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
exit 0
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# viewport-screenshot-gate — pre-push hook
|
|
3
|
+
#
|
|
4
|
+
# Warns if a PR touching UI code lacks both mobile and desktop screenshots
|
|
5
|
+
# in the PR body. Composed with the `accessibility` and
|
|
6
|
+
# `frontend-design` skills (mobile-first dual-quality invariant).
|
|
7
|
+
#
|
|
8
|
+
# UI paths: read from .void/config.json .paths.ui, default to
|
|
9
|
+
# **/{components,app,pages}/** and **/*.{tsx,jsx}
|
|
10
|
+
#
|
|
11
|
+
# Heuristic: PR body must reference both "mobile" and "desktop" markdown
|
|
12
|
+
# images (e.g.  and ) or be tagged with
|
|
13
|
+
# "no-ui-change: <reason>" in the body for non-UI PRs that happen to
|
|
14
|
+
# touch tsx files.
|
|
15
|
+
#
|
|
16
|
+
# Exit codes: 0 allow, 2 warn.
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
CONFIG="${VOIDCORP_CONFIG:-.void/config.json}"
|
|
21
|
+
|
|
22
|
+
BASE=$(gh pr view --json baseRefName --jq .baseRefName 2>/dev/null || echo "")
|
|
23
|
+
[[ -z "$BASE" ]] && exit 0
|
|
24
|
+
|
|
25
|
+
BASE_SHA=$(git merge-base "HEAD" "origin/$BASE" 2>/dev/null || echo "")
|
|
26
|
+
[[ -z "$BASE_SHA" ]] && exit 0
|
|
27
|
+
|
|
28
|
+
TOUCHED_UI=$(git diff --name-only "$BASE_SHA"..HEAD | grep -E '\.(tsx|jsx)$' | grep -vE '/__tests__/|\.(test|spec)\.' || true)
|
|
29
|
+
[[ -z "$TOUCHED_UI" ]] && exit 0
|
|
30
|
+
|
|
31
|
+
BODY=$(gh pr view --json body --jq .body 2>/dev/null || echo "")
|
|
32
|
+
[[ -z "$BODY" ]] && { printf "viewport-screenshot-gate: no open PR found, skipping.\n" >&2; exit 0; }
|
|
33
|
+
|
|
34
|
+
# Bypass marker for non-UI changes that happen to touch tsx files
|
|
35
|
+
if printf "%s" "$BODY" | grep -qiE 'no-ui-change:'; then
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
HAS_MOBILE=$(printf "%s" "$BODY" | grep -qiE '!\[[^]]*mobile[^]]*\]|mobile[[:space:]]*screenshot|mobile[[:space:]]*viewport' && echo "1" || echo "0")
|
|
40
|
+
HAS_DESKTOP=$(printf "%s" "$BODY" | grep -qiE '!\[[^]]*desktop[^]]*\]|desktop[[:space:]]*screenshot|desktop[[:space:]]*viewport' && echo "1" || echo "0")
|
|
41
|
+
|
|
42
|
+
if [[ "$HAS_MOBILE" == "0" || "$HAS_DESKTOP" == "0" ]]; then
|
|
43
|
+
printf "viewport-screenshot-gate (warn): PR touches UI but lacks both mobile and desktop screenshots.\n" >&2
|
|
44
|
+
printf " has_mobile=%s has_desktop=%s\n" "$HAS_MOBILE" "$HAS_DESKTOP" >&2
|
|
45
|
+
printf "\nAdd both viewports to the PR body. Mobile starts at 360–390px (iPhone 12 mini–15 Pro).\n" >&2
|
|
46
|
+
printf "If this PR has no UI change despite touching tsx, add 'no-ui-change: <reason>' to the body.\n" >&2
|
|
47
|
+
exit 2
|
|
48
|
+
fi
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Sources for `void-eas-build-profile` skill (see `docs/plans/skill-audits/void-eas-build-profile.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- Expo / EAS Build official documentation — no URL recorded in the audit — distilled the documented 3-profile eas.json convention (development/preview/production) and the per-option motivation that the docs scatter; added the void-machine defaults (APP_VARIANT side-by-side installs, secrets via `eas secret`, autoIncrement).
|
|
4
|
+
|
|
5
|
+
No external skill ships this verbatim; authored by distilling the official EAS Build docs into the void-machine eas.json convention.
|
|
6
|
+
|
|
7
|
+
Strategy: distill. Extract the load-bearing why behind each profile option and ship the void-machine 3-profile template, rather than copy a stale scaffold.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-eas-build-profile
|
|
3
|
+
description: Configure eas.json profiles (development, preview, production) with the right env, bundle ID, signing, distribution. The 3-profile structure that fits 95% of Expo apps.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# eas-build-profile
|
|
7
|
+
|
|
8
|
+
Use when configuring EAS Build for an Expo app. The default `eas.json` Expo scaffolds is fine to start; this skill ships the void-machine convention for the 3 standard profiles + the why behind each option.
|
|
9
|
+
|
|
10
|
+
## The 3-profile structure
|
|
11
|
+
|
|
12
|
+
```jsonc
|
|
13
|
+
{
|
|
14
|
+
"cli": { "version": ">= 12.0.0" },
|
|
15
|
+
"build": {
|
|
16
|
+
"development": {
|
|
17
|
+
"developmentClient": true,
|
|
18
|
+
"distribution": "internal",
|
|
19
|
+
"ios": { "simulator": true },
|
|
20
|
+
"android": { "buildType": "apk" },
|
|
21
|
+
"env": { "APP_VARIANT": "dev" }
|
|
22
|
+
},
|
|
23
|
+
"preview": {
|
|
24
|
+
"distribution": "internal",
|
|
25
|
+
"ios": { "simulator": false },
|
|
26
|
+
"android": { "buildType": "apk" },
|
|
27
|
+
"env": { "APP_VARIANT": "preview" }
|
|
28
|
+
},
|
|
29
|
+
"production": {
|
|
30
|
+
"distribution": "store",
|
|
31
|
+
"autoIncrement": true,
|
|
32
|
+
"env": { "APP_VARIANT": "prod" }
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"submit": {
|
|
36
|
+
"production": {
|
|
37
|
+
"ios": { "appleId": "team@voidcorp.io", "ascAppId": "1234567890", "appleTeamId": "ABCD1234" },
|
|
38
|
+
"android": { "serviceAccountKeyPath": "./google-play.json", "track": "internal" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Each profile, in plain words
|
|
45
|
+
|
|
46
|
+
### `development`
|
|
47
|
+
|
|
48
|
+
- **Use case**: dev on simulator + device with hot reload, Metro bundler attached
|
|
49
|
+
- **`developmentClient: true`** → builds a dev client (custom Expo Go) embedding your native deps. Without it, `expo-router` and custom modules don't work in Expo Go.
|
|
50
|
+
- **`distribution: "internal"`** → not for App Store; for your team
|
|
51
|
+
- **`ios.simulator: true`** → produces a `.app` runnable in iOS Simulator; runs `xcodebuild -sdk iphonesimulator`
|
|
52
|
+
- **`android.buildType: "apk"`** → APK (not AAB); apk is easier to install ad-hoc
|
|
53
|
+
|
|
54
|
+
Builds with `eas build -p ios --profile development` then `eas build:run -p ios` to install.
|
|
55
|
+
|
|
56
|
+
### `preview`
|
|
57
|
+
|
|
58
|
+
- **Use case**: TestFlight equivalents, stakeholder testing, QA
|
|
59
|
+
- **`distribution: "internal"`** → shareable link from EAS dashboard; no store submission
|
|
60
|
+
- **`ios.simulator: false`** → real device build
|
|
61
|
+
- **`android.buildType: "apk"`** → APK still (easier for stakeholders)
|
|
62
|
+
- Identical to production except distribution channel and variant env
|
|
63
|
+
|
|
64
|
+
### `production`
|
|
65
|
+
|
|
66
|
+
- **Use case**: App Store / Play Store submission
|
|
67
|
+
- **`distribution: "store"`** → signed for store distribution
|
|
68
|
+
- **`autoIncrement: true`** → bumps `buildNumber` (iOS) and `versionCode` (Android) per build; required by stores
|
|
69
|
+
- **Default `android.buildType: "aab"`** (App Bundle) — required by Play Store
|
|
70
|
+
|
|
71
|
+
## Env per profile
|
|
72
|
+
|
|
73
|
+
The `env` block in each profile sets vars **at build time** (baked into the JS bundle for `EXPO_PUBLIC_*`, available via `process.env.X` in `app.config.ts`).
|
|
74
|
+
|
|
75
|
+
Pattern: `APP_VARIANT` env switches the bundle ID, name, and API URL via `app.config.ts`:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// app.config.ts
|
|
79
|
+
const variant = process.env.APP_VARIANT ?? 'dev';
|
|
80
|
+
const apiUrls = {
|
|
81
|
+
dev: 'https://api-dev.voidcorp.io',
|
|
82
|
+
preview: 'https://api-preview.voidcorp.io',
|
|
83
|
+
prod: 'https://api.voidcorp.io',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default ({ config }) => ({
|
|
87
|
+
...config,
|
|
88
|
+
name: variant === 'prod' ? 'Solaar' : `Solaar ${variant}`,
|
|
89
|
+
ios: { bundleIdentifier: `io.voidcorp.solaar.${variant}` },
|
|
90
|
+
android: { package: `io.voidcorp.solaar.${variant}` },
|
|
91
|
+
extra: { apiUrl: apiUrls[variant] },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This pattern installs all 3 variants on one device — useful for QA comparing prod-vs-preview behavior.
|
|
96
|
+
|
|
97
|
+
## Secrets — never in eas.json
|
|
98
|
+
|
|
99
|
+
The `env` block in `eas.json` ships in the bundle. **NEVER** put secrets there. For server-side secrets needed during build (e.g., to pull private deps):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
eas secret:create --scope project --name NPM_TOKEN --value "..."
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
EAS injects secrets into the build environment; they don't end up in the JS bundle.
|
|
106
|
+
|
|
107
|
+
## Signing and credentials
|
|
108
|
+
|
|
109
|
+
Run once per profile:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
eas credentials
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Walks you through: iOS Distribution Certificate, Provisioning Profile, Push Notification Key, Android Keystore. Expo stores them encrypted on their servers.
|
|
116
|
+
|
|
117
|
+
For team setups: `eas credentials:configure` syncs across team members so anyone can build.
|
|
118
|
+
|
|
119
|
+
## `submit` config — for one-command store submission
|
|
120
|
+
|
|
121
|
+
After a production build, submit with:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
eas submit -p ios --latest
|
|
125
|
+
eas submit -p android --latest
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`submit` config in `eas.json` saves you from re-entering app store credentials each time. iOS requires Apple Team ID + ASC App ID; Android requires a service account JSON from Google Cloud (delegated rights for Play Store API).
|
|
129
|
+
|
|
130
|
+
## Channel-based OTA (`expo-updates`)
|
|
131
|
+
|
|
132
|
+
EAS Build embeds an `updates.channel` per build profile:
|
|
133
|
+
|
|
134
|
+
```jsonc
|
|
135
|
+
"production": {
|
|
136
|
+
"channel": "production",
|
|
137
|
+
// ...
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`expo-updates` then fetches OTA updates from the matching channel. See `void-ota-update-strategy` for the full pattern.
|
|
142
|
+
|
|
143
|
+
## Anti-patterns
|
|
144
|
+
|
|
145
|
+
- ✗ **Same bundle ID across variants** — can't install dev + prod on same device
|
|
146
|
+
- ✗ **Same signing config across variants** — staging users get prod data leaks
|
|
147
|
+
- ✗ **`env` for secrets** — leaks into bundle
|
|
148
|
+
- ✗ **Manual version bumping** — `autoIncrement` exists for a reason
|
|
149
|
+
- ✗ **5+ profiles** — usually means you haven't clarified variant strategy. 3 is enough.
|
|
150
|
+
|
|
151
|
+
## Verification
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
eas build --profile preview --platform ios --local # local build (no EAS minutes spent)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If local build succeeds, EAS will too. If it fails, the error is identical — debug locally before pushing to EAS.
|
|
158
|
+
|
|
159
|
+
## Composition
|
|
160
|
+
|
|
161
|
+
- `void-expo-config-plugins` — plugins define what's IN the binary; profiles define HOW it's built
|
|
162
|
+
- `void-ota-update-strategy` — channel-based OTA aligns with profile names
|
|
163
|
+
- `void-expo-router-pattern` — expo-router needs `developmentClient: true` in dev profile
|
|
164
|
+
- `void-env-validation` — runtime env via `extra` validated with same Zod discipline
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Harness metadata for this skill. Not part of the Agent Skills
|
|
2
|
+
# specification, and never copied into a consumer project: the SKILL.md
|
|
3
|
+
# beside it stays portable and validates against the official six fields.
|
|
4
|
+
# Read by this repository's graph, and by the installer for `runtimes`.
|
|
5
|
+
kind: standard
|
|
6
|
+
owner: folpe
|
|
7
|
+
runtimes: [claude, codex]
|
|
8
|
+
enforcement:
|
|
9
|
+
floor: ci
|
|
10
|
+
inline:
|
|
11
|
+
claude: active
|
|
12
|
+
codex: active
|
|
13
|
+
hermes: ci-only
|
|
14
|
+
eval_targets: [claude/anthropic/opus]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Sources for `void-expo-config-plugins` skill (see `docs/plans/skill-audits/void-expo-config-plugins.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- Expo config plugins / Expo Modules official documentation — no URL recorded in the audit — distilled the "Expo way" (config plugin OR Expo Module covers ~95% of native needs) into a decision tree (Expo module → community plugin → custom config plugin → Expo Module → eject) plus the common-modules table and a concrete custom-plugin example.
|
|
4
|
+
|
|
5
|
+
No external skill ships this verbatim; authored by distilling the official Expo docs into the void-machine "never eject by default" doctrine.
|
|
6
|
+
|
|
7
|
+
Strategy: distill. Frame ejecting as a one-way door and keep projects on Expo tooling via plugins, rather than restating the docs option-by-option.
|