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,368 @@
1
+ /**
2
+ * memlog — an append-only memory log: LLM-optimal working memory for a skill.
3
+ *
4
+ * A memlog is the dense, chronological record of everything that mattered in a piece of
5
+ * work — every item the user generated or accepted — kept minimal like human memory: only
6
+ * what's important, never bloated. It persists ACROSS sessions, so a fresh session can
7
+ * load it and continue. It is NOT a deliverable; downstream artifacts (a brief, a PRD, a
8
+ * deck, a report) are *derived* from it on demand. The host skill supplies the vocabulary
9
+ * by how it calls `append` — the tool stays neutral.
10
+ *
11
+ * It is a FLAT log: there are no sections or grouping. Every entry is one line, recorded
12
+ * at the END in the order it happened. The chronology itself is the structure — an event
13
+ * like "started technique X" is just another entry, same as an idea or an insight.
14
+ *
15
+ * Three invariants make it trustworthy:
16
+ *
17
+ * 1. Append-only, chronological. Entries land at the end, in the order they happen.
18
+ * Nothing is ever inserted backward, reordered, edited, or removed. There is no
19
+ * edit or delete subcommand by design; history is never rewritten.
20
+ * 2. Write-only / blind. Every command is an atomic, context-free write and echoes the
21
+ * new state as one line of JSON, so the caller never re-reads the file mid-session.
22
+ * The one time the file is read is on resume — and the caller reads it itself, not
23
+ * via this script.
24
+ * 3. No lifecycle status. A memory log has no "complete" flag. Whether the work is done,
25
+ * blocked, or paused is itself a fact that happened, so it is recorded as an entry
26
+ * (e.g. `append --type event --text "session complete"`), never as frontmatter the
27
+ * log would have to mutate.
28
+ *
29
+ * Atomicity: every write goes to a temp file, is flushed and fsync'd, then atomically
30
+ * renamed over the target, so a crash never leaves a half-written entry. Concurrent
31
+ * writers serialize on an O_EXCL lock file next to the memlog.
32
+ *
33
+ * Known limitation (by design, not a bug): there is no compaction, archival, or size
34
+ * cap. Append-only + no lifecycle status (invariant 3 above) means a `.memlog.md` grows
35
+ * without bound for the life of the workspace. If that ever becomes a real problem, the
36
+ * fix is a new host-skill-driven step, not a change to this script's invariants.
37
+ *
38
+ * The file shape (.memlog.md):
39
+ *
40
+ * ---
41
+ * topic: Onboarding flow for a budgeting app
42
+ * goal: lift week-1 retention
43
+ * updated: 2026-06-07T14:22
44
+ * ---
45
+ *
46
+ * - (note) user picked techniques: SCAMPER, then Six Thinking Hats
47
+ * - (technique) started SCAMPER
48
+ * - (idea) skip the signup wall: let people try with sample data first
49
+ * - (event) session complete
50
+ *
51
+ * Each entry may carry an optional `--type` — what KIND it is (idea, insight, question,
52
+ * decision, direction, assumption, gap, note, event, …) — and an optional `--by` naming
53
+ * who it came from (e.g. `user`, `coach`). Both render into one short inline tag:
54
+ * `(idea)`, `(idea by user)`, `(by coach)`. Omit them for a plain note. The host skill
55
+ * names the vocabulary; the script does not enforce one.
56
+ *
57
+ * Commands:
58
+ * init (--workspace DIR | --path FILE) [--field k=v ...] create the memlog (errors if it exists)
59
+ * append (--workspace DIR | --path FILE) --text STR [--type T] [--by W] append one entry at the end
60
+ * set (--workspace DIR | --path FILE) --key K --value V set/replace a frontmatter field
61
+ *
62
+ * Addressing: `--workspace` is the run folder, and the memlog is always
63
+ * {workspace}/.memlog.md. `--path` points straight at the memlog file instead.
64
+ *
65
+ * Zero dependencies on purpose: this file is copied verbatim to
66
+ * `{project-root}/_wizz/scripts/memlog.js` at install time, where there is no
67
+ * node_modules of any kind. Only `node:*` builtins may be required here.
68
+ *
69
+ * Node port of the former memlog.py (audit item 29, 2026-09-12): Node is now the only
70
+ * prerequisite of the Wizz core.
71
+ */
72
+
73
+ 'use strict';
74
+
75
+ const fs = require('node:fs');
76
+ const path = require('node:path');
77
+
78
+ const MEMLOG = '.memlog.md';
79
+ const LOCK_TIMEOUT_MS = 5000;
80
+ const LOCK_RETRY_MS = 50;
81
+ // A lock older than this belonged to a process that died mid-write; reclaim it
82
+ // instead of making every later caller wait out the full timeout.
83
+ const LOCK_STALE_MS = 30_000;
84
+
85
+ const EXIT_OK = 0;
86
+ const EXIT_RUNTIME = 1;
87
+ const EXIT_USAGE = 2;
88
+
89
+ // ─── helpers ───
90
+
91
+ /** Local timestamp in the frontmatter's `updated` format (YYYY-MM-DDTHH:MM). */
92
+ function now() {
93
+ const d = new Date();
94
+ const pad = (n) => String(n).padStart(2, '0');
95
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
96
+ }
97
+
98
+ /** Block the current thread for `ms` without a dependency and without a busy spin. */
99
+ function sleepSync(ms) {
100
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
101
+ }
102
+
103
+ /** Python's str.splitlines(): split on newlines and drop the empty tail a final \n leaves. */
104
+ function splitLines(text) {
105
+ const lines = text.split(/\r\n|\n|\r/);
106
+ if (lines.at(-1) === '') lines.pop();
107
+ return lines;
108
+ }
109
+
110
+ // ─── locking ───
111
+
112
+ /**
113
+ * Take an exclusive lock on `lockFile` (O_EXCL create), retrying until LOCK_TIMEOUT_MS.
114
+ * @param {string} lockFile
115
+ * @returns {number} open file descriptor for the lock
116
+ */
117
+ function acquireLock(lockFile) {
118
+ fs.mkdirSync(path.dirname(lockFile), { recursive: true });
119
+ const start = Date.now();
120
+ while (Date.now() - start < LOCK_TIMEOUT_MS) {
121
+ try {
122
+ return fs.openSync(lockFile, 'wx');
123
+ } catch (error) {
124
+ if (error.code !== 'EEXIST') throw error;
125
+ reclaimIfStale(lockFile);
126
+ sleepSync(LOCK_RETRY_MS);
127
+ }
128
+ }
129
+ throw new Error(
130
+ `Falha ao adquirir lock de ${lockFile} após ${LOCK_TIMEOUT_MS / 1000}s. ` + 'Outro processo pode estar gravando o arquivo de memória.',
131
+ );
132
+ }
133
+
134
+ /** Delete a lock left behind by a crashed writer (older than LOCK_STALE_MS). */
135
+ function reclaimIfStale(lockFile) {
136
+ try {
137
+ if (Date.now() - fs.statSync(lockFile).mtimeMs > LOCK_STALE_MS) fs.unlinkSync(lockFile);
138
+ } catch {
139
+ // Gone already, or not ours to clean up: the retry loop handles both.
140
+ }
141
+ }
142
+
143
+ /** Release the lock: close the descriptor and remove the lock file. */
144
+ function releaseLock(fd, lockFile) {
145
+ try {
146
+ fs.closeSync(fd);
147
+ } catch {
148
+ // Already closed.
149
+ }
150
+ try {
151
+ fs.unlinkSync(lockFile);
152
+ } catch {
153
+ // Another writer already reclaimed it as stale.
154
+ }
155
+ }
156
+
157
+ // ─── file shape ───
158
+
159
+ /** The memlog file, from either addressing mode: {workspace}/.memlog.md or an explicit --path. */
160
+ function resolveTarget(args) {
161
+ return args.path ? path.normalize(args.path) : path.join(args.workspace, MEMLOG);
162
+ }
163
+
164
+ /**
165
+ * Return [frontmatter Map in source order, body string]. Frontmatter is plain key: value.
166
+ * The closing fence is the first line that is *exactly* `---`, so a `---` inside a field
167
+ * value (topic/goal are free user text) never truncates the frontmatter.
168
+ * @param {string} text
169
+ * @returns {[Map<string, string>, string]}
170
+ */
171
+ function split(text) {
172
+ const lines = splitLines(text);
173
+ if (lines.length === 0 || lines[0] !== '---') throw new Error('.memlog.md has no frontmatter');
174
+ const end = lines.findIndex((line, i) => i >= 1 && line === '---');
175
+ if (end === -1) throw new Error('.memlog.md frontmatter is not terminated');
176
+ const meta = new Map();
177
+ for (const line of lines.slice(1, end)) {
178
+ const at = line.indexOf(':');
179
+ if (at === -1) continue;
180
+ meta.set(line.slice(0, at).trim(), line.slice(at + 1).trim());
181
+ }
182
+ return [
183
+ meta,
184
+ lines
185
+ .slice(end + 1)
186
+ .join('\n')
187
+ .replace(/^\n+/, ''),
188
+ ];
189
+ }
190
+
191
+ /**
192
+ * Render frontmatter + body back to the file shape.
193
+ * Newlines in values are neutralized so a multi-line field can't break the fence on re-read.
194
+ */
195
+ function render(meta, body) {
196
+ const fm = [...meta].map(([k, v]) => `${k}: ${splitLines(String(v)).join(' ')}`).join('\n');
197
+ return `---\n${fm}\n---\n\n${body.replace(/\n+$/, '')}\n`;
198
+ }
199
+
200
+ /** Stamp `updated` and keep it last so the field order stays predictable. */
201
+ function touch(meta) {
202
+ meta.delete('updated');
203
+ meta.set('updated', now());
204
+ }
205
+
206
+ /** Temp + write + fsync + atomic rename, so a crash never half-writes an entry. */
207
+ function writeAtomic(target, text) {
208
+ const tmp = `${target}.tmp`;
209
+ const fd = fs.openSync(tmp, 'w');
210
+ try {
211
+ fs.writeFileSync(fd, text, 'utf8');
212
+ fs.fsyncSync(fd);
213
+ } finally {
214
+ fs.closeSync(fd);
215
+ }
216
+ fs.renameSync(tmp, target);
217
+ }
218
+
219
+ function entryCount(body) {
220
+ return splitLines(body).filter((line) => line.startsWith('- ')).length;
221
+ }
222
+
223
+ /** Echo new state so the caller never re-reads the file to know where it stands. */
224
+ function ack(target, body) {
225
+ process.stdout.write(`${JSON.stringify({ ok: true, memlog: target, entries: entryCount(body) })}\n`);
226
+ }
227
+
228
+ /** Read and parse the memlog, turning a missing file into a friendly usage error. */
229
+ function readMemlog(target) {
230
+ let text;
231
+ try {
232
+ text = fs.readFileSync(target, 'utf8');
233
+ } catch (error) {
234
+ if (error.code === 'ENOENT') {
235
+ throw new UsageError(`${target} does not exist; run \`init\` before append/set`);
236
+ }
237
+ throw new Error(`failed to read ${target}: ${error.message}`);
238
+ }
239
+ return split(text);
240
+ }
241
+
242
+ // ─── commands ───
243
+
244
+ class UsageError extends Error {}
245
+
246
+ function cmdInit(args) {
247
+ const target = resolveTarget(args);
248
+ if (fs.existsSync(target)) {
249
+ throw new UsageError(`${target} already exists; use append/set to update it`);
250
+ }
251
+ fs.mkdirSync(path.dirname(target), { recursive: true });
252
+ const meta = new Map();
253
+ for (const pair of args.field) {
254
+ const at = pair.indexOf('=');
255
+ if (at === -1) throw new UsageError(`--field expects key=value, got '${pair}'`);
256
+ meta.set(pair.slice(0, at).trim(), pair.slice(at + 1).trim());
257
+ }
258
+ touch(meta);
259
+ writeAtomic(target, render(meta, ''));
260
+ ack(target, '');
261
+ return EXIT_OK;
262
+ }
263
+
264
+ /** Build one entry line: `- (type by who) text`, with the tag omitted when both are absent. */
265
+ function entryLine(args) {
266
+ const text = args.text.trim().split(/\s+/).filter(Boolean).join(' ');
267
+ let label = args.type || '';
268
+ if (args.by) label = `${label} by ${args.by}`.trim(); // attribution: "(idea by user)" / "(by coach)"
269
+ return `- ${label ? `(${label}) ` : ''}${text}`;
270
+ }
271
+
272
+ /** Run `mutate(meta, body)` under the lock and write the result atomically. */
273
+ function withLockedMemlog(target, mutate) {
274
+ const lockFile = `${target}.lock`;
275
+ const fd = acquireLock(lockFile);
276
+ try {
277
+ const [meta, body] = readMemlog(target);
278
+ const nextBody = mutate(meta, body);
279
+ touch(meta);
280
+ writeAtomic(target, render(meta, nextBody));
281
+ ack(target, nextBody);
282
+ return EXIT_OK;
283
+ } finally {
284
+ releaseLock(fd, lockFile);
285
+ }
286
+ }
287
+
288
+ function cmdAppend(args) {
289
+ const target = resolveTarget(args);
290
+ return withLockedMemlog(target, (_meta, body) => {
291
+ const entry = entryLine(args);
292
+ return body.trim() ? `${body.replace(/\n+$/, '')}\n${entry}` : entry; // always at the end
293
+ });
294
+ }
295
+
296
+ function cmdSet(args) {
297
+ const target = resolveTarget(args);
298
+ return withLockedMemlog(target, (meta, body) => {
299
+ meta.set(args.key, args.value);
300
+ return body;
301
+ });
302
+ }
303
+
304
+ // ─── CLI ───
305
+
306
+ const COMMANDS = {
307
+ init: { run: cmdInit, flags: { field: 'many' }, required: [] },
308
+ append: { run: cmdAppend, flags: { text: 'one', type: 'one', by: 'one' }, required: ['text'] },
309
+ set: { run: cmdSet, flags: { key: 'one', value: 'one' }, required: ['key', 'value'] },
310
+ };
311
+
312
+ const USAGE = 'usage: memlog.js {init,append,set} (--workspace DIR | --path FILE) [options]';
313
+
314
+ /**
315
+ * Parse argv for one subcommand. Throws UsageError on anything argparse would reject.
316
+ * @param {string[]} argv
317
+ * @returns {{spec: object, args: object}}
318
+ */
319
+ function parseArgs(argv) {
320
+ const [name, ...rest] = argv;
321
+ const spec = Object.prototype.hasOwnProperty.call(COMMANDS, name) ? COMMANDS[name] : null;
322
+ if (!spec) throw new UsageError(`invalid choice: '${name ?? ''}' (choose from init, append, set)`);
323
+ const flags = { workspace: 'one', path: 'one', ...spec.flags };
324
+ const args = { field: [] };
325
+ for (let i = 0; i < rest.length; i++) {
326
+ const key = rest[i].startsWith('--') ? rest[i].slice(2) : null;
327
+ const kind = key && Object.prototype.hasOwnProperty.call(flags, key) ? flags[key] : null;
328
+ if (!kind) throw new UsageError(`unrecognized argument: ${rest[i]}`);
329
+ const value = rest[++i];
330
+ if (value === undefined) throw new UsageError(`argument --${key}: expected one argument`);
331
+ if (kind === 'many') args[key].push(value);
332
+ else args[key] = value;
333
+ }
334
+ // Mutually exclusive AND required: exactly one of the two must be present.
335
+ if (Boolean(args.workspace) === Boolean(args.path)) {
336
+ throw new UsageError('one of the arguments --workspace --path is required (and not both)');
337
+ }
338
+ for (const required of spec.required) {
339
+ if (args[required] === undefined) throw new UsageError(`the following arguments are required: --${required}`);
340
+ }
341
+ return { spec, args };
342
+ }
343
+
344
+ /**
345
+ * Entry point. Returns the process exit code instead of throwing, so callers
346
+ * (tests included) can assert on it.
347
+ * @param {string[]} argv - argv without node and script
348
+ * @returns {number}
349
+ */
350
+ function main(argv) {
351
+ try {
352
+ const { spec, args } = parseArgs(argv);
353
+ return spec.run(args);
354
+ } catch (error) {
355
+ if (error instanceof UsageError) {
356
+ process.stderr.write(`${USAGE}\nerror: ${error.message}\n`);
357
+ return EXIT_USAGE;
358
+ }
359
+ process.stderr.write(`error: ${error.message}\n`);
360
+ return EXIT_RUNTIME;
361
+ }
362
+ }
363
+
364
+ if (require.main === module) {
365
+ process.exitCode = main(process.argv.slice(2));
366
+ }
367
+
368
+ module.exports = { main, split, render, entryCount, MEMLOG };
@@ -46,6 +46,20 @@ Optional `include` (aditivo, opcional):
46
46
  include files warn to stderr and are skipped (fail-open, matching the
47
47
  rest of this resolver); they never abort resolution. A toml with no
