wizz-method 2.0.0 → 2.1.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 (310) hide show
  1. package/LICENSE +60 -30
  2. package/README.md +80 -31
  3. package/SECURITY.md +24 -0
  4. package/THIRD-PARTY-NOTICES.md +136 -0
  5. package/package.json +31 -17
  6. package/skills-registry.yaml +128 -7
  7. package/src/bmm-skills/1-analysis/research/wizz-domain-research/SKILL.md +3 -4
  8. package/src/bmm-skills/1-analysis/research/wizz-domain-research/domain-steps/step-06-research-synthesis.md +1 -1
  9. package/src/bmm-skills/1-analysis/research/wizz-market-research/SKILL.md +3 -4
  10. package/src/bmm-skills/1-analysis/research/wizz-market-research/steps/step-06-research-completion.md +1 -1
  11. package/src/bmm-skills/1-analysis/research/wizz-technical-research/SKILL.md +3 -4
  12. package/src/bmm-skills/1-analysis/research/wizz-technical-research/technical-steps/step-06-research-synthesis.md +1 -1
  13. package/src/bmm-skills/1-analysis/wizz-agent-analyst/SKILL.md +3 -4
  14. package/src/bmm-skills/1-analysis/wizz-agent-tech-writer/SKILL.md +3 -4
  15. package/src/bmm-skills/1-analysis/wizz-document-project/SKILL.md +3 -4
  16. package/src/bmm-skills/1-analysis/wizz-document-project/workflows/deep-dive-instructions.md +1 -1
  17. package/src/bmm-skills/1-analysis/wizz-document-project/workflows/full-scan-instructions.md +1 -1
  18. package/src/bmm-skills/1-analysis/wizz-prfaq/SKILL.md +3 -4
  19. package/src/bmm-skills/1-analysis/wizz-prfaq/references/verdict.md +1 -1
  20. package/src/bmm-skills/1-analysis/wizz-product-brief/SKILL.md +1 -1
  21. package/src/bmm-skills/2-plan-workflows/wizz-agent-pm/SKILL.md +3 -4
  22. package/src/bmm-skills/2-plan-workflows/wizz-agent-ux-designer/SKILL.md +3 -4
  23. package/src/bmm-skills/2-plan-workflows/wizz-create-prd/SKILL.md +1 -1
  24. package/src/bmm-skills/2-plan-workflows/wizz-edit-prd/SKILL.md +1 -1
  25. package/src/bmm-skills/2-plan-workflows/wizz-prd/SKILL.md +1 -1
  26. package/src/bmm-skills/2-plan-workflows/wizz-ux/SKILL.md +1 -1
  27. package/src/bmm-skills/2-plan-workflows/wizz-validate-prd/SKILL.md +1 -1
  28. package/src/bmm-skills/3-solutioning/wizz-agent-architect/SKILL.md +3 -4
  29. package/src/bmm-skills/3-solutioning/wizz-architecture/SKILL.md +9 -9
  30. package/src/bmm-skills/3-solutioning/wizz-architecture/references/headless.md +1 -1
  31. package/src/bmm-skills/3-solutioning/wizz-check-implementation-readiness/SKILL.md +3 -4
  32. package/src/bmm-skills/3-solutioning/wizz-check-implementation-readiness/steps/step-06-final-assessment.md +1 -1
  33. package/src/bmm-skills/3-solutioning/wizz-create-architecture/SKILL.md +1 -1
  34. package/src/bmm-skills/3-solutioning/wizz-create-epics-and-stories/SKILL.md +3 -4
  35. package/src/bmm-skills/3-solutioning/wizz-create-epics-and-stories/steps/step-04-final-validation.md +1 -1
  36. package/src/bmm-skills/3-solutioning/wizz-generate-project-context/SKILL.md +3 -4
  37. package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-03-complete.md +1 -1
  38. package/src/bmm-skills/4-implementation/wizz-agent-dev/SKILL.md +3 -4
  39. package/src/bmm-skills/4-implementation/wizz-checkpoint-preview/SKILL.md +3 -4
  40. package/src/bmm-skills/4-implementation/wizz-checkpoint-preview/step-05-wrapup.md +1 -1
  41. package/src/bmm-skills/4-implementation/wizz-code-review/SKILL.md +3 -4
  42. package/src/bmm-skills/4-implementation/wizz-code-review/customize.toml +3 -8
  43. package/src/bmm-skills/4-implementation/wizz-code-review/review-prompts/blind-hunter.md +20 -0
  44. package/src/bmm-skills/4-implementation/wizz-code-review/steps/step-04-present.md +1 -1
  45. package/src/bmm-skills/4-implementation/wizz-correct-course/SKILL.md +4 -5
  46. package/src/bmm-skills/4-implementation/wizz-create-story/SKILL.md +4 -5
  47. package/src/bmm-skills/4-implementation/wizz-dev-story/SKILL.md +4 -5
  48. package/src/bmm-skills/4-implementation/wizz-investigate/SKILL.md +1 -1
  49. package/src/bmm-skills/4-implementation/wizz-qa-generate-e2e-tests/SKILL.md +4 -5
  50. package/src/bmm-skills/4-implementation/wizz-quick-dev/SKILL.md +4 -5
  51. package/src/bmm-skills/4-implementation/wizz-quick-dev/customize.toml +10 -22
  52. package/src/bmm-skills/4-implementation/wizz-quick-dev/review-prompts/blind-hunter.md +20 -0
  53. package/src/bmm-skills/4-implementation/wizz-quick-dev/step-05-present.md +1 -1
  54. package/src/bmm-skills/4-implementation/wizz-quick-dev/step-oneshot.md +1 -1
  55. package/src/bmm-skills/4-implementation/wizz-retrospective/SKILL.md +1 -2
  56. package/src/bmm-skills/4-implementation/wizz-sprint-planning/SKILL.md +1 -1
  57. package/src/bmm-skills/4-implementation/wizz-sprint-status/SKILL.md +5 -6
  58. package/src/core-skills/_shared/handoff-protocol.md +9 -0
  59. package/src/core-skills/wizz-advanced-elicitation/SKILL.md +2 -2
  60. package/src/core-skills/wizz-brainstorming/SKILL.md +6 -6
  61. package/src/core-skills/wizz-brainstorming/references/converge.md +1 -1
  62. package/src/core-skills/wizz-brainstorming/references/finalize.md +1 -1
  63. package/src/core-skills/wizz-brainstorming/references/headless.md +3 -3
  64. package/src/core-skills/wizz-brainstorming/references/mode-autonomous.md +1 -1
  65. package/src/core-skills/wizz-customize/SKILL.md +13 -10
  66. package/src/core-skills/wizz-forge-idea/SKILL.md +6 -6
  67. package/src/core-skills/wizz-forge-idea/scripts/__pycache__/resolve_personas.cpython-314.pyc +0 -0
  68. package/src/core-skills/wizz-forge-idea/scripts/resolve_personas.py +17 -1
  69. package/src/core-skills/wizz-party-mode/SKILL.md +3 -3
  70. package/src/core-skills/wizz-party-mode/references/create-party.md +1 -1
  71. package/src/core-skills/wizz-party-mode/references/party-memory.md +2 -2
  72. package/src/core-skills/wizz-party-mode/scripts/__pycache__/resolve_party.cpython-314.pyc +0 -0
  73. package/src/core-skills/wizz-party-mode/scripts/resolve_party.py +17 -1
  74. package/src/core-skills/wizz-review-adversarial-general/SKILL.md +1 -1
  75. package/src/core-skills/wizz-spec/SKILL.md +5 -5
  76. package/src/modules/lowticket/README.md +6 -6
  77. package/src/modules/lowticket/module.yaml +4 -1
  78. package/src/modules/lowticket/skills/{lowticket-funil → wizz-lowticket-funil}/SKILL.md +4 -4
  79. package/src/modules/lowticket/skills/{lowticket-funil → wizz-lowticket-funil}/references/copy-das-paginas.md +1 -1
  80. package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/SKILL.md +1 -1
  81. package/src/modules/lowticket/skills/{lowticket-minerador → wizz-lowticket-minerador}/SKILL.md +3 -3
  82. package/src/modules/lowticket/skills/{lowticket-minerador → wizz-lowticket-minerador}/references/rubrica.md +1 -1
  83. package/src/modules/lowticket/skills/{lowticket-pagina → wizz-lowticket-pagina}/SKILL.md +4 -4
  84. package/src/modules/lowticket/skills/{lowticket-trafego → wizz-lowticket-trafego}/SKILL.md +3 -3
  85. package/src/modules/lowticket/skills/{lowticket-trafego → wizz-lowticket-trafego}/references/reguas.md +1 -1
  86. package/src/modules/wizz/_shared/communication-rules.md +1 -1
  87. package/src/modules/wizz/_shared/despacho-barato.md +9 -0
  88. package/src/modules/wizz/_shared/token-economy.md +7 -0
  89. package/src/modules/wizz/agents/wizz-ads/SKILL.md +1 -1
  90. package/src/modules/wizz/agents/wizz-ads/customize.toml +1 -2
  91. package/src/modules/wizz/agents/wizz-copy/SKILL.md +1 -1
  92. package/src/modules/wizz/agents/wizz-copy/customize.toml +1 -2
  93. package/src/modules/wizz/agents/wizz-designer/SKILL.md +1 -1
  94. package/src/modules/wizz/agents/wizz-designer/customize.toml +1 -2
  95. package/src/modules/wizz/agents/wizz-growth/SKILL.md +1 -1
  96. package/src/modules/wizz/agents/wizz-growth/customize.toml +1 -2
  97. package/src/modules/wizz/agents/wizz-maestro/SKILL.md +5 -5
  98. package/src/modules/wizz/agents/wizz-maestro/customize.toml +4 -8
  99. package/src/modules/wizz/agents/wizz-memoria/SKILL.md +1 -1
  100. package/src/modules/wizz/agents/wizz-memoria/customize.toml +1 -2
  101. package/src/modules/wizz/agents/wizz-qa/SKILL.md +1 -1
  102. package/src/modules/wizz/agents/wizz-qa/customize.toml +1 -2
  103. package/src/modules/wizz/agents/wizz-seo/SKILL.md +1 -1
  104. package/src/modules/wizz/agents/wizz-seo/customize.toml +1 -2
  105. package/src/modules/wizz/agents/wizz-social/SKILL.md +1 -1
  106. package/src/modules/wizz/agents/wizz-social/customize.toml +1 -2
  107. package/src/modules/wizz/module.yaml +3 -0
  108. package/src/modules/wizz/overrides/wizz-agent-analyst.toml +1 -2
  109. package/src/modules/wizz/overrides/wizz-agent-architect.toml +1 -2
  110. package/src/modules/wizz/overrides/wizz-agent-dev.toml +1 -2
  111. package/src/modules/wizz/overrides/wizz-agent-pm.toml +1 -2
  112. package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +1 -2
  113. package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +1 -2
  114. package/src/modules/wizz/subagents/codex/wizz-exec-haiku.toml +2 -0
  115. package/src/modules/wizz/subagents/codex/wizz-exec-opus.toml +2 -0
  116. package/src/modules/wizz/subagents/codex/wizz-exec-review.toml +2 -0
  117. package/src/modules/wizz/subagents/codex/wizz-exec-sonnet.toml +2 -0
  118. package/src/modules/wizz/subagents/gemini/wizz-exec-haiku.md +4 -1
  119. package/src/modules/wizz/subagents/gemini/wizz-exec-opus.md +4 -1
  120. package/src/modules/wizz/subagents/gemini/wizz-exec-review.md +4 -1
  121. package/src/modules/wizz/subagents/gemini/wizz-exec-sonnet.md +4 -1
  122. package/src/modules/wizz/subagents/opencode/wizz-exec-haiku.md +4 -1
  123. package/src/modules/wizz/subagents/opencode/wizz-exec-opus.md +4 -1
  124. package/src/modules/wizz/subagents/opencode/wizz-exec-review.md +4 -1
  125. package/src/modules/wizz/subagents/opencode/wizz-exec-sonnet.md +4 -1
  126. package/src/modules/wizz/subagents/spec.yaml +148 -0
  127. package/src/modules/wizz/subagents/wizz-exec-haiku.md +4 -1
  128. package/src/modules/wizz/subagents/wizz-exec-opus.md +4 -1
  129. package/src/modules/wizz/subagents/wizz-exec-review.md +4 -1
  130. package/src/modules/wizz/subagents/wizz-exec-sonnet.md +4 -1
  131. package/src/scripts/__pycache__/resolve_customization.cpython-314.pyc +0 -0
  132. package/src/scripts/memlog.js +368 -0
  133. package/src/scripts/resolve_customization.py +124 -15
  134. package/src/skills-lib/_shared/complexity-signal.md +14 -0
  135. package/src/skills-lib/wizz-canvas-design/canvas-fonts/InstrumentSerif-OFL.txt +93 -0
  136. package/src/skills-lib/wizz-huashu-design/references/sfx-library.md +1 -1
  137. package/src/skills-lib/wizz-huashu-design/scripts/add-music.sh +1 -1
  138. package/src/skills-lib/wizz-huashu-design/scripts/mix-voiceover.sh +1 -1
  139. package/src/skills-lib/wizz-impeccable/LICENSE.txt +202 -0
  140. package/src/skills-lib/wizz-offer-forge/SKILL.md +1 -1
  141. package/src/skills-lib/wizz-react-components/LICENSE.txt +202 -0
  142. package/src/skills-lib/wizz-router/SKILL.md +2 -2
  143. package/src/skills-lib/wizz-supabase-postgres-best-practices/LICENSE +21 -0
  144. package/src/skills-lib/wizz-taste-skill/SKILL.md +1 -1
  145. package/src/skills-lib/wizz-tracking-audit/SKILL.md +1 -1
  146. package/tools/fetch-assets.mjs +62 -37
  147. package/tools/hooks/README.md +22 -0
  148. package/tools/hooks/rtk-rewrite.sh +280 -0
  149. package/tools/hooks/security-defensive-context.js +70 -0
  150. package/tools/hooks/session-rules.js +368 -0
  151. package/tools/hooks/wizz-decision-trace.js +389 -0
  152. package/tools/hooks/wizz-router-enforce.js +258 -0
  153. package/tools/installer/banner.js +1 -1
  154. package/tools/installer/commands/doctor.js +124 -0
  155. package/tools/installer/commands/install.js +1 -1
  156. package/tools/installer/commands/resolve.js +95 -0
  157. package/tools/installer/core/doctor.js +648 -0
  158. package/tools/installer/core/hash-cache.js +156 -0
  159. package/tools/installer/core/help-catalog.js +4 -1
  160. package/tools/installer/core/hooks-settings.js +178 -0
  161. package/tools/installer/core/installer.js +297 -15
  162. package/tools/installer/core/legacy-warnings.js +0 -4
  163. package/tools/installer/core/manifest-generator.js +121 -43
  164. package/tools/installer/core/manifest.js +36 -32
  165. package/tools/installer/core/module-config-writer.js +4 -1
  166. package/tools/installer/core/python-check.js +60 -63
  167. package/tools/installer/core/quick-update.js +76 -43
  168. package/tools/installer/core/resolved-config.js +168 -0
  169. package/tools/installer/core/resolved-customizations.js +736 -0
  170. package/tools/installer/core/resolved-includes.js +262 -0
  171. package/tools/installer/core/resolved-schema.js +148 -0
  172. package/tools/installer/core/user-file-preservation.js +40 -8
  173. package/tools/installer/core/wizz-dir.js +117 -0
  174. package/tools/installer/core/yaml-cache.js +105 -0
  175. package/tools/installer/fs-native.js +97 -6
  176. package/tools/installer/ide/_config-driven.js +12 -75
  177. package/tools/installer/ide/platform-codes.js +111 -16
  178. package/tools/installer/ide/platform-codes.yaml +45 -100
  179. package/tools/installer/ide/shared/path-utils.js +6 -208
  180. package/tools/installer/install-messages.yaml +4 -14
  181. package/tools/installer/modules/channel-plan.js +15 -2
  182. package/tools/installer/modules/config-collector.js +762 -0
  183. package/tools/installer/modules/config-values.js +352 -0
  184. package/tools/installer/modules/custom-module-manager.js +161 -28
  185. package/tools/installer/modules/env-vars.js +119 -0
  186. package/tools/installer/modules/external-manager.js +133 -60
  187. package/tools/installer/modules/git-cache-utils.js +125 -0
  188. package/tools/installer/modules/module-catalog.js +565 -0
  189. package/tools/installer/modules/module-installer.js +618 -0
  190. package/tools/installer/modules/module-interface.js +86 -0
  191. package/tools/installer/modules/official-modules.js +98 -2172
  192. package/tools/installer/modules/pin-spec.js +125 -0
  193. package/tools/installer/modules/plugin-resolver.js +4 -0
  194. package/tools/installer/modules/skills-lib.js +3 -6
  195. package/tools/installer/prompts.js +0 -3
  196. package/tools/installer/ui.js +89 -54
  197. package/tools/installer/wizz-cli.js +1 -1
  198. package/tools/lib/frontmatter.js +139 -0
  199. package/tools/lib/sync-targets.mjs +49 -0
  200. package/tools/lib/walk.js +93 -0
  201. package/wizz-modules.yaml +9 -0
  202. package/src/scripts/__pycache__/memlog.cpython-313.pyc +0 -0
  203. package/src/scripts/memlog.py +0 -233
  204. package/src/scripts/tests/__pycache__/test_memlog.cpython-313-pytest-9.1.1.pyc +0 -0
  205. package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-313-pytest-9.1.1.pyc +0 -0
  206. package/src/scripts/tests/test_memlog.py +0 -306
  207. package/src/skills-lib/wizz-huashu-design/assets/showcases/INDEX.md +0 -115
  208. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-build.html +0 -235
  209. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-build.png +0 -0
  210. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-pentagram.html +0 -229
  211. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-pentagram.png +0 -0
  212. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-takram.html +0 -288
  213. package/src/skills-lib/wizz-huashu-design/assets/showcases/cover/cover-takram.png +0 -0
  214. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-build.html +0 -503
  215. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-build.png +0 -0
  216. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-pentagram.html +0 -600
  217. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-pentagram.png +0 -0
  218. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-takram.html +0 -670
  219. package/src/skills-lib/wizz-huashu-design/assets/showcases/infographic/infographic-takram.png +0 -0
  220. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-build.html +0 -382
  221. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-build.png +0 -0
  222. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-pentagram.html +0 -536
  223. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-pentagram.png +0 -0
  224. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-takram.html +0 -497
  225. package/src/skills-lib/wizz-huashu-design/assets/showcases/ppt/ppt-takram.png +0 -0
  226. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-build.html +0 -385
  227. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-build.png +0 -0
  228. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-pentagram.html +0 -422
  229. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-pentagram.png +0 -0
  230. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-takram.html +0 -499
  231. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-nav/ainav-takram.png +0 -0
  232. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-build.html +0 -562
  233. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-build.png +0 -0
  234. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-pentagram.html +0 -548
  235. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-pentagram.png +0 -0
  236. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-takram.html +0 -696
  237. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-ai-writing/aiwriting-takram.png +0 -0
  238. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-build.html +0 -372
  239. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-build.png +0 -0
  240. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-pentagram.html +0 -460
  241. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-pentagram.png +0 -0
  242. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-takram.html +0 -494
  243. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-devdocs/devdocs-takram.png +0 -0
  244. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-build.html +0 -367
  245. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-build.png +0 -0
  246. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-pentagram.html +0 -368
  247. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-pentagram.png +0 -0
  248. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-takram.html +0 -459
  249. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-homepage/homepage-takram.png +0 -0
  250. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-build.html +0 -493
  251. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-build.png +0 -0
  252. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-pentagram.html +0 -556
  253. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-pentagram.png +0 -0
  254. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-takram.html +0 -604
  255. package/src/skills-lib/wizz-huashu-design/assets/showcases/website-saas/saas-takram.png +0 -0
  256. package/tools/installer/file-ops.js +0 -204
  257. package/tools/installer/ide/shared/skill-manifest.js +0 -57
  258. package/tools/installer/yaml-format.js +0 -245
  259. package/web-bundles/README.md +0 -46
  260. package/web-bundles/brainstorming-coach/INSTRUCTIONS.md +0 -86
  261. package/web-bundles/brainstorming-coach/SKILL.md +0 -83
  262. package/web-bundles/brainstorming-coach/brain-methods.csv +0 -62
  263. package/web-bundles/bundles.json +0 -139
  264. package/web-bundles/market-and-industry-research/INSTRUCTIONS.md +0 -88
  265. package/web-bundles/market-and-industry-research/SKILL.md +0 -59
  266. package/web-bundles/prd-coach/INSTRUCTIONS.md +0 -86
  267. package/web-bundles/prd-coach/SKILL.md +0 -101
  268. package/web-bundles/prd-coach/prd-template.md +0 -165
  269. package/web-bundles/prd-coach/prd-validation-checklist.md +0 -135
  270. package/web-bundles/prfaq-coach/INSTRUCTIONS.md +0 -86
  271. package/web-bundles/prfaq-coach/SKILL.md +0 -139
  272. package/web-bundles/product-brief-coach/INSTRUCTIONS.md +0 -86
  273. package/web-bundles/product-brief-coach/SKILL.md +0 -113
  274. package/web-bundles/ux-coach/INSTRUCTIONS.md +0 -92
  275. package/web-bundles/ux-coach/SKILL.md +0 -187
  276. package/web-bundles/ux-coach/ux-validation.md +0 -100
  277. /package/src/modules/lowticket/skills/{lowticket-funil → wizz-lowticket-funil}/references/mapa-do-funil.md +0 -0
  278. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/CATALOGO.md +0 -0
  279. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/01-principios.md +0 -0
  280. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/02-diagnostico-funil.md +0 -0
  281. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/03-campanha-bidcap.md +0 -0
  282. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/04-criativos.md +0 -0
  283. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/04a-criativos-ia.md +0 -0
  284. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/04b-criativos-formatos.md +0 -0
  285. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/05-oferta.md +0 -0
  286. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/06-pagina-vendas.md +0 -0
  287. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/06a-instagram.md +0 -0
  288. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/06b-player-vsl.md +0 -0
  289. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/07-funil-upsell.md +0 -0
  290. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/07a-copy-humanizacao.md +0 -0
  291. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/08-pesquisa-publico.md +0 -0
  292. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/09-especialista-coproducao.md +0 -0
  293. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/10-levantar-caixa.md +0 -0
  294. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/11-checklist-roi.md +0 -0
  295. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/12-mineracao-ofertas.md +0 -0
  296. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/12a-mineracao-veredito.md +0 -0
  297. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/12b-fabrica-de-ofertas.md +0 -0
  298. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/12c-anatomia-low-ticket.md +0 -0
  299. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/13-benchmarks-vsl.md +0 -0
  300. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/14-vocabulario.md +0 -0
  301. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/15-como-estender.md +0 -0
  302. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/17-rastreamento.md +0 -0
  303. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/18-copy-desejo-oferta.md +0 -0
  304. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/INDEX.md +0 -0
  305. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/guardrails.md +0 -0
  306. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/knowledge/pontos-em-aberto.md +0 -0
  307. /package/src/modules/lowticket/skills/{lowticket-metodologia → wizz-lowticket-metodologia}/references/swipe-file.md +0 -0
  308. /package/src/modules/lowticket/skills/{lowticket-pagina → wizz-lowticket-pagina}/references/metas-e-medicao.md +0 -0
  309. /package/src/modules/lowticket/skills/{lowticket-pagina → wizz-lowticket-pagina}/references/padroes-de-codigo.md +0 -0
  310. /package/src/modules/lowticket/skills/{lowticket-trafego → wizz-lowticket-trafego}/references/formato-do-diagnostico.md +0 -0
