wizz-method 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/package.json +39 -3
- package/skills-registry.yaml +102 -7
- package/src/bmm-skills/4-implementation/wizz-code-review/SKILL.md +2 -0
- package/src/bmm-skills/4-implementation/wizz-quick-dev/SKILL.md +5 -2
- package/src/core-skills/_shared/handoff-protocol.md +61 -0
- package/src/core-skills/wizz-customize/SKILL.md +2 -2
- package/src/core-skills/wizz-party-mode/references/mode-agent-team.md +1 -1
- package/src/core-skills/wizz-party-mode/references/mode-subagent.md +1 -1
- package/src/core-skills/wizz-review-adversarial-general/SKILL.md +2 -0
- package/src/modules/wizz/README.md +3 -3
- package/src/modules/wizz/_shared/communication-rules.md +13 -0
- package/src/modules/wizz/_shared/encerramento.md +2 -2
- package/src/modules/wizz/agents/wizz-ads/customize.toml +5 -3
- package/src/modules/wizz/agents/wizz-copy/customize.toml +5 -3
- package/src/modules/wizz/agents/wizz-designer/SKILL.md +2 -2
- package/src/modules/wizz/agents/wizz-designer/customize.toml +6 -4
- package/src/modules/wizz/agents/wizz-growth/customize.toml +11 -3
- package/src/modules/wizz/agents/wizz-maestro/SKILL.md +9 -5
- package/src/modules/wizz/agents/wizz-maestro/customize.toml +5 -7
- package/src/modules/wizz/agents/wizz-memoria/customize.toml +2 -4
- package/src/modules/wizz/agents/wizz-qa/SKILL.md +5 -5
- package/src/modules/wizz/agents/wizz-qa/customize.toml +9 -7
- package/src/modules/wizz/agents/wizz-seo/customize.toml +5 -3
- package/src/modules/wizz/agents/wizz-social/customize.toml +9 -8
- package/src/modules/wizz/module.yaml +1 -1
- package/src/modules/wizz/overrides/wizz-agent-analyst.toml +4 -5
- package/src/modules/wizz/overrides/wizz-agent-architect.toml +11 -3
- package/src/modules/wizz/overrides/wizz-agent-dev.toml +6 -4
- package/src/modules/wizz/overrides/wizz-agent-pm.toml +4 -2
- package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +3 -5
- package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +4 -2
- package/src/modules/wizz/scripts/wizz-init.mjs +3 -1
- package/src/scripts/__pycache__/resolve_customization.cpython-314.pyc +0 -0
- package/src/scripts/memlog.py +9 -0
- package/src/scripts/resolve_customization.py +93 -3
- package/src/skills-lib/adversarial-reviewer/SKILL.md +2 -0
- package/src/skills-lib/algorithmic-art/SKILL.md +29 -369
- package/src/skills-lib/algorithmic-art/references/interactive-artifact.md +139 -0
- package/src/skills-lib/algorithmic-art/references/p5js-implementation.md +121 -0
- package/src/skills-lib/algorithmic-art/references/philosophy-creation.md +88 -0
- package/src/skills-lib/canvas-design/SKILL.md +9 -38
- package/src/skills-lib/canvas-design/references/canvas-execution.md +21 -0
- package/src/skills-lib/canvas-design/references/philosophy-examples.md +25 -0
- package/src/skills-lib/cerebro/SKILL.md +8 -273
- package/src/skills-lib/cerebro/references/comandos-pesquisa-e-sync.md +44 -0
- package/src/skills-lib/cerebro/references/comandos-rotina-e-captura.md +94 -0
- package/src/skills-lib/cerebro/references/comandos-sessao.md +122 -0
- package/src/skills-lib/content-strategy/SKILL.md +12 -316
- package/src/skills-lib/content-strategy/references/content-types.md +52 -0
- package/src/skills-lib/content-strategy/references/ideation-sources.md +78 -0
- package/src/skills-lib/content-strategy/references/pillars-and-keywords.md +78 -0
- package/src/skills-lib/content-strategy/references/prioritization-and-output.md +57 -0
- package/src/skills-lib/decision-maker/SKILL.md +13 -466
- package/src/skills-lib/decision-maker/references/commands-and-edge-cases.md +40 -0
- package/src/skills-lib/decision-maker/references/output-format.md +161 -0
- package/src/skills-lib/decision-maker/references/references-and-extraction.md +129 -0
- package/src/skills-lib/decision-maker/references/six-decisions.md +122 -0
- package/src/skills-lib/decision-maker/references/wizz-method-handoff.md +22 -0
- package/src/skills-lib/find-skills/SKILL.md +9 -6
- package/src/skills-lib/form-cro/SKILL.md +12 -390
- package/src/skills-lib/form-cro/references/experiments.md +73 -0
- package/src/skills-lib/form-cro/references/field-optimization.md +92 -0
- package/src/skills-lib/form-cro/references/flow-and-errors.md +71 -0
- package/src/skills-lib/form-cro/references/measurement-output.md +41 -0
- package/src/skills-lib/form-cro/references/trust-and-form-types.md +54 -0
- package/src/skills-lib/graphify/SKILL.md +2 -20
- package/src/skills-lib/huashu-design/SKILL.md +42 -596
- package/src/skills-lib/huashu-design/references/anti-slop-principles.md +62 -0
- package/src/skills-lib/huashu-design/references/audio-design-rules.md +1 -1
- package/src/skills-lib/huashu-design/references/cross-agent-adaptation.md +14 -0
- package/src/skills-lib/huashu-design/references/design-direction-fallback.md +113 -0
- package/src/skills-lib/huashu-design/references/exception-handling.md +18 -0
- package/src/skills-lib/huashu-design/references/fact-verification.md +36 -0
- package/src/skills-lib/huashu-design/references/ios-prototype.md +146 -0
- package/src/skills-lib/huashu-design/references/sfx-library.md +7 -0
- package/src/skills-lib/huashu-design/references/starter-components.md +24 -0
- package/src/skills-lib/huashu-design/references/video-export.md +1 -1
- package/src/skills-lib/huashu-design/references/watermark-policy.md +23 -0
- package/src/skills-lib/huashu-design/scripts/add-music.sh +12 -1
- package/src/skills-lib/huashu-design/scripts/mix-voiceover.sh +11 -0
- package/src/skills-lib/humanizer/SKILL.md +23 -431
- package/src/skills-lib/humanizer/references/ai-writing-patterns.md +314 -0
- package/src/skills-lib/humanizer/references/full-example.md +72 -0
- package/src/skills-lib/humanizer/references/personality-and-soul.md +36 -0
- package/src/skills-lib/impeccable/SKILL.md +37 -153
- package/src/skills-lib/impeccable/references/design-rules.md +95 -0
- package/src/skills-lib/impeccable/references/pin-unpin-and-hooks.md +17 -0
- package/src/skills-lib/impeccable/references/routing-rules.md +28 -0
- package/src/skills-lib/implementation-planner/SKILL.md +22 -529
- package/src/skills-lib/implementation-planner/references/folder-structure-and-dependencies.md +132 -0
- package/src/skills-lib/implementation-planner/references/handoff-template.md +34 -0
- package/src/skills-lib/implementation-planner/references/implementation-phases.md +54 -0
- package/src/skills-lib/implementation-planner/references/implementation-types.md +28 -0
- package/src/skills-lib/implementation-planner/references/motion-path-implementation.md +57 -0
- package/src/skills-lib/implementation-planner/references/output-templates.md +92 -0
- package/src/skills-lib/implementation-planner/references/performance-plan.md +52 -0
- package/src/skills-lib/inicio-de-projeto/SKILL.md +4 -224
- package/src/skills-lib/inicio-de-projeto/references/implementacao-api-forms.md +112 -0
- package/src/skills-lib/inicio-de-projeto/references/padroes-arquiteturais-e-pastas.md +71 -0
- package/src/skills-lib/inicio-de-projeto/references/seguranca-e-regras-codigo.md +26 -0
- package/src/skills-lib/launch-strategy/SKILL.md +9 -311
- package/src/skills-lib/launch-strategy/references/five-phase-approach.md +76 -0
- package/src/skills-lib/launch-strategy/references/launch-checklist.md +34 -0
- package/src/skills-lib/launch-strategy/references/orb-framework.md +76 -0
- package/src/skills-lib/launch-strategy/references/post-launch-and-ongoing.md +64 -0
- package/src/skills-lib/launch-strategy/references/product-hunt-strategy.md +52 -0
- package/src/skills-lib/marketing-psychology/SKILL.md +18 -401
- package/src/skills-lib/marketing-psychology/references/design-and-delivery-models.md +56 -0
- package/src/skills-lib/marketing-psychology/references/foundational-thinking-models.md +76 -0
- package/src/skills-lib/marketing-psychology/references/growth-and-scaling-models.md +46 -0
- package/src/skills-lib/marketing-psychology/references/influencing-behavior.md +71 -0
- package/src/skills-lib/marketing-psychology/references/pricing-psychology.md +31 -0
- package/src/skills-lib/marketing-psychology/references/understanding-buyers.md +116 -0
- package/src/skills-lib/motion-3d-director/SKILL.md +23 -370
- package/src/skills-lib/motion-3d-director/references/image-to-video-workflow.md +166 -0
- package/src/skills-lib/motion-3d-director/references/motion-paths.md +119 -0
- package/src/skills-lib/motion-3d-director/references/performance-and-handoff.md +51 -0
- package/src/skills-lib/popup-cro/SKILL.md +11 -414
- package/src/skills-lib/popup-cro/references/design-copy-compliance.md +81 -0
- package/src/skills-lib/popup-cro/references/experiments.md +82 -0
- package/src/skills-lib/popup-cro/references/rules-measurement-output.md +87 -0
- package/src/skills-lib/popup-cro/references/triggers-and-popup-types.md +108 -0
- package/src/skills-lib/signup-flow-cro/SKILL.md +13 -321
- package/src/skills-lib/signup-flow-cro/references/experiments.md +72 -0
- package/src/skills-lib/signup-flow-cro/references/field-optimization.md +49 -0
- package/src/skills-lib/signup-flow-cro/references/flow-structure.md +38 -0
- package/src/skills-lib/signup-flow-cro/references/measurement-output-patterns.md +62 -0
- package/src/skills-lib/signup-flow-cro/references/trust-and-post-submit.md +40 -0
- package/src/skills-lib/taste-redesign/SKILL.md +10 -146
- package/src/skills-lib/taste-redesign/references/design-audit.md +120 -0
- package/src/skills-lib/taste-redesign/references/upgrade-techniques.md +31 -0
- package/src/skills-lib/ui-ux-pro-max/SKILL.md +9 -353
- package/src/skills-lib/ui-ux-pro-max/references/common-rules-checklist.md +76 -0
- package/src/skills-lib/ui-ux-pro-max/references/rules-quick-reference.md +70 -0
- package/src/skills-lib/ui-ux-pro-max/references/search-reference.md +45 -0
- package/src/skills-lib/ui-ux-pro-max/references/workflow-guide.md +157 -0
- package/src/skills-lib/web-security/SKILL.md +13 -187
- package/src/skills-lib/web-security/references/checklist-deploy.md +52 -0
- package/src/skills-lib/web-security/references/headers-rate-limit-cors.md +78 -0
- package/src/skills-lib/web-security/references/owasp-top5-detalhado.md +51 -0
- package/src/skills-lib/wizz-router/SKILL.md +20 -9
- package/src/skills-lib/wizz-router/references/auditoria-360.md +4 -4
- package/src/skills-lib/wizz-router/references/routing-table-flat.md +15 -15
- package/tools/fetch-assets.mjs +277 -0
- package/tools/installer/commands/fetch-assets.js +71 -0
- package/tools/installer/commands/install.js +35 -3
- package/tools/installer/commands/trace-report.js +131 -0
- package/tools/installer/core/config.js +9 -0
- package/tools/installer/core/help-catalog.js +181 -0
- package/tools/installer/core/install-paths.js +48 -3
- package/tools/installer/core/installer.js +253 -618
- package/tools/installer/core/manifest-generator.js +8 -1
- package/tools/installer/core/manifest.js +67 -22
- package/tools/installer/core/module-config-writer.js +110 -0
- package/tools/installer/core/preflight-tools-check.js +82 -0
- package/tools/installer/core/quick-update.js +209 -0
- package/tools/installer/core/user-file-preservation.js +250 -0
- package/tools/installer/modules/channel-resolver.js +34 -2
- package/tools/installer/modules/cli-config.js +127 -34
- package/tools/installer/modules/deps-cache.js +28 -1
- package/tools/installer/modules/env-vars.js +446 -0
- package/tools/installer/modules/external-manager.js +40 -6
- package/tools/installer/modules/mcp-config.js +180 -37
- package/tools/installer/modules/module-help-schema.js +2 -1
- package/tools/installer/modules/official-modules.js +1 -1
- package/tools/installer/modules/registry-resolve.js +74 -0
- package/tools/installer/modules/skills-lib.js +11 -15
- package/tools/installer/ui.js +71 -5
- package/wizz-modules.yaml +15 -5
- package/.claude-plugin/marketplace.json +0 -80
- package/AGENTS.md +0 -12
- package/build/artifacts/llms-full.txt +0 -4049
- package/build/artifacts/llms.txt +0 -28
- package/build/site/404.html +0 -55
- package/build/site/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js +0 -1
- package/build/site/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js +0 -1
- package/build/site/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js +0 -1
- package/build/site/_astro/ec.0vx5m.js +0 -3
- package/build/site/_astro/ec.v4551.css +0 -1
- package/build/site/_astro/index.DdjI3lF_.css +0 -1
- package/build/site/_astro/page.B1D-nYk3.js +0 -1
- package/build/site/_astro/print.DNXP8c50.css +0 -1
- package/build/site/_astro/ui-core.D_Lfcn_I.js +0 -2
- package/build/site/diagrams/checkpoint-preview-diagram-fr.webp +0 -0
- package/build/site/diagrams/checkpoint-preview-diagram.png +0 -0
- package/build/site/diagrams/quick-dev-diagram-fr.webp +0 -0
- package/build/site/diagrams/quick-dev-diagram.png +0 -0
- package/build/site/explanation/advanced-elicitation/index.html +0 -105
- package/build/site/explanation/adversarial-review/index.html +0 -109
- package/build/site/explanation/analysis-phase/index.html +0 -129
- package/build/site/explanation/brainstorming/index.html +0 -92
- package/build/site/explanation/checkpoint-preview/index.html +0 -121
- package/build/site/explanation/established-projects-faq/index.html +0 -107
- package/build/site/explanation/forensic-investigation/index.html +0 -167
- package/build/site/explanation/named-agents/index.html +0 -187
- package/build/site/explanation/party-mode/index.html +0 -256
- package/build/site/explanation/preventing-agent-conflicts/index.html +0 -185
- package/build/site/explanation/project-context/index.html +0 -198
- package/build/site/explanation/quick-dev/index.html +0 -113
- package/build/site/explanation/web-bundles/index.html +0 -178
- package/build/site/explanation/why-solutioning-matters/index.html +0 -168
- package/build/site/how-to/customize-wizz/index.html +0 -277
- package/build/site/how-to/established-projects/index.html +0 -165
- package/build/site/how-to/expand-wizz-for-your-org/index.html +0 -245
- package/build/site/how-to/get-answers-about-wizz/index.html +0 -129
- package/build/site/how-to/install-custom-modules/index.html +0 -197
- package/build/site/how-to/install-wizz/index.html +0 -330
- package/build/site/how-to/non-interactive-installation/index.html +0 -73
- package/build/site/how-to/project-context/index.html +0 -141
- package/build/site/how-to/quick-fixes/index.html +0 -122
- package/build/site/how-to/shard-large-documents/index.html +0 -103
- package/build/site/how-to/upgrade-to-v6/index.html +0 -185
- package/build/site/how-to/use-web-bundles/index.html +0 -99
- package/build/site/img/wizz-dark.png +0 -0
- package/build/site/img/wizz-light.png +0 -0
- package/build/site/index.html +0 -128
- package/build/site/llms-full.txt +0 -4049
- package/build/site/llms.txt +0 -28
- package/build/site/pagefind/fragment/en_175de32.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_24258fb.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_24f53a6.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_27ba8f9.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_296ddb9.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_2b5aa5c.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_49047e0.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_4a187d2.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_514725b.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_583316f.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_6465dfb.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_67825a4.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_82aec61.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_85dcebf.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_887ce56.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_89a1a7a.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_8ade291.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_8c11f8a.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_8c1bde3.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_92d7cc7.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_94bfc21.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_9b57d7d.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_ab62b53.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_b0d23ee.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_ba9fb37.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_bb113eb.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_bfc56b6.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_c6d9e48.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_cdd772f.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_cdd885c.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_cefed6a.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_d890205.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_da351b7.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_ea289f9.pf_fragment +0 -0
- package/build/site/pagefind/fragment/en_f1c3711.pf_fragment +0 -0
- package/build/site/pagefind/index/en_5b9d8c6.pf_index +0 -0
- package/build/site/pagefind/index/en_868614c.pf_index +0 -0
- package/build/site/pagefind/index/en_e4f9bff.pf_index +0 -0
- package/build/site/pagefind/pagefind-entry.json +0 -1
- package/build/site/pagefind/pagefind-highlight.js +0 -1064
- package/build/site/pagefind/pagefind-modular-ui.css +0 -214
- package/build/site/pagefind/pagefind-modular-ui.js +0 -8
- package/build/site/pagefind/pagefind-ui.css +0 -1
- package/build/site/pagefind/pagefind-ui.js +0 -2
- package/build/site/pagefind/pagefind.en_4e69d7f053.pf_meta +0 -0
- package/build/site/pagefind/pagefind.js +0 -6
- package/build/site/pagefind/wasm.en.pagefind +0 -0
- package/build/site/pagefind/wasm.unknown.pagefind +0 -0
- package/build/site/reference/agents/index.html +0 -168
- package/build/site/reference/commands/index.html +0 -254
- package/build/site/reference/core-tools/index.html +0 -384
- package/build/site/reference/modules/index.html +0 -132
- package/build/site/reference/testing/index.html +0 -218
- package/build/site/reference/workflow-map/index.html +0 -266
- package/build/site/roadmap/index.html +0 -77
- package/build/site/robots.txt +0 -37
- package/build/site/sitemap-0.xml +0 -1
- package/build/site/sitemap-index.xml +0 -1
- package/build/site/tutorials/getting-started/index.html +0 -386
- package/build/site/wizz-icon-orange.svg +0 -7
- package/build/site/workflow-map-diagram-fr.html +0 -375
- package/build/site/workflow-map-diagram.html +0 -375
- package/evals/bmm-skills/wizz-product-brief/evals.json +0 -237
- package/evals/bmm-skills/wizz-product-brief/files/branfield-memo.md +0 -46
- package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/addendum.md +0 -40
- package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/brief.md +0 -56
- package/evals/bmm-skills/wizz-product-brief/files/forkbird-brief/decision-log.md +0 -27
- package/evals/bmm-skills/wizz-product-brief/files/meridian-mobility-report.md +0 -116
- package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/addendum.md +0 -41
- package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/brief.md +0 -57
- package/evals/bmm-skills/wizz-product-brief/files/mossridge-brief/decision-log.md +0 -29
- package/evals/bmm-skills/wizz-product-brief/files/pantry-bridge-interviews.md +0 -90
- package/evals/bmm-skills/wizz-product-brief/files/q2-brainstorm.md +0 -101
- package/evals/bmm-skills/wizz-product-brief/triggers.json +0 -18
- package/evals/routing/dataset.json +0 -290
- package/evals/routing/run-routing-eval.mjs +0 -89
- package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-ad.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-educational-alt.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-educational.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-tech.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-tutorial-alt.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/bgm-tutorial.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/container/card-flip.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/container/card-snap.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/container/modal-open.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/container/stack-collapse.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/feedback/achievement.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/feedback/error-tone.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/feedback/notification-pop.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/feedback/success-chime.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/impact/brand-stamp.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/impact/drop-thud.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/impact/logo-reveal-v2.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/impact/logo-reveal.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/keyboard/delete-key.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/keyboard/enter.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/keyboard/space-tap.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/keyboard/type-fast.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/keyboard/type.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/magic/ai-process.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/magic/sparkle.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/magic/transform.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/progress/complete-done.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/progress/generate-start.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/progress/loading-tick.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/terminal/command-execute.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/terminal/cursor-blink.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/terminal/output-appear.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/transition/dissolve.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/transition/slide-in.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/transition/swipe-horizontal.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/transition/whoosh-fast.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/transition/whoosh.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/click-soft.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/click.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/focus.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/hover-subtle.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/tap-finger.mp3 +0 -0
- package/src/skills-lib/huashu-design/assets/sfx/ui/toggle-on.mp3 +0 -0
- package/src/squads/README.md +0 -39
- package/src/squads/advisory-board/README.md +0 -34
- package/src/squads/advisory-board/agents/board-chair.md +0 -161
- package/src/squads/advisory-board/agents/brene-brown.md +0 -296
- package/src/squads/advisory-board/agents/charlie-munger.md +0 -590
- package/src/squads/advisory-board/agents/derek-sivers.md +0 -268
- package/src/squads/advisory-board/agents/naval-ravikant.md +0 -251
- package/src/squads/advisory-board/agents/patrick-lencioni.md +0 -394
- package/src/squads/advisory-board/agents/peter-thiel.md +0 -269
- package/src/squads/advisory-board/agents/ray-dalio.md +0 -567
- package/src/squads/advisory-board/agents/reid-hoffman.md +0 -278
- package/src/squads/advisory-board/agents/simon-sinek.md +0 -291
- package/src/squads/advisory-board/agents/yvon-chouinard.md +0 -275
- package/src/squads/advisory-board/squad.yaml +0 -50
- package/src/squads/brand-squad/README.md +0 -60
- package/src/squads/brand-squad/agents/al-ries.md +0 -175
- package/src/squads/brand-squad/agents/alina-wheeler.md +0 -184
- package/src/squads/brand-squad/agents/archetype-consultant.md +0 -215
- package/src/squads/brand-squad/agents/brand-chief.md +0 -158
- package/src/squads/brand-squad/agents/byron-sharp.md +0 -169
- package/src/squads/brand-squad/agents/david-aaker.md +0 -166
- package/src/squads/brand-squad/agents/denise-yohn.md +0 -172
- package/src/squads/brand-squad/agents/domain-scout.md +0 -135
- package/src/squads/brand-squad/agents/donald-miller.md +0 -179
- package/src/squads/brand-squad/agents/emily-heyward.md +0 -147
- package/src/squads/brand-squad/agents/jean-noel-kapferer.md +0 -189
- package/src/squads/brand-squad/agents/kevin-keller.md +0 -199
- package/src/squads/brand-squad/agents/marty-neumeier.md +0 -170
- package/src/squads/brand-squad/agents/miller-sticky-brand.md +0 -180
- package/src/squads/brand-squad/agents/naming-strategist.md +0 -171
- package/src/squads/brand-squad/squad.yaml +0 -117
- package/src/squads/c-level-squad/README.md +0 -29
- package/src/squads/c-level-squad/agents/caio-architect.md +0 -235
- package/src/squads/c-level-squad/agents/cio-engineer.md +0 -209
- package/src/squads/c-level-squad/agents/cmo-architect.md +0 -208
- package/src/squads/c-level-squad/agents/coo-orchestrator.md +0 -193
- package/src/squads/c-level-squad/agents/cto-architect.md +0 -194
- package/src/squads/c-level-squad/agents/vision-chief.md +0 -201
- package/src/squads/c-level-squad/squad.yaml +0 -45
- package/src/squads/claude-code-mastery/README.md +0 -146
- package/src/squads/claude-code-mastery/agents/claude-mastery-chief.md +0 -554
- package/src/squads/claude-code-mastery/agents/config-engineer.md +0 -865
- package/src/squads/claude-code-mastery/agents/hooks-architect.md +0 -1013
- package/src/squads/claude-code-mastery/agents/mcp-integrator.md +0 -791
- package/src/squads/claude-code-mastery/agents/project-integrator.md +0 -1196
- package/src/squads/claude-code-mastery/agents/roadmap-sentinel.md +0 -931
- package/src/squads/claude-code-mastery/agents/skill-craftsman.md +0 -1250
- package/src/squads/claude-code-mastery/agents/swarm-orchestrator.md +0 -1008
- package/src/squads/copy-squad/README.md +0 -65
- package/src/squads/copy-squad/agents/andre-chaperon.md +0 -206
- package/src/squads/copy-squad/agents/ben-settle.md +0 -194
- package/src/squads/copy-squad/agents/claude-hopkins.md +0 -182
- package/src/squads/copy-squad/agents/clayton-makepeace.md +0 -225
- package/src/squads/copy-squad/agents/copy-chief.md +0 -166
- package/src/squads/copy-squad/agents/dan-kennedy.md +0 -202
- package/src/squads/copy-squad/agents/dan-koe.md +0 -223
- package/src/squads/copy-squad/agents/david-deutsch.md +0 -197
- package/src/squads/copy-squad/agents/david-ogilvy.md +0 -198
- package/src/squads/copy-squad/agents/eugene-schwartz.md +0 -238
- package/src/squads/copy-squad/agents/frank-kern.md +0 -195
- package/src/squads/copy-squad/agents/gary-bencivenga.md +0 -197
- package/src/squads/copy-squad/agents/gary-halbert.md +0 -219
- package/src/squads/copy-squad/agents/jim-rutz.md +0 -193
- package/src/squads/copy-squad/agents/joe-sugarman.md +0 -234
- package/src/squads/copy-squad/agents/john-carlton.md +0 -203
- package/src/squads/copy-squad/agents/jon-benson.md +0 -196
- package/src/squads/copy-squad/agents/parris-lampropoulos.md +0 -188
- package/src/squads/copy-squad/agents/robert-collier.md +0 -183
- package/src/squads/copy-squad/agents/russell-brunson.md +0 -229
- package/src/squads/copy-squad/agents/ry-schwartz.md +0 -185
- package/src/squads/copy-squad/agents/stefan-georgi.md +0 -188
- package/src/squads/copy-squad/agents/todd-brown.md +0 -171
- package/src/squads/copy-squad/squad.yaml +0 -87
- package/src/squads/cybersecurity/README.md +0 -38
- package/src/squads/cybersecurity/agents/busterer.md +0 -108
- package/src/squads/cybersecurity/agents/cartographer.md +0 -114
- package/src/squads/cybersecurity/agents/chris-sanders.md +0 -205
- package/src/squads/cybersecurity/agents/command-generator.md +0 -121
- package/src/squads/cybersecurity/agents/cyber-chief.md +0 -120
- package/src/squads/cybersecurity/agents/dirber.md +0 -111
- package/src/squads/cybersecurity/agents/fuzzer.md +0 -121
- package/src/squads/cybersecurity/agents/georgia-weidman.md +0 -178
- package/src/squads/cybersecurity/agents/jim-manico.md +0 -182
- package/src/squads/cybersecurity/agents/marcus-carey.md +0 -200
- package/src/squads/cybersecurity/agents/omar-santos.md +0 -206
- package/src/squads/cybersecurity/agents/peter-kim.md +0 -179
- package/src/squads/cybersecurity/agents/ripper.md +0 -121
- package/src/squads/cybersecurity/agents/rogue.md +0 -116
- package/src/squads/cybersecurity/agents/shannon-runner.md +0 -108
- package/src/squads/cybersecurity/squad.yaml +0 -56
- package/src/squads/data-squad/README.md +0 -30
- package/src/squads/data-squad/agents/avinash-kaushik.md +0 -268
- package/src/squads/data-squad/agents/data-chief.md +0 -167
- package/src/squads/data-squad/agents/david-spinks.md +0 -277
- package/src/squads/data-squad/agents/nick-mehta.md +0 -294
- package/src/squads/data-squad/agents/peter-fader.md +0 -246
- package/src/squads/data-squad/agents/sean-ellis.md +0 -303
- package/src/squads/data-squad/agents/wes-kao.md +0 -268
- package/src/squads/data-squad/squad.yaml +0 -46
- package/src/squads/design-squad/README.md +0 -31
- package/src/squads/design-squad/agents/brad-frost.md +0 -185
- package/src/squads/design-squad/agents/dan-mall.md +0 -178
- package/src/squads/design-squad/agents/dave-malouf.md +0 -198
- package/src/squads/design-squad/agents/design-chief.md +0 -109
- package/src/squads/design-squad/agents/design-system-architect.md +0 -109
- package/src/squads/design-squad/agents/ui-engineer.md +0 -102
- package/src/squads/design-squad/agents/ux-designer.md +0 -105
- package/src/squads/design-squad/agents/visual-generator.md +0 -108
- package/src/squads/design-squad/squad.yaml +0 -48
- package/src/squads/hormozi-squad/README.md +0 -39
- package/src/squads/hormozi-squad/agents/hormozi-ads.md +0 -159
- package/src/squads/hormozi-squad/agents/hormozi-advisor.md +0 -178
- package/src/squads/hormozi-squad/agents/hormozi-audit.md +0 -178
- package/src/squads/hormozi-squad/agents/hormozi-chief.md +0 -111
- package/src/squads/hormozi-squad/agents/hormozi-closer.md +0 -179
- package/src/squads/hormozi-squad/agents/hormozi-content.md +0 -166
- package/src/squads/hormozi-squad/agents/hormozi-copy.md +0 -152
- package/src/squads/hormozi-squad/agents/hormozi-hooks.md +0 -177
- package/src/squads/hormozi-squad/agents/hormozi-launch.md +0 -160
- package/src/squads/hormozi-squad/agents/hormozi-leads.md +0 -198
- package/src/squads/hormozi-squad/agents/hormozi-models.md +0 -191
- package/src/squads/hormozi-squad/agents/hormozi-offers.md +0 -197
- package/src/squads/hormozi-squad/agents/hormozi-pricing.md +0 -151
- package/src/squads/hormozi-squad/agents/hormozi-retention.md +0 -166
- package/src/squads/hormozi-squad/agents/hormozi-scale.md +0 -175
- package/src/squads/hormozi-squad/agents/hormozi-workshop.md +0 -160
- package/src/squads/hormozi-squad/squad.yaml +0 -60
- package/src/squads/movement/README.md +0 -29
- package/src/squads/movement/agents/analista-de-impacto.md +0 -350
- package/src/squads/movement/agents/estrategista-de-ciclo.md +0 -301
- package/src/squads/movement/agents/fenomenologo.md +0 -169
- package/src/squads/movement/agents/identitario.md +0 -265
- package/src/squads/movement/agents/manifestador.md +0 -279
- package/src/squads/movement/agents/movement-architect.md +0 -210
- package/src/squads/movement/agents/movement-chief.md +0 -135
- package/src/squads/movement/squad.yaml +0 -45
- package/src/squads/storytelling/README.md +0 -35
- package/src/squads/storytelling/agents/blake-snyder.md +0 -225
- package/src/squads/storytelling/agents/dan-harmon.md +0 -167
- package/src/squads/storytelling/agents/joseph-campbell.md +0 -184
- package/src/squads/storytelling/agents/keith-johnstone.md +0 -157
- package/src/squads/storytelling/agents/kindra-hall.md +0 -162
- package/src/squads/storytelling/agents/marshall-ganz.md +0 -167
- package/src/squads/storytelling/agents/matthew-dicks.md +0 -152
- package/src/squads/storytelling/agents/nancy-duarte.md +0 -154
- package/src/squads/storytelling/agents/oren-klaff.md +0 -166
- package/src/squads/storytelling/agents/park-howell.md +0 -152
- package/src/squads/storytelling/agents/shawn-coyne.md +0 -208
- package/src/squads/storytelling/agents/story-chief.md +0 -155
- package/src/squads/storytelling/squad.yaml +0 -52
- package/src/squads/traffic-masters/README.md +0 -39
- package/src/squads/traffic-masters/agents/ad-midas.md +0 -149
- package/src/squads/traffic-masters/agents/ads-analyst.md +0 -135
- package/src/squads/traffic-masters/agents/creative-analyst.md +0 -142
- package/src/squads/traffic-masters/agents/depesh-mandalia.md +0 -174
- package/src/squads/traffic-masters/agents/fiscal.md +0 -144
- package/src/squads/traffic-masters/agents/kasim-aslam.md +0 -158
- package/src/squads/traffic-masters/agents/media-buyer.md +0 -159
- package/src/squads/traffic-masters/agents/molly-pittman.md +0 -185
- package/src/squads/traffic-masters/agents/nicholas-kusmich.md +0 -157
- package/src/squads/traffic-masters/agents/pedro-sobral.md +0 -158
- package/src/squads/traffic-masters/agents/performance-analyst.md +0 -135
- package/src/squads/traffic-masters/agents/pixel-specialist.md +0 -144
- package/src/squads/traffic-masters/agents/ralph-burns.md +0 -163
- package/src/squads/traffic-masters/agents/scale-optimizer.md +0 -144
- package/src/squads/traffic-masters/agents/tom-breeze.md +0 -175
- package/src/squads/traffic-masters/agents/traffic-chief.md +0 -97
- package/src/squads/traffic-masters/squad.yaml +0 -59
- package/tools/bundle-web-bundles.js +0 -117
- package/tools/format-workflow-md.js +0 -263
- package/tools/hooks/README.md +0 -17
- package/tools/hooks/security-defensive-context.js +0 -70
- package/tools/hooks/session-rules.js +0 -38
- package/tools/hooks/wizz-router-enforce.js +0 -188
- package/tools/javascript-conventions.md +0 -5
- package/tools/migrate-custom-module-paths.js +0 -124
- package/tools/skill-validator.md +0 -368
- package/tools/sync-global.mjs +0 -84
- package/tools/validate-sidebar-order.js +0 -388
- package/tools/validate-skills.js +0 -708
- package/tools/validate-svg-changes.sh +0 -356
- /package/tools/installer/{cli-utils.js → banner.js} +0 -0
|
@@ -19,34 +19,32 @@
|
|
|
19
19
|
// a `claude mcp add` command renderer for the recommend path.
|
|
20
20
|
|
|
21
21
|
const path = require('node:path');
|
|
22
|
+
const crypto = require('node:crypto');
|
|
22
23
|
const fs = require('../fs-native');
|
|
23
24
|
const { defaultExec } = require('./cli-config');
|
|
25
|
+
const { resolveAreaEntries } = require('./registry-resolve');
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* Resolve the recommended MCP entries for the chosen areas, deduped by id.
|
|
27
29
|
* Empty / undefined / containing 'all' means every area. The cross-cutting
|
|
28
30
|
* `mcp_utility:` servers are always included.
|
|
29
31
|
*
|
|
32
|
+
* Wrapper fino sobre `resolveAreaEntries` (A16): a resolução por área em si
|
|
33
|
+
* (sentinel `wantAll`, dedupe por Map, lista cross-cutting) vive em
|
|
34
|
+
* `registry-resolve.js`; aqui só ficam a forma da entrada de MCP e o filtro
|
|
35
|
+
* de elegibilidade (precisa de `server`).
|
|
36
|
+
*
|
|
30
37
|
* @param {Object} registry - Parsed skills-registry.yaml
|
|
31
38
|
* @param {string[]} [selectedAreas] - Area keys to resolve
|
|
32
39
|
* @returns {Array<{id: string, when: string, server: Object, areas: string[]}>}
|
|
33
40
|
* One entry per unique MCP id, carrying which area(s) recommended it.
|
|
34
41
|
*/
|
|
35
42
|
function resolveMcps(registry, selectedAreas) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const add = (mcp, areaKey) => {
|
|
42
|
-
if (!mcp || !mcp.id || !mcp.server) return;
|
|
43
|
-
const existing = byId.get(mcp.id);
|
|
44
|
-
if (existing) {
|
|
45
|
-
if (areaKey && !existing.areas.includes(areaKey)) existing.areas.push(areaKey);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
byId.set(mcp.id, {
|
|
49
|
-
id: mcp.id,
|
|
43
|
+
return resolveAreaEntries(registry, selectedAreas, {
|
|
44
|
+
listKey: 'mcps',
|
|
45
|
+
utilityKey: 'mcp_utility',
|
|
46
|
+
isActionable: (mcp) => !!mcp.server,
|
|
47
|
+
mapEntry: (mcp) => ({
|
|
50
48
|
when: mcp.when || '',
|
|
51
49
|
server: mcp.server,
|
|
52
50
|
// `setup` (optional) declares how to make a `command:`-relative server
|
|
@@ -55,17 +53,8 @@ function resolveMcps(registry, selectedAreas) {
|
|
|
55
53
|
// verify it boots. Carried here so prepareMcps() can act on it; dropped
|
|
56
54
|
// from what toServerConfig() writes (it never belongs in .mcp.json).
|
|
57
55
|
setup: mcp.setup || null,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
for (const area of chosen) {
|
|
63
|
-
for (const mcp of (areas[area] && areas[area].mcps) || []) add(mcp, area);
|
|
64
|
-
}
|
|
65
|
-
// Cross-cutting servers are offered regardless of area selection.
|
|
66
|
-
for (const mcp of (registry && registry.mcp_utility) || []) add(mcp, null);
|
|
67
|
-
|
|
68
|
-
return [...byId.values()];
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
69
58
|
}
|
|
70
59
|
|
|
71
60
|
/**
|
|
@@ -81,6 +70,22 @@ function toServerConfig(server) {
|
|
|
81
70
|
return out;
|
|
82
71
|
}
|
|
83
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Content marker for a server block (A13: "Merge aditivo do .mcp.json congela
|
|
75
|
+
* pins de segurança para sempre"). Hashes the NORMALIZED (`toServerConfig`)
|
|
76
|
+
* shape, not the raw registry `server`, so the hash matches exactly what
|
|
77
|
+
* lands on disk in `.mcp.json` — a block written by the installer and a block
|
|
78
|
+
* hand-typed by a user with the same effective config hash identically.
|
|
79
|
+
* @param {Object} server - { command, args?, env? }
|
|
80
|
+
* @returns {string} sha256 hex digest
|
|
81
|
+
*/
|
|
82
|
+
function hashServerBlock(server) {
|
|
83
|
+
return crypto
|
|
84
|
+
.createHash('sha256')
|
|
85
|
+
.update(JSON.stringify(toServerConfig(server || {})))
|
|
86
|
+
.digest('hex');
|
|
87
|
+
}
|
|
88
|
+
|
|
84
89
|
/**
|
|
85
90
|
* POSIX-quote a path so it survives interpolation into a shell command even
|
|
86
91
|
* when it contains spaces or shell metacharacters. Single-quote wrapped, with
|
|
@@ -111,8 +116,19 @@ function substituteBin(command, binPath) {
|
|
|
111
116
|
* does not always inherit the user's ~/.local/bin on PATH, so a relative name
|
|
112
117
|
* fails with ENOENT even when the tool is installed. We resolve and write the
|
|
113
118
|
* absolute path instead. Tries `command -v` first (honors the current PATH),
|
|
114
|
-
* then the conventional user-local bin
|
|
115
|
-
* --user` land executables
|
|
119
|
+
* then the conventional user-local bin dirs where `uv tool` / `pipx` / `pip
|
|
120
|
+
* --user` land executables:
|
|
121
|
+
* - `~/.local/bin` (uv tool / pipx / pip --user on Linux, and pip --user
|
|
122
|
+
* on modern macOS with `--user` in a non-framework Python)
|
|
123
|
+
* - `/opt/homebrew/bin` and `/usr/local/bin` (Homebrew on Apple Silicon and
|
|
124
|
+
* Intel respectively); a client launched via `npx` from a GUI app often
|
|
125
|
+
* inherits a minimal PATH that never saw `brew shellenv`, so a Homebrew
|
|
126
|
+
* install looks absent and gets reinstalled via uv/pipx/pip (duplicate
|
|
127
|
+
* binary) unless we check here too
|
|
128
|
+
* - `~/Library/Python/<version>/bin` (macOS `pip install --user`, which
|
|
129
|
+
* lands executables under a Python-version-specific directory, not
|
|
130
|
+
* `~/.local/bin`)
|
|
131
|
+
* Returns null when the binary is nowhere to be found.
|
|
116
132
|
*
|
|
117
133
|
* @param {string} bin - Binary name to locate
|
|
118
134
|
* @param {Function} [exec] - Injected runner (command, opts) => {ok, stdout,...}
|
|
@@ -125,11 +141,31 @@ async function resolveBinPath(bin, exec = defaultExec) {
|
|
|
125
141
|
const found = (viaWhich.stdout || '').trim().split('\n')[0].trim();
|
|
126
142
|
if (found) return found;
|
|
127
143
|
}
|
|
144
|
+
|
|
128
145
|
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
129
|
-
|
|
130
|
-
|
|
146
|
+
const candidateDirs = [];
|
|
147
|
+
if (home) candidateDirs.push(path.join(home, '.local', 'bin'));
|
|
148
|
+
candidateDirs.push('/opt/homebrew/bin', '/usr/local/bin');
|
|
149
|
+
|
|
150
|
+
for (const dir of candidateDirs) {
|
|
151
|
+
const candidate = path.join(dir, bin);
|
|
131
152
|
if (await fs.pathExists(candidate)) return candidate;
|
|
132
153
|
}
|
|
154
|
+
|
|
155
|
+
if (home && process.platform === 'darwin') {
|
|
156
|
+
const pyUserBase = path.join(home, 'Library', 'Python');
|
|
157
|
+
try {
|
|
158
|
+
const versions = await fs.readdir(pyUserBase);
|
|
159
|
+
for (const version of versions) {
|
|
160
|
+
const candidate = path.join(pyUserBase, version, 'bin', bin);
|
|
161
|
+
if (await fs.pathExists(candidate)) return candidate;
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
// No ~/Library/Python directory; pip --user was never used here, or
|
|
165
|
+
// there is nothing to enumerate. Not an error condition.
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
133
169
|
return null;
|
|
134
170
|
}
|
|
135
171
|
|
|
@@ -247,20 +283,93 @@ function renderAddCommand({ id, server }) {
|
|
|
247
283
|
return `claude mcp add ${id}${envFlags ? ` ${envFlags}` : ''} -- ${cmd}`.replaceAll(/\s+/g, ' ').trim();
|
|
248
284
|
}
|
|
249
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Split resolved MCP entries into those that still need the DETECT/INSTALL/
|
|
288
|
+
* VERIFY/RESOLVE pipeline (prepareMcps) and those whose id is already present
|
|
289
|
+
* in `.mcp.json` and will be skipped anyway by the additive merge in
|
|
290
|
+
* writeMcpConfig. Filtering here avoids paying for a subprocess-heavy setup
|
|
291
|
+
* (npm install -g, browser download, binary verification) on every
|
|
292
|
+
* re-install for servers we already know will be discarded downstream.
|
|
293
|
+
*
|
|
294
|
+
* Read failures (missing/malformed `.mcp.json`) fall back to "prepare
|
|
295
|
+
* everything", the safe default, and let writeMcpConfig raise the real
|
|
296
|
+
* error later if the file truly is invalid JSON.
|
|
297
|
+
*
|
|
298
|
+
* @param {Object} args
|
|
299
|
+
* @param {string} args.projectDir - Project root where `.mcp.json` lives
|
|
300
|
+
* @param {Array<{id: string}>} args.mcps - Resolved MCP entries to partition
|
|
301
|
+
* @returns {Promise<{toPrepare: Array<Object>, alreadyConfigured: string[]}>}
|
|
302
|
+
*/
|
|
303
|
+
async function partitionAlreadyConfigured({ projectDir, mcps }) {
|
|
304
|
+
if (!mcps || mcps.length === 0) return { toPrepare: [], alreadyConfigured: [] };
|
|
305
|
+
|
|
306
|
+
const file = path.join(projectDir, '.mcp.json');
|
|
307
|
+
let existingIds = new Set();
|
|
308
|
+
if (await fs.pathExists(file)) {
|
|
309
|
+
try {
|
|
310
|
+
const config = JSON.parse(await fs.readFile(file, 'utf8'));
|
|
311
|
+
const servers =
|
|
312
|
+
config && typeof config === 'object' && config.mcpServers && !Array.isArray(config.mcpServers) ? config.mcpServers : null;
|
|
313
|
+
if (servers) existingIds = new Set(Object.keys(servers));
|
|
314
|
+
} catch {
|
|
315
|
+
return { toPrepare: [...mcps], alreadyConfigured: [] };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const toPrepare = [];
|
|
320
|
+
const alreadyConfigured = [];
|
|
321
|
+
for (const mcp of mcps) {
|
|
322
|
+
if (mcp && mcp.id && existingIds.has(mcp.id)) alreadyConfigured.push(mcp.id);
|
|
323
|
+
else toPrepare.push(mcp);
|
|
324
|
+
}
|
|
325
|
+
return { toPrepare, alreadyConfigured };
|
|
326
|
+
}
|
|
327
|
+
|
|
250
328
|
/**
|
|
251
329
|
* Merge the chosen MCP entries into `<projectDir>/.mcp.json`, additively.
|
|
252
330
|
* Reads any existing file (preserving unknown keys and existing servers),
|
|
253
|
-
* adds
|
|
331
|
+
* adds ids not already present, and writes back pretty-printed JSON.
|
|
332
|
+
*
|
|
333
|
+
* A13 ("Merge aditivo do .mcp.json congela pins de segurança para sempre"):
|
|
334
|
+
* for an id already present, `previousPins[id]` (the hash the installer
|
|
335
|
+
* recorded the LAST time it wrote that block, from
|
|
336
|
+
* `skill-deps-cache.json`/`deps-cache.js`) tells us whether the on-disk block
|
|
337
|
+
* is still exactly what we wrote or whether the user hand-edited it:
|
|
338
|
+
* - on-disk hash === current registry hash → nothing to do (current)
|
|
339
|
+
* - on-disk hash === previousPins[id] (untouched) → the registry pin moved
|
|
340
|
+
* and the user never touched this block: SAFE to apply the update automatically
|
|
341
|
+
* (`pinUpdated`). This is not overwriting a customization — it is finishing
|
|
342
|
+
* an update the user already implicitly opted into by never editing our block.
|
|
343
|
+
* - on-disk hash !== previousPins[id] (or no recorded hash — pre-A13 install)
|
|
344
|
+
* → the user's edit (or an unknown state) wins; NEVER overwritten, only
|
|
345
|
+
* surfaced (`pinCustomized`) so the caller can warn "update available, but
|
|
346
|
+
* this server was customized".
|
|
254
347
|
*
|
|
255
348
|
* @param {Object} args
|
|
256
349
|
* @param {string} args.projectDir - Project root where `.mcp.json` lives
|
|
257
350
|
* @param {Array<{id: string, server: Object}>} args.mcps - Entries to write
|
|
351
|
+
* @param {Record<string,string>} [args.previousPins] - id => hash recorded at
|
|
352
|
+
* the installer's last write of that block (from skill-deps-cache.json)
|
|
258
353
|
* @param {(absPath: string) => void} [args.trackFile] - Record the written file
|
|
259
|
-
* @
|
|
260
|
-
*
|
|
354
|
+
* @param {boolean} [args.dryRun] - Compute the merge (added/skipped/pinHashes/
|
|
355
|
+
* etc.) WITHOUT touching disk. Used by fresh installs (A14): `.mcp.json`
|
|
356
|
+
* lives outside `_wizz/`, so it must not be mutated until the atomic
|
|
357
|
+
* install's tmp→real swap has succeeded — but `pinHashes` is still needed
|
|
358
|
+
* beforehand to seed `skill-deps-cache.json`. The caller re-invokes without
|
|
359
|
+
* `dryRun` after the swap to perform the real write.
|
|
360
|
+
* @returns {Promise<{added: string[], skipped: string[], file: string|null,
|
|
361
|
+
* pinHashes: Record<string,string>, pinUpdated: Array<{id:string,from:string,to:string}>,
|
|
362
|
+
* pinCustomized: Array<{id:string}>}>}
|
|
363
|
+
* `added` = ids newly written. `skipped` = ids already current, nothing to
|
|
364
|
+
* do. `pinCustomized` = ids left intact because the on-disk block diverges
|
|
365
|
+
* from what we last wrote (a separate bucket from `skipped` so the caller
|
|
366
|
+
* can warn specifically about those). `pinHashes` = id => hash of what is
|
|
367
|
+
* now on disk for every resolved id, meant to be persisted as the NEXT
|
|
368
|
+
* `previousPins`.
|
|
261
369
|
*/
|
|
262
|
-
async function writeMcpConfig({ projectDir, mcps, trackFile = () => {} }) {
|
|
263
|
-
|
|
370
|
+
async function writeMcpConfig({ projectDir, mcps, previousPins = {}, trackFile = () => {}, dryRun = false }) {
|
|
371
|
+
const empty = { added: [], skipped: [], file: null, pinHashes: {}, pinUpdated: [], pinCustomized: [] };
|
|
372
|
+
if (!mcps || mcps.length === 0) return empty;
|
|
264
373
|
|
|
265
374
|
const file = path.join(projectDir, '.mcp.json');
|
|
266
375
|
let config = {};
|
|
@@ -276,29 +385,63 @@ async function writeMcpConfig({ projectDir, mcps, trackFile = () => {} }) {
|
|
|
276
385
|
|
|
277
386
|
const added = [];
|
|
278
387
|
const skipped = [];
|
|
388
|
+
const pinHashes = {};
|
|
389
|
+
const pinUpdated = [];
|
|
390
|
+
const pinCustomized = [];
|
|
391
|
+
let changed = false;
|
|
392
|
+
|
|
279
393
|
for (const mcp of mcps) {
|
|
394
|
+
const newHash = hashServerBlock(mcp.server);
|
|
395
|
+
|
|
280
396
|
if (Object.prototype.hasOwnProperty.call(config.mcpServers, mcp.id)) {
|
|
281
|
-
|
|
397
|
+
const onDisk = config.mcpServers[mcp.id];
|
|
398
|
+
const onDiskHash = hashServerBlock(onDisk);
|
|
399
|
+
|
|
400
|
+
if (onDiskHash === newHash) {
|
|
401
|
+
skipped.push(mcp.id); // already current, nothing to do
|
|
402
|
+
pinHashes[mcp.id] = newHash;
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const recordedHash = previousPins[mcp.id];
|
|
407
|
+
if (recordedHash && recordedHash === onDiskHash) {
|
|
408
|
+
// Untouched since our last write, and the registry pin moved — safe
|
|
409
|
+
// to apply automatically. Never a silent overwrite of user work.
|
|
410
|
+
config.mcpServers[mcp.id] = toServerConfig(mcp.server);
|
|
411
|
+
pinUpdated.push({ id: mcp.id, from: recordedHash, to: newHash });
|
|
412
|
+
pinHashes[mcp.id] = newHash;
|
|
413
|
+
changed = true;
|
|
414
|
+
} else {
|
|
415
|
+
// No recorded hash (pre-A13 install) or the hash diverges: the user
|
|
416
|
+
// may have hand-edited this block. Never clobber it — only report.
|
|
417
|
+
pinCustomized.push({ id: mcp.id });
|
|
418
|
+
pinHashes[mcp.id] = onDiskHash;
|
|
419
|
+
}
|
|
282
420
|
continue;
|
|
283
421
|
}
|
|
422
|
+
|
|
284
423
|
config.mcpServers[mcp.id] = toServerConfig(mcp.server);
|
|
285
424
|
added.push(mcp.id);
|
|
425
|
+
pinHashes[mcp.id] = newHash;
|
|
426
|
+
changed = true;
|
|
286
427
|
}
|
|
287
428
|
|
|
288
|
-
if (
|
|
429
|
+
if (!changed || dryRun) return { added, skipped, file, pinHashes, pinUpdated, pinCustomized };
|
|
289
430
|
|
|
290
431
|
await fs.writeJson(file, config, { spaces: 2 });
|
|
291
432
|
trackFile(file);
|
|
292
|
-
return { added, skipped, file };
|
|
433
|
+
return { added, skipped, file, pinHashes, pinUpdated, pinCustomized };
|
|
293
434
|
}
|
|
294
435
|
|
|
295
436
|
module.exports = {
|
|
296
437
|
resolveMcps,
|
|
297
438
|
toServerConfig,
|
|
439
|
+
hashServerBlock,
|
|
298
440
|
renderAddCommand,
|
|
299
441
|
writeMcpConfig,
|
|
300
442
|
prepareMcp,
|
|
301
443
|
prepareMcps,
|
|
444
|
+
partitionAlreadyConfigured,
|
|
302
445
|
resolveBinPath,
|
|
303
446
|
shellQuote,
|
|
304
447
|
substituteBin,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Canonical schema for per-module `module-help.csv` files.
|
|
3
3
|
*
|
|
4
|
-
* Both the merger (`
|
|
4
|
+
* Both the merger (`core/help-catalog.js` `mergeModuleHelpCatalogs`, exposed
|
|
5
|
+
* on `Installer` as a thin wrapper) and the synthesizer
|
|
5
6
|
* (`PluginResolver._buildSynthesizedHelpCsv`) emit this exact header. The
|
|
6
7
|
* merger compares each per-module file's header against this string and
|
|
7
8
|
* warns on drift, so any rename here must be matched in external module
|
|
@@ -3,7 +3,7 @@ const fs = require('../fs-native');
|
|
|
3
3
|
const yaml = require('yaml');
|
|
4
4
|
const prompts = require('../prompts');
|
|
5
5
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../project-root');
|
|
6
|
-
const { CLIUtils } = require('../
|
|
6
|
+
const { CLIUtils } = require('../banner');
|
|
7
7
|
const { ExternalModuleManager } = require('./external-manager');
|
|
8
8
|
|
|
9
9
|
class OfficialModules {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Resolução genérica de entradas por área do skills-registry.yaml.
|
|
2
|
+
//
|
|
3
|
+
// A16 (auditoria 2026-07-07): resolveMcps (mcp-config.js), resolveClis
|
|
4
|
+
// (cli-config.js) e resolveSkillIds (skills-lib.js) implementavam
|
|
5
|
+
// literalmente o mesmo algoritmo — sentinel `wantAll` -> `chosen = wantAll ?
|
|
6
|
+
// Object.keys(areas) : selectedAreas` -> dedupe por Map acumulando `areas[]`
|
|
7
|
+
// -> inclusão da lista cross-cutting (`mcp_utility`/`cli_utility`/`utility`)
|
|
8
|
+
// -> só a FORMA da entrada final (quais campos ela carrega) mudava por
|
|
9
|
+
// chamador. Esta função extrai o algoritmo; os três módulos originais viram
|
|
10
|
+
// wrappers finos que só declaram o que é específico deles: a chave da lista
|
|
11
|
+
// por área/utility, o filtro de elegibilidade (`isActionable`) e a forma dos
|
|
12
|
+
// campos extras (`mapEntry`).
|
|
13
|
+
//
|
|
14
|
+
// Contrato preservado: mesma assinatura pública e mesmo comportamento
|
|
15
|
+
// observável dos três resolvers originais. As suítes test/test-mcp-config.js,
|
|
16
|
+
// test/test-cli-config.js e o teste de instalação que cobre skills-lib.js são
|
|
17
|
+
// o safety net desta extração.
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Resolve entradas cross-cutting-aware por área, deduplicadas por `id`.
|
|
21
|
+
*
|
|
22
|
+
* Vazio/undefined/contendo `'all'` em `selectedAreas` significa "todas as
|
|
23
|
+
* áreas" (mesmo sentinel usado pelos três resolvers originais). A lista
|
|
24
|
+
* `utilityKey` no topo do registry (ex.: `mcp_utility`, `cli_utility`,
|
|
25
|
+
* `utility`) é sempre incluída, independente da seleção de área.
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} registry - skills-registry.yaml já parseado
|
|
28
|
+
* @param {string[]} [selectedAreas] - Chaves de área a resolver
|
|
29
|
+
* @param {Object} opts
|
|
30
|
+
* @param {string} opts.listKey - Chave da lista por área (ex.: 'mcps', 'clis', 'skills')
|
|
31
|
+
* @param {string} opts.utilityKey - Chave da lista cross-cutting no topo do registry
|
|
32
|
+
* @param {(raw: Object) => boolean} [opts.isActionable] - Filtro extra de elegibilidade
|
|
33
|
+
* além de exigir `id` (que esta função já garante). Default: sempre true.
|
|
34
|
+
* @param {(raw: Object) => Object} [opts.mapEntry] - Molda os campos extras da entrada
|
|
35
|
+
* resolvida. `id` e `areas` são sempre geridos por esta função e sobrescrevem
|
|
36
|
+
* qualquer campo homônimo devolvido por `mapEntry`. Default: devolve o objeto
|
|
37
|
+
* cru como veio do registry.
|
|
38
|
+
* @returns {Array<Object>} Uma entrada por id único, com `id` + `areas: string[]`
|
|
39
|
+
* somados aos campos de `mapEntry`. Quando o mesmo id aparece em mais de uma
|
|
40
|
+
* área, `areas` acumula todas elas (a primeira ocorrência decide os demais
|
|
41
|
+
* campos, igual ao comportamento original).
|
|
42
|
+
*/
|
|
43
|
+
function resolveAreaEntries(registry, selectedAreas, opts) {
|
|
44
|
+
const { listKey, utilityKey, isActionable = () => true, mapEntry = (raw) => raw } = opts;
|
|
45
|
+
const byId = new Map();
|
|
46
|
+
const areas = (registry && registry.areas) || {};
|
|
47
|
+
const wantAll = !selectedAreas || selectedAreas.length === 0 || selectedAreas.includes('all');
|
|
48
|
+
const chosen = wantAll ? Object.keys(areas) : selectedAreas;
|
|
49
|
+
|
|
50
|
+
const add = (raw, areaKey) => {
|
|
51
|
+
if (!raw || !raw.id) return;
|
|
52
|
+
if (!isActionable(raw)) return;
|
|
53
|
+
const existing = byId.get(raw.id);
|
|
54
|
+
if (existing) {
|
|
55
|
+
if (areaKey && !existing.areas.includes(areaKey)) existing.areas.push(areaKey);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
byId.set(raw.id, {
|
|
59
|
+
...mapEntry(raw),
|
|
60
|
+
id: raw.id,
|
|
61
|
+
areas: areaKey ? [areaKey] : [],
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
for (const area of chosen) {
|
|
66
|
+
for (const raw of (areas[area] && areas[area][listKey]) || []) add(raw, area);
|
|
67
|
+
}
|
|
68
|
+
// A lista cross-cutting é oferecida independente da seleção de área.
|
|
69
|
+
for (const raw of (registry && registry[utilityKey]) || []) add(raw, null);
|
|
70
|
+
|
|
71
|
+
return [...byId.values()];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { resolveAreaEntries };
|
|
@@ -24,31 +24,27 @@ const path = require('node:path');
|
|
|
24
24
|
const fs = require('../fs-native');
|
|
25
25
|
const yaml = require('yaml');
|
|
26
26
|
const { getProjectRoot, getSourcePath } = require('../project-root');
|
|
27
|
+
const { resolveAreaEntries } = require('./registry-resolve');
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Resolve which skill ids to install from the registry for the chosen areas.
|
|
30
31
|
* Empty / undefined / containing 'all' means every area. Utility skills
|
|
31
32
|
* (graphify, find-skills, ...) are cross-cutting and always included.
|
|
33
|
+
*
|
|
34
|
+
* Wrapper fino sobre `resolveAreaEntries` (A16): a resolução por área vive em
|
|
35
|
+
* `registry-resolve.js`; aqui só sobra reduzir as entradas resolvidas ao
|
|
36
|
+
* `id` (esta função nunca precisou de mais nada — nem de `areas`).
|
|
37
|
+
*
|
|
32
38
|
* @param {Object} registry - Parsed skills-registry.yaml
|
|
33
39
|
* @param {string[]} [selectedAreas] - Area keys to install
|
|
34
40
|
* @returns {string[]} Deduped skill ids
|
|
35
41
|
*/
|
|
36
42
|
function resolveSkillIds(registry, selectedAreas) {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
for (const area of chosen) {
|
|
43
|
-
const skills = (areas[area] && areas[area].skills) || [];
|
|
44
|
-
for (const skill of skills) {
|
|
45
|
-
if (skill && skill.id) ids.add(skill.id);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
for (const util of (registry && registry.utility) || []) {
|
|
49
|
-
if (util && util.id) ids.add(util.id);
|
|
50
|
-
}
|
|
51
|
-
return [...ids];
|
|
43
|
+
const entries = resolveAreaEntries(registry, selectedAreas, {
|
|
44
|
+
listKey: 'skills',
|
|
45
|
+
utilityKey: 'utility',
|
|
46
|
+
});
|
|
47
|
+
return entries.map((entry) => entry.id);
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
/**
|
package/tools/installer/ui.js
CHANGED
|
@@ -5,7 +5,7 @@ const yaml = require('yaml');
|
|
|
5
5
|
const fs = require('./fs-native');
|
|
6
6
|
const { getProjectRoot } = require('./project-root');
|
|
7
7
|
const installerPackageJson = require('../../package.json');
|
|
8
|
-
const { CLIUtils } = require('./
|
|
8
|
+
const { CLIUtils } = require('./banner');
|
|
9
9
|
const { ExternalModuleManager } = require('./modules/external-manager');
|
|
10
10
|
const { resolveModuleVersion } = require('./modules/version-resolver');
|
|
11
11
|
const { Manifest } = require('./core/manifest');
|
|
@@ -238,6 +238,7 @@ class UI {
|
|
|
238
238
|
choices.push({
|
|
239
239
|
name: 'Quick Update',
|
|
240
240
|
value: 'quick-update',
|
|
241
|
+
hint: 'Atualiza só os módulos instalados. Não instala skills/MCPs/CLIs novos (use Modify Wizz Installation para isso)',
|
|
241
242
|
});
|
|
242
243
|
}
|
|
243
244
|
|
|
@@ -434,6 +435,18 @@ class UI {
|
|
|
434
435
|
const selectedAreas = await this.selectSkillAreas(selectedModules, options);
|
|
435
436
|
const mcpPlan = await this.selectMcps(selectedModules, selectedAreas, options);
|
|
436
437
|
const cliPlan = await this.selectClis(selectedModules, selectedAreas, options);
|
|
438
|
+
|
|
439
|
+
// 3.8-E1: local routing-trace opt-in. Only relevant when wizz-router is
|
|
440
|
+
// actually part of the install (bmm), and — like the MCP/CLI pickers
|
|
441
|
+
// above — only offered on a genuinely interactive TTY (never --yes/CI).
|
|
442
|
+
// `null` (not asked) is distinct from `false` (asked, declined) so the
|
|
443
|
+
// final summary can tell the two apart.
|
|
444
|
+
let traceEnabled = null;
|
|
445
|
+
if (selectedModules.includes('bmm')) {
|
|
446
|
+
const traceInteractive = !(!!options.yes || !process.stdin.isTTY);
|
|
447
|
+
traceEnabled = await this.promptTraceOptIn(confirmedDirectory, { interactive: traceInteractive });
|
|
448
|
+
}
|
|
449
|
+
|
|
437
450
|
const { moduleConfigs, setOverrides } = await this.collectModuleConfigs(confirmedDirectory, selectedModules, {
|
|
438
451
|
...options,
|
|
439
452
|
channelOptions,
|
|
@@ -466,19 +479,25 @@ class UI {
|
|
|
466
479
|
setOverrides,
|
|
467
480
|
skipPrompts: options.yes || false,
|
|
468
481
|
channelOptions,
|
|
482
|
+
traceEnabled,
|
|
469
483
|
};
|
|
470
484
|
}
|
|
471
485
|
|
|
472
486
|
/**
|
|
473
487
|
* Load and parse skills-registry.yaml from the package root.
|
|
488
|
+
* A corrupted/unparsable registry still degrades to null (areas/MCPs/CLIs
|
|
489
|
+
* come back empty rather than crashing the install), but that degradation
|
|
490
|
+
* is never silent: it is logged so the failure is diagnosable instead of
|
|
491
|
+
* looking like "nothing to choose from" (audit finding M11).
|
|
474
492
|
* @returns {Object|null} Parsed registry, or null when absent/unreadable
|
|
475
493
|
*/
|
|
476
494
|
_loadSkillsRegistry() {
|
|
495
|
+
const registryPath = path.join(getProjectRoot(), 'skills-registry.yaml');
|
|
496
|
+
if (!fs.existsSync(registryPath)) return null;
|
|
477
497
|
try {
|
|
478
|
-
const registryPath = path.join(getProjectRoot(), 'skills-registry.yaml');
|
|
479
|
-
if (!fs.existsSync(registryPath)) return null;
|
|
480
498
|
return yaml.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
481
|
-
} catch {
|
|
499
|
+
} catch (error) {
|
|
500
|
+
console.warn(`⚠ skills-registry.yaml failed to parse (${error.message}). Areas/MCPs/CLIs will be empty until this is fixed.`);
|
|
482
501
|
return null;
|
|
483
502
|
}
|
|
484
503
|
}
|
|
@@ -660,7 +679,9 @@ class UI {
|
|
|
660
679
|
options: missing.map((c) => ({
|
|
661
680
|
label: c.id,
|
|
662
681
|
value: c.id,
|
|
663
|
-
|
|
682
|
+
// M27/M14: prefer the upgrade/verify-failure reason when present —
|
|
683
|
+
// more actionable than the generic `when` in those two cases.
|
|
684
|
+
hint: c.upgradeMessage || c.verifyWarning || c.when,
|
|
664
685
|
})),
|
|
665
686
|
initialValues: [],
|
|
666
687
|
required: false,
|
|
@@ -669,6 +690,51 @@ class UI {
|
|
|
669
690
|
return split(selected || []);
|
|
670
691
|
}
|
|
671
692
|
|
|
693
|
+
/**
|
|
694
|
+
* 3.8-E1: ask whether to opt into the local routing-trace measurement and,
|
|
695
|
+
* if yes, persist `WIZZ_TRACE=1` into the project's
|
|
696
|
+
* `.claude/settings.local.json` (chave `env`) — the exact merge-writer 3.3
|
|
697
|
+
* built for MCP env vars (`persistProjectEnv`), reused here so there is
|
|
698
|
+
* only one implementation of "merge a value into settings.local.json's
|
|
699
|
+
* `env` key without clobbering what's already there" (see
|
|
700
|
+
* `tools/installer/modules/env-vars.js`).
|
|
701
|
+
*
|
|
702
|
+
* The trace is entirely local: `tools/hooks/wizz-router-enforce.js`
|
|
703
|
+
* (already installed globally) reads `process.env.WIZZ_TRACE` and, when
|
|
704
|
+
* set, appends one JSON line per routed prompt to
|
|
705
|
+
* `~/.claude/wizz-trace.jsonl` on this machine — nothing leaves it. Claude
|
|
706
|
+
* Code merges a project's `.claude/settings.local.json` `env` key into
|
|
707
|
+
* every subprocess it spawns for that project, so setting the key here is
|
|
708
|
+
* enough to turn the hook's trace on for sessions in this project, with no
|
|
709
|
+
* change to the hook itself.
|
|
710
|
+
*
|
|
711
|
+
* `interactive` is computed by the caller (not read from `process.stdin`
|
|
712
|
+
* here) so this stays a plain, TTY-independent function to unit test —
|
|
713
|
+
* mirrors the seam `promptMissingEnvVars`/`resolveEnvVars` already use in
|
|
714
|
+
* env-vars.js. Never opts in silently: a `false`/no-TTY caller always
|
|
715
|
+
* skips without prompting, so telemetry is opt-in by construction, never
|
|
716
|
+
* default-on.
|
|
717
|
+
*
|
|
718
|
+
* @param {string} projectDir - Project root (where `.claude/` lives)
|
|
719
|
+
* @param {Object} [opts]
|
|
720
|
+
* @param {boolean} [opts.interactive=false] - Whether to actually prompt
|
|
721
|
+
* @returns {Promise<boolean>} Whether WIZZ_TRACE was turned on
|
|
722
|
+
*/
|
|
723
|
+
async promptTraceOptIn(projectDir, opts = {}) {
|
|
724
|
+
const { interactive = false } = opts;
|
|
725
|
+
if (!interactive) return false;
|
|
726
|
+
|
|
727
|
+
const enable = await prompts.confirm({
|
|
728
|
+
message: 'Quer ligar o medidor de roteamento? (local, grava só em ~/.claude/wizz-trace.jsonl na sua máquina, nunca sai daqui)',
|
|
729
|
+
default: false,
|
|
730
|
+
});
|
|
731
|
+
if (!enable) return false;
|
|
732
|
+
|
|
733
|
+
const { persistProjectEnv } = require('./modules/env-vars');
|
|
734
|
+
await persistProjectEnv(projectDir, { WIZZ_TRACE: '1' });
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
|
|
672
738
|
/**
|
|
673
739
|
* Prompt for tool/IDE selection (called after module configuration)
|
|
674
740
|
* Uses a split prompt approach:
|
package/wizz-modules.yaml
CHANGED
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
# default_channel (optional) — the install channel when the user does not
|
|
8
8
|
# override with --channel/--pin/--next. Valid values: stable | next.
|
|
9
9
|
# Omit to inherit the installer's hardcoded default (stable).
|
|
10
|
+
#
|
|
11
|
+
# type: upstream-org — the module lives in a third-party org (bmad-code-org)
|
|
12
|
+
# and Wizz delegates trust to that upstream: the installer resolves and
|
|
13
|
+
# downloads it without Wizz controlling the repo. Decision recorded on
|
|
14
|
+
# 2026-07-07 (audit task 2.10, finding A4): honest label instead of forking,
|
|
15
|
+
# acceptable because every upstream module is defaultSelected: false and the
|
|
16
|
+
# install is explicit opt-in. Revisit (fork under wizzcomms) if an upstream
|
|
17
|
+
# repo changes owner, disappears, or ships something unexpected.
|
|
18
|
+
# type: experimental — same delegated trust, plus unstable by upstream's
|
|
19
|
+
# own definition.
|
|
10
20
|
|
|
11
21
|
modules:
|
|
12
22
|
bmad-method-test-architecture-enterprise:
|
|
@@ -16,7 +26,7 @@ modules:
|
|
|
16
26
|
name: "Wizz Test Architect"
|
|
17
27
|
description: "Quality strategy, test automation, and release gates for enterprise teams"
|
|
18
28
|
defaultSelected: false
|
|
19
|
-
type:
|
|
29
|
+
type: upstream-org
|
|
20
30
|
npmPackage: bmad-method-test-architecture-enterprise
|
|
21
31
|
default_channel: stable
|
|
22
32
|
|
|
@@ -27,7 +37,7 @@ modules:
|
|
|
27
37
|
name: "Wizz Builder"
|
|
28
38
|
description: "Build AI agents, workflows, and modules from a conversation"
|
|
29
39
|
defaultSelected: false
|
|
30
|
-
type:
|
|
40
|
+
type: upstream-org
|
|
31
41
|
npmPackage: bmad-builder
|
|
32
42
|
default_channel: stable
|
|
33
43
|
|
|
@@ -49,7 +59,7 @@ modules:
|
|
|
49
59
|
name: "Wizz Creative Intelligence Suite"
|
|
50
60
|
description: "Brainstorming, ideation, storytelling, design thinking, and problem-solving"
|
|
51
61
|
defaultSelected: false
|
|
52
|
-
type:
|
|
62
|
+
type: upstream-org
|
|
53
63
|
npmPackage: bmad-creative-intelligence-suite
|
|
54
64
|
default_channel: stable
|
|
55
65
|
|
|
@@ -60,7 +70,7 @@ modules:
|
|
|
60
70
|
name: "Wizz Game Dev Studio"
|
|
61
71
|
description: "Game design and development for Unity, Unreal, Godot, and Phaser."
|
|
62
72
|
defaultSelected: false
|
|
63
|
-
type:
|
|
73
|
+
type: upstream-org
|
|
64
74
|
npmPackage: bmad-game-dev-studio
|
|
65
75
|
default_channel: stable
|
|
66
76
|
|
|
@@ -72,6 +82,6 @@ modules:
|
|
|
72
82
|
name: "Whiteport Design Studio"
|
|
73
83
|
description: "Strategic UX and Design first planning methodology"
|
|
74
84
|
defaultSelected: false
|
|
75
|
-
type:
|
|
85
|
+
type: upstream-org
|
|
76
86
|
npmPackage: bmad-wds
|
|
77
87
|
default_channel: stable
|