wizz-method 1.4.1 → 1.5.1

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 (574) hide show
  1. package/README.md +6 -4
  2. package/package.json +39 -3
  3. package/skills-registry.yaml +109 -8
  4. package/src/bmm-skills/4-implementation/wizz-code-review/SKILL.md +2 -0
  5. package/src/bmm-skills/4-implementation/wizz-quick-dev/SKILL.md +5 -2
  6. package/src/core-skills/_shared/handoff-protocol.md +61 -0
  7. package/src/core-skills/wizz-customize/SKILL.md +2 -2
  8. package/src/core-skills/wizz-party-mode/references/mode-agent-team.md +1 -1
  9. package/src/core-skills/wizz-party-mode/references/mode-subagent.md +1 -1
  10. package/src/core-skills/wizz-review-adversarial-general/SKILL.md +2 -0
  11. package/src/modules/wizz/README.md +3 -3
  12. package/src/modules/wizz/_shared/communication-rules.md +13 -0
  13. package/src/modules/wizz/_shared/encerramento.md +2 -2
  14. package/src/modules/wizz/agents/wizz-ads/customize.toml +5 -3
  15. package/src/modules/wizz/agents/wizz-copy/customize.toml +5 -3
  16. package/src/modules/wizz/agents/wizz-designer/SKILL.md +2 -2
  17. package/src/modules/wizz/agents/wizz-designer/customize.toml +6 -4
  18. package/src/modules/wizz/agents/wizz-growth/customize.toml +11 -3
  19. package/src/modules/wizz/agents/wizz-maestro/SKILL.md +9 -5
  20. package/src/modules/wizz/agents/wizz-maestro/customize.toml +5 -7
  21. package/src/modules/wizz/agents/wizz-memoria/customize.toml +2 -4
  22. package/src/modules/wizz/agents/wizz-qa/SKILL.md +5 -5
  23. package/src/modules/wizz/agents/wizz-qa/customize.toml +9 -7
  24. package/src/modules/wizz/agents/wizz-seo/customize.toml +5 -3
  25. package/src/modules/wizz/agents/wizz-social/customize.toml +9 -8
  26. package/src/modules/wizz/module.yaml +1 -1
  27. package/src/modules/wizz/overrides/wizz-agent-analyst.toml +4 -5
  28. package/src/modules/wizz/overrides/wizz-agent-architect.toml +11 -3
  29. package/src/modules/wizz/overrides/wizz-agent-dev.toml +6 -4
  30. package/src/modules/wizz/overrides/wizz-agent-pm.toml +4 -2
  31. package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +3 -5
  32. package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +4 -2
  33. package/src/modules/wizz/scripts/wizz-init.mjs +3 -1
  34. package/src/scripts/__pycache__/resolve_customization.cpython-314.pyc +0 -0
  35. package/src/scripts/memlog.py +9 -0
  36. package/src/scripts/resolve_customization.py +93 -3
  37. package/src/skills-lib/adversarial-reviewer/SKILL.md +2 -0
  38. package/src/skills-lib/algorithmic-art/SKILL.md +29 -369
  39. package/src/skills-lib/algorithmic-art/references/interactive-artifact.md +139 -0
  40. package/src/skills-lib/algorithmic-art/references/p5js-implementation.md +121 -0
  41. package/src/skills-lib/algorithmic-art/references/philosophy-creation.md +88 -0
  42. package/src/skills-lib/canvas-design/SKILL.md +9 -38
  43. package/src/skills-lib/canvas-design/references/canvas-execution.md +21 -0
  44. package/src/skills-lib/canvas-design/references/philosophy-examples.md +25 -0
  45. package/src/skills-lib/cerebro/SKILL.md +8 -273
  46. package/src/skills-lib/cerebro/references/comandos-pesquisa-e-sync.md +44 -0
  47. package/src/skills-lib/cerebro/references/comandos-rotina-e-captura.md +94 -0
  48. package/src/skills-lib/cerebro/references/comandos-sessao.md +122 -0
  49. package/src/skills-lib/content-strategy/SKILL.md +12 -316
  50. package/src/skills-lib/content-strategy/references/content-types.md +52 -0
  51. package/src/skills-lib/content-strategy/references/ideation-sources.md +78 -0
  52. package/src/skills-lib/content-strategy/references/pillars-and-keywords.md +78 -0
  53. package/src/skills-lib/content-strategy/references/prioritization-and-output.md +57 -0
  54. package/src/skills-lib/decision-maker/SKILL.md +13 -466
  55. package/src/skills-lib/decision-maker/references/commands-and-edge-cases.md +40 -0
  56. package/src/skills-lib/decision-maker/references/output-format.md +161 -0
  57. package/src/skills-lib/decision-maker/references/references-and-extraction.md +129 -0
  58. package/src/skills-lib/decision-maker/references/six-decisions.md +122 -0
  59. package/src/skills-lib/decision-maker/references/wizz-method-handoff.md +22 -0
  60. package/src/skills-lib/find-skills/SKILL.md +9 -6
  61. package/src/skills-lib/form-cro/SKILL.md +12 -390
  62. package/src/skills-lib/form-cro/references/experiments.md +73 -0
  63. package/src/skills-lib/form-cro/references/field-optimization.md +92 -0
  64. package/src/skills-lib/form-cro/references/flow-and-errors.md +71 -0
  65. package/src/skills-lib/form-cro/references/measurement-output.md +41 -0
  66. package/src/skills-lib/form-cro/references/trust-and-form-types.md +54 -0
  67. package/src/skills-lib/graphify/SKILL.md +2 -20
  68. package/src/skills-lib/huashu-design/SKILL.md +42 -596
  69. package/src/skills-lib/huashu-design/references/anti-slop-principles.md +62 -0
  70. package/src/skills-lib/huashu-design/references/audio-design-rules.md +1 -1
  71. package/src/skills-lib/huashu-design/references/cross-agent-adaptation.md +14 -0
  72. package/src/skills-lib/huashu-design/references/design-direction-fallback.md +113 -0
  73. package/src/skills-lib/huashu-design/references/exception-handling.md +18 -0
  74. package/src/skills-lib/huashu-design/references/fact-verification.md +36 -0
  75. package/src/skills-lib/huashu-design/references/ios-prototype.md +146 -0
  76. package/src/skills-lib/huashu-design/references/sfx-library.md +7 -0
  77. package/src/skills-lib/huashu-design/references/starter-components.md +24 -0
  78. package/src/skills-lib/huashu-design/references/video-export.md +1 -1
  79. package/src/skills-lib/huashu-design/references/watermark-policy.md +23 -0
  80. package/src/skills-lib/huashu-design/scripts/add-music.sh +12 -1
  81. package/src/skills-lib/huashu-design/scripts/mix-voiceover.sh +11 -0
  82. package/src/skills-lib/humanizer/SKILL.md +23 -431
  83. package/src/skills-lib/humanizer/references/ai-writing-patterns.md +314 -0
  84. package/src/skills-lib/humanizer/references/full-example.md +72 -0
  85. package/src/skills-lib/humanizer/references/personality-and-soul.md +36 -0
  86. package/src/skills-lib/impeccable/SKILL.md +37 -153
  87. package/src/skills-lib/impeccable/references/design-rules.md +95 -0
  88. package/src/skills-lib/impeccable/references/pin-unpin-and-hooks.md +17 -0
  89. package/src/skills-lib/impeccable/references/routing-rules.md +28 -0
  90. package/src/skills-lib/implementation-planner/SKILL.md +22 -529
  91. package/src/skills-lib/implementation-planner/references/folder-structure-and-dependencies.md +132 -0
  92. package/src/skills-lib/implementation-planner/references/handoff-template.md +34 -0
  93. package/src/skills-lib/implementation-planner/references/implementation-phases.md +54 -0
  94. package/src/skills-lib/implementation-planner/references/implementation-types.md +28 -0
  95. package/src/skills-lib/implementation-planner/references/motion-path-implementation.md +57 -0
  96. package/src/skills-lib/implementation-planner/references/output-templates.md +92 -0
  97. package/src/skills-lib/implementation-planner/references/performance-plan.md +52 -0
  98. package/src/skills-lib/inicio-de-projeto/SKILL.md +4 -224
  99. package/src/skills-lib/inicio-de-projeto/references/implementacao-api-forms.md +112 -0
  100. package/src/skills-lib/inicio-de-projeto/references/padroes-arquiteturais-e-pastas.md +71 -0
  101. package/src/skills-lib/inicio-de-projeto/references/seguranca-e-regras-codigo.md +26 -0
  102. package/src/skills-lib/launch-strategy/SKILL.md +9 -311
  103. package/src/skills-lib/launch-strategy/references/five-phase-approach.md +76 -0
  104. package/src/skills-lib/launch-strategy/references/launch-checklist.md +34 -0
  105. package/src/skills-lib/launch-strategy/references/orb-framework.md +76 -0
  106. package/src/skills-lib/launch-strategy/references/post-launch-and-ongoing.md +64 -0
  107. package/src/skills-lib/launch-strategy/references/product-hunt-strategy.md +52 -0
  108. package/src/skills-lib/marketing-psychology/SKILL.md +18 -401
  109. package/src/skills-lib/marketing-psychology/references/design-and-delivery-models.md +56 -0
  110. package/src/skills-lib/marketing-psychology/references/foundational-thinking-models.md +76 -0
  111. package/src/skills-lib/marketing-psychology/references/growth-and-scaling-models.md +46 -0
  112. package/src/skills-lib/marketing-psychology/references/influencing-behavior.md +71 -0
  113. package/src/skills-lib/marketing-psychology/references/pricing-psychology.md +31 -0
  114. package/src/skills-lib/marketing-psychology/references/understanding-buyers.md +116 -0
  115. package/src/skills-lib/motion-3d-director/SKILL.md +23 -370
  116. package/src/skills-lib/motion-3d-director/references/image-to-video-workflow.md +166 -0
  117. package/src/skills-lib/motion-3d-director/references/motion-paths.md +119 -0
  118. package/src/skills-lib/motion-3d-director/references/performance-and-handoff.md +51 -0
  119. package/src/skills-lib/popup-cro/SKILL.md +11 -414
  120. package/src/skills-lib/popup-cro/references/design-copy-compliance.md +81 -0
  121. package/src/skills-lib/popup-cro/references/experiments.md +82 -0
  122. package/src/skills-lib/popup-cro/references/rules-measurement-output.md +87 -0
  123. package/src/skills-lib/popup-cro/references/triggers-and-popup-types.md +108 -0
  124. package/src/skills-lib/signup-flow-cro/SKILL.md +13 -321
  125. package/src/skills-lib/signup-flow-cro/references/experiments.md +72 -0
  126. package/src/skills-lib/signup-flow-cro/references/field-optimization.md +49 -0
  127. package/src/skills-lib/signup-flow-cro/references/flow-structure.md +38 -0
  128. package/src/skills-lib/signup-flow-cro/references/measurement-output-patterns.md +62 -0
  129. package/src/skills-lib/signup-flow-cro/references/trust-and-post-submit.md +40 -0
  130. package/src/skills-lib/taste-redesign/SKILL.md +10 -146
  131. package/src/skills-lib/taste-redesign/references/design-audit.md +120 -0
  132. package/src/skills-lib/taste-redesign/references/upgrade-techniques.md +31 -0
  133. package/src/skills-lib/ui-ux-pro-max/SKILL.md +9 -353
  134. package/src/skills-lib/ui-ux-pro-max/references/common-rules-checklist.md +76 -0
  135. package/src/skills-lib/ui-ux-pro-max/references/rules-quick-reference.md +70 -0
  136. package/src/skills-lib/ui-ux-pro-max/references/search-reference.md +45 -0
  137. package/src/skills-lib/ui-ux-pro-max/references/workflow-guide.md +157 -0
  138. package/src/skills-lib/web-security/SKILL.md +13 -187
  139. package/src/skills-lib/web-security/references/checklist-deploy.md +52 -0
  140. package/src/skills-lib/web-security/references/headers-rate-limit-cors.md +78 -0
  141. package/src/skills-lib/web-security/references/owasp-top5-detalhado.md +51 -0
  142. package/src/skills-lib/wizz-router/SKILL.md +20 -9
  143. package/src/skills-lib/wizz-router/references/auditoria-360.md +4 -4
  144. package/src/skills-lib/wizz-router/references/routing-table-flat.md +15 -15
  145. package/tools/fetch-assets.mjs +277 -0
  146. package/tools/installer/commands/fetch-assets.js +71 -0
  147. package/tools/installer/commands/install.js +35 -3
  148. package/tools/installer/commands/trace-report.js +131 -0
  149. package/tools/installer/core/config.js +9 -0
  150. package/tools/installer/core/help-catalog.js +181 -0
  151. package/tools/installer/core/install-paths.js +48 -3
  152. package/tools/installer/core/installer.js +253 -618
  153. package/tools/installer/core/manifest-generator.js +8 -1
  154. package/tools/installer/core/manifest.js +67 -22
  155. package/tools/installer/core/module-config-writer.js +110 -0
  156. package/tools/installer/core/preflight-tools-check.js +82 -0
  157. package/tools/installer/core/quick-update.js +209 -0
  158. package/tools/installer/core/user-file-preservation.js +250 -0
  159. package/tools/installer/modules/channel-resolver.js +34 -2
  160. package/tools/installer/modules/cli-config.js +127 -34
  161. package/tools/installer/modules/deps-cache.js +28 -1
  162. package/tools/installer/modules/env-vars.js +446 -0
  163. package/tools/installer/modules/external-manager.js +40 -6
  164. package/tools/installer/modules/mcp-config.js +180 -37
  165. package/tools/installer/modules/module-help-schema.js +2 -1
  166. package/tools/installer/modules/official-modules.js +1 -1
  167. package/tools/installer/modules/registry-resolve.js +74 -0
  168. package/tools/installer/modules/skills-lib.js +11 -15
  169. package/tools/installer/ui.js +71 -5
  170. package/wizz-modules.yaml +15 -5
  171. package/.claude-plugin/marketplace.json +0 -80
  172. package/AGENTS.md +0 -12
  173. package/build/artifacts/llms-full.txt +0 -4049
  174. package/build/artifacts/llms.txt +0 -28
  175. package/build/site/404.html +0 -55
  176. package/build/site/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js +0 -1
  177. package/build/site/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js +0 -1
  178. package/build/site/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js +0 -1
  179. package/build/site/_astro/ec.0vx5m.js +0 -3
  180. package/build/site/_astro/ec.v4551.css +0 -1
  181. package/build/site/_astro/index.DdjI3lF_.css +0 -1
  182. package/build/site/_astro/page.B1D-nYk3.js +0 -1
  183. package/build/site/_astro/print.DNXP8c50.css +0 -1
  184. package/build/site/_astro/ui-core.D_Lfcn_I.js +0 -2
  185. package/build/site/diagrams/checkpoint-preview-diagram-fr.webp +0 -0
  186. package/build/site/diagrams/checkpoint-preview-diagram.png +0 -0
  187. package/build/site/diagrams/quick-dev-diagram-fr.webp +0 -0
  188. package/build/site/diagrams/quick-dev-diagram.png +0 -0
  189. package/build/site/explanation/advanced-elicitation/index.html +0 -105
  190. package/build/site/explanation/adversarial-review/index.html +0 -109
  191. package/build/site/explanation/analysis-phase/index.html +0 -129
  192. package/build/site/explanation/brainstorming/index.html +0 -92
  193. package/build/site/explanation/checkpoint-preview/index.html +0 -121
  194. package/build/site/explanation/established-projects-faq/index.html +0 -107
  195. package/build/site/explanation/forensic-investigation/index.html +0 -167
  196. package/build/site/explanation/named-agents/index.html +0 -187
  197. package/build/site/explanation/party-mode/index.html +0 -256
  198. package/build/site/explanation/preventing-agent-conflicts/index.html +0 -185
  199. package/build/site/explanation/project-context/index.html +0 -198
  200. package/build/site/explanation/quick-dev/index.html +0 -113
  201. package/build/site/explanation/web-bundles/index.html +0 -178
  202. package/build/site/explanation/why-solutioning-matters/index.html +0 -168
  203. package/build/site/how-to/customize-wizz/index.html +0 -277
  204. package/build/site/how-to/established-projects/index.html +0 -165
  205. package/build/site/how-to/expand-wizz-for-your-org/index.html +0 -245
  206. package/build/site/how-to/get-answers-about-wizz/index.html +0 -129
  207. package/build/site/how-to/install-custom-modules/index.html +0 -197
  208. package/build/site/how-to/install-wizz/index.html +0 -330
  209. package/build/site/how-to/non-interactive-installation/index.html +0 -73
  210. package/build/site/how-to/project-context/index.html +0 -141
  211. package/build/site/how-to/quick-fixes/index.html +0 -122
  212. package/build/site/how-to/shard-large-documents/index.html +0 -103
  213. package/build/site/how-to/upgrade-to-v6/index.html +0 -185
  214. package/build/site/how-to/use-web-bundles/index.html +0 -99
  215. package/build/site/img/wizz-dark.png +0 -0
  216. package/build/site/img/wizz-light.png +0 -0
  217. package/build/site/index.html +0 -128
  218. package/build/site/llms-full.txt +0 -4049
  219. package/build/site/llms.txt +0 -28
  220. package/build/site/pagefind/fragment/en_175de32.pf_fragment +0 -0
  221. package/build/site/pagefind/fragment/en_24258fb.pf_fragment +0 -0
  222. package/build/site/pagefind/fragment/en_24f53a6.pf_fragment +0 -0
  223. package/build/site/pagefind/fragment/en_27ba8f9.pf_fragment +0 -0
  224. package/build/site/pagefind/fragment/en_296ddb9.pf_fragment +0 -0
  225. package/build/site/pagefind/fragment/en_2b5aa5c.pf_fragment +0 -0
  226. package/build/site/pagefind/fragment/en_49047e0.pf_fragment +0 -0
  227. package/build/site/pagefind/fragment/en_4a187d2.pf_fragment +0 -0
  228. package/build/site/pagefind/fragment/en_514725b.pf_fragment +0 -0
  229. package/build/site/pagefind/fragment/en_583316f.pf_fragment +0 -0
  230. package/build/site/pagefind/fragment/en_6465dfb.pf_fragment +0 -0
  231. package/build/site/pagefind/fragment/en_67825a4.pf_fragment +0 -0
  232. package/build/site/pagefind/fragment/en_82aec61.pf_fragment +0 -0
  233. package/build/site/pagefind/fragment/en_85dcebf.pf_fragment +0 -0
  234. package/build/site/pagefind/fragment/en_887ce56.pf_fragment +0 -0
  235. package/build/site/pagefind/fragment/en_89a1a7a.pf_fragment +0 -0
  236. package/build/site/pagefind/fragment/en_8ade291.pf_fragment +0 -0
  237. package/build/site/pagefind/fragment/en_8c11f8a.pf_fragment +0 -0
  238. package/build/site/pagefind/fragment/en_8c1bde3.pf_fragment +0 -0
  239. package/build/site/pagefind/fragment/en_92d7cc7.pf_fragment +0 -0
  240. package/build/site/pagefind/fragment/en_94bfc21.pf_fragment +0 -0
  241. package/build/site/pagefind/fragment/en_9b57d7d.pf_fragment +0 -0
  242. package/build/site/pagefind/fragment/en_ab62b53.pf_fragment +0 -0
  243. package/build/site/pagefind/fragment/en_b0d23ee.pf_fragment +0 -0
  244. package/build/site/pagefind/fragment/en_ba9fb37.pf_fragment +0 -0
  245. package/build/site/pagefind/fragment/en_bb113eb.pf_fragment +0 -0
  246. package/build/site/pagefind/fragment/en_bfc56b6.pf_fragment +0 -0
  247. package/build/site/pagefind/fragment/en_c6d9e48.pf_fragment +0 -0
  248. package/build/site/pagefind/fragment/en_cdd772f.pf_fragment +0 -0
  249. package/build/site/pagefind/fragment/en_cdd885c.pf_fragment +0 -0
  250. package/build/site/pagefind/fragment/en_cefed6a.pf_fragment +0 -0
  251. package/build/site/pagefind/fragment/en_d890205.pf_fragment +0 -0
  252. package/build/site/pagefind/fragment/en_da351b7.pf_fragment +0 -0
  253. package/build/site/pagefind/fragment/en_ea289f9.pf_fragment +0 -0
  254. package/build/site/pagefind/fragment/en_f1c3711.pf_fragment +0 -0
  255. package/build/site/pagefind/index/en_5b9d8c6.pf_index +0 -0
  256. package/build/site/pagefind/index/en_868614c.pf_index +0 -0
  257. package/build/site/pagefind/index/en_e4f9bff.pf_index +0 -0
  258. package/build/site/pagefind/pagefind-entry.json +0 -1
  259. package/build/site/pagefind/pagefind-highlight.js +0 -1064
  260. package/build/site/pagefind/pagefind-modular-ui.css +0 -214
  261. package/build/site/pagefind/pagefind-modular-ui.js +0 -8
  262. package/build/site/pagefind/pagefind-ui.css +0 -1
  263. package/build/site/pagefind/pagefind-ui.js +0 -2
  264. package/build/site/pagefind/pagefind.en_4e69d7f053.pf_meta +0 -0
  265. package/build/site/pagefind/pagefind.js +0 -6
  266. package/build/site/pagefind/wasm.en.pagefind +0 -0
  267. package/build/site/pagefind/wasm.unknown.pagefind +0 -0
  268. package/build/site/reference/agents/index.html +0 -168
  269. package/build/site/reference/commands/index.html +0 -254
  270. package/build/site/reference/core-tools/index.html +0 -384
  271. package/build/site/reference/modules/index.html +0 -132
  272. package/build/site/reference/testing/index.html +0 -218
  273. package/build/site/reference/workflow-map/index.html +0 -266
  274. package/build/site/roadmap/index.html +0 -77
  275. package/build/site/robots.txt +0 -37
  276. package/build/site/sitemap-0.xml +0 -1
  277. package/build/site/sitemap-index.xml +0 -1
  278. package/build/site/tutorials/getting-started/index.html +0 -386
  279. package/build/site/wizz-icon-orange.svg +0 -7
  280. package/build/site/workflow-map-diagram-fr.html +0 -375
  281. package/build/site/workflow-map-diagram.html +0 -375
  282. package/evals/bmm-skills/wizz-product-brief/evals.json +0 -237
  283. package/evals/bmm-skills/wizz-product-brief/files/branfield-memo.md +0 -46
  284. package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/addendum.md +0 -40
  285. package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/brief.md +0 -56
  286. package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/decision-log.md +0 -27
  287. package/evals/bmm-skills/wizz-product-brief/files/meridian-mobility-report.md +0 -116
  288. package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/addendum.md +0 -41
  289. package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/brief.md +0 -57
  290. package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/decision-log.md +0 -29
  291. package/evals/bmm-skills/wizz-product-brief/files/pantry-bridge-interviews.md +0 -90
  292. package/evals/bmm-skills/wizz-product-brief/files/q2-brainstorm.md +0 -101
  293. package/evals/bmm-skills/wizz-product-brief/triggers.json +0 -18
  294. package/evals/routing/dataset.json +0 -290
  295. package/evals/routing/run-routing-eval.mjs +0 -89
  296. package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  297. package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  298. package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  299. package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  300. package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  301. package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  302. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  303. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  304. package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  305. package/src/skills-lib/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  306. package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  307. package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  308. package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  309. package/src/skills-lib/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  310. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  311. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  312. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  313. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  314. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  315. package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  316. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  317. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  318. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  319. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  320. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  321. package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  322. package/src/skills-lib/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  323. package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  324. package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  325. package/src/skills-lib/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  326. package/src/skills-lib/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  327. package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  328. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  329. package/src/skills-lib/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  330. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  331. package/src/skills-lib/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  332. package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  333. package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  334. package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  335. package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  336. package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  337. package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  338. package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  339. package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  340. package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  341. package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  342. package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  343. package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  344. package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  345. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  346. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  347. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  348. package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  349. package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  350. package/src/skills-lib/huashu-design/assets/bgm-ad.mp3 +0 -0
  351. package/src/skills-lib/huashu-design/assets/bgm-educational-alt.mp3 +0 -0
  352. package/src/skills-lib/huashu-design/assets/bgm-educational.mp3 +0 -0
  353. package/src/skills-lib/huashu-design/assets/bgm-tech.mp3 +0 -0
  354. package/src/skills-lib/huashu-design/assets/bgm-tutorial-alt.mp3 +0 -0
  355. package/src/skills-lib/huashu-design/assets/bgm-tutorial.mp3 +0 -0
  356. package/src/skills-lib/huashu-design/assets/sfx/container/card-flip.mp3 +0 -0
  357. package/src/skills-lib/huashu-design/assets/sfx/container/card-snap.mp3 +0 -0
  358. package/src/skills-lib/huashu-design/assets/sfx/container/modal-open.mp3 +0 -0
  359. package/src/skills-lib/huashu-design/assets/sfx/container/stack-collapse.mp3 +0 -0
  360. package/src/skills-lib/huashu-design/assets/sfx/feedback/achievement.mp3 +0 -0
  361. package/src/skills-lib/huashu-design/assets/sfx/feedback/error-tone.mp3 +0 -0
  362. package/src/skills-lib/huashu-design/assets/sfx/feedback/notification-pop.mp3 +0 -0
  363. package/src/skills-lib/huashu-design/assets/sfx/feedback/success-chime.mp3 +0 -0
  364. package/src/skills-lib/huashu-design/assets/sfx/impact/brand-stamp.mp3 +0 -0
  365. package/src/skills-lib/huashu-design/assets/sfx/impact/drop-thud.mp3 +0 -0
  366. package/src/skills-lib/huashu-design/assets/sfx/impact/logo-reveal-v2.mp3 +0 -0
  367. package/src/skills-lib/huashu-design/assets/sfx/impact/logo-reveal.mp3 +0 -0
  368. package/src/skills-lib/huashu-design/assets/sfx/keyboard/delete-key.mp3 +0 -0
  369. package/src/skills-lib/huashu-design/assets/sfx/keyboard/enter.mp3 +0 -0
  370. package/src/skills-lib/huashu-design/assets/sfx/keyboard/space-tap.mp3 +0 -0
  371. package/src/skills-lib/huashu-design/assets/sfx/keyboard/type-fast.mp3 +0 -0
  372. package/src/skills-lib/huashu-design/assets/sfx/keyboard/type.mp3 +0 -0
  373. package/src/skills-lib/huashu-design/assets/sfx/magic/ai-process.mp3 +0 -0
  374. package/src/skills-lib/huashu-design/assets/sfx/magic/sparkle.mp3 +0 -0
  375. package/src/skills-lib/huashu-design/assets/sfx/magic/transform.mp3 +0 -0
  376. package/src/skills-lib/huashu-design/assets/sfx/progress/complete-done.mp3 +0 -0
  377. package/src/skills-lib/huashu-design/assets/sfx/progress/generate-start.mp3 +0 -0
  378. package/src/skills-lib/huashu-design/assets/sfx/progress/loading-tick.mp3 +0 -0
  379. package/src/skills-lib/huashu-design/assets/sfx/terminal/command-execute.mp3 +0 -0
  380. package/src/skills-lib/huashu-design/assets/sfx/terminal/cursor-blink.mp3 +0 -0
  381. package/src/skills-lib/huashu-design/assets/sfx/terminal/output-appear.mp3 +0 -0
  382. package/src/skills-lib/huashu-design/assets/sfx/transition/dissolve.mp3 +0 -0
  383. package/src/skills-lib/huashu-design/assets/sfx/transition/slide-in.mp3 +0 -0
  384. package/src/skills-lib/huashu-design/assets/sfx/transition/swipe-horizontal.mp3 +0 -0
  385. package/src/skills-lib/huashu-design/assets/sfx/transition/whoosh-fast.mp3 +0 -0
  386. package/src/skills-lib/huashu-design/assets/sfx/transition/whoosh.mp3 +0 -0
  387. package/src/skills-lib/huashu-design/assets/sfx/ui/click-soft.mp3 +0 -0
  388. package/src/skills-lib/huashu-design/assets/sfx/ui/click.mp3 +0 -0
  389. package/src/skills-lib/huashu-design/assets/sfx/ui/focus.mp3 +0 -0
  390. package/src/skills-lib/huashu-design/assets/sfx/ui/hover-subtle.mp3 +0 -0
  391. package/src/skills-lib/huashu-design/assets/sfx/ui/tap-finger.mp3 +0 -0
  392. package/src/skills-lib/huashu-design/assets/sfx/ui/toggle-on.mp3 +0 -0
  393. package/src/squads/README.md +0 -39
  394. package/src/squads/advisory-board/README.md +0 -34
  395. package/src/squads/advisory-board/agents/board-chair.md +0 -161
  396. package/src/squads/advisory-board/agents/brene-brown.md +0 -296
  397. package/src/squads/advisory-board/agents/charlie-munger.md +0 -590
  398. package/src/squads/advisory-board/agents/derek-sivers.md +0 -268
  399. package/src/squads/advisory-board/agents/naval-ravikant.md +0 -251
  400. package/src/squads/advisory-board/agents/patrick-lencioni.md +0 -394
  401. package/src/squads/advisory-board/agents/peter-thiel.md +0 -269
  402. package/src/squads/advisory-board/agents/ray-dalio.md +0 -567
  403. package/src/squads/advisory-board/agents/reid-hoffman.md +0 -278
  404. package/src/squads/advisory-board/agents/simon-sinek.md +0 -291
  405. package/src/squads/advisory-board/agents/yvon-chouinard.md +0 -275
  406. package/src/squads/advisory-board/squad.yaml +0 -50
  407. package/src/squads/brand-squad/README.md +0 -60
  408. package/src/squads/brand-squad/agents/al-ries.md +0 -175
  409. package/src/squads/brand-squad/agents/alina-wheeler.md +0 -184
  410. package/src/squads/brand-squad/agents/archetype-consultant.md +0 -215
  411. package/src/squads/brand-squad/agents/brand-chief.md +0 -158
  412. package/src/squads/brand-squad/agents/byron-sharp.md +0 -169
  413. package/src/squads/brand-squad/agents/david-aaker.md +0 -166
  414. package/src/squads/brand-squad/agents/denise-yohn.md +0 -172
  415. package/src/squads/brand-squad/agents/domain-scout.md +0 -135
  416. package/src/squads/brand-squad/agents/donald-miller.md +0 -179
  417. package/src/squads/brand-squad/agents/emily-heyward.md +0 -147
  418. package/src/squads/brand-squad/agents/jean-noel-kapferer.md +0 -189
  419. package/src/squads/brand-squad/agents/kevin-keller.md +0 -199
  420. package/src/squads/brand-squad/agents/marty-neumeier.md +0 -170
  421. package/src/squads/brand-squad/agents/miller-sticky-brand.md +0 -180
  422. package/src/squads/brand-squad/agents/naming-strategist.md +0 -171
  423. package/src/squads/brand-squad/squad.yaml +0 -117
  424. package/src/squads/c-level-squad/README.md +0 -29
  425. package/src/squads/c-level-squad/agents/caio-architect.md +0 -235
  426. package/src/squads/c-level-squad/agents/cio-engineer.md +0 -209
  427. package/src/squads/c-level-squad/agents/cmo-architect.md +0 -208
  428. package/src/squads/c-level-squad/agents/coo-orchestrator.md +0 -193
  429. package/src/squads/c-level-squad/agents/cto-architect.md +0 -194
  430. package/src/squads/c-level-squad/agents/vision-chief.md +0 -201
  431. package/src/squads/c-level-squad/squad.yaml +0 -45
  432. package/src/squads/claude-code-mastery/README.md +0 -146
  433. package/src/squads/claude-code-mastery/agents/claude-mastery-chief.md +0 -554
  434. package/src/squads/claude-code-mastery/agents/config-engineer.md +0 -865
  435. package/src/squads/claude-code-mastery/agents/hooks-architect.md +0 -1013
  436. package/src/squads/claude-code-mastery/agents/mcp-integrator.md +0 -791
  437. package/src/squads/claude-code-mastery/agents/project-integrator.md +0 -1196
  438. package/src/squads/claude-code-mastery/agents/roadmap-sentinel.md +0 -931
  439. package/src/squads/claude-code-mastery/agents/skill-craftsman.md +0 -1250
  440. package/src/squads/claude-code-mastery/agents/swarm-orchestrator.md +0 -1008
  441. package/src/squads/copy-squad/README.md +0 -65
  442. package/src/squads/copy-squad/agents/andre-chaperon.md +0 -206
  443. package/src/squads/copy-squad/agents/ben-settle.md +0 -194
  444. package/src/squads/copy-squad/agents/claude-hopkins.md +0 -182
  445. package/src/squads/copy-squad/agents/clayton-makepeace.md +0 -225
  446. package/src/squads/copy-squad/agents/copy-chief.md +0 -166
  447. package/src/squads/copy-squad/agents/dan-kennedy.md +0 -202
  448. package/src/squads/copy-squad/agents/dan-koe.md +0 -223
  449. package/src/squads/copy-squad/agents/david-deutsch.md +0 -197
  450. package/src/squads/copy-squad/agents/david-ogilvy.md +0 -198
  451. package/src/squads/copy-squad/agents/eugene-schwartz.md +0 -238
  452. package/src/squads/copy-squad/agents/frank-kern.md +0 -195
  453. package/src/squads/copy-squad/agents/gary-bencivenga.md +0 -197
  454. package/src/squads/copy-squad/agents/gary-halbert.md +0 -219
  455. package/src/squads/copy-squad/agents/jim-rutz.md +0 -193
  456. package/src/squads/copy-squad/agents/joe-sugarman.md +0 -234
  457. package/src/squads/copy-squad/agents/john-carlton.md +0 -203
  458. package/src/squads/copy-squad/agents/jon-benson.md +0 -196
  459. package/src/squads/copy-squad/agents/parris-lampropoulos.md +0 -188
  460. package/src/squads/copy-squad/agents/robert-collier.md +0 -183
  461. package/src/squads/copy-squad/agents/russell-brunson.md +0 -229
  462. package/src/squads/copy-squad/agents/ry-schwartz.md +0 -185
  463. package/src/squads/copy-squad/agents/stefan-georgi.md +0 -188
  464. package/src/squads/copy-squad/agents/todd-brown.md +0 -171
  465. package/src/squads/copy-squad/squad.yaml +0 -87
  466. package/src/squads/cybersecurity/README.md +0 -38
  467. package/src/squads/cybersecurity/agents/busterer.md +0 -108
  468. package/src/squads/cybersecurity/agents/cartographer.md +0 -114
  469. package/src/squads/cybersecurity/agents/chris-sanders.md +0 -205
  470. package/src/squads/cybersecurity/agents/command-generator.md +0 -121
  471. package/src/squads/cybersecurity/agents/cyber-chief.md +0 -120
  472. package/src/squads/cybersecurity/agents/dirber.md +0 -111
  473. package/src/squads/cybersecurity/agents/fuzzer.md +0 -121
  474. package/src/squads/cybersecurity/agents/georgia-weidman.md +0 -178
  475. package/src/squads/cybersecurity/agents/jim-manico.md +0 -182
  476. package/src/squads/cybersecurity/agents/marcus-carey.md +0 -200
  477. package/src/squads/cybersecurity/agents/omar-santos.md +0 -206
  478. package/src/squads/cybersecurity/agents/peter-kim.md +0 -179
  479. package/src/squads/cybersecurity/agents/ripper.md +0 -121
  480. package/src/squads/cybersecurity/agents/rogue.md +0 -116
  481. package/src/squads/cybersecurity/agents/shannon-runner.md +0 -108
  482. package/src/squads/cybersecurity/squad.yaml +0 -56
  483. package/src/squads/data-squad/README.md +0 -30
  484. package/src/squads/data-squad/agents/avinash-kaushik.md +0 -268
  485. package/src/squads/data-squad/agents/data-chief.md +0 -167
  486. package/src/squads/data-squad/agents/david-spinks.md +0 -277
  487. package/src/squads/data-squad/agents/nick-mehta.md +0 -294
  488. package/src/squads/data-squad/agents/peter-fader.md +0 -246
  489. package/src/squads/data-squad/agents/sean-ellis.md +0 -303
  490. package/src/squads/data-squad/agents/wes-kao.md +0 -268
  491. package/src/squads/data-squad/squad.yaml +0 -46
  492. package/src/squads/design-squad/README.md +0 -31
  493. package/src/squads/design-squad/agents/brad-frost.md +0 -185
  494. package/src/squads/design-squad/agents/dan-mall.md +0 -178
  495. package/src/squads/design-squad/agents/dave-malouf.md +0 -198
  496. package/src/squads/design-squad/agents/design-chief.md +0 -109
  497. package/src/squads/design-squad/agents/design-system-architect.md +0 -109
  498. package/src/squads/design-squad/agents/ui-engineer.md +0 -102
  499. package/src/squads/design-squad/agents/ux-designer.md +0 -105
  500. package/src/squads/design-squad/agents/visual-generator.md +0 -108
  501. package/src/squads/design-squad/squad.yaml +0 -48
  502. package/src/squads/hormozi-squad/README.md +0 -39
  503. package/src/squads/hormozi-squad/agents/hormozi-ads.md +0 -159
  504. package/src/squads/hormozi-squad/agents/hormozi-advisor.md +0 -178
  505. package/src/squads/hormozi-squad/agents/hormozi-audit.md +0 -178
  506. package/src/squads/hormozi-squad/agents/hormozi-chief.md +0 -111
  507. package/src/squads/hormozi-squad/agents/hormozi-closer.md +0 -179
  508. package/src/squads/hormozi-squad/agents/hormozi-content.md +0 -166
  509. package/src/squads/hormozi-squad/agents/hormozi-copy.md +0 -152
  510. package/src/squads/hormozi-squad/agents/hormozi-hooks.md +0 -177
  511. package/src/squads/hormozi-squad/agents/hormozi-launch.md +0 -160
  512. package/src/squads/hormozi-squad/agents/hormozi-leads.md +0 -198
  513. package/src/squads/hormozi-squad/agents/hormozi-models.md +0 -191
  514. package/src/squads/hormozi-squad/agents/hormozi-offers.md +0 -197
  515. package/src/squads/hormozi-squad/agents/hormozi-pricing.md +0 -151
  516. package/src/squads/hormozi-squad/agents/hormozi-retention.md +0 -166
  517. package/src/squads/hormozi-squad/agents/hormozi-scale.md +0 -175
  518. package/src/squads/hormozi-squad/agents/hormozi-workshop.md +0 -160
  519. package/src/squads/hormozi-squad/squad.yaml +0 -60
  520. package/src/squads/movement/README.md +0 -29
  521. package/src/squads/movement/agents/analista-de-impacto.md +0 -350
  522. package/src/squads/movement/agents/estrategista-de-ciclo.md +0 -301
  523. package/src/squads/movement/agents/fenomenologo.md +0 -169
  524. package/src/squads/movement/agents/identitario.md +0 -265
  525. package/src/squads/movement/agents/manifestador.md +0 -279
  526. package/src/squads/movement/agents/movement-architect.md +0 -210
  527. package/src/squads/movement/agents/movement-chief.md +0 -135
  528. package/src/squads/movement/squad.yaml +0 -45
  529. package/src/squads/storytelling/README.md +0 -35
  530. package/src/squads/storytelling/agents/blake-snyder.md +0 -225
  531. package/src/squads/storytelling/agents/dan-harmon.md +0 -167
  532. package/src/squads/storytelling/agents/joseph-campbell.md +0 -184
  533. package/src/squads/storytelling/agents/keith-johnstone.md +0 -157
  534. package/src/squads/storytelling/agents/kindra-hall.md +0 -162
  535. package/src/squads/storytelling/agents/marshall-ganz.md +0 -167
  536. package/src/squads/storytelling/agents/matthew-dicks.md +0 -152
  537. package/src/squads/storytelling/agents/nancy-duarte.md +0 -154
  538. package/src/squads/storytelling/agents/oren-klaff.md +0 -166
  539. package/src/squads/storytelling/agents/park-howell.md +0 -152
  540. package/src/squads/storytelling/agents/shawn-coyne.md +0 -208
  541. package/src/squads/storytelling/agents/story-chief.md +0 -155
  542. package/src/squads/storytelling/squad.yaml +0 -52
  543. package/src/squads/traffic-masters/README.md +0 -39
  544. package/src/squads/traffic-masters/agents/ad-midas.md +0 -149
  545. package/src/squads/traffic-masters/agents/ads-analyst.md +0 -135
  546. package/src/squads/traffic-masters/agents/creative-analyst.md +0 -142
  547. package/src/squads/traffic-masters/agents/depesh-mandalia.md +0 -174
  548. package/src/squads/traffic-masters/agents/fiscal.md +0 -144
  549. package/src/squads/traffic-masters/agents/kasim-aslam.md +0 -158
  550. package/src/squads/traffic-masters/agents/media-buyer.md +0 -159
  551. package/src/squads/traffic-masters/agents/molly-pittman.md +0 -185
  552. package/src/squads/traffic-masters/agents/nicholas-kusmich.md +0 -157
  553. package/src/squads/traffic-masters/agents/pedro-sobral.md +0 -158
  554. package/src/squads/traffic-masters/agents/performance-analyst.md +0 -135
  555. package/src/squads/traffic-masters/agents/pixel-specialist.md +0 -144
  556. package/src/squads/traffic-masters/agents/ralph-burns.md +0 -163
  557. package/src/squads/traffic-masters/agents/scale-optimizer.md +0 -144
  558. package/src/squads/traffic-masters/agents/tom-breeze.md +0 -175
  559. package/src/squads/traffic-masters/agents/traffic-chief.md +0 -97
  560. package/src/squads/traffic-masters/squad.yaml +0 -59
  561. package/tools/bundle-web-bundles.js +0 -117
  562. package/tools/format-workflow-md.js +0 -263
  563. package/tools/hooks/README.md +0 -17
  564. package/tools/hooks/security-defensive-context.js +0 -70
  565. package/tools/hooks/session-rules.js +0 -38
  566. package/tools/hooks/wizz-router-enforce.js +0 -188
  567. package/tools/javascript-conventions.md +0 -5
  568. package/tools/migrate-custom-module-paths.js +0 -124
  569. package/tools/skill-validator.md +0 -368
  570. package/tools/sync-global.mjs +0 -84
  571. package/tools/validate-sidebar-order.js +0 -388
  572. package/tools/validate-skills.js +0 -708
  573. package/tools/validate-svg-changes.sh +0 -356
  574. /package/tools/installer/{cli-utils.js → banner.js} +0 -0