48
48
  `include` key resolves exactly as before this feature existed.
49
+
50
+ `_shared/` fallback: after `wizz install` the skill directory is moved
51
+ out of `_wizz/` into the IDE folder (`.claude/skills/<skill>/`), so a
52
+ shipped `include = ["../../_shared/x.md"]` no longer resolves. When the
53
+ base-relative path is missing AND the include mentions `_shared/`, the
54
+ segment after the LAST `_shared/` is looked up under
55
+ `<project-root>/_wizz/<module>/_shared/` for every module that has one,
56
+ modules sorted by name, first hit wins.
57
+
58
+ Containment: when a project root is known, an include whose base-relative
59
+ path escapes that root (`../../../../outside.md`) is refused with a warning
60
+ before it is read. The `_shared/` fallback candidates live under
61
+ `<project-root>/_wizz/` by construction, so they always pass. A standalone
62
+ skill with no resolvable project root keeps the unrestricted behaviour.
49
63
  """
50
64
 
51
65
  import argparse
@@ -67,6 +81,8 @@ except ImportError:
67
81
 
68
82
  _MISSING = object()
69
83
  _KEYED_MERGE_FIELDS = ("code", "id")
84
+ _WIZZ_FOLDER_NAME = "_wizz"
85
+ _SHARED_DIR_NAME = "_shared"
70
86
 
71
87
 
72
88
  def find_project_root(start: Path):
@@ -114,19 +130,90 @@ _INCLUDE_TARGET_FIELD = "activation_steps_append"
114
130
 
115
131
  def _read_include_file(path: Path):
116
132
  """Read an include file's raw text. Returns None (and warns to stderr)
