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,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-dependency-direction
|
|
3
|
+
description: Enforce the @repo/* import direction in a Turborepo workspace. Concrete violations + fixes. Composes with core:hexagonal-architecture and the boundary-direction-check hook.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dependency-direction
|
|
7
|
+
|
|
8
|
+
Use when adding an `import` statement that crosses a package boundary, or when fixing a `boundary-direction-check` hook violation. This skill is the **operational guide** for the rules core `void-hexagonal-architecture` and `boundary-direction-check` enforce mechanically.
|
|
9
|
+
|
|
10
|
+
## The rule
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
@repo/core → nothing internal
|
|
14
|
+
@repo/auth → @repo/core
|
|
15
|
+
@repo/db → @repo/core
|
|
16
|
+
@repo/ui → @repo/core
|
|
17
|
+
@repo/<feat> → @repo/core (and only @repo/core)
|
|
18
|
+
apps/<app> → any @repo/*
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**No `@repo/*` package imports another `@repo/*` except `@repo/core`.** All composition happens at the app level. If `@repo/billing` needs the user, it defines a port; the consuming app wires `@repo/auth`'s adapter into that port.
|
|
22
|
+
|
|
23
|
+
This sounds restrictive. It is. It is what keeps the monorepo from collapsing into a hairball.
|
|
24
|
+
|
|
25
|
+
## Why core is the only allowed dependency
|
|
26
|
+
|
|
27
|
+
`@repo/core` ships **primitives** with no internal deps:
|
|
28
|
+
|
|
29
|
+
- `logger` (pino)
|
|
30
|
+
- `env` (Zod-validated env)
|
|
31
|
+
- `errors` (typed error classes)
|
|
32
|
+
- `Result`, `Option`, `pipe` (functional utilities)
|
|
33
|
+
|
|
34
|
+
These are leaf utilities. Everything else is composition.
|
|
35
|
+
|
|
36
|
+
## Common violation: `@repo/billing` wants the user
|
|
37
|
+
|
|
38
|
+
**Wrong**:
|
|
39
|
+
```ts
|
|
40
|
+
// packages/billing/src/billing.service.ts
|
|
41
|
+
import { db } from '@repo/db'; // ✗
|
|
42
|
+
import { getCurrentUser } from '@repo/auth'; // ✗
|
|
43
|
+
|
|
44
|
+
export async function cancelSubscription() {
|
|
45
|
+
const user = await getCurrentUser();
|
|
46
|
+
await db.update(subscriptions)...
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Right** — define the port in `@repo/billing`, wire the adapter in the app:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// packages/billing/src/billing.types.ts (port)
|
|
54
|
+
export interface BillingPorts {
|
|
55
|
+
readonly userRepo: { findById(id: string): Promise<User | null> };
|
|
56
|
+
readonly subscriptionRepo: { update(id: string, p: Partial<Sub>): Promise<void> };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// packages/billing/src/billing.service.ts (pure)
|
|
60
|
+
export function makeBillingService(ports: BillingPorts) {
|
|
61
|
+
return {
|
|
62
|
+
async cancelSubscription(userId: string) {
|
|
63
|
+
const user = await ports.userRepo.findById(userId);
|
|
64
|
+
// ... domain logic only
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// apps/web/src/adapters/billing.ts (composition)
|
|
70
|
+
import { makeBillingService } from '@repo/billing';
|
|
71
|
+
import { db } from '@repo/db';
|
|
72
|
+
import { userRepo, subRepo } from '@/repositories';
|
|
73
|
+
export const billing = makeBillingService({ userRepo, subscriptionRepo: subRepo });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The app is the integration point. Packages are pure capabilities.
|
|
77
|
+
|
|
78
|
+
## Common violation: types from another package
|
|
79
|
+
|
|
80
|
+
**Wrong**:
|
|
81
|
+
```ts
|
|
82
|
+
// packages/billing/src/billing.types.ts
|
|
83
|
+
import type { User } from '@repo/auth'; // ✗ types still create coupling
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Right** — declare your own User type narrowed to what billing needs:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// packages/billing/src/billing.types.ts
|
|
90
|
+
export interface BillingUser {
|
|
91
|
+
readonly id: string;
|
|
92
|
+
readonly email: string;
|
|
93
|
+
readonly orgId: string;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If `@repo/auth`'s `User` and `@repo/billing`'s `BillingUser` should be the same shape, factor the shape into `@repo/core/types`. But almost always, each package wants a narrower projection — that's good.
|
|
98
|
+
|
|
99
|
+
## Common violation: `@repo/ui` calls a service
|
|
100
|
+
|
|
101
|
+
**Wrong**:
|
|
102
|
+
```tsx
|
|
103
|
+
// packages/ui/src/UserAvatar.tsx
|
|
104
|
+
import { getCurrentUser } from '@repo/auth'; // ✗
|
|
105
|
+
export function UserAvatar() {
|
|
106
|
+
const user = use(getCurrentUser()); // ✗ side effect in UI
|
|
107
|
+
return <Avatar src={user.avatarUrl} />;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Right**:
|
|
112
|
+
```tsx
|
|
113
|
+
// packages/ui/src/Avatar.tsx (dumb prop-driven)
|
|
114
|
+
export function Avatar({ src, fallback }: { src: string; fallback: string }) {
|
|
115
|
+
return <img src={src} alt={fallback} />;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// apps/web/src/components/CurrentUserAvatar.tsx (binding, NOT in @repo/ui)
|
|
119
|
+
import { Avatar } from '@repo/ui';
|
|
120
|
+
import { useCurrentUser } from '@/hooks';
|
|
121
|
+
export function CurrentUserAvatar() {
|
|
122
|
+
const user = useCurrentUser();
|
|
123
|
+
return <Avatar src={user.avatarUrl} fallback={user.name} />;
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`@repo/ui` exports primitives with no I/O. Bindings to actual data live in apps.
|
|
128
|
+
|
|
129
|
+
## The `apps/<app>` → `apps/<other-app>` rule
|
|
130
|
+
|
|
131
|
+
**Never** import from another app:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// apps/web/src/foo.ts
|
|
135
|
+
import { whatever } from '../../mobile/src/...'; // ✗ — even via @repo/* alias if you set it up
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
If two apps need the same code, that code goes in a `@repo/*` package. There is no "shared/" directory between apps.
|
|
139
|
+
|
|
140
|
+
## When you genuinely need cross-package access
|
|
141
|
+
|
|
142
|
+
You don't. Re-read the section on ports. If after that you still think you do, write an ADR (`void-decide`) documenting the exception with the reversal cost. 90% of "I need this" turns out to be "I forgot to define the port".
|
|
143
|
+
|
|
144
|
+
## Mechanical enforcement
|
|
145
|
+
|
|
146
|
+
The `boundary-direction-check` hook (core) blocks Edit/Write that introduces a forbidden import. Override by tagging the import line `// allow-boundary: <reason>` — but think hard first, because each exception is a small future grind.
|
|
147
|
+
|
|
148
|
+
## Workflow
|
|
149
|
+
|
|
150
|
+
1. **Before adding the import**, ask: does this cross a `@repo/*` boundary?
|
|
151
|
+
2. **If yes**, ask: is the destination `@repo/core`? OK. Anything else? Stop.
|
|
152
|
+
3. **Define a port** in your package, wire the adapter in the app.
|
|
153
|
+
4. **If the hook complains**, do not tag-and-move-on. Refactor.
|
|
154
|
+
|
|
155
|
+
## Composition
|
|
156
|
+
|
|
157
|
+
- `void-hexagonal-architecture` — doctrine on ports + adapters direction (core).
|
|
158
|
+
- `boundary-direction-check` hook (core) — mechanical gate.
|
|
159
|
+
- `void-package-extraction` — most boundary problems come from premature extraction.
|
|
160
|
+
- `void-service-package` — the 5+5 layout includes a `<name>.types.ts` precisely for owning your own types.
|
|
@@ -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,5 @@
|
|
|
1
|
+
Sources for `void-package-extraction` skill (see `docs/plans/skill-audits/void-package-extraction.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- No external source. Native 3-question decision gate for the monorepo-specific "should this be extracted into a package?" trade-off.
|
|
4
|
+
|
|
5
|
+
Strategy: native. The gate is monorepo-specific; single-app code reorganization has no equivalent boundary cost, so nothing external was adapted.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-package-extraction
|
|
3
|
+
description: Decide whether code in apps/<app>/ should be extracted into a new packages/<name>/ workspace. Most extractions are premature; this skill is the decision gate.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# package-extraction
|
|
7
|
+
|
|
8
|
+
Use when you are tempted to move code out of `apps/<app>/src/` into a new `packages/<name>/`. The instinct is good — sharing is virtuous — but **80% of extractions are premature** and end up creating coupling without the reuse benefit.
|
|
9
|
+
|
|
10
|
+
This skill is the gate. Composes with `void-service-package` (which is the creation workflow once you've decided yes).
|
|
11
|
+
|
|
12
|
+
## When this skill triggers
|
|
13
|
+
|
|
14
|
+
- "Let's extract this into a package so both apps can use it"
|
|
15
|
+
- "This helper is generic, it shouldn't live in apps/"
|
|
16
|
+
- "We're duplicating this in apps/web and apps/mobile"
|
|
17
|
+
- Any review comment "extract to packages/"
|
|
18
|
+
|
|
19
|
+
## The 3-question gate
|
|
20
|
+
|
|
21
|
+
Extract if and only if **all three** answers are yes:
|
|
22
|
+
|
|
23
|
+
1. **Are there ≥ 2 distinct consumers RIGHT NOW** (not "maybe later")? Distinct = different `apps/<name>/` packages.
|
|
24
|
+
2. **Would inlining the code in both apps cost > 30 minutes of duplication discipline per change**? If a 5-line helper diverges, the answer is no.
|
|
25
|
+
3. **Does the code own a CONCEPT, not just a function?** "billing engine" yes. "string utilities" no — those are scattered helpers, not a package.
|
|
26
|
+
|
|
27
|
+
If you can't say yes to all three, **inline the code in each app instead**. Duplication is cheaper than the wrong boundary.
|
|
28
|
+
|
|
29
|
+
## When NOT to extract
|
|
30
|
+
|
|
31
|
+
- ✗ Code used in only one app, "in case we need it later" — YAGNI, extract when the second consumer appears
|
|
32
|
+
- ✗ Helpers that wrap a single library function (`isValidEmail(s) { return z.string().email().safeParse(s).success }`) — copy 3 lines, don't add a package
|
|
33
|
+
- ✗ React components used in only one app — they belong in `apps/<app>/src/components/`
|
|
34
|
+
- ✗ Server logic specific to one app's route handlers — even if "feels generic", lives where it's used
|
|
35
|
+
- ✗ Types only — types live next to their use; if shared, in `@repo/api-types` (one package for the contracts, not one per concept)
|
|
36
|
+
|
|
37
|
+
## When YES to extract
|
|
38
|
+
|
|
39
|
+
- ✓ Auth logic consumed by web + mobile + worker
|
|
40
|
+
- ✓ A complete domain service (billing, scheduling, notifications) with own ports + adapters
|
|
41
|
+
- ✓ UI primitives consumed by web + mobile (Tappable, tokens) — that is `@repo/ui`
|
|
42
|
+
- ✓ A data model with its repository, shared by HTTP handlers and a background job
|
|
43
|
+
|
|
44
|
+
## Cost of premature extraction
|
|
45
|
+
|
|
46
|
+
- **Boundary thrashing**: API of the new package changes weekly because nobody knows what it should expose. PRs touching the package + every consumer.
|
|
47
|
+
- **Wrong abstraction**: extracted too early, before the second consumer's needs were clear. The package overfits the first consumer; the second has to fight it.
|
|
48
|
+
- **Import-direction violations**: the package starts importing from where it shouldn't (`@repo/db` from `@repo/billing`) because the boundary wasn't thought through.
|
|
49
|
+
- **Build complexity**: another tsconfig, another package.json, another dist target.
|
|
50
|
+
|
|
51
|
+
The cheap fix is to NOT extract until forced.
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
1. **Inline the duplication first.** Write the code in both apps. Live with it for one full feature cycle.
|
|
56
|
+
2. **Observe drift.** Are the two copies diverging? If yes, they were never the same concept — keep them separate. If they stay identical, you have a real case for extraction.
|
|
57
|
+
3. **Name the boundary in one sentence.** "This package owns <X>, exposes <Y>, is consumed by <Z>." If you can't, you're not ready.
|
|
58
|
+
4. **Run `void-service-package`** to create it properly (5+5 layout, port direction).
|
|
59
|
+
5. **Open a PR with ADR.** Extraction is structural; document via `void-decide`.
|
|
60
|
+
|
|
61
|
+
## Reverse: when to UN-extract
|
|
62
|
+
|
|
63
|
+
A package with one consumer for 6+ months should be inlined back. The boundary was a guess; reality says no. Reverse-extraction is a valid PR ("merge @repo/billing back into apps/web/src/services/billing").
|
|
64
|
+
|
|
65
|
+
## Composition
|
|
66
|
+
|
|
67
|
+
- `void-service-package` — the creation workflow (use this skill to decide, that one to create).
|
|
68
|
+
- `void-decide` — extractions are ADR-worthy.
|
|
69
|
+
- `void-dependency-direction` — extracted packages must respect `@repo/*` import direction.
|
|
70
|
+
- `void-hexagonal-architecture` — extracted packages own ports; adapters live in consumer apps.
|
|
@@ -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,5 @@
|
|
|
1
|
+
Sources for `void-service-package` skill (see `docs/plans/skill-audits/void-service-package.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- No external source. Native distillation of the `01-monorepo-layout.md` module (which describes the 5+5 topology) into a step-by-step package-creation workflow.
|
|
4
|
+
|
|
5
|
+
Strategy: native. The module says "this is how packages look"; the skill says "here is exactly what to do to create one". Composes with hexagonal-architecture, DDD, and functional.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-service-package
|
|
3
|
+
description: "Create or extend a packages/<name>/ service in a harness-monorepo workspace: the 5+5 file layout, @repo/* boundaries, ports-and-adapters direction. Composes with hexagonal-architecture, DDD."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# service-package
|
|
7
|
+
|
|
8
|
+
Use when adding a new `packages/<name>/` package to a Turborepo workspace that follows the void-machine `pack-monorepo` conventions, or when extending an existing one. The pack module document defines the topology (see `claude/modules/01-monorepo-layout.md`); this skill is the **execution checklist** for creating one.
|
|
9
|
+
|
|
10
|
+
If you are working in `apps/<app>/` business code, this skill does not apply — that is internal application code, not a shared package.
|
|
11
|
+
|
|
12
|
+
## When this skill triggers
|
|
13
|
+
|
|
14
|
+
- "Add a `@repo/billing` package" / "extract billing into its own package"
|
|
15
|
+
- "Create a new shared service for X"
|
|
16
|
+
- "Move logic from apps/web into a package so apps/api can use it too"
|
|
17
|
+
- Any creation of a new directory under `packages/` at the top level
|
|
18
|
+
|
|
19
|
+
## The 5+5 layout (mandatory)
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
packages/<name>/
|
|
23
|
+
├── package.json
|
|
24
|
+
├── tsconfig.json # extends ../../tsconfig.strict.json
|
|
25
|
+
├── src/
|
|
26
|
+
│ ├── <name>.service.ts # domain logic
|
|
27
|
+
│ ├── <name>.repository.ts # I/O (DB, HTTP, queue)
|
|
28
|
+
│ ├── <name>.helper.ts # pure functions
|
|
29
|
+
│ ├── <name>.types.ts # Zod schemas + inferred TS types
|
|
30
|
+
│ ├── index.ts # public barrel
|
|
31
|
+
│ ├── <name>.service.test.ts
|
|
32
|
+
│ ├── <name>.repository.test.ts
|
|
33
|
+
│ ├── <name>.helper.test.ts
|
|
34
|
+
│ ├── <name>.types.test.ts
|
|
35
|
+
│ └── index.test.ts # contract tests on the barrel
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The "5+5" is **five source files + five test files**, paired one-to-one. No `utils/`, no `lib/`, no `common/`. A file does one thing.
|
|
39
|
+
|
|
40
|
+
## Direction of dependencies
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
service ─→ repository (port) service ─→ helper service ─→ types
|
|
44
|
+
↑
|
|
45
|
+
adapter (in apps/<app>/src/adapters/<name>/)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- `service.ts` defines the **interface** the repository must satisfy (the port).
|
|
49
|
+
- The concrete adapter lives in the **consuming app**, under `apps/<app>/src/adapters/`, not in this package.
|
|
50
|
+
- `repository.ts` in this package may hold a default/in-memory implementation for tests, but the prod adapter is wired by the app.
|
|
51
|
+
- `helper.ts` is pure. No I/O. No `Date.now()`. Take time as a parameter.
|
|
52
|
+
|
|
53
|
+
If your package needs `@repo/db` directly: stop. Move the DB-touching code into an adapter in the consuming app. The package owns the **port**, not the adapter.
|
|
54
|
+
|
|
55
|
+
## Allowed imports (enforced by `boundary-direction-check`)
|
|
56
|
+
|
|
57
|
+
| This package | May import |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `@repo/<name>` | `@repo/core` (logger, env, errors, Result/Option/pipe). Nothing else `@repo/*`. |
|
|
60
|
+
|
|
61
|
+
If you find yourself needing to import another `@repo/*`, you are blurring layers. Two valid fixes:
|
|
62
|
+
- Move the shared concept into `@repo/core`
|
|
63
|
+
- Reshape the boundary so the consumer composes the two packages explicitly
|
|
64
|
+
|
|
65
|
+
## `package.json` template
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"name": "@repo/<name>",
|
|
70
|
+
"version": "0.0.0",
|
|
71
|
+
"private": true,
|
|
72
|
+
"type": "module",
|
|
73
|
+
"exports": {
|
|
74
|
+
".": {
|
|
75
|
+
"types": "./src/index.ts",
|
|
76
|
+
"default": "./src/index.ts"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"dependencies": {
|
|
80
|
+
"@repo/core": "workspace:*",
|
|
81
|
+
"zod": "catalog:"
|
|
82
|
+
},
|
|
83
|
+
"devDependencies": {
|
|
84
|
+
"tsconfig": "workspace:*",
|
|
85
|
+
"vitest": "catalog:"
|
|
86
|
+
},
|
|
87
|
+
"scripts": {
|
|
88
|
+
"test": "vitest run",
|
|
89
|
+
"typecheck": "tsc --noEmit"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`exports` points at `src/index.ts` directly — Turborepo + tsup compile at the app boundary, packages stay as TS source for fast iteration.
|
|
95
|
+
|
|
96
|
+
## Workflow
|
|
97
|
+
|
|
98
|
+
1. **Confirm the boundary first.** Before any file, write one line in the PR description: *"This package owns X, exposes Y, and is consumed by Z."* If you cannot, the package is premature.
|
|
99
|
+
2. **Create the directory + `package.json` + `tsconfig.json`** (extends `../../tsconfig.strict.json`).
|
|
100
|
+
3. **Write the types file first** (`<name>.types.ts`): Zod schemas + inferred types. Tests assert that invalid payloads parse to errors.
|
|
101
|
+
4. **Write the service.test.ts** describing the public behavior, then `service.ts` to make it pass (TDD strict, see `void-tdd`).
|
|
102
|
+
5. **Write the helper + helper.test.ts** as pure-function tests (table-driven).
|
|
103
|
+
6. **Write the repository port** (`repository.ts`): just the interface and a default in-memory implementation. Real DB adapter lives in the consuming app.
|
|
104
|
+
7. **Export from `index.ts`** only what consumers must touch. No re-exports of internal helpers.
|
|
105
|
+
8. **Add to `tsconfig.base.json` paths** if your monorepo uses TS path aliases (most do).
|
|
106
|
+
9. **Run `bunx turbo run typecheck test --filter @repo/<name>`** before commit.
|
|
107
|
+
|
|
108
|
+
## Anti-patterns
|
|
109
|
+
|
|
110
|
+
- ✗ A `utils/` or `common/` directory — split into helpers per concern instead.
|
|
111
|
+
- ✗ A `<name>.types.ts` that's only TypeScript types with no Zod schema — at boundaries you need runtime validation. Internal-only types live next to their use.
|
|
112
|
+
- ✗ Importing the concrete DB into `service.ts` — wire the adapter in the app.
|
|
113
|
+
- ✗ Re-exporting an entire submodule from `index.ts` (`export * from './internal'`) — list explicit names so the public surface is auditable.
|
|
114
|
+
- ✗ Adding a sixth source file because "it doesn't fit anywhere" — that's a code smell. Either the boundary is wrong (split the package) or the file collapses into an existing one.
|
|
115
|
+
|
|
116
|
+
## Composition
|
|
117
|
+
|
|
118
|
+
- `void-hexagonal-architecture` — port direction enforced. Service defines port; adapter is in app, not package.
|
|
119
|
+
- `void-domain-driven-design` — name the package per aggregate or capability, not per technical concern.
|
|
120
|
+
- `void-functional` — `helper.ts` is pure; pass time, randomness, and side effects as parameters.
|
|
121
|
+
- `void-tdd` — strict on `service.ts` and `helper.ts`; souple on `repository.ts` if it only forwards.
|
|
122
|
+
- `void-typescript-strict` — `tsconfig.strict.json` is mandatory; no `any`, no `as` casts in committed code.
|
|
@@ -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-turbo-pipeline-tuning` skill (see `docs/plans/skill-audits/void-turbo-pipeline-tuning.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- Turborepo docs — official guidance on dependsOn, outputs, and cache keys
|
|
4
|
+
- Vercel best-practices guide — remote-cache and pipeline tuning recommendations
|
|
5
|
+
- Repeated stumbles on real monorepos — the "bug -> cause -> fix" table for the 5 most common pipeline failures
|
|
6
|
+
|
|
7
|
+
Strategy: distill. Condenses Turborepo and Vercel guidance plus real-world failure patterns into a focused tuning skill, including when to leave defaults alone.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-turbo-pipeline-tuning
|
|
3
|
+
description: Configure turbo.json tasks correctly — dependsOn, outputs, cache keys, persistent tasks, remote cache. Get build speed right without over-engineering.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# turbo-pipeline-tuning
|
|
7
|
+
|
|
8
|
+
Use when adding or modifying tasks in `turbo.json`, or when the monorepo's CI/local build feels slow. Turborepo's value is incremental caching; getting `dependsOn`, `outputs`, and cache keys right is the difference between "build in 4s" and "build in 90s".
|
|
9
|
+
|
|
10
|
+
If you don't have `turbo.json` (single-app), this skill does not apply.
|
|
11
|
+
|
|
12
|
+
## The 4 fields that matter
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"tasks": {
|
|
17
|
+
"build": {
|
|
18
|
+
"dependsOn": ["^build"], // 1. order
|
|
19
|
+
"outputs": ["dist/**", ".next/**"],// 2. cache artifacts
|
|
20
|
+
"inputs": ["src/**", "tsconfig.json"], // 3. cache key (optional, smart default exists)
|
|
21
|
+
"cache": true // 4. on/off
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
90% of pipeline bugs come from getting one of these wrong.
|
|
28
|
+
|
|
29
|
+
## `dependsOn` cheatsheet
|
|
30
|
+
|
|
31
|
+
- `^build` — depends on `build` of upstream workspace packages (the package's own deps)
|
|
32
|
+
- `build` — depends on `build` of the SAME package (rare; usually you want `^build`)
|
|
33
|
+
- `lint` — depends on `lint` of the SAME package
|
|
34
|
+
- `^lint` — depends on `lint` of upstream (rare; lint usually doesn't depend on others)
|
|
35
|
+
- `db:generate` — explicit task name in another package
|
|
36
|
+
|
|
37
|
+
The mental model: `^X` = wait for X in workspace deps. Bare `X` = wait for X in this package.
|
|
38
|
+
|
|
39
|
+
## `outputs` — get this right or kill cache
|
|
40
|
+
|
|
41
|
+
If a task writes files Turborepo doesn't know about, the cache is **wrong** (next run reads stale outputs). Common misses:
|
|
42
|
+
|
|
43
|
+
- ✗ `tsc --noEmit` writes nothing → `"outputs": []` (empty array, NOT omitted)
|
|
44
|
+
- ✓ `next build` → `"outputs": [".next/**", "!.next/cache/**"]`
|
|
45
|
+
- ✓ `tsup build` → `"outputs": ["dist/**"]`
|
|
46
|
+
- ✓ `drizzle-kit generate` → `"outputs": ["drizzle/**", "src/**/__generated__/**"]`
|
|
47
|
+
- ✗ Forgetting to list `dist/` → next consumer fails to import the freshly-built code
|
|
48
|
+
|
|
49
|
+
When a task has NO outputs (typecheck, lint, test), explicitly `"outputs": []`. Otherwise Turbo assumes "everything" and bloats the cache.
|
|
50
|
+
|
|
51
|
+
## `inputs` — most of the time, leave it alone
|
|
52
|
+
|
|
53
|
+
Default is "all files in the package not in `.gitignore`". That's almost always right. Override only when:
|
|
54
|
+
|
|
55
|
+
- A task reads files outside the package (rare, fragile) → list them explicitly
|
|
56
|
+
- A task should NOT invalidate on certain file changes (e.g., README.md, *.md) → `"inputs": ["src/**", "package.json", "tsconfig.json"]` to scope
|
|
57
|
+
|
|
58
|
+
Over-restricting `inputs` is the #1 source of "the cache lied to me" bugs. When in doubt, omit.
|
|
59
|
+
|
|
60
|
+
## `cache: false` — when
|
|
61
|
+
|
|
62
|
+
- Tasks with non-deterministic output (deploy, publish, OTA push)
|
|
63
|
+
- Tasks that mutate external state (DB migration push, registry publish)
|
|
64
|
+
- Watch / dev tasks (`"persistent": true` instead, see below)
|
|
65
|
+
|
|
66
|
+
`dev` is the canonical persistent task:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
"dev": { "cache": false, "persistent": true }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`persistent: true` tells Turbo "this task never ends" so it doesn't wait for completion before considering downstream tasks runnable.
|
|
73
|
+
|
|
74
|
+
## Remote cache: when to bother
|
|
75
|
+
|
|
76
|
+
Remote cache (Vercel Remote Cache, Turbo's hosted, self-host) is worth it when:
|
|
77
|
+
|
|
78
|
+
- Team ≥ 3 developers AND/OR
|
|
79
|
+
- CI runs ≥ 10 times per day AND/OR
|
|
80
|
+
- Build times ≥ 1 minute
|
|
81
|
+
|
|
82
|
+
For solo dev with local cache only, skip. The setup overhead exceeds the benefit.
|
|
83
|
+
|
|
84
|
+
Setup: `npx turbo login && npx turbo link`. CI: pass `TURBO_TOKEN` and `TURBO_TEAM` env vars.
|
|
85
|
+
|
|
86
|
+
## Common bugs and fixes
|
|
87
|
+
|
|
88
|
+
| Symptom | Likely cause | Fix |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| "Build seems to skip my changes" | Wrong `inputs` glob | Remove the inputs override; let Turbo default handle it |
|
|
91
|
+
| "Downstream package imports stale code" | Missing `outputs` entry | Add `dist/**` (or whatever the build writes) |
|
|
92
|
+
| "Cache key changes every run" | Generated file outside `outputs` | List the generated path in `outputs` |
|
|
93
|
+
| "Turbo runs tasks in wrong order" | Missing `dependsOn: ["^build"]` | Add it |
|
|
94
|
+
| "Full rebuild every CI run" | No remote cache OR build artifact ignored by .gitignore but not in outputs | Set up remote cache; verify outputs match |
|
|
95
|
+
|
|
96
|
+
## When NOT to add a task
|
|
97
|
+
|
|
98
|
+
- One-shot scripts: use a package.json script, not a Turbo task
|
|
99
|
+
- Tasks that run < 1 second: not worth the overhead
|
|
100
|
+
- Tasks specific to one developer's flow: keep in their shell history
|
|
101
|
+
|
|
102
|
+
Turbo tasks are for things the team runs in CI or routinely locally. Keep the surface small.
|
|
103
|
+
|
|
104
|
+
## Workflow
|
|
105
|
+
|
|
106
|
+
1. **Sketch the dependency DAG on paper.** What runs before what? Across packages?
|
|
107
|
+
2. **Write the minimal `dependsOn` + `outputs`** for each task. Don't overthink `inputs`.
|
|
108
|
+
3. **`turbo build --dry-run`** to see the plan.
|
|
109
|
+
4. **`turbo build --summarize`** to verify cache hits in CI.
|
|
110
|
+
5. **If a cache miss surprises you, `turbo build --verbose`** shows the cache key inputs.
|
|
111
|
+
|
|
112
|
+
## Composition
|
|
113
|
+
|
|
114
|
+
- `void-service-package` — new packages need their tasks declared in turbo.json (build, typecheck, test).
|
|
115
|
+
- `void-dependency-direction` — Turbo's `^build` only works correctly if package dependencies are well-declared in package.json.
|
|
116
|
+
- `void-tdd` — `test` task must have `"outputs": []`; otherwise vitest's cache directory pollutes Turbo's cache.
|
|
@@ -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,5 @@
|
|
|
1
|
+
Sources for `void-cache-component-pattern` skill (see `docs/plans/skill-audits/void-cache-component-pattern.md` for the full audit):
|
|
2
|
+
|
|
3
|
+
- No external source listed in the audit. Authored against the Next.js 16 Cache Components feature (cached-by-default model, 'use cache' / 'use no cache', revalidateTag/revalidatePath).
|
|
4
|
+
|
|
5
|
+
Strategy: distill. Codified natively from the Next 16 cache model; no upstream skill was adapted.
|