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.
Files changed (341) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -4
  3. package/bin/void-harness.mjs +12 -0
  4. package/bin/void-machine.mjs +12 -0
  5. package/core-assets/.claude-plugin/plugin.json +253 -0
  6. package/core-assets/.gitkeep +0 -0
  7. package/core-assets/PHILOSOPHY.md +218 -0
  8. package/core-assets/PROJECT-DOCTRINE.template.md +14 -0
  9. package/core-assets/adapters/security/manifest.yaml +96 -0
  10. package/core-assets/agents/.gitkeep +0 -0
  11. package/core-assets/agents/accessibility-specialist.md +59 -0
  12. package/core-assets/agents/api-integration-engineer.md +59 -0
  13. package/core-assets/agents/code-explorer.md +94 -0
  14. package/core-assets/agents/code-explorer.source +7 -0
  15. package/core-assets/agents/data-migration-engineer.md +59 -0
  16. package/core-assets/agents/devex-docs-engineer.md +57 -0
  17. package/core-assets/agents/doctrine-critic.md +91 -0
  18. package/core-assets/agents/doctrine-critic.source +11 -0
  19. package/core-assets/agents/domain-architect.md +56 -0
  20. package/core-assets/agents/experience-designer.md +59 -0
  21. package/core-assets/agents/frontend-engineer.md +60 -0
  22. package/core-assets/agents/independent-code-reviewer.md +61 -0
  23. package/core-assets/agents/migration-planner.md +97 -0
  24. package/core-assets/agents/migration-planner.source +7 -0
  25. package/core-assets/agents/observability-sre-engineer.md +59 -0
  26. package/core-assets/agents/pdf-specialist.md +58 -0
  27. package/core-assets/agents/performance-engineer.md +58 -0
  28. package/core-assets/agents/product-challenger.md +55 -0
  29. package/core-assets/agents/security-engineer.md +66 -0
  30. package/core-assets/agents/silent-failure-hunter.md +94 -0
  31. package/core-assets/agents/silent-failure-hunter.source +8 -0
  32. package/core-assets/agents/solution-architect.md +57 -0
  33. package/core-assets/agents/test-qa-engineer.md +60 -0
  34. package/core-assets/agents/type-design-analyzer.md +93 -0
  35. package/core-assets/agents/type-design-analyzer.source +8 -0
  36. package/core-assets/agents/visual-craft-director.md +62 -0
  37. package/core-assets/codex/hooks.json +157 -0
  38. package/core-assets/contract-history/visual-craft-director/v2.yaml +43 -0
  39. package/core-assets/data/catalog.v3.json +10479 -0
  40. package/core-assets/data/certification.json +1800 -0
  41. package/core-assets/data/identity.json +8 -0
  42. package/core-assets/data/model.json +4226 -0
  43. package/core-assets/enforce/ci-enforce.sh +183 -0
  44. package/core-assets/hooks/_checks.sh +145 -0
  45. package/core-assets/hooks/_hooklib.sh +163 -0
  46. package/core-assets/hooks/_syntax-worker.cjs +503 -0
  47. package/core-assets/hooks/_void-hook.mjs +5459 -0
  48. package/core-assets/hooks/activation-meter.sh +13 -0
  49. package/core-assets/hooks/anti-ai-slop-grep.sh +38 -0
  50. package/core-assets/hooks/auto-format.sh +9 -0
  51. package/core-assets/hooks/axe-precommit.sh +35 -0
  52. package/core-assets/hooks/block-dangerous-bash.sh +10 -0
  53. package/core-assets/hooks/block-protected-push.sh +81 -0
  54. package/core-assets/hooks/boundary-direction-check.sh +10 -0
  55. package/core-assets/hooks/control-character-grep.sh +10 -0
  56. package/core-assets/hooks/fowler-refactors.txt +71 -0
  57. package/core-assets/hooks/large-cl-grep.sh +9 -0
  58. package/core-assets/hooks/llm-cost-precommit.sh +55 -0
  59. package/core-assets/hooks/migration-lint.sh +58 -0
  60. package/core-assets/hooks/migration-pr-template.sh +55 -0
  61. package/core-assets/hooks/no-ai-design-slop.sh +10 -0
  62. package/core-assets/hooks/no-any-grep.sh +10 -0
  63. package/core-assets/hooks/no-as-cast-grep.sh +10 -0
  64. package/core-assets/hooks/no-console-log-grep.sh +10 -0
  65. package/core-assets/hooks/no-null-grep.sh +10 -0
  66. package/core-assets/hooks/no-only-no-skip.sh +10 -0
  67. package/core-assets/hooks/outcome-meter.sh +13 -0
  68. package/core-assets/hooks/pre-PR-review-evidence.sh +47 -0
  69. package/core-assets/hooks/protect-sensitive-files.sh +10 -0
  70. package/core-assets/hooks/refactor-named-grep.sh +49 -0
  71. package/core-assets/hooks/secret-in-content.sh +10 -0
  72. package/core-assets/hooks/sessionstart-context.sh +9 -0
  73. package/core-assets/hooks/stop-typecheck.sh +9 -0
  74. package/core-assets/hooks/tdd-guard.md +90 -0
  75. package/core-assets/hooks/tdd-guard.sh +10 -0
  76. package/core-assets/hooks/test-name-lint.sh +10 -0
  77. package/core-assets/hooks/tidying-commit-prefix.sh +37 -0
  78. package/core-assets/hooks/trim-large-output.sh +9 -0
  79. package/core-assets/hooks/tsc-noemit-precommit.sh +22 -0
  80. package/core-assets/hooks/ubiquitous-language-lint.sh +58 -0
  81. package/core-assets/hooks/viewport-screenshot-gate.sh +48 -0
  82. package/core-assets/modules/.gitkeep +0 -0
  83. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/.source +7 -0
  84. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/SKILL.md +164 -0
  85. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/harness.yaml +14 -0
  86. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/.source +7 -0
  87. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/SKILL.md +178 -0
  88. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/harness.yaml +14 -0
  89. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/.source +8 -0
  90. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/SKILL.md +209 -0
  91. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/harness.yaml +14 -0
  92. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/.source +7 -0
  93. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/SKILL.md +194 -0
  94. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/harness.yaml +14 -0
  95. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/.source +5 -0
  96. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/SKILL.md +160 -0
  97. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/harness.yaml +14 -0
  98. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/.source +5 -0
  99. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/SKILL.md +70 -0
  100. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/harness.yaml +14 -0
  101. package/core-assets/packs/pack-monorepo/skills/void-service-package/.source +5 -0
  102. package/core-assets/packs/pack-monorepo/skills/void-service-package/SKILL.md +122 -0
  103. package/core-assets/packs/pack-monorepo/skills/void-service-package/harness.yaml +14 -0
  104. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/.source +7 -0
  105. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/SKILL.md +116 -0
  106. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/harness.yaml +14 -0
  107. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/.source +5 -0
  108. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/SKILL.md +162 -0
  109. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/harness.yaml +14 -0
  110. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/.source +5 -0
  111. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/SKILL.md +161 -0
  112. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/harness.yaml +14 -0
  113. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/.source +5 -0
  114. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/SKILL.md +176 -0
  115. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/harness.yaml +14 -0
  116. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/.source +5 -0
  117. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/SKILL.md +129 -0
  118. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/harness.yaml +14 -0
  119. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/.source +5 -0
  120. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/SKILL.md +107 -0
  121. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/harness.yaml +14 -0
  122. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/.source +5 -0
  123. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/SKILL.md +153 -0
  124. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/harness.yaml +14 -0
  125. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/.source +5 -0
  126. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/SKILL.md +204 -0
  127. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/harness.yaml +14 -0
  128. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/.source +8 -0
  129. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/SKILL.md +266 -0
  130. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/harness.yaml +14 -0
  131. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/.source +5 -0
  132. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/SKILL.md +178 -0
  133. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/harness.yaml +14 -0
  134. package/core-assets/packs/pack-react/skills/void-accessibility-check/.source +8 -0
  135. package/core-assets/packs/pack-react/skills/void-accessibility-check/SKILL.md +136 -0
  136. package/core-assets/packs/pack-react/skills/void-accessibility-check/harness.yaml +14 -0
  137. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/.source +5 -0
  138. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/SKILL.md +116 -0
  139. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/harness.yaml +14 -0
  140. package/core-assets/packs/pack-react/skills/void-form-pattern/.source +7 -0
  141. package/core-assets/packs/pack-react/skills/void-form-pattern/SKILL.md +157 -0
  142. package/core-assets/packs/pack-react/skills/void-form-pattern/harness.yaml +14 -0
  143. package/core-assets/packs/pack-react/skills/void-state-architecture/.source +5 -0
  144. package/core-assets/packs/pack-react/skills/void-state-architecture/SKILL.md +160 -0
  145. package/core-assets/packs/pack-react/skills/void-state-architecture/harness.yaml +14 -0
  146. package/core-assets/packs/pack-server/skills/void-background-job-pattern/.source +6 -0
  147. package/core-assets/packs/pack-server/skills/void-background-job-pattern/SKILL.md +214 -0
  148. package/core-assets/packs/pack-server/skills/void-background-job-pattern/harness.yaml +14 -0
  149. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/.source +6 -0
  150. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/SKILL.md +168 -0
  151. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/harness.yaml +14 -0
  152. package/core-assets/packs/pack-server/skills/void-env-validation/.source +6 -0
  153. package/core-assets/packs/pack-server/skills/void-env-validation/SKILL.md +131 -0
  154. package/core-assets/packs/pack-server/skills/void-env-validation/harness.yaml +14 -0
  155. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/.source +6 -0
  156. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/SKILL.md +149 -0
  157. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/harness.yaml +14 -0
  158. package/core-assets/packs/pack-server/skills/void-server-action/.source +7 -0
  159. package/core-assets/packs/pack-server/skills/void-server-action/SKILL.md +181 -0
  160. package/core-assets/packs/pack-server/skills/void-server-action/harness.yaml +14 -0
  161. package/core-assets/packs/pack-server/skills/void-testing-server-modules/.source +7 -0
  162. package/core-assets/packs/pack-server/skills/void-testing-server-modules/SKILL.md +73 -0
  163. package/core-assets/packs/pack-server/skills/void-testing-server-modules/harness.yaml +14 -0
  164. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/.source +7 -0
  165. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/SKILL.md +205 -0
  166. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/harness.yaml +14 -0
  167. package/core-assets/policies/core.yaml +95 -0
  168. package/core-assets/policies/ui.yaml +23 -0
  169. package/core-assets/profiles/base.yaml +29 -0
  170. package/core-assets/profiles/expo-config.yaml +36 -0
  171. package/core-assets/profiles/expo.yaml +35 -0
  172. package/core-assets/profiles/monorepo.yaml +33 -0
  173. package/core-assets/profiles/nextjs-config.yaml +31 -0
  174. package/core-assets/profiles/nextjs.yaml +31 -0
  175. package/core-assets/profiles/node-server.yaml +31 -0
  176. package/core-assets/profiles/pwa.yaml +33 -0
  177. package/core-assets/profiles/react.yaml +39 -0
  178. package/core-assets/profiles/sql.yaml +39 -0
  179. package/core-assets/profiles/typescript.yaml +39 -0
  180. package/core-assets/skills/.gitkeep +0 -0
  181. package/core-assets/skills/void-accessibility/.source +15 -0
  182. package/core-assets/skills/void-accessibility/SKILL.md +275 -0
  183. package/core-assets/skills/void-accessibility/harness.yaml +17 -0
  184. package/core-assets/skills/void-api-and-interface-design/.source +13 -0
  185. package/core-assets/skills/void-api-and-interface-design/SKILL.md +231 -0
  186. package/core-assets/skills/void-api-and-interface-design/harness.yaml +16 -0
  187. package/core-assets/skills/void-async-safety/.source +13 -0
  188. package/core-assets/skills/void-async-safety/SKILL.md +287 -0
  189. package/core-assets/skills/void-async-safety/harness.yaml +16 -0
  190. package/core-assets/skills/void-audit/.source +15 -0
  191. package/core-assets/skills/void-audit/SKILL.md +83 -0
  192. package/core-assets/skills/void-audit/harness.yaml +14 -0
  193. package/core-assets/skills/void-autopilot/.source +21 -0
  194. package/core-assets/skills/void-autopilot/SKILL.md +358 -0
  195. package/core-assets/skills/void-autopilot/harness.yaml +14 -0
  196. package/core-assets/skills/void-brainstorm/.source +14 -0
  197. package/core-assets/skills/void-brainstorm/SKILL.md +271 -0
  198. package/core-assets/skills/void-brainstorm/harness.yaml +14 -0
  199. package/core-assets/skills/void-checkpoint/.source +39 -0
  200. package/core-assets/skills/void-checkpoint/SKILL.md +227 -0
  201. package/core-assets/skills/void-checkpoint/harness.yaml +14 -0
  202. package/core-assets/skills/void-claude-md/.source +15 -0
  203. package/core-assets/skills/void-claude-md/SKILL.md +180 -0
  204. package/core-assets/skills/void-claude-md/harness.yaml +14 -0
  205. package/core-assets/skills/void-code-review/.source +14 -0
  206. package/core-assets/skills/void-code-review/SKILL.md +232 -0
  207. package/core-assets/skills/void-code-review/harness.yaml +15 -0
  208. package/core-assets/skills/void-commit-discipline/.source +9 -0
  209. package/core-assets/skills/void-commit-discipline/SKILL.md +211 -0
  210. package/core-assets/skills/void-commit-discipline/harness.yaml +15 -0
  211. package/core-assets/skills/void-context/.source +15 -0
  212. package/core-assets/skills/void-context/SKILL.md +167 -0
  213. package/core-assets/skills/void-context/harness.yaml +14 -0
  214. package/core-assets/skills/void-debug/.source +11 -0
  215. package/core-assets/skills/void-debug/SKILL.md +211 -0
  216. package/core-assets/skills/void-debug/harness.yaml +14 -0
  217. package/core-assets/skills/void-decide/.source +9 -0
  218. package/core-assets/skills/void-decide/SKILL.md +147 -0
  219. package/core-assets/skills/void-decide/harness.yaml +14 -0
  220. package/core-assets/skills/void-devex-audit/.source +8 -0
  221. package/core-assets/skills/void-devex-audit/SKILL.md +113 -0
  222. package/core-assets/skills/void-devex-audit/harness.yaml +15 -0
  223. package/core-assets/skills/void-doctor/.source +15 -0
  224. package/core-assets/skills/void-doctor/SKILL.md +83 -0
  225. package/core-assets/skills/void-doctor/harness.yaml +14 -0
  226. package/core-assets/skills/void-domain-driven-design/.source +13 -0
  227. package/core-assets/skills/void-domain-driven-design/SKILL.md +292 -0
  228. package/core-assets/skills/void-domain-driven-design/harness.yaml +15 -0
  229. package/core-assets/skills/void-frontend-design/.source +19 -0
  230. package/core-assets/skills/void-frontend-design/SKILL.md +274 -0
  231. package/core-assets/skills/void-frontend-design/harness.yaml +17 -0
  232. package/core-assets/skills/void-functional/.source +14 -0
  233. package/core-assets/skills/void-functional/SKILL.md +312 -0
  234. package/core-assets/skills/void-functional/harness.yaml +15 -0
  235. package/core-assets/skills/void-graph/.source +15 -0
  236. package/core-assets/skills/void-graph/SKILL.md +80 -0
  237. package/core-assets/skills/void-graph/harness.yaml +14 -0
  238. package/core-assets/skills/void-hexagonal-architecture/.source +12 -0
  239. package/core-assets/skills/void-hexagonal-architecture/SKILL.md +276 -0
  240. package/core-assets/skills/void-hexagonal-architecture/harness.yaml +15 -0
  241. package/core-assets/skills/void-implement/.source +39 -0
  242. package/core-assets/skills/void-implement/SKILL.md +183 -0
  243. package/core-assets/skills/void-implement/harness.yaml +14 -0
  244. package/core-assets/skills/void-learn/.source +13 -0
  245. package/core-assets/skills/void-learn/SKILL.md +226 -0
  246. package/core-assets/skills/void-learn/harness.yaml +14 -0
  247. package/core-assets/skills/void-llm-cost-discipline/.source +13 -0
  248. package/core-assets/skills/void-llm-cost-discipline/SKILL.md +299 -0
  249. package/core-assets/skills/void-llm-cost-discipline/harness.yaml +15 -0
  250. package/core-assets/skills/void-make-pdf/.source +9 -0
  251. package/core-assets/skills/void-make-pdf/SKILL.md +52 -0
  252. package/core-assets/skills/void-make-pdf/harness.yaml +15 -0
  253. package/core-assets/skills/void-merge/.source +8 -0
  254. package/core-assets/skills/void-merge/SKILL.md +111 -0
  255. package/core-assets/skills/void-merge/harness.yaml +14 -0
  256. package/core-assets/skills/void-migrations/.source +13 -0
  257. package/core-assets/skills/void-migrations/SKILL.md +264 -0
  258. package/core-assets/skills/void-migrations/harness.yaml +17 -0
  259. package/core-assets/skills/void-observability/.source +12 -0
  260. package/core-assets/skills/void-observability/SKILL.md +245 -0
  261. package/core-assets/skills/void-observability/harness.yaml +15 -0
  262. package/core-assets/skills/void-plan/.source +15 -0
  263. package/core-assets/skills/void-plan/SKILL.md +239 -0
  264. package/core-assets/skills/void-plan/harness.yaml +14 -0
  265. package/core-assets/skills/void-plan-review/.source +12 -0
  266. package/core-assets/skills/void-plan-review/SKILL.md +128 -0
  267. package/core-assets/skills/void-plan-review/harness.yaml +15 -0
  268. package/core-assets/skills/void-qa/.source +15 -0
  269. package/core-assets/skills/void-qa/SKILL.md +103 -0
  270. package/core-assets/skills/void-qa/harness.yaml +15 -0
  271. package/core-assets/skills/void-refactor/.source +9 -0
  272. package/core-assets/skills/void-refactor/SKILL.md +220 -0
  273. package/core-assets/skills/void-refactor/harness.yaml +15 -0
  274. package/core-assets/skills/void-retrospective/.source +9 -0
  275. package/core-assets/skills/void-retrospective/SKILL.md +71 -0
  276. package/core-assets/skills/void-retrospective/harness.yaml +15 -0
  277. package/core-assets/skills/void-security-audit/.source +12 -0
  278. package/core-assets/skills/void-security-audit/SKILL.md +138 -0
  279. package/core-assets/skills/void-security-audit/harness.yaml +15 -0
  280. package/core-assets/skills/void-security-guidance/.source +12 -0
  281. package/core-assets/skills/void-security-guidance/SKILL.md +255 -0
  282. package/core-assets/skills/void-security-guidance/harness.yaml +15 -0
  283. package/core-assets/skills/void-source-driven-development/.source +12 -0
  284. package/core-assets/skills/void-source-driven-development/SKILL.md +158 -0
  285. package/core-assets/skills/void-source-driven-development/harness.yaml +15 -0
  286. package/core-assets/skills/void-tdd/.source +15 -0
  287. package/core-assets/skills/void-tdd/SKILL.md +394 -0
  288. package/core-assets/skills/void-tdd/harness.yaml +15 -0
  289. package/core-assets/skills/void-testing/.source +19 -0
  290. package/core-assets/skills/void-testing/SKILL.md +301 -0
  291. package/core-assets/skills/void-testing/harness.yaml +17 -0
  292. package/core-assets/skills/void-ticket/.source +18 -0
  293. package/core-assets/skills/void-ticket/SKILL.md +239 -0
  294. package/core-assets/skills/void-ticket/harness.yaml +14 -0
  295. package/core-assets/skills/void-typescript-strict/.source +10 -0
  296. package/core-assets/skills/void-typescript-strict/SKILL.md +294 -0
  297. package/core-assets/skills/void-typescript-strict/harness.yaml +17 -0
  298. package/core-assets/skills/void-ui-review/.source +12 -0
  299. package/core-assets/skills/void-ui-review/SKILL.md +97 -0
  300. package/core-assets/skills/void-ui-review/harness.yaml +15 -0
  301. package/core-assets/skills/void-verify/.source +12 -0
  302. package/core-assets/skills/void-verify/SKILL.md +184 -0
  303. package/core-assets/skills/void-verify/harness.yaml +15 -0
  304. package/core-assets/specialists/accessibility-specialist.source +11 -0
  305. package/core-assets/specialists/accessibility-specialist.yaml +30 -0
  306. package/core-assets/specialists/api-integration-engineer.source +11 -0
  307. package/core-assets/specialists/api-integration-engineer.yaml +30 -0
  308. package/core-assets/specialists/data-migration-engineer.source +11 -0
  309. package/core-assets/specialists/data-migration-engineer.yaml +30 -0
  310. package/core-assets/specialists/devex-docs-engineer.source +11 -0
  311. package/core-assets/specialists/devex-docs-engineer.yaml +29 -0
  312. package/core-assets/specialists/domain-architect.source +11 -0
  313. package/core-assets/specialists/domain-architect.yaml +28 -0
  314. package/core-assets/specialists/experience-designer.source +15 -0
  315. package/core-assets/specialists/experience-designer.yaml +38 -0
  316. package/core-assets/specialists/frontend-engineer.source +11 -0
  317. package/core-assets/specialists/frontend-engineer.yaml +32 -0
  318. package/core-assets/specialists/independent-code-reviewer.source +10 -0
  319. package/core-assets/specialists/independent-code-reviewer.yaml +37 -0
  320. package/core-assets/specialists/migrations.json +15 -0
  321. package/core-assets/specialists/observability-sre-engineer.source +11 -0
  322. package/core-assets/specialists/observability-sre-engineer.yaml +30 -0
  323. package/core-assets/specialists/pdf-specialist.source +11 -0
  324. package/core-assets/specialists/pdf-specialist.yaml +29 -0
  325. package/core-assets/specialists/performance-engineer.source +11 -0
  326. package/core-assets/specialists/performance-engineer.yaml +29 -0
  327. package/core-assets/specialists/product-challenger.source +10 -0
  328. package/core-assets/specialists/product-challenger.yaml +27 -0
  329. package/core-assets/specialists/security-engineer.source +13 -0
  330. package/core-assets/specialists/security-engineer.yaml +41 -0
  331. package/core-assets/specialists/solution-architect.source +13 -0
  332. package/core-assets/specialists/solution-architect.yaml +32 -0
  333. package/core-assets/specialists/test-qa-engineer.source +14 -0
  334. package/core-assets/specialists/test-qa-engineer.yaml +35 -0
  335. package/core-assets/specialists/visual-craft-director.source +17 -0
  336. package/core-assets/specialists/visual-craft-director.yaml +60 -0
  337. package/core-assets/templates/github/dependency-audit.mjs +54 -0
  338. package/core-assets/templates/github/void-dependency-audit.yml +35 -0
  339. package/core-assets/templates/github/void-security.yml +85 -0
  340. package/dist/main.js +57001 -0
  341. package/package.json +66 -4
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: void-parallel-routes-slots
3
+ description: Use Next.js parallel routes (@slot) and intercepting routes ((.)foo) — when they're the right tool, when they're an anti-pattern. The "modal that's also a deep-linkable page" archetype.
4
+ ---
5
+
6
+ # parallel-routes-slots
7
+
8
+ Use when you need to render **multiple independent UI pieces in the same layout that can navigate independently**, or to **show a modal that's also a deep-linkable route**. Parallel routes and intercepting routes are powerful but easy to mis-apply.
9
+
10
+ If you only need a different page at a different URL → use a normal route. No slots needed.
11
+
12
+ ## Parallel routes (`@slot`)
13
+
14
+ A `@slot` folder is a **named layout slot** that can be filled by any of its child pages.
15
+
16
+ ```
17
+ app/dashboard/
18
+ ├── @analytics/
19
+ │ ├── page.tsx # default content for the slot
20
+ │ └── audience/page.tsx # different content at the slot
21
+ ├── @team/
22
+ │ ├── page.tsx
23
+ │ └── invite/page.tsx
24
+ └── layout.tsx # consumes both slots
25
+ ```
26
+
27
+ ```tsx
28
+ // app/dashboard/layout.tsx
29
+ export default function Layout({
30
+ children,
31
+ analytics,
32
+ team,
33
+ }: {
34
+ children: React.ReactNode;
35
+ analytics: React.ReactNode;
36
+ team: React.ReactNode;
37
+ }) {
38
+ return (
39
+ <div className="grid grid-cols-3 gap-4">
40
+ <main className="col-span-2">{children}</main>
41
+ <aside>{analytics}</aside>
42
+ <aside>{team}</aside>
43
+ </div>
44
+ );
45
+ }
46
+ ```
47
+
48
+ Each slot can independently navigate. The URL `/dashboard/audience/invite` could render `@analytics/audience` AND `@team/invite` AND the main `children` page simultaneously.
49
+
50
+ ## When parallel routes WIN
51
+
52
+ - **Dashboard layouts** with widgets that load independently and can be refreshed/navigated without rerouting the main view
53
+ - **Admin panels** with side panels showing different details based on selection
54
+ - **Layouts where streaming partial content matters**: each slot has its own loading.tsx, so the user sees content as each piece arrives
55
+
56
+ ## When parallel routes LOSE
57
+
58
+ - A single page with sections → just compose components in the page, no slots needed
59
+ - Conditional rendering based on user role → handle in the page, not via slots
60
+ - Modals (use intercepting routes — different mechanism, below)
61
+ - Mobile-first apps where slot layouts collapse to stack anyway → adds complexity for no gain on mobile
62
+
63
+ ## Default content (`page.tsx`) per slot
64
+
65
+ Every slot **must** have a `page.tsx` rendering its default empty state. Without it, you get a 404 when the slot is "empty" but the parent route renders. Common forgetting → cryptic Next errors.
66
+
67
+ ## Intercepting routes — the modal pattern
68
+
69
+ `(.)foo`, `(..)foo`, `(..)(..)foo`, `(...)foo` intercept a URL and render a different component **based on how the user arrived**.
70
+
71
+ ```
72
+ app/
73
+ ├── photos/
74
+ │ ├── [id]/
75
+ │ │ └── page.tsx # full-page photo view
76
+ │ └── page.tsx # photo grid
77
+ └── @modal/
78
+ └── (.)photos/[id]/
79
+ └── page.tsx # modal photo view
80
+ ```
81
+
82
+ When the user is on `/photos` and clicks a photo, the URL changes to `/photos/123` but they see a MODAL on top of the grid (the intercepting route fires). If they refresh or share the link, they get the full-page view.
83
+
84
+ This is the **deep-linkable modal** pattern — modal for in-app navigation, full page for direct link.
85
+
86
+ ## Intercepting route syntax
87
+
88
+ | Pattern | Means |
89
+ |---|---|
90
+ | `(.)foo` | Intercept `foo` from the same level |
91
+ | `(..)foo` | Intercept `foo` from one level up |
92
+ | `(..)(..)foo` | Intercept from two levels up |
93
+ | `(...)foo` | Intercept from the root |
94
+
95
+ The dots count is **route-segment** counts, not file-path. Easy to miscount.
96
+
97
+ ## When intercepting routes WIN
98
+
99
+ - Photo viewer, image gallery (the canonical use case)
100
+ - "Edit" / "Quick view" overlays that should be linkable
101
+ - Onboarding wizards that take over the UI but stay on a route
102
+
103
+ ## When intercepting routes LOSE
104
+
105
+ - Truly transient modals (delete confirmation, settings) — use state, not routes
106
+ - Mobile drawers / sheets — usually trigger different UX patterns, intercepting is overkill
107
+ - Modals that aren't shareable — adds URL complexity for no benefit
108
+
109
+ ## Anti-patterns
110
+
111
+ - ✗ **Slots without default `page.tsx`** — runtime errors when slot is "empty"
112
+ - ✗ **Nested intercepting routes** — debugging becomes impossible
113
+ - ✗ **Mixing slots with `useState` modal management** in the same surface — pick one
114
+ - ✗ **Slot for what should be a component** — if the content doesn't navigate independently, it's a component, not a slot
115
+ - ✗ **Intercepting routes that don't have a non-intercepting fallback** — refresh shows 404 instead of the full-page view
116
+
117
+ ## Workflow
118
+
119
+ 1. **Default**: simple route. No slots. No interception.
120
+ 2. **Need independent loading + navigation** of UI pieces in same layout? → parallel routes
121
+ 3. **Need a modal that's also a deep link** (refresh works, share link works)? → intercepting routes
122
+ 4. **Otherwise**: state-managed modal/sheet via `useState` + Radix Dialog.
123
+
124
+ ## Composition
125
+
126
+ - `void-route-group-decision` — slots and intercepting routes live within route groups.
127
+ - `void-cache-component-pattern` — each slot has its own cache scope.
128
+ - `void-loading-error-boundaries` — slots can have their own `loading.tsx`, `error.tsx`.
129
+ - `void-state-architecture` — transient modals use `useState`, not routes.
@@ -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-route-group-decision` skill (see `docs/plans/skill-audits/void-route-group-decision.md` for the full audit):
2
+
3
+ - No external source listed in the audit. Original void-machine convention: group route groups (name) by trust boundary, not visual section, behind a 3-condition gate.
4
+
5
+ Strategy: native. Authored from scratch as a void-machine convention; no external source.
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: void-route-group-decision
3
+ description: Decide when to use a (route-group), what to name it, and how to share layouts. The void-machine convention groups by trust boundary, not by visual section.
4
+ ---
5
+
6
+ # route-group-decision
7
+
8
+ Use when adding any new route in `app/`, or when refactor an existing flat `app/` into groups. Route groups (folders named `(name)`) don't affect URL but DO affect layout and convention scope.
9
+
10
+ ## The void-machine convention
11
+
12
+ ```
13
+ app/
14
+ ├── (api|actions)/ # trust boundaries (Server Actions, route handlers)
15
+ │ ├── (actions)/<feature>/
16
+ │ └── (api)/<resource>/route.ts
17
+ ├── (marketing)/ # public, statically rendered, no auth
18
+ │ ├── layout.tsx # marketing nav + footer
19
+ │ ├── page.tsx # /
20
+ │ ├── pricing/page.tsx # /pricing
21
+ │ └── blog/[slug]/page.tsx
22
+ ├── (app)/ # authenticated app
23
+ │ ├── layout.tsx # auth gate + app shell
24
+ │ ├── dashboard/page.tsx
25
+ │ └── settings/page.tsx
26
+ └── api/webhooks/<source>/route.ts # webhooks NOT in (api|actions) — different lifecycle
27
+ ```
28
+
29
+ The principle: **group by trust boundary and rendering model, not by visual section**.
30
+
31
+ ## Why these specific groups
32
+
33
+ - `(api|actions)` — every file inside is a trust boundary. The skill `void-server-action` applies. The "no fetch in components" rule applies in reverse: these files MUST fetch / mutate.
34
+ - `(marketing)` — statically renderable (Cache Components opted in by default), no auth, indexable by search engines. Different layout (marketing nav vs app shell).
35
+ - `(app)` — authenticated. Layout checks session, redirects to login if absent. All routes inside trust the layout's auth gate.
36
+ - `api/webhooks/<source>/` — NOT in a route group because the convention is path-stable for external systems. Stripe sends to `/api/webhooks/stripe`, period.
37
+
38
+ ## When to add a new group
39
+
40
+ You need ALL three:
41
+
42
+ 1. **A distinct layout** the new routes share (not just a different page)
43
+ 2. **A distinct trust posture** OR rendering model (cached vs dynamic, auth vs public)
44
+ 3. **≥ 2 routes** that fit the group
45
+
46
+ If you'd only put one route inside, don't add the group. Put the route in the closest existing group or at top level.
47
+
48
+ ## Naming the group
49
+
50
+ - Use parentheses: `(name)` — they're invisible in URL
51
+ - Lowercase, single word, plural if it represents a category
52
+ - Conventional names: `(api|actions)`, `(marketing)`, `(app)`, `(admin)`, `(public)`, `(authed)`
53
+ - Avoid: `(misc)`, `(stuff)`, `(my-new-feature)` — groups are coarse, not feature-scoped
54
+
55
+ ## Sharing layouts across groups
56
+
57
+ You can't directly — groups are siblings, each owns its layout. To share a header across `(marketing)` and `(app)`:
58
+
59
+ - Option A: put the shared header in `app/layout.tsx` (the root)
60
+ - Option B: extract the header as a component, import in each group's layout
61
+
62
+ A is cleaner if the header is truly shared by every group. B is right if only some groups share it.
63
+
64
+ ## The `app/layout.tsx` (root)
65
+
66
+ ONE root layout, contains:
67
+
68
+ - `<html>` and `<body>` tags (mandatory — only the root layout has these)
69
+ - Providers needed everywhere (Theme, i18n, Sentry, query client if RQ used)
70
+ - Global stylesheets
71
+
72
+ Should NOT contain:
73
+
74
+ - Navigation (lives in group layouts)
75
+ - Auth check (lives in `(app)/layout.tsx`)
76
+ - Marketing-specific markup
77
+
78
+ If root layout grows past 40 lines, you have layout-creep — push down.
79
+
80
+ ## Parallel routes and intercepting routes — separate concept
81
+
82
+ `@modal`, `(.)`, `(..)`, `(..)(..)`, `(...)` are **NOT** route groups. They're parallel/intercepting routes. See `void-parallel-routes-slots` for that pattern.
83
+
84
+ A route group is `(name)` (parentheses around a folder). Don't confuse them.
85
+
86
+ ## Anti-patterns
87
+
88
+ - ✗ **`(feature-name)` group for one route** — premature. Put the route at top level until you have a second.
89
+ - ✗ **Auth check in every page** instead of the `(app)/layout.tsx` — repetition + miss risk
90
+ - ✗ **Mixing public + authed routes in the same group** — the layout can't enforce a uniform auth posture
91
+ - ✗ **Group nesting**: `(app)/(admin)/...` — usually a smell. Flatten to `(admin)/` and put the auth check in its layout
92
+ - ✗ **Renaming a group after launch** — the convention is propagated through skill references and CLAUDE.md modules; rename is cheap technically but expensive culturally
93
+
94
+ ## Workflow
95
+
96
+ 1. **List the routes you're adding.** 3 routes? They probably go in one group.
97
+ 2. **Identify the trust posture.** Public? Authed? Trust boundary? That picks the group.
98
+ 3. **Check existing groups.** Does one fit? If yes, use it. Don't create new groups for routes that fit.
99
+ 4. **Layout content:** what's truly shared between these routes? That's the layout. Everything else is page-specific.
100
+ 5. **If creating a new group**, write an ADR (`void-decide`). Group convention drift is annoying to undo.
101
+
102
+ ## Composition
103
+
104
+ - `void-cache-component-pattern` — `(marketing)` is cache-by-default; `(app)` mostly `'use no cache'`.
105
+ - `void-server-action` — `(actions)/` is where Server Actions live.
106
+ - `void-decide` — adding/renaming groups is ADR-worthy.
107
+ - `void-security-guidance` — `(app)/layout.tsx` is the auth boundary; redirects centralized here.
@@ -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-install-prompt-ux` skill (see `docs/plans/skill-audits/void-install-prompt-ux.md` for the full audit):
2
+
3
+ - No external source audited — native VoidCorp skill (beforeinstallprompt capture, engagement-signal threshold, dismiss cooldown, iOS fallback).
4
+
5
+ Strategy: native. Original VoidCorp authoring, not derived from an external source.
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: void-install-prompt-ux
3
+ description: Surface the PWA install prompt at the right moment (engagement signal) with the right UI (custom button, not auto-prompt). Capture beforeinstallprompt, defer, recover declined.
4
+ ---
5
+
6
+ # install-prompt-ux
7
+
8
+ Use when adding "Install app" UX to a PWA, or when figuring out why the default browser prompt doesn't appear / appears at the wrong time. Default browser behavior is broken for most apps — too early, too generic, no recovery.
9
+
10
+ This skill is the void-machine pattern: capture the event, defer it, surface a custom button at a meaningful moment.
11
+
12
+ ## The browser default is bad
13
+
14
+ Without custom code, Chrome (etc.) decides when to show a small browser-styled "Add to Home Screen" toast. The decision is opaque (engagement heuristic), the UI is generic, and once dismissed it doesn't reappear soon. Users either miss it or click "Cancel" reflexively.
15
+
16
+ Solution: hijack the prompt, defer it, show your own button.
17
+
18
+ ## The `beforeinstallprompt` flow
19
+
20
+ ```tsx
21
+ // apps/web/src/components/InstallPrompt.tsx
22
+ 'use client';
23
+
24
+ import { useEffect, useState } from 'react';
25
+
26
+ interface BIPEvent extends Event {
27
+ prompt: () => Promise<void>;
28
+ userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
29
+ }
30
+
31
+ export function InstallPrompt() {
32
+ const [deferred, setDeferred] = useState<BIPEvent | null>(null);
33
+ const [isInstalled, setIsInstalled] = useState(false);
34
+
35
+ useEffect(() => {
36
+ // 1. Capture the event when the browser fires it
37
+ const onBIP = (e: Event) => {
38
+ e.preventDefault(); // don't show browser default
39
+ setDeferred(e as BIPEvent);
40
+ };
41
+ window.addEventListener('beforeinstallprompt', onBIP);
42
+
43
+ // 2. Detect already-installed (PWA opened from home screen)
44
+ const onInstalled = () => {
45
+ setIsInstalled(true);
46
+ setDeferred(null);
47
+ };
48
+ window.addEventListener('appinstalled', onInstalled);
49
+
50
+ // 3. Sanity check: are we already in standalone mode?
51
+ if (window.matchMedia('(display-mode: standalone)').matches) {
52
+ setIsInstalled(true);
53
+ }
54
+
55
+ return () => {
56
+ window.removeEventListener('beforeinstallprompt', onBIP);
57
+ window.removeEventListener('appinstalled', onInstalled);
58
+ };
59
+ }, []);
60
+
61
+ if (isInstalled || !deferred) return null;
62
+
63
+ async function handleInstall() {
64
+ if (!deferred) return;
65
+ await deferred.prompt(); // shows the browser native prompt NOW
66
+ const { outcome } = await deferred.userChoice;
67
+ setDeferred(null); // one shot per page load; can't re-prompt
68
+ if (outcome === 'accepted') {
69
+ // Tracked, navigated to standalone — onInstalled fires shortly
70
+ } else {
71
+ // User dismissed — store decision, don't pester
72
+ localStorage.setItem('install-dismissed-at', String(Date.now()));
73
+ }
74
+ }
75
+
76
+ return (
77
+ <button onClick={handleInstall}>Installer l'app</button>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ## When to show your custom button
83
+
84
+ NOT immediately. Show only after an engagement signal — proof the user finds the app useful:
85
+
86
+ | Signal | Threshold (default) |
87
+ |---|---|
88
+ | Sessions completed | ≥ 2 |
89
+ | Time in-app this session | ≥ 30 seconds |
90
+ | Key action completed | 1 (e.g., created their first contact in Solaar) |
91
+ | Days since first visit | ≥ 1 |
92
+
93
+ Combine: "shown after 2 sessions AND ≥ 30s AND not dismissed in the last 7 days". The combination kills the "saw an empty app, prompted to install, declined forever" failure.
94
+
95
+ ```tsx
96
+ const ENGAGEMENT_THRESHOLD = { sessions: 2, secondsThisSession: 30 };
97
+
98
+ function shouldShow(state) {
99
+ const dismissedAt = Number(localStorage.getItem('install-dismissed-at') ?? 0);
100
+ const daysSinceDismiss = (Date.now() - dismissedAt) / (24 * 60 * 60 * 1000);
101
+ if (dismissedAt && daysSinceDismiss < 7) return false;
102
+ return state.sessions >= ENGAGEMENT_THRESHOLD.sessions &&
103
+ state.secondsThisSession >= ENGAGEMENT_THRESHOLD.secondsThisSession;
104
+ }
105
+ ```
106
+
107
+ ## Recovery: dismissed → can we re-prompt?
108
+
109
+ Once `beforeinstallprompt` is dismissed, Chrome won't refire for at least 90 days (per their heuristic, not contractual). Strategies:
110
+
111
+ - **Cooldown**: store `install-dismissed-at`, don't show button for 7-14 days. After cooldown, if `deferred` is again non-null (Chrome decided to re-fire), show.
112
+ - **Fallback for unsupported browsers** (Safari iOS): provide instructions in a help page ("Tap Share → Add to Home Screen").
113
+
114
+ iOS Safari doesn't fire `beforeinstallprompt` at all. The button can still be useful as a "How to install on iPhone" link.
115
+
116
+ ## Placement of the install button
117
+
118
+ Three patterns; pick one based on app type:
119
+
120
+ - **A. In the settings/profile menu**: discoverable for power users, low-friction. Default.
121
+ - **B. As a dismissible banner**: more aggressive; for content-heavy apps where install is the conversion goal
122
+ - **C. After a key action**: e.g., "Just created your first contact! Install the app to access it offline." Highest conversion when timed right.
123
+
124
+ Avoid: modal pop-ups on first visit (worst conversion + user trust).
125
+
126
+ ## Anti-patterns
127
+
128
+ - ✗ **Calling `deferred.prompt()` without user gesture** — browsers reject; the prompt won't fire
129
+ - ✗ **Showing the install button before SW registers** — install prompt requires manifest + SW; show only after `serviceWorker.ready`
130
+ - ✗ **No recovery for dismissed users** — silent forever
131
+ - ✗ **Pestering on every page** — kills trust; one button in the settings menu is enough for most apps
132
+ - ✗ **No handling for iOS** — Safari doesn't fire BIP; without a fallback "how to install" page, iOS users have no path
133
+
134
+ ## Anatomy of a great PWA install flow (Solaar archetype)
135
+
136
+ 1. New visitor → no install UX
137
+ 2. Visit 2, 30s in → small "Installer" button appears in settings menu (subtle)
138
+ 3. After creating first contact → contextual prompt: "Vos contacts dans la poche. Installer ?"
139
+ 4. User dismisses → 7-day cooldown
140
+ 5. After 7 days, if still using the app → re-prompt in the contextual spot, not in face
141
+
142
+ ## Verification
143
+
144
+ DevTools → Application → Manifest → "Add to home screen" button (forces install in dev).
145
+ Lighthouse → PWA category → "Installable" should be green; otherwise read the failure reasons (usually missing icon, missing start_url, etc.).
146
+
147
+ ## Composition
148
+
149
+ - `void-manifest-checklist` — installability requires a valid manifest first
150
+ - `void-service-worker-strategy` — installability requires SW registered
151
+ - `void-accessibility-check` — install button is interactive; needs label, focus ring
152
+ - `void-observability` — track install events (`window.addEventListener('appinstalled', ...)`) for conversion measurement
153
+ - `void-frontend-design` — when to show, where to place — UX trade-offs covered here
@@ -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-manifest-checklist` skill (see `docs/plans/skill-audits/void-manifest-checklist.md` for the full audit):
2
+
3
+ - No external source audited — native VoidCorp skill (field-by-field manifest checklist with the WHY for each, anti-pattern list, optional-fields-worth-adding section).
4
+
5
+ Strategy: native. Original VoidCorp authoring, not derived from an external source.
@@ -0,0 +1,204 @@
1
+ ---
2
+ name: void-manifest-checklist
3
+ description: "Get manifest.webmanifest right the first time — required fields, icon sizes (192, 512, maskable), display modes, scope, start_url. Single artifact: every field motivated, no dead options."
4
+ ---
5
+
6
+ # manifest-checklist
7
+
8
+ Use when creating or updating the web app manifest. The manifest is the document that tells browsers "this is a PWA, install it like an app". A wrong manifest is the difference between "no install prompt ever" and "installable on all platforms".
9
+
10
+ If you have no manifest yet, this skill is the green-field checklist. If you have one and "install" doesn't work somewhere, this skill is the debug.
11
+
12
+ ## File location and reference
13
+
14
+ ```
15
+ apps/<app>/public/manifest.webmanifest # the file
16
+ apps/<app>/app/layout.tsx # references via <link>
17
+ ```
18
+
19
+ Reference in `<head>`:
20
+
21
+ ```tsx
22
+ // app/layout.tsx
23
+ export const metadata = {
24
+ manifest: '/manifest.webmanifest',
25
+ };
26
+ ```
27
+
28
+ Or for Next 16's typed metadata.ts:
29
+
30
+ ```ts
31
+ // app/manifest.ts
32
+ import type { MetadataRoute } from 'next';
33
+
34
+ export default function manifest(): MetadataRoute.Manifest {
35
+ return { /* ... */ };
36
+ }
37
+ ```
38
+
39
+ Use the TS file if your stack supports it — typo-safe.
40
+
41
+ ## Required fields
42
+
43
+ ```json
44
+ {
45
+ "name": "Solaar",
46
+ "short_name": "Solaar",
47
+ "description": "Relationship intelligence companion.",
48
+ "start_url": "/",
49
+ "scope": "/",
50
+ "display": "standalone",
51
+ "background_color": "#0a0a0a",
52
+ "theme_color": "#0a0a0a",
53
+ "lang": "fr",
54
+ "dir": "ltr",
55
+ "icons": [
56
+ {
57
+ "src": "/icons/icon-192.png",
58
+ "sizes": "192x192",
59
+ "type": "image/png",
60
+ "purpose": "any"
61
+ },
62
+ {
63
+ "src": "/icons/icon-512.png",
64
+ "sizes": "512x512",
65
+ "type": "image/png",
66
+ "purpose": "any"
67
+ },
68
+ {
69
+ "src": "/icons/icon-maskable-192.png",
70
+ "sizes": "192x192",
71
+ "type": "image/png",
72
+ "purpose": "maskable"
73
+ },
74
+ {
75
+ "src": "/icons/icon-maskable-512.png",
76
+ "sizes": "512x512",
77
+ "type": "image/png",
78
+ "purpose": "maskable"
79
+ }
80
+ ]
81
+ }
82
+ ```
83
+
84
+ Every field above has a reason. Skipping ANY breaks installability on some platform.
85
+
86
+ ## Field-by-field
87
+
88
+ ### `name` and `short_name`
89
+
90
+ - `name`: full name shown in the install prompt and OS app list
91
+ - `short_name`: home screen label (truncated platforms). ≤ 12 chars ideal
92
+
93
+ Distinct values when the full name is long: `name: "Solaar by VoidCorp"`, `short_name: "Solaar"`.
94
+
95
+ ### `start_url` and `scope`
96
+
97
+ - `start_url`: where the app opens on launch from home screen. Almost always `/`.
98
+ - `scope`: paths that "belong to" the app. Outside scope, the OS opens browser instead of in-app. Almost always `/`.
99
+
100
+ If you scope to `/app/` and the user visits `/marketing/`, they'll bounce out to browser. Usually undesired.
101
+
102
+ ### `display`
103
+
104
+ | Value | Effect |
105
+ |---|---|
106
+ | `standalone` | Full-screen app, no browser UI. **Default for PWAs.** |
107
+ | `fullscreen` | Even hides the status bar (for games) |
108
+ | `minimal-ui` | Some browser controls visible |
109
+ | `browser` | Normal browser tab (no PWA-ness) |
110
+
111
+ Use `standalone`. The others are niche.
112
+
113
+ ### `theme_color` and `background_color`
114
+
115
+ - `theme_color`: status bar / title bar color in standalone mode
116
+ - `background_color`: splash screen color before the app's CSS loads
117
+
118
+ Set both to your app's primary background. Mismatch causes a flash on launch.
119
+
120
+ ### `lang` and `dir`
121
+
122
+ - `lang`: primary language ISO code (`fr`, `en`, `pt-BR`)
123
+ - `dir`: `ltr` or `rtl`
124
+
125
+ Don't omit. AT and OS use them for accessibility hints.
126
+
127
+ ### `icons`
128
+
129
+ The minimum: **4 icons** — 192 and 512 in both `any` and `maskable` purposes.
130
+
131
+ - `any` purpose: standard square icons (used on browsers, older Android)
132
+ - `maskable`: safe-zone respected (used by Android adaptive icons, where the OS clips to circle/squircle/etc.). MUST have 20% padding around the actual logo
133
+
134
+ Larger sizes (1024) are nice but not required. iOS uses its own `apple-touch-icon.png` (set separately in `<head>`).
135
+
136
+ Generate from one SVG via:
137
+
138
+ ```bash
139
+ npx pwa-asset-generator logo.svg public/icons/ --maskable-only false --padding "20%"
140
+ ```
141
+
142
+ ## Optional fields worth adding
143
+
144
+ ```json
145
+ {
146
+ "categories": ["productivity", "business"],
147
+ "screenshots": [
148
+ {
149
+ "src": "/screenshots/home-narrow.png",
150
+ "sizes": "390x844",
151
+ "form_factor": "narrow",
152
+ "label": "Accueil sur mobile"
153
+ },
154
+ {
155
+ "src": "/screenshots/home-wide.png",
156
+ "sizes": "1280x720",
157
+ "form_factor": "wide",
158
+ "label": "Accueil sur desktop"
159
+ }
160
+ ],
161
+ "shortcuts": [
162
+ {
163
+ "name": "Nouveau contact",
164
+ "url": "/contacts/new",
165
+ "icons": [{ "src": "/icons/new-contact.png", "sizes": "96x96" }]
166
+ }
167
+ ],
168
+ "share_target": {
169
+ "action": "/share",
170
+ "method": "POST",
171
+ "enctype": "multipart/form-data",
172
+ "params": { "title": "title", "text": "text", "url": "url" }
173
+ }
174
+ }
175
+ ```
176
+
177
+ - `categories`: helps Play Store / OS app categorization
178
+ - `screenshots`: shown in install prompt on Android (Chrome). **Set form_factor** so each is shown on the right platform
179
+ - `shortcuts`: appear on long-press of the app icon (Android)
180
+ - `share_target`: receive shared content from other apps
181
+
182
+ ## Anti-patterns
183
+
184
+ - ✗ **Same icon for `any` and `maskable`** — maskable needs 20% padding; non-padded icon gets clipped on Android
185
+ - ✗ **Both `manifest.webmanifest` and `manifest.json`** — confuse browsers; pick `.webmanifest` (correct mime type)
186
+ - ✗ **`start_url: "/?source=pwa"`** with tracking query — breaks back-navigation, surprises the user
187
+ - ✗ **`scope: "."`** — relative scope is fragile; use `/`
188
+ - ✗ **Missing maskable icon** — Android adaptive icons render with broken padding
189
+ - ✗ **Theme color set on `<meta>` but missing in manifest** — inconsistent splash screen
190
+
191
+ ## Verification
192
+
193
+ Browser DevTools → Application → Manifest:
194
+
195
+ - Shows parsed manifest with warnings
196
+ - "Installability" badge red? Read the reasons listed
197
+ - Use Chrome DevTools Lighthouse → PWA category for a comprehensive audit (target 100)
198
+
199
+ ## Composition
200
+
201
+ - `void-install-prompt-ux` — installability depends on manifest being valid
202
+ - `void-service-worker-strategy` — SW + manifest are the two PWA artifacts; both required for install prompt
203
+ - `void-accessibility-check` — `lang` + `dir` are a11y signals
204
+ - `void-frontend-design` — theme_color and icon design should match the brand
@@ -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]