117
- when the file is missing or unreadable, so a broken/renamed include
118
- never aborts resolution — same fail-open philosophy as the optional
119
- team/user layers above."""
120
- if not path.is_file():
121
- sys.stderr.write(f"warning: include not found, skipping: {path}\n")
122
- return None
133
+ when the file is unreadable, so a broken include never aborts
134
+ resolution — same fail-open philosophy as the optional team/user layers
135
+ above. Existence (and the `_shared/` fallback) is `_find_include_file`'s
136
+ job."""
123
137
  try:
124
138
  return path.read_text(encoding="utf-8")
125
139
  except OSError as error:
126
- sys.stderr.write(f"warning: failed to read include {path}: {error}\n")
140
+ sys.stderr.write(f"warning: include not readable, skipping: {path}: {error}\n")
127
141
  return None
128
142
 
129
143
 
144
+ def _shared_fallback_candidates(rel_path: str, project_root):
145
+ """Absolute candidates for an include whose base-relative path is missing.
146
+
147
+ The verbatim install pipeline moves each skill directory OUT of `_wizz/`
148
+ into the IDE folder (`.claude/skills/<skill>/customize.toml`) while the
149
+ file keeps its shipped `include = ["../../_shared/x.md"]`. From there that
150
+ resolves to `.claude/_shared/x.md`, which does not exist, and every
151
+ included paragraph was dropped silently. The real shared files live at
152
+ `<project-root>/_wizz/<module>/_shared/`. So: take the segment after the
153
+ LAST `_shared/` in the include and look for it under every module directly
154
+ under `_wizz/` that has a `_shared/` folder, modules sorted by name (first
155
+ hit wins upstream). Nothing else is guessed: an include without `_shared/`
156
+ gets no fallback. Mirror of `sharedFallbackCandidates` in
157
+ tools/installer/core/resolved-includes.js."""
158
+ if project_root is None or not isinstance(rel_path, str):
159
+ return []
160
+ posix = rel_path.replace("\\", "/")
161
+ marker = _SHARED_DIR_NAME + "/"
162
+ index = posix.rfind(marker)
163
+ if index == -1:
164
+ return []
165
+ segment = posix[index + len(marker):]
166
+ parts = segment.split("/")
167
+ if not segment or any(part in ("", "..", ".") for part in parts):
168
+ return []
169
+
170
+ wizz_root = project_root / _WIZZ_FOLDER_NAME
171
+ try:
172
+ modules = sorted(entry.name for entry in wizz_root.iterdir() if entry.is_dir())
173
+ except OSError:
174
+ return []
175
+ candidates = []
176
+ for name in modules:
177
+ shared_dir = wizz_root / name / _SHARED_DIR_NAME
178
+ if not shared_dir.is_dir():
179
+ continue
180
+ candidates.append(shared_dir.joinpath(*parts))
181
+ return candidates
182
+
183
+
184
+ def _is_outside_project_root(base_dir: Path, rel_path: str, project_root):
185
+ """True when the base-relative include escapes the project root.
186
+
187
+ Hardening (2026-09-11): a customize.toml must not pull arbitrary files
188
+ from the user's home or from a sibling checkout into an agent's
189
+ activation steps, so `include = ["../../../../outside.md"]` is refused
190
+ before it is ever read. The `_shared/` fallback candidates are built
191
+ under `<project-root>/_wizz/` by construction and always pass. When no
192
+ project root is resolvable (standalone skill) there is nothing to be
193
+ outside of and the old unrestricted behaviour stands. Mirror of
194
+ `isOutsideProjectRoot` in tools/installer/core/resolved-includes.js."""
195
+ if project_root is None:
196
+ return False
197
+ primary = (base_dir / rel_path).resolve()
198
+ try:
199
+ primary.relative_to(Path(project_root).resolve())
200
+ except ValueError:
201
+ return True
202
+ return False
203
+
204
+
205
+ def _find_include_file(base_dir: Path, rel_path: str, project_root):
206
+ """Absolute path the include actually points at, or None. Base-relative
207
+ first, then the `_shared/` fallback above."""
208
+ primary = (base_dir / rel_path).resolve()
209
+ if primary.is_file():
210
+ return primary
211
+ for candidate in _shared_fallback_candidates(rel_path, project_root):
212
+ if candidate.is_file():
213
+ return candidate
214
+ return None
215
+
216
+
130
217
  def _split_include_paragraphs(text: str):
