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
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User file preservation: scan → backup → restore.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `Installer` (installer god-object breakup, A15/A17,
|
|
5
|
+
* auditoria 2026-07-07, item 3.1). These three functions form one coherent
|
|
6
|
+
* unit around updates: `detectCustomFiles` scans an existing `_wizz/` for
|
|
7
|
+
* files the user added or modified since the last install, `backupUserFiles`
|
|
8
|
+
* copies them out of the way before the update overwrites `_wizz/`, and
|
|
9
|
+
* `restoreUserFiles` copies them back afterwards. All state that the
|
|
10
|
+
* original methods read off `this` (the `Manifest` instance for hashing) is
|
|
11
|
+
* now an explicit parameter — no class, no shared mutable state between
|
|
12
|
+
* calls.
|
|
13
|
+
*/
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
const fs = require('../fs-native');
|
|
16
|
+
const prompts = require('../prompts');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Detect custom and modified files.
|
|
20
|
+
* @param {string} wizzDir - WIZZ installation directory
|
|
21
|
+
* @param {Array} existingFilesManifest - Previous files from files-manifest.csv
|
|
22
|
+
* @param {Object} deps - Injected dependencies
|
|
23
|
+
* @param {Object} deps.manifest - Manifest instance (used for calculateFileHash)
|
|
24
|
+
* @returns {Object} Object with customFiles and modifiedFiles arrays
|
|
25
|
+
*/
|
|
26
|
+
async function detectCustomFiles(wizzDir, existingFilesManifest, { manifest }) {
|
|
27
|
+
const customFiles = [];
|
|
28
|
+
const modifiedFiles = [];
|
|
29
|
+
|
|
30
|
+
// Memory subtrees (v6.1: _wizz/_memory, current: _wizz/memory) hold
|
|
31
|
+
// per-user runtime data generated by agents with sidecars. These files
|
|
32
|
+
// aren't installer-managed and must never be reported as "custom" or
|
|
33
|
+
// "modified" — they're user state, not user overrides.
|
|
34
|
+
const wizzMemoryPaths = ['_memory', 'memory'];
|
|
35
|
+
|
|
36
|
+
// Check if the manifest has hashes - if not, we can't detect modifications
|
|
37
|
+
let manifestHasHashes = false;
|
|
38
|
+
if (existingFilesManifest && existingFilesManifest.length > 0) {
|
|
39
|
+
manifestHasHashes = existingFilesManifest.some((f) => f.hash);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Build map of previously installed files from files-manifest.csv with their hashes
|
|
43
|
+
const installedFilesMap = new Map();
|
|
44
|
+
for (const fileEntry of existingFilesManifest) {
|
|
45
|
+
if (fileEntry.path) {
|
|
46
|
+
const absolutePath = path.join(wizzDir, fileEntry.path);
|
|
47
|
+
installedFilesMap.set(path.normalize(absolutePath), {
|
|
48
|
+
hash: fileEntry.hash,
|
|
49
|
+
relativePath: fileEntry.path,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Recursively scan wizzDir for all files
|
|
55
|
+
const scanDirectory = async (dir) => {
|
|
56
|
+
try {
|
|
57
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
const fullPath = path.join(dir, entry.name);
|
|
60
|
+
|
|
61
|
+
if (entry.isDirectory()) {
|
|
62
|
+
// Skip certain directories
|
|
63
|
+
if (entry.name === 'node_modules' || entry.name === '.git') {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
await scanDirectory(fullPath);
|
|
67
|
+
} else if (entry.isFile()) {
|
|
68
|
+
const normalizedPath = path.normalize(fullPath);
|
|
69
|
+
const fileInfo = installedFilesMap.get(normalizedPath);
|
|
70
|
+
|
|
71
|
+
// Skip certain system files that are auto-generated
|
|
72
|
+
const relativePath = path.relative(wizzDir, fullPath);
|
|
73
|
+
const fileName = path.basename(fullPath);
|
|
74
|
+
|
|
75
|
+
// Skip _config directory EXCEPT for modified agent customizations
|
|
76
|
+
if (relativePath.startsWith('_config/') || relativePath.startsWith('_config\\')) {
|
|
77
|
+
// Special handling for .customize.yaml files - only preserve if modified
|
|
78
|
+
if (relativePath.includes('/agents/') && fileName.endsWith('.customize.yaml')) {
|
|
79
|
+
// Check if the customization file has been modified from manifest
|
|
80
|
+
const manifestPath = path.join(wizzDir, '_config', 'manifest.yaml');
|
|
81
|
+
if (await fs.pathExists(manifestPath)) {
|
|
82
|
+
const crypto = require('node:crypto');
|
|
83
|
+
const currentContent = await fs.readFile(fullPath, 'utf8');
|
|
84
|
+
const currentHash = crypto.createHash('sha256').update(currentContent).digest('hex');
|
|
85
|
+
|
|
86
|
+
const yaml = require('yaml');
|
|
87
|
+
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
|
88
|
+
const manifestData = yaml.parse(manifestContent);
|
|
89
|
+
const originalHash = manifestData.agentCustomizations?.[relativePath];
|
|
90
|
+
|
|
91
|
+
// Only add to customFiles if hash differs (user modified)
|
|
92
|
+
if (originalHash && currentHash !== originalHash) {
|
|
93
|
+
customFiles.push(fullPath);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (wizzMemoryPaths.some((mp) => relativePath === mp || relativePath.startsWith(mp + '/'))) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Skip config.yaml files - these are regenerated on each install/update
|
|
105
|
+
if (fileName === 'config.yaml') {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!fileInfo) {
|
|
110
|
+
// File not in manifest = custom file
|
|
111
|
+
// EXCEPT: Agent .md files in module folders are generated files, not custom
|
|
112
|
+
// Only treat .md files under _config/agents/ as custom
|
|
113
|
+
if (!(fileName.endsWith('.md') && relativePath.includes('/agents/') && !relativePath.startsWith('_config/'))) {
|
|
114
|
+
customFiles.push(fullPath);
|
|
115
|
+
}
|
|
116
|
+
} else if (manifestHasHashes && fileInfo.hash) {
|
|
117
|
+
// File in manifest with hash - check if it was modified
|
|
118
|
+
const currentHash = await manifest.calculateFileHash(fullPath);
|
|
119
|
+
if (currentHash && currentHash !== fileInfo.hash) {
|
|
120
|
+
// Hash changed = file was modified
|
|
121
|
+
modifiedFiles.push({
|
|
122
|
+
path: fullPath,
|
|
123
|
+
relativePath: fileInfo.relativePath,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} catch (error) {
|
|
130
|
+
// Best-effort: a permission error mid-scan must not silently decide
|
|
131
|
+
// what gets preserved on the next update (this scan is what
|
|
132
|
+
// detects custom/modified files), so warn instead of swallowing it.
|
|
133
|
+
await prompts.log.warn(`Warning: could not scan ${dir} for custom/modified files: ${error.message}`);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
await scanDirectory(wizzDir);
|
|
138
|
+
return { customFiles, modifiedFiles };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Back up custom and modified files to temp directories before overwriting.
|
|
143
|
+
* Returns the temp directory paths (or undefined if no files to back up).
|
|
144
|
+
* @param {Object} paths - InstallPaths instance
|
|
145
|
+
* @param {string[]} customFiles - Absolute paths of custom (user-added) files
|
|
146
|
+
* @param {Object[]} modifiedFiles - Array of { path, relativePath } for modified files
|
|
147
|
+
* @returns {Object} { tempBackupDir, tempModifiedBackupDir } — undefined if no files
|
|
148
|
+
*/
|
|
149
|
+
async function backupUserFiles(paths, customFiles, modifiedFiles) {
|
|
150
|
+
let tempBackupDir;
|
|
151
|
+
let tempModifiedBackupDir;
|
|
152
|
+
|
|
153
|
+
if (customFiles.length > 0) {
|
|
154
|
+
tempBackupDir = path.join(paths.projectRoot, '_wizz-custom-backup-temp');
|
|
155
|
+
await fs.ensureDir(tempBackupDir);
|
|
156
|
+
|
|
157
|
+
for (const customFile of customFiles) {
|
|
158
|
+
const relativePath = path.relative(paths.wizzDir, customFile);
|
|
159
|
+
const backupPath = path.join(tempBackupDir, relativePath);
|
|
160
|
+
await fs.ensureDir(path.dirname(backupPath));
|
|
161
|
+
await fs.copy(customFile, backupPath);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (modifiedFiles.length > 0) {
|
|
166
|
+
tempModifiedBackupDir = path.join(paths.projectRoot, '_wizz-modified-backup-temp');
|
|
167
|
+
await fs.ensureDir(tempModifiedBackupDir);
|
|
168
|
+
|
|
169
|
+
for (const modifiedFile of modifiedFiles) {
|
|
170
|
+
const relativePath = path.relative(paths.wizzDir, modifiedFile.path);
|
|
171
|
+
const tempBackupPath = path.join(tempModifiedBackupDir, relativePath);
|
|
172
|
+
await fs.ensureDir(path.dirname(tempBackupPath));
|
|
173
|
+
await fs.copy(modifiedFile.path, tempBackupPath, { overwrite: true });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return { tempBackupDir, tempModifiedBackupDir };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Restore custom and modified files that were backed up before the update.
|
|
182
|
+
* No-op for fresh installs (updateState is null).
|
|
183
|
+
* @param {Object} paths - InstallPaths instance
|
|
184
|
+
* @param {Object|null} updateState - From _prepareUpdateState, or null for fresh installs
|
|
185
|
+
* @returns {Object} { customFiles, modifiedFiles } — lists of restored files
|
|
186
|
+
*/
|
|
187
|
+
async function restoreUserFiles(paths, updateState) {
|
|
188
|
+
const noFiles = { customFiles: [], modifiedFiles: [] };
|
|
189
|
+
|
|
190
|
+
if (!updateState || (updateState.customFiles.length === 0 && updateState.modifiedFiles.length === 0)) {
|
|
191
|
+
return noFiles;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let restoredCustomFiles = [];
|
|
195
|
+
let restoredModifiedFiles = [];
|
|
196
|
+
|
|
197
|
+
await prompts.tasks([
|
|
198
|
+
{
|
|
199
|
+
title: 'Finalizing installation',
|
|
200
|
+
task: async (message) => {
|
|
201
|
+
if (updateState.customFiles.length > 0) {
|
|
202
|
+
message(`Restoring ${updateState.customFiles.length} custom files...`);
|
|
203
|
+
|
|
204
|
+
for (const originalPath of updateState.customFiles) {
|
|
205
|
+
const relativePath = path.relative(paths.wizzDir, originalPath);
|
|
206
|
+
const backupPath = path.join(updateState.tempBackupDir, relativePath);
|
|
207
|
+
|
|
208
|
+
if (await fs.pathExists(backupPath)) {
|
|
209
|
+
await fs.ensureDir(path.dirname(originalPath));
|
|
210
|
+
await fs.copy(backupPath, originalPath, { overwrite: true });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (updateState.tempBackupDir && (await fs.pathExists(updateState.tempBackupDir))) {
|
|
215
|
+
await fs.remove(updateState.tempBackupDir);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
restoredCustomFiles = updateState.customFiles;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (updateState.modifiedFiles.length > 0) {
|
|
222
|
+
restoredModifiedFiles = updateState.modifiedFiles;
|
|
223
|
+
|
|
224
|
+
if (updateState.tempModifiedBackupDir && (await fs.pathExists(updateState.tempModifiedBackupDir))) {
|
|
225
|
+
message(`Restoring ${restoredModifiedFiles.length} modified files as .bak...`);
|
|
226
|
+
|
|
227
|
+
for (const modifiedFile of restoredModifiedFiles) {
|
|
228
|
+
const relativePath = path.relative(paths.wizzDir, modifiedFile.path);
|
|
229
|
+
const tempBackupPath = path.join(updateState.tempModifiedBackupDir, relativePath);
|
|
230
|
+
const bakPath = modifiedFile.path + '.bak';
|
|
231
|
+
|
|
232
|
+
if (await fs.pathExists(tempBackupPath)) {
|
|
233
|
+
await fs.ensureDir(path.dirname(bakPath));
|
|
234
|
+
await fs.copy(tempBackupPath, bakPath, { overwrite: true });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
await fs.remove(updateState.tempModifiedBackupDir);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return 'Installation finalized';
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
]);
|
|
246
|
+
|
|
247
|
+
return { customFiles: restoredCustomFiles, modifiedFiles: restoredModifiedFiles };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
module.exports = { detectCustomFiles, backupUserFiles, restoreUserFiles };
|
|
@@ -22,6 +22,24 @@ const USER_AGENT = 'wizz-method-installer';
|
|
|
22
22
|
// Per-process cache: { 'owner/repo' => string[] sorted desc } of pure-semver tags.
|
|
23
23
|
const tagCache = new Map();
|
|
24
24
|
|
|
25
|
+
// Retry pontual (1 re-tentativa, backoff curto) para chamadas à API do
|
|
26
|
+
// GitHub. Só re-tenta em erro de rede transitório (timeout, ECONNRESET,
|
|
27
|
+
// ENOTFOUND, EAI_AGAIN, 5xx). Erros lógicos (4xx, ex.: 404 de tag inexistente)
|
|
28
|
+
// nunca são re-tentados — propagam direto.
|
|
29
|
+
const FETCH_RETRY_DELAY_MS = 300;
|
|
30
|
+
const TRANSIENT_ERROR_CODES = new Set(['ECONNRESET', 'ENOTFOUND', 'EAI_AGAIN', 'ETIMEDOUT']);
|
|
31
|
+
|
|
32
|
+
function isTransientError(error) {
|
|
33
|
+
if (!error) return false;
|
|
34
|
+
if (typeof error.statusCode === 'number') return error.statusCode >= 500;
|
|
35
|
+
if (error.code && TRANSIENT_ERROR_CODES.has(error.code)) return true;
|
|
36
|
+
return /timed out/i.test(error.message || '');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function delay(ms) {
|
|
40
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
41
|
+
}
|
|
42
|
+
|
|
25
43
|
/**
|
|
26
44
|
* Parse a GitHub repo URL into { owner, repo }. Returns null if the URL is
|
|
27
45
|
* not a GitHub URL the resolver can handle.
|
|
@@ -44,7 +62,7 @@ function parseGitHubRepo(url) {
|
|
|
44
62
|
return null;
|
|
45
63
|
}
|
|
46
64
|
|
|
47
|
-
function
|
|
65
|
+
function fetchJsonOnce(url, { timeout = DEFAULT_TIMEOUT_MS } = {}) {
|
|
48
66
|
const headers = {
|
|
49
67
|
'User-Agent': USER_AGENT,
|
|
50
68
|
Accept: 'application/vnd.github+json',
|
|
@@ -74,11 +92,25 @@ function fetchJson(url, { timeout = DEFAULT_TIMEOUT_MS } = {}) {
|
|
|
74
92
|
req.on('error', reject);
|
|
75
93
|
req.on('timeout', () => {
|
|
76
94
|
req.destroy();
|
|
77
|
-
|
|
95
|
+
const err = new Error(`GitHub API request timed out: ${url}`);
|
|
96
|
+
err.code = 'ETIMEDOUT';
|
|
97
|
+
reject(err);
|
|
78
98
|
});
|
|
79
99
|
});
|
|
80
100
|
}
|
|
81
101
|
|
|
102
|
+
// Wrapper com 1 re-tentativa em erro transitório (ver isTransientError acima).
|
|
103
|
+
// Erro não-transitório (404 de tag, JSON malformado etc.) propaga direto.
|
|
104
|
+
async function fetchJson(url, options = {}) {
|
|
105
|
+
try {
|
|
106
|
+
return await fetchJsonOnce(url, options);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (!isTransientError(error)) throw error;
|
|
109
|
+
await delay(FETCH_RETRY_DELAY_MS);
|
|
110
|
+
return fetchJsonOnce(url, options);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
82
114
|
/**
|
|
83
115
|
* Strip a leading 'v' and return a valid semver string, or null if the tag
|
|
84
116
|
* is not valid semver or is a prerelease (contains -alpha/-beta/-rc/etc.).
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
const { exec } = require('node:child_process');
|
|
28
28
|
const { promisify } = require('node:util');
|
|
29
|
+
const { resolveAreaEntries } = require('./registry-resolve');
|
|
29
30
|
|
|
30
31
|
const execAsync = promisify(exec);
|
|
31
32
|
|
|
@@ -79,42 +80,33 @@ function matchesPlatform(cli, tag) {
|
|
|
79
80
|
* `platform:` gate does not match the current OS/arch are dropped too, so a
|
|
80
81
|
* Mac-only tool is never even suggested on Linux/Windows.
|
|
81
82
|
*
|
|
83
|
+
* Wrapper fino sobre `resolveAreaEntries` (A16): a resolução por área em si
|
|
84
|
+
* vive em `registry-resolve.js`; aqui só ficam a forma da entrada de CLI e o
|
|
85
|
+
* filtro de elegibilidade (precisa de `install` + bater o gate de plataforma).
|
|
86
|
+
*
|
|
82
87
|
* @param {Object} registry - Parsed skills-registry.yaml
|
|
83
88
|
* @param {string[]} [selectedAreas] - Area keys to resolve
|
|
84
89
|
* @param {string} [platformTag] - Current "<platform>-<arch>" (injectable for tests)
|
|
85
|
-
* @returns {Array<{id: string, when: string, check: string, install: string, platform: (string|string[]|undefined), areas: string[]}>}
|
|
90
|
+
* @returns {Array<{id: string, when: string, check: string, install: string, platform: (string|string[]|undefined), min_version: (string|undefined), verify: (string|undefined), areas: string[]}>}
|
|
86
91
|
*/
|
|
87
92
|
function resolveClis(registry, selectedAreas, platformTag = currentPlatformTag()) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const add = (cli, areaKey) => {
|
|
94
|
-
if (!cli || !cli.id || !cli.install) return; // not actionable without an install command
|
|
95
|
-
if (!matchesPlatform(cli, platformTag)) return; // gated to another OS/arch
|
|
96
|
-
const existing = byId.get(cli.id);
|
|
97
|
-
if (existing) {
|
|
98
|
-
if (areaKey && !existing.areas.includes(areaKey)) existing.areas.push(areaKey);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
byId.set(cli.id, {
|
|
102
|
-
id: cli.id,
|
|
93
|
+
return resolveAreaEntries(registry, selectedAreas, {
|
|
94
|
+
listKey: 'clis',
|
|
95
|
+
utilityKey: 'cli_utility',
|
|
96
|
+
isActionable: (cli) => !!cli.install && matchesPlatform(cli, platformTag),
|
|
97
|
+
mapEntry: (cli) => ({
|
|
103
98
|
when: cli.when || '',
|
|
104
99
|
check: cli.check || '',
|
|
105
100
|
install: cli.install,
|
|
106
101
|
platform: cli.platform,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for (const cli of (registry && registry.cli_utility) || []) add(cli, null);
|
|
116
|
-
|
|
117
|
-
return [...byId.values()];
|
|
102
|
+
// M27: pin below which `detectClis` reports the entry as needing an
|
|
103
|
+
// upgrade instead of `installed: true`.
|
|
104
|
+
min_version: cli.min_version,
|
|
105
|
+
// M14: post-check/post-install probe for minimal runtime deps (e.g.
|
|
106
|
+
// clone-and-run tools where `check` only proves the clone exists).
|
|
107
|
+
verify: cli.verify,
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
118
110
|
}
|
|
119
111
|
|
|
120
112
|
/**
|
|
@@ -127,12 +119,58 @@ function renderInstallCommand(cli) {
|
|
|
127
119
|
return (cli && cli.install) || '';
|
|
128
120
|
}
|
|
129
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Extract the first "x.y.z" version number found in a command's output.
|
|
124
|
+
* @param {string} text
|
|
125
|
+
* @returns {string|null}
|
|
126
|
+
*/
|
|
127
|
+
function extractVersion(text) {
|
|
128
|
+
const m = String(text || '').match(/\d+\.\d+\.\d+/);
|
|
129
|
+
return m ? m[0] : null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Compare two "x.y.z" version strings numerically, segment by segment (no
|
|
134
|
+
* external semver dependency needed for this simple 3-part comparison).
|
|
135
|
+
* @param {string} a
|
|
136
|
+
* @param {string} b
|
|
137
|
+
* @returns {number} negative if a<b, 0 if equal, positive if a>b
|
|
138
|
+
*/
|
|
139
|
+
function compareSemver(a, b) {
|
|
140
|
+
const pa = String(a)
|
|
141
|
+
.split('.')
|
|
142
|
+
.map((n) => Number(n) || 0);
|
|
143
|
+
const pb = String(b)
|
|
144
|
+
.split('.')
|
|
145
|
+
.map((n) => Number(n) || 0);
|
|
146
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
147
|
+
const diff = (pa[i] || 0) - (pb[i] || 0);
|
|
148
|
+
if (diff !== 0) return diff;
|
|
149
|
+
}
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
130
153
|
/**
|
|
131
154
|
* Annotate each CLI with `installed: boolean` by running its `check` command.
|
|
132
155
|
* Immutable: returns new objects, never mutates the input. An entry without a
|
|
133
156
|
* `check` cannot be verified, so it is reported as not installed (we offer it
|
|
134
157
|
* rather than silently assume it is present).
|
|
135
158
|
*
|
|
159
|
+
* M27 (drift do RTK, 0.30.1 rodando com pin v0.43.0): when the entry declares
|
|
160
|
+
* `min_version`, a passing `check` is not enough — we also parse the version
|
|
161
|
+
* out of the check's output and compare it against the pin. Below the pin,
|
|
162
|
+
* the entry comes back `installed: false` (so the caller's existing "missing
|
|
163
|
+
* => offer install" path naturally becomes "offer upgrade") plus an
|
|
164
|
+
* `upgradeMessage` the caller can surface. A version that cannot be parsed
|
|
165
|
+
* falls back to the old ok-only behavior (nothing to compare against).
|
|
166
|
+
*
|
|
167
|
+
* M14 (assimetria MCP vs CLI): when the entry declares `verify` (a check of
|
|
168
|
+
* minimal runtime deps, e.g. `command -v ffmpeg`, for clone-and-run tools
|
|
169
|
+
* where `check` only proves "the clone exists"), it also runs AFTER `check`
|
|
170
|
+
* passes. A failing `verify` means the tool is not genuinely usable, so the
|
|
171
|
+
* entry is reported `installed: false` with a `verifyWarning` — never an
|
|
172
|
+
* abort, just a clearer "not really installed yet" signal (CLIs stay opt-in).
|
|
173
|
+
*
|
|
136
174
|
* @param {Array<Object>} clis - Resolved CLI entries
|
|
137
175
|
* @param {Function} [exec] - Injected runner (command, opts) => {ok,...}
|
|
138
176
|
* @returns {Promise<Array<Object>>} Copies with an added `installed` flag.
|
|
@@ -142,7 +180,32 @@ async function detectClis(clis, exec = defaultExec) {
|
|
|
142
180
|
(clis || []).map(async (cli) => {
|
|
143
181
|
if (!cli.check) return { ...cli, installed: false };
|
|
144
182
|
const res = await exec(cli.check, { timeoutMs: 5000 });
|
|
145
|
-
return { ...cli, installed:
|
|
183
|
+
if (!res.ok) return { ...cli, installed: false };
|
|
184
|
+
|
|
185
|
+
if (cli.min_version) {
|
|
186
|
+
const installedVersion = extractVersion(res.stdout) || extractVersion(res.stderr);
|
|
187
|
+
if (installedVersion && compareSemver(installedVersion, cli.min_version) < 0) {
|
|
188
|
+
return {
|
|
189
|
+
...cli,
|
|
190
|
+
installed: false,
|
|
191
|
+
installedVersion,
|
|
192
|
+
upgradeMessage: `atualizando ${cli.id} ${installedVersion} → ${cli.min_version}`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (cli.verify) {
|
|
198
|
+
const verified = await exec(cli.verify, { timeoutMs: 15_000 });
|
|
199
|
+
if (!verified.ok) {
|
|
200
|
+
return {
|
|
201
|
+
...cli,
|
|
202
|
+
installed: false,
|
|
203
|
+
verifyWarning: `${cli.id}: presente, mas a verificação de dependências falhou (${(verified.stderr || 'erro desconhecido').trim()}) — não considerado plenamente instalado`,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return { ...cli, installed: true };
|
|
146
209
|
}),
|
|
147
210
|
);
|
|
148
211
|
}
|
|
@@ -152,24 +215,54 @@ async function detectClis(clis, exec = defaultExec) {
|
|
|
152
215
|
* a failed install (network, EACCES, missing command) lands in `failed` with
|
|
153
216
|
* its error so the caller can warn and continue the broader install.
|
|
154
217
|
*
|
|
218
|
+
* M14: when the entry declares `verify`, it runs once the install succeeds
|
|
219
|
+
* (mirrors mcp-config's post-install VERIFY step). A failing verify does NOT
|
|
220
|
+
* move the entry to `failed` — the install itself worked (e.g. `git clone`
|
|
221
|
+
* for a clone-and-run tool) — it only adds a `warnings` entry so the caller
|
|
222
|
+
* can tell the user their runtime deps (ffmpeg, Ruby, Python...) still need
|
|
223
|
+
* attention. CLIs are opt-in and fail-open: a warning, never an abort.
|
|
224
|
+
*
|
|
155
225
|
* @param {Object} args
|
|
156
|
-
* @param {Array<{id: string, install?: string}>} args.clis - Entries to install
|
|
226
|
+
* @param {Array<{id: string, install?: string, verify?: string}>} args.clis - Entries to install
|
|
157
227
|
* @param {Function} [args.exec] - Injected runner (command, opts) => {ok,...}
|
|
158
|
-
* @returns {Promise<{installed: string[], failed: Array<{id: string, error: string}>}>}
|
|
228
|
+
* @returns {Promise<{installed: string[], failed: Array<{id: string, error: string}>, warnings: Array<{id: string, warning: string}>}>}
|
|
159
229
|
*/
|
|
160
230
|
async function installClis({ clis, exec = defaultExec }) {
|
|
161
231
|
const installed = [];
|
|
162
232
|
const failed = [];
|
|
233
|
+
const warnings = [];
|
|
163
234
|
for (const cli of clis || []) {
|
|
164
235
|
if (!cli.install) {
|
|
165
236
|
failed.push({ id: cli.id, error: 'sem comando de instalação no registry' });
|
|
166
237
|
continue;
|
|
167
238
|
}
|
|
168
239
|
const res = await exec(cli.install, { timeoutMs: 300_000 });
|
|
169
|
-
if (res.ok)
|
|
170
|
-
|
|
240
|
+
if (!res.ok) {
|
|
241
|
+
failed.push({ id: cli.id, error: (res.stderr || 'falha desconhecida').trim() });
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
installed.push(cli.id);
|
|
245
|
+
if (cli.verify) {
|
|
246
|
+
const verified = await exec(cli.verify, { timeoutMs: 60_000 });
|
|
247
|
+
if (!verified.ok) {
|
|
248
|
+
warnings.push({
|
|
249
|
+
id: cli.id,
|
|
250
|
+
warning: `verificação pós-install falhou, dependência mínima pode estar ausente: ${(verified.stderr || 'erro desconhecido').trim()}`,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
171
254
|
}
|
|
172
|
-
return { installed, failed };
|
|
255
|
+
return { installed, failed, warnings };
|
|
173
256
|
}
|
|
174
257
|
|
|
175
|
-
module.exports = {
|
|
258
|
+
module.exports = {
|
|
259
|
+
resolveClis,
|
|
260
|
+
renderInstallCommand,
|
|
261
|
+
detectClis,
|
|
262
|
+
installClis,
|
|
263
|
+
defaultExec,
|
|
264
|
+
matchesPlatform,
|
|
265
|
+
currentPlatformTag,
|
|
266
|
+
extractVersion,
|
|
267
|
+
compareSemver,
|
|
268
|
+
};
|
|
@@ -59,7 +59,11 @@ function shapeMcp(mcp) {
|
|
|
59
59
|
* @param {Object} args
|
|
60
60
|
* @param {string[]} [args.selectedAreas] - Chosen area keys ([] => all areas)
|
|
61
61
|
* @param {{toInstall?: Object[], toRecommend?: Object[], alreadyInstalled?: Object[]}} [args.cliPlan]
|
|
62
|
-
* @param {{toWrite?: Object[], toRecommend?: Object[]}} [args.mcpPlan]
|
|
62
|
+
* @param {{toWrite?: Object[], toRecommend?: Object[], pinHashes?: Record<string,string>}} [args.mcpPlan]
|
|
63
|
+
* `pinHashes` (A13) is `writeMcpConfig`'s `pinHashes` result: id => content
|
|
64
|
+
* hash of the server block as it now stands on disk. Persisted here as
|
|
65
|
+
* `mcps.pins` so the NEXT install can tell an untouched block (safe to
|
|
66
|
+
* auto-update the pin) from a user-customized one (never overwritten).
|
|
63
67
|
* @returns {Object} The manifest to be written.
|
|
64
68
|
*/
|
|
65
69
|
function buildDepsCache({ selectedAreas, cliPlan = {}, mcpPlan = {} }) {
|
|
@@ -75,6 +79,7 @@ function buildDepsCache({ selectedAreas, cliPlan = {}, mcpPlan = {} }) {
|
|
|
75
79
|
mcps: {
|
|
76
80
|
written: (mcpPlan.toWrite || []).map(shapeMcp),
|
|
77
81
|
recommended: (mcpPlan.toRecommend || []).map(shapeMcp),
|
|
82
|
+
pins: mcpPlan.pinHashes && typeof mcpPlan.pinHashes === 'object' ? { ...mcpPlan.pinHashes } : {},
|
|
78
83
|
},
|
|
79
84
|
};
|
|
80
85
|
}
|
|
@@ -130,10 +135,32 @@ async function writeDepsCache({ wizzDir, selectedAreas, cliPlan, mcpPlan, trackF
|
|
|
130
135
|
return { wrote: true, file, counts };
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Read the MCP pin hashes recorded by the LAST install (A13), if any. Used
|
|
140
|
+
* before the next `writeMcpConfig` call so it can tell an untouched block
|
|
141
|
+
* (safe to auto-update the pin) from a user-customized one. Never throws: a
|
|
142
|
+
* missing or corrupt cache (or a pre-A13 cache with no `mcps.pins` key) is
|
|
143
|
+
* simply "no history", which downstream treats the same as "customized" —
|
|
144
|
+
* the conservative, never-overwrite default.
|
|
145
|
+
* @param {string} wizzDir - Installed `_wizz` directory
|
|
146
|
+
* @returns {Promise<Record<string,string>>} Map of mcp id => sha256 hash
|
|
147
|
+
*/
|
|
148
|
+
async function readPreviousMcpPins(wizzDir) {
|
|
149
|
+
const file = path.join(wizzDir, '_config', CACHE_BASENAME);
|
|
150
|
+
if (!(await fs.pathExists(file))) return {};
|
|
151
|
+
try {
|
|
152
|
+
const cache = JSON.parse(await fs.readFile(file, 'utf8'));
|
|
153
|
+
return (cache && cache.mcps && cache.mcps.pins && typeof cache.mcps.pins === 'object' && cache.mcps.pins) || {};
|
|
154
|
+
} catch {
|
|
155
|
+
return {};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
133
159
|
module.exports = {
|
|
134
160
|
buildDepsCache,
|
|
135
161
|
isEmptyDepsCache,
|
|
136
162
|
writeDepsCache,
|
|
163
|
+
readPreviousMcpPins,
|
|
137
164
|
shapeCli,
|
|
138
165
|
shapeMcp,
|
|
139
166
|
CACHE_BASENAME,
|