@@ -0,0 +1,565 @@
1
+ /**
2
+ * Catálogo de módulos (leitura pura) — item 20, etapa 2 (auditoria 2026-09-11).
3
+ *
4
+ * Parte do split de official-modules.js: tudo que LÊ módulos (listar,
5
+ * descrever, localizar fonte, localizar _wizz/, ler config existente) sem
6
+ * prompt, sem spinner, sem instalar. Métodos que costumavam viver na classe
7
+ * OfficialModules continuam acessíveis por lá via delegação, para os callers
8
+ * e testes existentes não mudarem.
9
+ *
10
+ * Nada aqui deve importar `prompts` (regra do relatório: o único módulo que
11
+ * importa prompts é o config-collector).
12
+ */
13
+
14
+ const path = require('node:path');
15
+ const fs = require('../fs-native');
16
+ const yaml = require('yaml');
17
+ const { getProjectRoot, getSourcePath, getModulePath } = require('../project-root');
18
+ const { ExternalModuleManager } = require('./external-manager');
19
+ const { loadYamlCached } = require('../core/yaml-cache');
20
+ const { detectWizzDir } = require('../core/wizz-dir');
21
+
22
+ /**
23
+ * Parse a config.toml or config.user.toml written by writeCentralConfig.
24
+ * Only handles the subset of TOML the installer produces: [core],
25
+ * [modules.<code>], string/bool/number scalar values. [agents.*] and other
26
+ * sections are ignored. Returns a plain object keyed by section name where
27
+ * module sections use the bare code (e.g. "bmm"), not the full "modules.bmm".
28
+ */
29
+ function parseCentralToml(content) {
30
+ const result = {};
31
+ let currentSection = null;
32
+
33
+ for (const rawLine of content.split('\n')) {
34
+ const line = rawLine.trim();
35
+ if (!line || line.startsWith('#')) continue;
36
+
37
+ const sectionMatch = line.match(/^\[([^\]]+)\]\s*$/);
38
+ if (sectionMatch) {
39
+ const name = sectionMatch[1];
40
+ if (name === 'core') {
41
+ currentSection = 'core';
42
+ } else if (name.startsWith('modules.')) {
43
+ currentSection = name.slice('modules.'.length);
44
+ } else {
45
+ currentSection = null;
46
+ }
47
+ if (currentSection && !result[currentSection]) {
48
+ result[currentSection] = {};
49
+ }
50
+ continue;
51
+ }
52
+
53
+ if (!currentSection) continue;
54
+
55
+ const kvMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/);
56
+ if (!kvMatch) continue;
57
+
58
+ const key = kvMatch[1];
59
+ const raw = kvMatch[2].trim();
60
+ let value;
61
+ if (raw.startsWith('"') && raw.endsWith('"')) {
62
+ value = raw.slice(1, -1).replaceAll(/\\(["\\nrbt])/g, (_, c) => ({ '"': '"', '\\': '\\', n: '\n', r: '\r', b: '\b', t: '\t' })[c]);
63
+ } else if (raw === 'true') {
64
+ value = true;
65
+ } else if (raw === 'false') {
66
+ value = false;
67
+ } else if (raw !== '' && !isNaN(raw)) {
68
+ value = Number(raw);
69
+ } else {
70
+ value = raw;
71
+ }
72
+ result[currentSection][key] = value;
73
+ }
74
+
75
+ return result;
76
+ }
77
+
78
+ /**
79
+ * Localiza o module.yaml de um módulo: caminho padrão (src/modules/<code> ou
80
+ * core/bmm) primeiro, depois findModuleSource (que cobre externo/custom).
81
+ * Extrai a resolução copiada 3x em official-modules.js (OM-02, auditoria
82
+ * 2026-09-11) — scanModuleSchemas, collectModuleConfigQuick e
83
+ * collectModuleConfig tinham blocos idênticos.
84
+ *
85
+ * @param {(moduleCode: string, options?: Object) => Promise<string|null>} findModuleSourceFn
86
+ * A função de busca do dono da chamada (normalmente OfficialModules#findModuleSource).
87
+ * @param {string} moduleName
88
+ * @param {Object} [options] - Opções repassadas a findModuleSourceFn
89
+ * @returns {Promise<string|null>} Caminho absoluto para o module.yaml, ou null
90
+ */
91
+ async function resolveModuleConfigPath(findModuleSourceFn, moduleName, options = {}) {
92
+ const standardPath = path.join(getModulePath(moduleName), 'module.yaml');
93
+ if (await fs.pathExists(standardPath)) {
94
+ return standardPath;
95
+ }
96
+ const moduleSourcePath = await findModuleSourceFn(moduleName, { silent: true, ...options });
97
+ if (moduleSourcePath) {
98
+ return path.join(moduleSourcePath, 'module.yaml');
99
+ }
100
+ return null;
101
+ }
102
+
103
+ // Campos de metadata de module.yaml que não são perguntas de config.
104
+ // interface_version (auditoria 2026-09-11, item 25 — ver module-interface.js)
105
+ // é um escalar de contrato, não uma pergunta: sem essa entrada ele seria
106
+ // contado como "config real" pelo hasNoConfig do config-collector, do
107
+ // mesmo jeito que default_selected precisou entrar aqui antes dele.
108
+ // description e module_version entraram no review da Fase 4 (2026-09-12)
109
+ // pelo mesmo motivo: metadados escalares, não perguntas.
110
+ const MODULE_METADATA_FIELDS = new Set([
111
+ 'code',
112
+ 'name',
113
+ 'header',
114
+ 'subheader',
115
+ 'description',
116
+ 'module_version',
117
+ 'default_selected',
118
+ 'interface_version',
119
+ ]);
120
+
121
+ /**
122
+ * True when a config field has no default value at all. An explicit empty
123
+ * string (`default: ""`) is a real default meaning "defaults to blank" — it
124
+ * must NOT force a required prompt. Centralized so the express/customize/
125
+ * skip-prompts paths stay consistent.
126
+ * @param {*} defaultValue - The field's `default` value from module.yaml.
127
+ * @returns {boolean} True when the field has no usable default.
128
+ */
129
+ function isMissingDefault(defaultValue) {
130
+ return defaultValue === undefined || defaultValue === null;
131
+ }
132
+
133
+ /**
134
+ * Camada de leitura pura do OfficialModules: listar, descrever e localizar
135
+ * módulos. 0 prompts. Os métodos de coleta interativa ficam no restante de
136
+ * official-modules.js (config-collector), que delega aqui.
137
+ */
138
+ class ModuleCatalog {
139
+ /**
140
+ * @param {Object} [options]
141
+ * @param {ExternalModuleManager} [options.externalModuleManager]
142
+ * @param {Object|null} [options.channelOptions]
143
+ * @param {(moduleCode: string, options?: Object) => Promise<string|null>} [options.findModuleSource]
144
+ * Ponto único de resolução de fonte usado INTERNAMENTE pelo catálogo.
145
+ * OfficialModules injeta aqui o próprio wrapper, de modo que stubar
146
+ * `officialModules.findModuleSource` (padrão dos testes) também
147
+ * intercepta listAvailable/getModuleInfo/scanModuleSchemas — antes o
148
+ * catálogo chamava só o seu próprio método e o stub não pegava.
149
+ */
150
+ constructor(options = {}) {
151
+ this.externalModuleManager = options.externalModuleManager || new ExternalModuleManager();
152
+ this.channelOptions = options.channelOptions || null;
153
+ this.resolveModuleSource = options.findModuleSource || ((code, opts) => this.findModuleSource(code, opts));
154
+ /**
155
+ * Erros de leitura acumulados (module.yaml ilegível). O catálogo não
156
+ * importa `prompts` — quem avisa o usuário é OfficialModules, que drena
157
+ * esta lista depois de cada chamada (item 20: o split tinha trocado os
158
+ * `prompts.log.warn` originais por `catch {}` mudos).
159
+ * @type {Array<{module: string, error: Error}>}
160
+ */
161
+ this.loadErrors = [];
162
+ }
163
+
164
+ /**
165
+ * Drena os erros de leitura acumulados desde a última chamada.
166
+ * @returns {Array<{module: string, error: Error}>}
167
+ */
168
+ takeLoadErrors() {
169
+ const errors = this.loadErrors;
170
+ this.loadErrors = [];
171
+ return errors;
172
+ }
173
+
174
+ /**
175
+ * List all available built-in modules (core and bmm) plus bundled src/modules.
176
+ * All other modules come from wizz-modules.yaml
177
+ * @returns {Object} Object with modules array
178
+ */
179
+ async listAvailable() {
180
+ const modules = [];
181
+
182
+ // Add built-in core module (directly under src/core-skills)
183
+ const corePath = getSourcePath('core-skills');
184
+ if (await fs.pathExists(corePath)) {
185
+ const coreInfo = await this.getModuleInfo(corePath, 'core', 'src/core-skills');
186
+ if (coreInfo) {
187
+ modules.push(coreInfo);
188
+ }
189
+ }
190
+
191
+ // Add built-in bmm module (directly under src/bmm-skills)
192
+ const bmmPath = getSourcePath('bmm-skills');
193
+ if (await fs.pathExists(bmmPath)) {
194
+ const bmmInfo = await this.getModuleInfo(bmmPath, 'bmm', 'src/bmm-skills');
195
+ if (bmmInfo) {
196
+ modules.push(bmmInfo);
197
+ }
198
+ }
199
+
200
+ // Add bundled local modules (src/modules/<code>), e.g. wizz. Without this
201
+ // they never appear in the picker nor in the --yes defaults, even with
202
+ // default_selected: true — findModuleSource resolves them, but nothing
203
+ // ever selects them (bug: maestro/agentes de área não instalavam via npx).
204
+ const bundledDir = getSourcePath('modules');
205
+ if (await fs.pathExists(bundledDir)) {
206
+ const entries = await fs.readdir(bundledDir, { withFileTypes: true });
207
+ const seen = new Set(modules.map((m) => m.id));
208
+ for (const entry of entries) {
209
+ if (!entry.isDirectory()) continue;
210
+ const modulePath = path.join(bundledDir, entry.name);
211
+ if (!(await fs.pathExists(path.join(modulePath, 'module.yaml')))) continue;
212
+ const info = await this.getModuleInfo(modulePath, entry.name, `src/modules/${entry.name}`);
213
+ if (info && !seen.has(info.id)) {
214
+ modules.push(info);
215
+ seen.add(info.id);
216
+ }
217
+ }
218
+ }
219
+
220
+ return { modules };
221
+ }
222
+
223
+ /**
224
+ * Get module information from a module path
225
+ * @param {string} modulePath - Path to the module directory
226
+ * @param {string} defaultName - Default name for the module
227
+ * @param {string} sourceDescription - Description of where the module was found
228
+ * @returns {Object|null} Module info or null if not a valid module
229
+ */
230
+ async getModuleInfo(modulePath, defaultName, sourceDescription) {
231
+ const moduleConfigPath = path.join(modulePath, 'module.yaml');
232
+
233
+ if (!(await fs.pathExists(moduleConfigPath))) {
234
+ // Check resolution cache for strategy 5 modules (no module.yaml on disk)
235
+ const { CustomModuleManager } = require('./custom-module-manager');
236
+ const customMgr = new CustomModuleManager();
237
+ const resolved = customMgr.getResolution(defaultName);
238
+ if (resolved && resolved.synthesizedModuleYaml) {
239
+ return {
240
+ id: resolved.code,
241
+ path: modulePath,
242
+ name: resolved.name,
243
+ description: resolved.description,
244
+ version: resolved.version || '1.0.0',
245
+ source: sourceDescription,
246
+ dependencies: [],
247
+ defaultSelected: false,
248
+ };
249
+ }
250
+ return null;
251
+ }
252
+
253
+ const moduleInfo = {
254
+ id: defaultName,
255
+ path: modulePath,
256
+ name: defaultName
257
+ .split('-')
258
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
259
+ .join(' '),
260
+ description: 'Wizz Method Module',
261
+ version: '5.0.0',
262
+ source: sourceDescription,
263
+ };
264
+
265
+ // Read module config for metadata
266
+ try {
267
+ const config = await loadYamlCached(moduleConfigPath);
268
+ if (config) {
269
+ // Use the code property as the id if available
270
+ if (config.code) {
271
+ moduleInfo.id = config.code;
272
+ }
273
+
274
+ moduleInfo.name = config.name || moduleInfo.name;
275
+ moduleInfo.description = config.description || moduleInfo.description;
276
+ moduleInfo.version = config.version || moduleInfo.version;
277
+ moduleInfo.dependencies = config.dependencies || [];
278
+ moduleInfo.defaultSelected = config.default_selected === undefined ? false : config.default_selected;
279
+ }
280
+ } catch (error) {
281
+ // Sem prompts aqui (regra do split): um module.yaml quebrado degrada
282
+ // para os defaults acima em vez de falhar a listagem inteira, mas o
283
+ // erro é registrado para OfficialModules avisar o usuário.
284
+ this.loadErrors.push({ module: defaultName, error });
285
+ }
286
+
287
+ return moduleInfo;
288
+ }
289
+
290
+ /**
291
+ * Find the source path for a module by searching all possible locations
292
+ * @param {string} moduleCode - Code of the module to find (from module.yaml)
293
+ * @returns {string|null} Path to the module source or null if not found
294
+ */
295
+ async findModuleSource(moduleCode, options = {}) {
296
+ // Inherit channelOptions from the install-scoped instance when the caller
297
+ // didn't pass one explicitly. Keeps pre-install config collection and the
298
+ // actual install step looking at the same git ref.
299
+ if (options.channelOptions === undefined && this.channelOptions) {
300
+ options = { ...options, channelOptions: this.channelOptions };
301
+ }
302
+
303
+ // Check for core module (directly under src/core-skills)
304
+ if (moduleCode === 'core') {
305
+ const corePath = getSourcePath('core-skills');
306
+ if (await fs.pathExists(corePath)) {
307
+ return corePath;
308
+ }
309
+ }
310
+
311
+ // Check for built-in bmm module (directly under src/bmm-skills)
312
+ if (moduleCode === 'bmm') {
313
+ const bmmPath = getSourcePath('bmm-skills');
314
+ if (await fs.pathExists(bmmPath)) {
315
+ return bmmPath;
316
+ }
317
+ }
318
+
319
+ // Check bundled local modules (directly under src/modules/<code>), e.g. wizz.
320
+ // These ship inside this repo and are auto-discovered by list-options.js.
321
+ const bundledPath = getSourcePath('modules', moduleCode);
322
+ if (await fs.pathExists(path.join(bundledPath, 'module.yaml'))) {
323
+ return bundledPath;
324
+ }
325
+
326
+ // Check external official modules (pass channelOptions so channel plan applies)
327
+ const externalSource = await this.externalModuleManager.findExternalModuleSource(moduleCode, options);
328
+ if (externalSource) {
329
+ return externalSource;
330
+ }
331
+
332
+ // Check custom modules (from user-provided URLs, already cloned to cache)
333
+ const { CustomModuleManager } = require('./custom-module-manager');
334
+ const customMgr = new CustomModuleManager();
335
+ const customSource = await customMgr.findModuleSourceByCode(moduleCode, options);
336
+ if (customSource) {
337
+ return customSource;
338
+ }
339
+
340
+ return null;
341
+ }
342
+
343
+ /**
344
+ * Find the wizz installation directory in a project
345
+ * V6+ installations can use ANY folder name but ALWAYS have _config/manifest.yaml
346
+ * Delegated to core/wizz-dir.js, the single owner of `_wizz` resolution
347
+ * (item 20, auditoria 2026-09-11) — semântica inalterada.
348
+ * @param {string} projectDir - Project directory
349
+ * @returns {Promise<string>} Path to wizz directory
350
+ */
351
+ async findWizzDir(projectDir) {
352
+ return detectWizzDir(projectDir);
353
+ }
354
+
355
+ /**
356
+ * Load existing config if it exists from module config files.
357
+ * Populates `this.existingConfig` (plain object module → key → value).
358
+ * @param {string} projectDir - Target project directory
359
+ * @returns {Promise<boolean>} True when any prior config was found
360
+ */
361
+ async loadExistingConfig(projectDir) {
362
+ this.existingConfigData = {};
363
+
364
+ // Check if project directory exists first
365
+ if (!(await fs.pathExists(projectDir))) {
366
+ return false;
367
+ }
368
+
369
+ // Find the actual wizz directory (handles custom folder names)
370
+ const wizzDir = await this.findWizzDir(projectDir);
371
+
372
+ // Check if wizz directory exists
373
+ if (!(await fs.pathExists(wizzDir))) {
374
+ return false;
375
+ }
376
+
377
+ // Primary source: installer-written config.toml + config.user.toml (v6+).
378
+ // Both files together hold all install answers; config.user.toml carries
379
+ // user-scoped keys like user_name that would otherwise be re-prompted on
380
+ // every reinstall.
381
+ let foundAny = false;
382
+ for (const fileName of ['config.toml', 'config.user.toml']) {
383
+ const tomlPath = path.join(wizzDir, fileName);
384
+ if (!(await fs.pathExists(tomlPath))) continue;
385
+ try {
386
+ const content = await fs.readFile(tomlPath, 'utf8');
387
+ const parsed = parseCentralToml(content);
388
+ for (const [section, values] of Object.entries(parsed)) {
389
+ if (values && typeof values === 'object' && !Array.isArray(values)) {
390
+ if (!this.existingConfigData[section]) this.existingConfigData[section] = {};
391
+ Object.assign(this.existingConfigData[section], values);
392
+ foundAny = true;
393
+ }
394
+ }
395
+ } catch {
396
+ // Ignore parse errors
397
+ }
398
+ }
399
+
400
+ if (foundAny) {
401
+ return true;
402
+ }
403
+
404
+ // Fallback: legacy per-module config.yaml files (pre-v6 installations).
405
+ const entries = await fs.readdir(wizzDir, { withFileTypes: true });
406
+ const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom', 'hooks']);
407
+ for (const entry of entries) {
408
+ if (entry.isDirectory()) {
409
+ if (nonModuleDirs.has(entry.name)) {
410
+ continue;
411
+ }
412
+
413
+ const moduleConfigPath = path.join(wizzDir, entry.name, 'config.yaml');
414
+
415
+ if (await fs.pathExists(moduleConfigPath)) {
416
+ try {
417
+ const content = await fs.readFile(moduleConfigPath, 'utf8');
418
+ const moduleConfig = yaml.parse(content);
419
+ // Only keep plain object parses. A corrupt config.yaml that parses
420
+ // to a scalar or array would crash later code that does `key in cfg`
421
+ // / `Object.keys(cfg)`; treat it the same as a parse error.
422
+ if (moduleConfig && typeof moduleConfig === 'object' && !Array.isArray(moduleConfig)) {
423
+ this.existingConfigData[entry.name] = moduleConfig;
424
+ foundAny = true;
425
+ }
426
+ } catch {
427
+ // Ignore parse errors for individual modules
428
+ }
429
+ }
430
+ }
431
+ }
432
+
433
+ if (foundAny) {
434
+ await this._hoistCoreKeysFromLegacyModuleConfigs();
435
+ }
436
+
437
+ return foundAny;
438
+ }
439
+
440
+ /**
441
+ * Migrate prior answers when a key has moved from a non-core module to core
442
+ * (e.g. project_name moving from bmm to core in #2279). Without this, the
443
+ * partition logic in writeCentralConfig drops the value from the bmm bucket
444
+ * (because it's now a core key) without re-homing it under [core], so the
445
+ * user's prior answer silently disappears on the next install/quick-update.
446
+ */
447
+ async _hoistCoreKeysFromLegacyModuleConfigs() {
448
+ const coreSchemaPath = path.join(getSourcePath(), 'core-skills', 'module.yaml');
449
+ if (!(await fs.pathExists(coreSchemaPath))) return;
450
+
451
+ let coreSchema;
452
+ try {
453
+ coreSchema = await loadYamlCached(coreSchemaPath);
454
+ } catch {
455
+ return;
456
+ }
457
+ if (!coreSchema || typeof coreSchema !== 'object') return;
458
+
459
+ const coreKeys = new Set(
460
+ Object.entries(coreSchema)
461
+ .filter(([, v]) => v && typeof v === 'object' && 'prompt' in v)
462
+ .map(([k]) => k),
463
+ );
464
+ if (coreKeys.size === 0) return;
465
+
466
+ // Belt-and-suspenders: loadExistingConfig already filters non-object parses,
467
+ // but anyone calling _hoistCoreKeysFromLegacyModuleConfigs in isolation (or
468
+ // future code paths populating existingConfigData directly) shouldn't be
469
+ // able to crash this with a scalar / array.
470
+ const existingCore = this.existingConfigData.core;
471
+ this.existingConfigData.core = existingCore && typeof existingCore === 'object' && !Array.isArray(existingCore) ? existingCore : {};
472
+
473
+ for (const [moduleName, cfg] of Object.entries(this.existingConfigData)) {
474
+ if (moduleName === 'core' || !cfg || typeof cfg !== 'object' || Array.isArray(cfg)) continue;
475
+ for (const key of Object.keys(cfg)) {
476
+ if (!coreKeys.has(key)) continue;
477
+ if (!(key in this.existingConfigData.core)) {
478
+ this.existingConfigData.core[key] = cfg[key];
479
+ }
480
+ delete cfg[key];
481
+ }
482
+ }
483
+ }
484
+
485
+ /**
486
+ * Pre-scan module schemas to gather metadata for the configuration gateway prompt.
487
+ * Returns info about which modules have configurable options.
488
+ * @param {Array} modules - List of non-core module names
489
+ * @returns {Promise<Array>} Array of {moduleName, displayName, questionCount, hasFieldsWithoutDefaults}
490
+ */
491
+ async scanModuleSchemas(modules) {
492
+ const results = [];
493
+
494
+ for (const moduleName of modules) {
495
+ const moduleConfigPath = await resolveModuleConfigPath(this.resolveModuleSource, moduleName);
496
+ if (!moduleConfigPath) {
497
+ continue;
498
+ }
499
+
500
+ try {
501
+ const moduleConfig = await loadYamlCached(moduleConfigPath);
502
+ if (!moduleConfig) continue;
503
+
504
+ const displayName = moduleConfig.header || `${moduleName.toUpperCase()} Module`;
505
+ const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
506
+ const questionKeys = configKeys.filter((key) => {
507
+ if (MODULE_METADATA_FIELDS.has(key)) return false;
508
+ const item = moduleConfig[key];
509
+ return item && typeof item === 'object' && item.prompt;
510
+ });
511
+
512
+ const hasFieldsWithoutDefaults = questionKeys.some((key) => {
513
+ const item = moduleConfig[key];
514
+ return isMissingDefault(item.default);
515
+ });
516
+
517
+ results.push({
518
+ moduleName,
519
+ displayName,
520
+ questionCount: questionKeys.length,
521
+ hasFieldsWithoutDefaults,
522
+ });
523
+ } catch (error) {
524
+ // Sem prompts aqui: uma schema ilegível simplesmente não aparece no
525
+ // gateway de customização. O erro sobe por loadErrors para
526
+ // OfficialModules emitir o warn que existia antes do split.
527
+ this.loadErrors.push({ module: moduleName, error });
528
+ }
529
+ }
530
+
531
+ return results;
532
+ }
533
+
534
+ /**
535
+ * Private: Get list of all files in a directory
536
+ * @param {string} dir - Directory path
537
+ * @param {string} baseDir - Base directory for relative paths
538
+ * @returns {Array} List of relative file paths
539
+ */
540
+ async getFileList(dir, baseDir = dir) {
541
+ const files = [];
542
+ const entries = await fs.readdir(dir, { withFileTypes: true });
543
+
544
+ for (const entry of entries) {
545
+ const fullPath = path.join(dir, entry.name);
546
+
547
+ if (entry.isDirectory()) {
548
+ const subFiles = await this.getFileList(fullPath, baseDir);
549
+ files.push(...subFiles);
550
+ } else {
551
+ files.push(path.relative(baseDir, fullPath));
552
+ }
553
+ }
554
+
555
+ return files;
556
+ }
557
+ }
558
+
559
+ module.exports = {
560
+ ModuleCatalog,
561
+ parseCentralToml,
562
+ resolveModuleConfigPath,
563
+ isMissingDefault,
564
+ MODULE_METADATA_FIELDS,
565
+ };