131
218
  """Split an included markdown file into instruction strings.
132
219
 
@@ -144,7 +231,7 @@ def _split_include_paragraphs(text: str):
144
231
  return paragraphs
145
232
 
146
233
 
147
- def resolve_includes(data, base_dir: Path):
234
+ def resolve_includes(data, base_dir: Path, project_root=None, skill_name: str = ""):
148
235
  """Expand `include = [...]` keys found in any table of `data`.
149
236
 
150
237
  Purely additive: a table without `include` comes back unchanged. When
@@ -163,7 +250,22 @@ def resolve_includes(data, base_dir: Path):
163
250
  if not isinstance(rel_path, str):
164
251
  sys.stderr.write(f"warning: include entries must be strings, got: {rel_path!r}\n")
165
252
  continue
166
- text = _read_include_file((base_dir / rel_path).resolve())
253
+ if _is_outside_project_root(base_dir, rel_path, project_root):
254
+ sys.stderr.write(
255
+ f'warning: include outside the project root, skipping: "{rel_path}" '
256
+ f"(skill: {skill_name or '?'})\n"
257
+ )
258
+ continue
259
+ target = _find_include_file(base_dir, rel_path, project_root)
260
+ if target is None:
261
+ primary = (base_dir / rel_path).resolve()
262
+ sys.stderr.write(
263
+ f'warning: include not found, skipping: "{rel_path}" '
264
+ f"(skill: {skill_name or '?'}; tried {primary} and every "
265
+ f"{_WIZZ_FOLDER_NAME}/*/{_SHARED_DIR_NAME}/)\n"
266
+ )
267
+ continue
268
+ text = _read_include_file(target)
167
269
  if text is not None:
168
270
  included_paragraphs.extend(_split_include_paragraphs(text))
169
271
  elif "include" in data:
@@ -173,7 +275,9 @@ def resolve_includes(data, base_dir: Path):
173
275
  for key, value in data.items():
174
276
  if key == "include":
175
277
  continue
176
- result[key] = resolve_includes(value, base_dir) if isinstance(value, dict) else value
278
+ result[key] = (
279
+ resolve_includes(value, base_dir, project_root, skill_name) if isinstance(value, dict) else value
280
+ )
177
281
 
178
282
  if included_paragraphs:
179
283
  existing = result.get(_INCLUDE_TARGET_FIELD, [])
@@ -294,20 +398,25 @@ def main():
294
398
  skill_name = skill_dir.name
295
399
  defaults_path = skill_dir / "customize.toml"
296
400
 
297
- defaults = resolve_includes(load_toml(defaults_path, required=True), defaults_path.parent)
298
-
299
401
  # Prefer the project that contains this skill. Only fall back to cwd if
300
402
  # the skill isn't inside a recognizable project tree (unusual but possible
301
403
  # for standalone skills invoked directly). Using cwd first is unsafe when
302
404
  # an ancestor of cwd happens to have a stray _wizz/ from another project.
405
+ # Resolved BEFORE the base layer: the `_shared/` include fallback needs it.
303
406
  project_root = find_project_root(skill_dir) or find_project_root(Path.cwd())