@@ -1,708 +0,0 @@
1
- /**
2
- * Deterministic Skill Validator
3
- *
4
- * Validates 12 deterministic rules across all skill directories.
5
- * Acts as a fast first-pass complement to the inference-based skill validator.
6
- *
7
- * What it checks:
8
- * - SKILL-01: SKILL.md exists
9
- * - SKILL-02: SKILL.md frontmatter has name
10
- * - SKILL-03: SKILL.md frontmatter has description
11
- * - SKILL-04: name format (lowercase, hyphens, no forbidden substrings)
12
- * - SKILL-05: name matches directory basename
13
- * - SKILL-06: description quality (length, "Use when"/"Use if")
14
- * - SKILL-07: SKILL.md has body content after frontmatter
15
- * - PATH-02: no installed_path variable
16
- * - STEP-01: step filename format
17
- * - STEP-06: step frontmatter has no name/description
18
- * - STEP-07: step count 2-10
19
- * - SEQ-02: no time estimates
20
- *
21
- * Usage:
22
- * node tools/validate-skills.js # All skills, human-readable
23
- * node tools/validate-skills.js path/to/skill-dir # Single skill
24
- * node tools/validate-skills.js --strict # Exit 1 on HIGH+ findings
25
- * node tools/validate-skills.js --json # JSON output
26
- */
27
-
28
- const fs = require('node:fs');
29
- const path = require('node:path');
30
-
31
- const PROJECT_ROOT = path.resolve(__dirname, '..');
32
- const SRC_DIR = path.join(PROJECT_ROOT, 'src');
33
-
34
- // --- CLI Parsing ---
35
-
36
- const args = process.argv.slice(2);
37
- const STRICT = args.includes('--strict');
38
- const JSON_OUTPUT = args.includes('--json');
39
- const positionalArgs = args.filter((a) => !a.startsWith('--'));
40
-
41
- // --- Constants ---
42
-
43
- // Aceita o namespace do motor WIZZ (wizz-) e o namespace próprio da Wizz (wizz-).
44
- const NAME_REGEX = /^(wizz|wizz)-[a-z0-9]+(-[a-z0-9]+)*$/;
45
- const STEP_FILENAME_REGEX = /^step-\d{2}[a-z]?-[a-z0-9-]+\.md$/;
46
- const TIME_ESTIMATE_PATTERNS = [/takes?\s+\d+\s*min/i, /~\s*\d+\s*min/i, /estimated\s+time/i, /\bETA\b/];
47
-
48
- const SEVERITY_ORDER = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3 };
49
-
50
- // --- Output Escaping ---
51
-
52
- function escapeAnnotation(str) {
53
- return str.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
54
- }
55
-
56
- function escapeTableCell(str) {
57
- return String(str).replaceAll('|', String.raw`\|`);
58
- }
59
-
60
- // --- Frontmatter Parsing ---
61
-
62
- /**
63
- * Parse YAML frontmatter from a markdown file.
64
- * Returns an object with key-value pairs, or null if no frontmatter.
65
- */
66
- function parseFrontmatter(content) {
67
- const trimmed = content.trimStart();
68
- if (!trimmed.startsWith('---')) return null;
69
-
70
- let endIndex = trimmed.indexOf('\n---\n', 3);
71
- if (endIndex === -1) {
72
- // Handle file ending with \n---
73
- if (trimmed.endsWith('\n---')) {
74
- endIndex = trimmed.length - 4;
75
- } else {
76
- return null;
77
- }
78
- }
79
-
80
- const fmBlock = trimmed.slice(3, endIndex).trim();
81
- if (fmBlock === '') return {};
82
-
83
- const result = {};
84
- for (const line of fmBlock.split('\n')) {
85
- const colonIndex = line.indexOf(':');
86
- if (colonIndex === -1) continue;
87
- // Skip indented lines (nested YAML values)
88
- if (line[0] === ' ' || line[0] === '\t') continue;
89
- const key = line.slice(0, colonIndex).trim();
90
- let value = line.slice(colonIndex + 1).trim();
91
- // Strip surrounding quotes (single or double)
92
- if ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"'))) {
93
- value = value.slice(1, -1);
94
- }
95
- result[key] = value;
96
- }
97
-
98
- return result;
99
- }
100
-
101
- /**
102
- * Parse YAML frontmatter, handling multiline values (description often spans lines).
103
- * Returns an object with key-value pairs, or null if no frontmatter.
104
- */
105
- function parseFrontmatterMultiline(content) {
106
- const trimmed = content.trimStart();
107
- if (!trimmed.startsWith('---')) return null;
108
-
109
- let endIndex = trimmed.indexOf('\n---\n', 3);
110
- if (endIndex === -1) {
111
- // Handle file ending with \n---
112
- if (trimmed.endsWith('\n---')) {
113
- endIndex = trimmed.length - 4;
114
- } else {
115
- return null;
116
- }
117
- }
118
-
119
- const fmBlock = trimmed.slice(3, endIndex).trim();
120
- if (fmBlock === '') return {};
121
-
122
- const result = {};
123
- let currentKey = null;
124
- let currentValue = '';
125
-
126
- for (const line of fmBlock.split('\n')) {
127
- const colonIndex = line.indexOf(':');
128
- // New key-value pair: must start at column 0 (no leading whitespace) and have a colon
129
- if (colonIndex > 0 && line[0] !== ' ' && line[0] !== '\t') {
130
- // Save previous key
131
- if (currentKey !== null) {
132
- result[currentKey] = stripQuotes(currentValue.trim());
133
- }
134
- currentKey = line.slice(0, colonIndex).trim();
135
- currentValue = line.slice(colonIndex + 1);
136
- } else if (currentKey !== null) {
137
- // Skip YAML comment lines
138
- if (line.trimStart().startsWith('#')) continue;
139
- // Continuation of multiline value
140
- currentValue += '\n' + line;
141
- }
142
- }
143
-
144
- // Save last key
145
- if (currentKey !== null) {
146
- result[currentKey] = stripQuotes(currentValue.trim());
147
- }
148
-
149
- return result;
150
- }
151
-
152
- function stripQuotes(value) {
153
- if ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"'))) {
154
- return value.slice(1, -1);
155
- }
156
- return value;
157
- }
158
-
159
- // --- Safe File Reading ---
160
-
161
- /**
162
- * Read a file safely, returning null on error.
163
- * Pushes a warning finding if the file cannot be read.
164
- */
165
- function safeReadFile(filePath, findings, relFile) {
166
- try {
167
- return fs.readFileSync(filePath, 'utf-8');
168
- } catch (error) {
169
- findings.push({
170
- rule: 'READ-ERR',
171
- title: 'File Read Error',
172
- severity: 'MEDIUM',
173
- file: relFile || path.basename(filePath),
174
- detail: `Cannot read file: ${error.message}`,
175
- fix: 'Check file permissions and ensure the file exists.',
176
- });
177
- return null;
178
- }
179
- }
180
-
181
- // --- Code Block Stripping ---
182
-
183
- function stripCodeBlocks(content) {
184
- return content.replaceAll(/```[\s\S]*?```/g, (m) => m.replaceAll(/[^\n]/g, ''));
185
- }
186
-
187
- // --- Skill Discovery ---
188
-
189
- function discoverSkillDirs(rootDirs) {
190
- const skillDirs = [];
191
-
192
- function walk(dir) {
193
- if (!fs.existsSync(dir)) return;
194
- const entries = fs.readdirSync(dir, { withFileTypes: true });
195
-
196
- for (const entry of entries) {
197
- if (!entry.isDirectory()) continue;
198
- if (entry.name === 'node_modules' || entry.name === '.git') continue;
199
-
200
- const fullPath = path.join(dir, entry.name);
201
- const skillMd = path.join(fullPath, 'SKILL.md');
202
-
203
- if (fs.existsSync(skillMd)) {
204
- skillDirs.push(fullPath);
205
- }
206
-
207
- // Keep walking into subdirectories to find nested skills
208
- walk(fullPath);
209
- }
210
- }
211
-
212
- for (const rootDir of rootDirs) {
213
- walk(rootDir);
214
- }
215
-
216
- return skillDirs.sort();
217
- }
218
-
219
- // --- File Collection ---
220
-
221
- function collectSkillFiles(skillDir) {
222
- const files = [];
223
-
224
- function walk(dir) {
225
- const entries = fs.readdirSync(dir, { withFileTypes: true });
226
- for (const entry of entries) {
227
- if (entry.name === 'node_modules' || entry.name === '.git') continue;
228
- const fullPath = path.join(dir, entry.name);
229
- if (entry.isDirectory()) {
230
- walk(fullPath);
231
- } else if (entry.isFile()) {
232
- files.push(fullPath);
233
- }
234
- }
235
- }
236
-
237
- walk(skillDir);
238
- return files;
239
- }
240
-
241
- // --- Rule Checks ---
242
-
243
- function validateSkill(skillDir) {
244
- const findings = [];
245
- const dirName = path.basename(skillDir);
246
- const skillMdPath = path.join(skillDir, 'SKILL.md');
247
- const workflowMdPath = path.join(skillDir, 'workflow.md');
248
- const stepsDir = path.join(skillDir, 'steps');
249
-
250
- // Collect all files in the skill for PATH-02 and SEQ-02
251
- const allFiles = collectSkillFiles(skillDir);
252
-
253
- // --- SKILL-01: SKILL.md must exist ---
254
- if (!fs.existsSync(skillMdPath)) {
255
- findings.push({
256
- rule: 'SKILL-01',
257
- title: 'SKILL.md Must Exist',
258
- severity: 'CRITICAL',
259
- file: 'SKILL.md',
260
- detail: 'SKILL.md not found in skill directory.',
261
- fix: 'Create SKILL.md as the skill entrypoint.',
262
- });
263
- // Cannot check SKILL-02 through SKILL-07 without SKILL.md
264
- return findings;
265
- }
266
-
267
- const skillContent = safeReadFile(skillMdPath, findings, 'SKILL.md');
268
- if (skillContent === null) return findings;
269
- const skillFm = parseFrontmatterMultiline(skillContent);
270
-
271
- // --- SKILL-02: frontmatter has name ---
272
- if (!skillFm || !('name' in skillFm)) {
273
- findings.push({
274
- rule: 'SKILL-02',
275
- title: 'SKILL.md Must Have name in Frontmatter',
276
- severity: 'CRITICAL',
277
- file: 'SKILL.md',
278
- detail: 'Frontmatter is missing the `name` field.',
279
- fix: 'Add `name: <skill-name>` to the frontmatter.',
280
- });
281
- } else if (skillFm.name === '') {
282
- findings.push({
283
- rule: 'SKILL-02',
284
- title: 'SKILL.md Must Have name in Frontmatter',
285
- severity: 'CRITICAL',
286
- file: 'SKILL.md',
287
- detail: 'Frontmatter `name` field is empty.',
288
- fix: 'Set `name` to the skill directory name (kebab-case).',
289
- });
290
- }
291
-
292
- // --- SKILL-03: frontmatter has description ---
293
- if (!skillFm || !('description' in skillFm)) {
294
- findings.push({
295
- rule: 'SKILL-03',
296
- title: 'SKILL.md Must Have description in Frontmatter',
297
- severity: 'CRITICAL',
298
- file: 'SKILL.md',
299
- detail: 'Frontmatter is missing the `description` field.',
300
- fix: 'Add `description: <what it does and when to use it>` to the frontmatter.',
301
- });
302
- } else if (skillFm.description === '') {
303
- findings.push({
304
- rule: 'SKILL-03',
305
- title: 'SKILL.md Must Have description in Frontmatter',
306
- severity: 'CRITICAL',
307
- file: 'SKILL.md',
308
- detail: 'Frontmatter `description` field is empty.',
309
- fix: 'Add a description stating what the skill does and when to use it.',
310
- });
311
- }
312
-
313
- const name = skillFm && skillFm.name;
314
- const description = skillFm && skillFm.description;
315
-
316
- // --- SKILL-04: name format ---
317
- // Skills vendored under `src/skills-lib/` are third-party/global skills that
318
- // keep their upstream names (no `wizz-` prefix) BY DESIGN — same policy as the
319
- // credited BMAD engine internals. Exempt them from the wizz-owned naming rule.
320
- // SKILL-05 (name must match the directory basename) still applies to them.
321
- const isVendoredGlobal = skillDir.split(path.sep).includes('skills-lib');
322
- if (name && !isVendoredGlobal && !NAME_REGEX.test(name)) {
323
- findings.push({
324
- rule: 'SKILL-04',
325
- title: 'name Format',
326
- severity: 'HIGH',
327
- file: 'SKILL.md',
328
- detail: `name "${name}" does not match pattern: ${NAME_REGEX}`,
329
- fix: 'Rename to comply with lowercase letters, numbers, and hyphens only (max 64 chars).',
330
- });
331
- }
332
-
333
- // --- SKILL-05: name matches directory ---
334
- if (name && name !== dirName) {
335
- findings.push({
336
- rule: 'SKILL-05',
337
- title: 'name Must Match Directory Name',
338
- severity: 'HIGH',
339
- file: 'SKILL.md',
340
- detail: `name "${name}" does not match directory name "${dirName}".`,
341
- fix: `Change name to "${dirName}" or rename the directory.`,
342
- });
343
- }
344
-
345
- // --- SKILL-06: description quality ---
346
- if (description) {
347
- if (description.length > 1024) {
348
- findings.push({
349
- rule: 'SKILL-06',
350
- title: 'description Quality',
351
- severity: 'MEDIUM',
352
- file: 'SKILL.md',
353
- detail: `description is ${description.length} characters (max 1024).`,
354
- fix: 'Shorten the description to 1024 characters or less.',
355
- });
356
- }
357
-
358
- if (
359
- !/use\s+when\b/i.test(description) &&
360
- !/use\s+if\b/i.test(description) &&
361
- !/use\s+para\b/i.test(description) &&
362
- !/use\s+quando\b/i.test(description)
363
- ) {
364
- findings.push({
365
- rule: 'SKILL-06',
366
- title: 'description Quality',
367
- severity: 'MEDIUM',
368
- file: 'SKILL.md',
369
- detail: 'description does not contain "Use when", "Use if", "Use para", or "Use quando" trigger phrase.',
370
- fix: 'Append a "Use when..." or "Use para..." clause to explain when to invoke this skill.',
371
- });
372
- }
373
- }
374
-
375
- // --- SKILL-07: SKILL.md must have body content after frontmatter ---
376
- {
377
- const trimmed = skillContent.trimStart();
378
- let bodyStart = -1;
379
- if (trimmed.startsWith('---')) {
380
- let endIdx = trimmed.indexOf('\n---\n', 3);
381
- if (endIdx !== -1) {
382
- bodyStart = endIdx + 4;
383
- } else if (trimmed.endsWith('\n---')) {
384
- bodyStart = trimmed.length; // no body at all
385
- }
386
- } else {
387
- bodyStart = 0; // no frontmatter, entire file is body
388
- }
389
- const body = bodyStart >= 0 ? trimmed.slice(bodyStart).trim() : '';
390
- if (body === '') {
391
- findings.push({
392
- rule: 'SKILL-07',
393
- title: 'SKILL.md Must Have Body Content',
394
- severity: 'HIGH',
395
- file: 'SKILL.md',
396
- detail: 'SKILL.md has no content after frontmatter. L2 instructions are required.',
397
- fix: 'Add markdown body with skill instructions after the closing ---.',
398
- });
399
- }
400
- }
401
-
402
- // --- PATH-02: no installed_path ---
403
- for (const filePath of allFiles) {
404
- // Only check markdown and yaml files
405
- const ext = path.extname(filePath);
406
- if (!['.md', '.yaml', '.yml'].includes(ext)) continue;
407
-
408
- const relFile = path.relative(skillDir, filePath);
409
- const content = safeReadFile(filePath, findings, relFile);
410
- if (content === null) continue;
411
-
412
- // Check frontmatter for installed_path key
413
- const fm = parseFrontmatter(content);
414
- if (fm && 'installed_path' in fm) {
415
- findings.push({
416
- rule: 'PATH-02',
417
- title: 'No installed_path Variable',
418
- severity: 'HIGH',
419
- file: relFile,
420
- detail: 'Frontmatter contains `installed_path:` key.',
421
- fix: 'Remove `installed_path` from frontmatter. Use relative paths instead.',
422
- });
423
- }
424
-
425
- // Check content for any mention of installed_path (variable ref, prose, bare text)
426
- const stripped = stripCodeBlocks(content);
427
- const lines = stripped.split('\n');
428
- for (const [i, line] of lines.entries()) {
429
- if (/installed_path/i.test(line)) {
430
- findings.push({
431
- rule: 'PATH-02',
432
- title: 'No installed_path Variable',
433
- severity: 'HIGH',
434
- file: relFile,
435
- line: i + 1,
436
- detail: '`installed_path` reference found in content.',
437
- fix: 'Remove all installed_path usage. Use relative paths (`./path` or `../path`) instead.',
438
- });
439
- }
440
- }
441
- }
442
-
443
- // --- STEP-01: step filename format ---
444
- // --- STEP-06: step frontmatter no name/description ---
445
- // --- STEP-07: step count ---
446
- // Only check the literal steps/ directory (variant directories like steps-c, steps-v
447
- // use different naming conventions and are excluded per the rule specification)
448
- if (fs.existsSync(stepsDir) && fs.statSync(stepsDir).isDirectory()) {
449
- const stepDirName = 'steps';
450
- const stepFiles = fs.readdirSync(stepsDir).filter((f) => f.endsWith('.md'));
451
-
452
- // STEP-01: filename format
453
- for (const stepFile of stepFiles) {
454
- if (!STEP_FILENAME_REGEX.test(stepFile)) {
455
- findings.push({
456
- rule: 'STEP-01',
457
- title: 'Step File Naming',
458
- severity: 'MEDIUM',
459
- file: path.join(stepDirName, stepFile),
460
- detail: `Filename "${stepFile}" does not match pattern: ${STEP_FILENAME_REGEX}`,
461
- fix: 'Rename to step-NN-description.md (NN = zero-padded number, optional letter suffix).',
462
- });
463
- }
464
- }
465
-
466
- // STEP-06: step frontmatter has no name/description
467
- for (const stepFile of stepFiles) {
468
- const stepPath = path.join(stepsDir, stepFile);
469
- const stepContent = safeReadFile(stepPath, findings, path.join(stepDirName, stepFile));
470
- if (stepContent === null) continue;
471
- const stepFm = parseFrontmatter(stepContent);
472
-
473
- if (stepFm) {
474
- if ('name' in stepFm) {
475
- findings.push({
476
- rule: 'STEP-06',
477
- title: 'Step File Frontmatter: No name or description',
478
- severity: 'MEDIUM',
479
- file: path.join(stepDirName, stepFile),
480
- detail: 'Step file frontmatter contains `name:` — this is metadata noise.',
481
- fix: 'Remove `name:` from step file frontmatter.',
482
- });
483
- }
484
- if ('description' in stepFm) {
485
- findings.push({
486
- rule: 'STEP-06',
487
- title: 'Step File Frontmatter: No name or description',
488
- severity: 'MEDIUM',
489
- file: path.join(stepDirName, stepFile),
490
- detail: 'Step file frontmatter contains `description:` — this is metadata noise.',
491
- fix: 'Remove `description:` from step file frontmatter.',
492
- });
493
- }
494
- }
495
- }
496
-
497
- // STEP-07: step count 2-10
498
- const stepCount = stepFiles.filter((f) => f.startsWith('step-')).length;
499
- if (stepCount > 0 && (stepCount < 2 || stepCount > 10)) {
500
- const detail =
501
- stepCount < 2
502
- ? `Only ${stepCount} step file found — consider inlining into workflow.md.`
503
- : `${stepCount} step files found — more than 10 risks LLM context degradation.`;
504
- findings.push({
505
- rule: 'STEP-07',
506
- title: 'Step Count',
507
- severity: 'LOW',
508
- file: stepDirName + '/',
509
- detail,
510
- fix: stepCount > 10 ? 'Consider consolidating steps.' : 'Consider expanding or inlining.',
511
- });
512
- }
513
- }
514
-
515
- // --- SEQ-02: no time estimates ---
516
- for (const filePath of allFiles) {
517
- const ext = path.extname(filePath);
518
- if (!['.md', '.yaml', '.yml'].includes(ext)) continue;
519
-
520
- const relFile = path.relative(skillDir, filePath);
521
- const content = safeReadFile(filePath, findings, relFile);
522
- if (content === null) continue;
523
- const stripped = stripCodeBlocks(content);
524
- const lines = stripped.split('\n');
525
-
526
- for (const [i, line] of lines.entries()) {
527
- for (const pattern of TIME_ESTIMATE_PATTERNS) {
528
- if (pattern.test(line)) {
529
- findings.push({
530
- rule: 'SEQ-02',
531
- title: 'No Time Estimates',
532
- severity: 'LOW',
533
- file: relFile,
534
- line: i + 1,
535
- detail: `Time estimate pattern found: "${line.trim()}"`,
536
- fix: 'Remove time estimates — AI execution speed varies too much.',
537
- });
538
- break; // Only report once per line
539
- }
540
- }
541
- }
542
- }
543
-
544
- return findings;
545
- }
546
-
547
- // --- Output Formatting ---
548
-
549
- function formatHumanReadable(results) {
550
- const output = [];
551
- let totalFindings = 0;
552
- const severityCounts = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };
553
-
554
- output.push(
555
- `\nValidating skills in: ${SRC_DIR}`,
556
- `Mode: ${STRICT ? 'STRICT (exit 1 on HIGH+)' : 'WARNING (exit 0)'}${JSON_OUTPUT ? ' + JSON' : ''}\n`,
557
- );
558
-
559
- let totalSkills = 0;
560
- let skillsWithFindings = 0;
561
-
562
- for (const { skillDir, findings } of results) {
563
- totalSkills++;
564
- const relDir = path.relative(PROJECT_ROOT, skillDir);
565
-
566
- if (findings.length > 0) {
567
- skillsWithFindings++;
568
- output.push(`\n${relDir}`);
569
-
570
- for (const f of findings) {
571
- totalFindings++;
572
- severityCounts[f.severity]++;
573
- const location = f.line ? ` (line ${f.line})` : '';
574
- output.push(` [${f.severity}] ${f.rule} — ${f.title}`, ` File: ${f.file}${location}`, ` ${f.detail}`);
575
-
576
- if (process.env.GITHUB_ACTIONS) {
577
- const absFile = path.join(skillDir, f.file);
578
- const ghFile = path.relative(PROJECT_ROOT, absFile);
579
- const line = f.line || 1;
580
- const level = f.severity === 'LOW' ? 'notice' : 'warning';
581
- console.log(`::${level} file=${ghFile},line=${line}::${escapeAnnotation(`${f.rule}: ${f.detail}`)}`);
582
- }
583
- }
584
- }
585
- }
586
-
587
- // Summary
588
- output.push(
589
- `\n${'─'.repeat(60)}`,
590
- `\nSummary:`,
591
- ` Skills scanned: ${totalSkills}`,
592
- ` Skills with findings: ${skillsWithFindings}`,
593
- ` Total findings: ${totalFindings}`,
594
- );
595
-
596
- if (totalFindings > 0) {
597
- output.push('', ` | Severity | Count |`, ` |----------|-------|`);
598
- for (const sev of ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW']) {
599
- if (severityCounts[sev] > 0) {
600
- output.push(` | ${sev.padEnd(8)} | ${String(severityCounts[sev]).padStart(5)} |`);
601
- }
602
- }
603
- }
604
-
605
- const hasHighPlus = severityCounts.CRITICAL > 0 || severityCounts.HIGH > 0;
606
-
607
- if (totalFindings === 0) {
608
- output.push(`\n All skills passed validation!`);
609
- } else if (STRICT && hasHighPlus) {
610
- output.push(`\n [STRICT MODE] HIGH+ findings found — exiting with failure.`);
611
- } else if (STRICT) {
612
- output.push(`\n [STRICT MODE] Only MEDIUM/LOW findings — pass.`);
613
- } else {
614
- output.push(`\n Run with --strict to treat HIGH+ findings as errors.`);
615
- }
616
-
617
- output.push('');
618
-
619
- // Write GitHub Actions step summary
620
- if (process.env.GITHUB_STEP_SUMMARY) {
621
- let summary = '## Skill Validation\n\n';
622
- if (totalFindings > 0) {
623
- summary += '| Skill | Rule | Severity | File | Detail |\n';
624
- summary += '|-------|------|----------|------|--------|\n';
625
- for (const { skillDir, findings } of results) {
626
- const relDir = path.relative(PROJECT_ROOT, skillDir);
627
- for (const f of findings) {
628
- summary += `| ${escapeTableCell(relDir)} | ${f.rule} | ${f.severity} | ${escapeTableCell(f.file)} | ${escapeTableCell(f.detail)} |\n`;
629
- }
630
- }
631
- summary += '\n';
632
- }
633
- summary += `**${totalSkills} skills scanned, ${totalFindings} findings**\n`;
634
- fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);
635
- }
636
-
637
- return { output: output.join('\n'), hasHighPlus };
638
- }
639
-
640
- function formatJson(results) {
641
- const allFindings = [];
642
- for (const { skillDir, findings } of results) {
643
- const relDir = path.relative(PROJECT_ROOT, skillDir);
644
- for (const f of findings) {
645
- allFindings.push({
646
- skill: relDir,
647
- rule: f.rule,
648
- title: f.title,
649
- severity: f.severity,
650
- file: f.file,
651
- line: f.line || null,
652
- detail: f.detail,
653
- fix: f.fix,
654
- });
655
- }
656
- }
657
-
658
- // Sort by severity
659
- allFindings.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
660
-
661
- const hasHighPlus = allFindings.some((f) => f.severity === 'CRITICAL' || f.severity === 'HIGH');
662
-
663
- return { output: JSON.stringify(allFindings, null, 2), hasHighPlus };
664
- }
665
-
666
- // --- Main ---
667
-
668
- if (require.main === module) {
669
- // Determine which skills to validate
670
- let skillDirs;
671
-
672
- if (positionalArgs.length > 0) {
673
- // Single skill directory specified
674
- const target = path.resolve(positionalArgs[0]);
675
- if (!fs.existsSync(target) || !fs.statSync(target).isDirectory()) {
676
- console.error(`Error: "${positionalArgs[0]}" is not a valid directory.`);
677
- process.exit(2);
678
- }
679
- skillDirs = [target];
680
- } else {
681
- // Discover all skills
682
- skillDirs = discoverSkillDirs([SRC_DIR]);
683
- }
684
-
685
- if (skillDirs.length === 0) {
686
- console.error('No skill directories found.');
687
- process.exit(2);
688
- }
689
-
690
- // Validate each skill
691
- const results = [];
692
- for (const skillDir of skillDirs) {
693
- const findings = validateSkill(skillDir);
694
- results.push({ skillDir, findings });
695
- }
696
-
697
- // Format output
698
- const { output, hasHighPlus } = JSON_OUTPUT ? formatJson(results) : formatHumanReadable(results);
699
- console.log(output);
700
-
701
- // Exit code
702
- if (STRICT && hasHighPlus) {
703
- process.exit(1);
704
- }
705
- }
706
-
707
- // --- Exports (for testing) ---
708
- module.exports = { parseFrontmatter, parseFrontmatterMultiline, validateSkill, discoverSkillDirs };