304
407
 
408
+ defaults = resolve_includes(
409
+ load_toml(defaults_path, required=True), defaults_path.parent, project_root, skill_name
410
+ )
411
+
305
412
  team = {}
306
413
  user = {}
307
414
  if project_root:
308
- custom_dir = project_root / "_wizz" / "custom"
309
- team = resolve_includes(load_toml(custom_dir / f"{skill_name}.toml"), custom_dir)
310
- user = resolve_includes(load_toml(custom_dir / f"{skill_name}.user.toml"), custom_dir)
415
+ custom_dir = project_root / _WIZZ_FOLDER_NAME / "custom"
416
+ team = resolve_includes(load_toml(custom_dir / f"{skill_name}.toml"), custom_dir, project_root, skill_name)
417
+ user = resolve_includes(
418
+ load_toml(custom_dir / f"{skill_name}.user.toml"), custom_dir, project_root, skill_name
419
+ )
311
420
 
312
421
  merged = deep_merge(defaults, team)
313
422
  merged = deep_merge(merged, user)
@@ -0,0 +1,14 @@
1
+ # Sinal de complexidade (fonte única)
2
+ #
3
+ # Lido por wizz-router (SKILL.md), wizz-maestro (SKILL.md) e wizz-quick-dev
4
+ # (SKILL.md) como a FONTE CANÔNICA do parágrafo de regra abaixo. As SKILL.md
5
+ # não fazem include automático dele (skills são pastas autocontidas copiadas
6
+ # verbatim), então editar aqui NÃO propaga sozinho — quem editar este
7
+ # parágrafo precisa replicar a mudança manualmente nas 3 SKILL.md (PT-BR
8
+ # idêntico (após a normalização do teste: backticks, prefixo wizz-, "(você)") em wizz-router/wizz-maestro; tradução em inglês em
9
+ # wizz-quick-dev). `test/test-dispatch-rule-consistency.js` compara o texto
10
+ # do bloco (não só os números) contra as 3 cópias e falha em qualquer
11
+ # divergência de wording, não só de limiar.
12
+ # ---
13
+
14
+ Regra de dispatch: SE 2+ áreas → maestro, sempre. SENÃO conte os 3 fatores restantes (multi-passo, precisa planejar, gera artefato memorável); 2+ fatores → maestro. A cláusula de área decide sozinha, sem somar com mais nada.
@@ -0,0 +1,93 @@
1
+ Copyright 2022 The Instrument Serif Project Authors (https://github.com/Instrument/instrument-serif)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ https://openfontlicense.org
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -12,7 +12,7 @@
12
12
  > 仓库和已下载的缓存中)。用某个 SFX 前先 `ls assets/sfx/<category>/` 确认文件存在;
13
13
  > 缺失就跑 `npx --yes wizz-method fetch-assets --bundle huashu-audio --dest
14
14
  > assets`(路径相对本 skill 根目录)。离线时手动下载
15
- > `https://github.com/wizzcomms/wizz-method/releases/download/assets-v1/huashu-audio.tar.gz`
15
+ > `npx wizz-method fetch-assets --bundle huashu-audio` (2 partes em `https://wizz-assets.junior-aec.workers.dev/huashu-audio-1.tar.gz` e `.../huashu-audio-2.tar.gz`)
16
16
  > 解压到 `assets/`,能力不受影响,只是首次用要等下载。
17
17
 
18
18
  ---