wizz-method 1.16.1 → 1.17.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/package.json +4 -2
- package/removals.txt +6 -0
- package/skills-registry.yaml +55 -24
- package/src/bmm-skills/3-solutioning/wizz-generate-project-context/project-context-template.md +5 -0
- package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-01-discover.md +16 -5
- package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-03-complete.md +5 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/customize.toml +3 -1
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/__pycache__/sprint_status.cpython-313.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/customize.toml +3 -1
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/__pycache__/sprint_plan.cpython-313.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-advanced-elicitation/scripts/__pycache__/pick_methods.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-advanced-elicitation/scripts/tests/__pycache__/test_pick_methods.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/__pycache__/brain.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/__pycache__/resolve_personas.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/tests/__pycache__/test_resolve_personas.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/__pycache__/resolve_party.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/tests/__pycache__/test_resolve_party.cpython-314.pyc +0 -0
- package/src/modules/wizz/_shared/encerramento.md +22 -0
- package/src/modules/wizz/agents/wizz-designer/SKILL.md +1 -1
- package/src/modules/wizz/agents/wizz-maestro/SKILL.md +4 -0
- package/src/modules/wizz/agents/wizz-qa/SKILL.md +6 -0
- package/src/modules/wizz/agents/wizz-social/SKILL.md +1 -0
- package/src/modules/wizz/subagents/codex/wizz-exec-haiku.toml +12 -0
- package/src/modules/wizz/subagents/codex/wizz-exec-opus.toml +12 -0
- package/src/modules/wizz/subagents/codex/wizz-exec-review.toml +11 -0
- package/src/modules/wizz/subagents/codex/wizz-exec-sonnet.toml +12 -0
- package/src/modules/wizz/subagents/gemini/wizz-exec-haiku.md +12 -0
- package/src/modules/wizz/subagents/gemini/wizz-exec-opus.md +12 -0
- package/src/modules/wizz/subagents/gemini/wizz-exec-review.md +11 -0
- package/src/modules/wizz/subagents/gemini/wizz-exec-sonnet.md +12 -0
- package/src/modules/wizz/subagents/opencode/wizz-exec-haiku.md +12 -0
- package/src/modules/wizz/subagents/opencode/wizz-exec-opus.md +12 -0
- package/src/modules/wizz/subagents/opencode/wizz-exec-review.md +11 -0
- package/src/modules/wizz/subagents/opencode/wizz-exec-sonnet.md +12 -0
- package/src/modules/wizz/subagents/wizz-exec-haiku.md +12 -0
- package/src/modules/wizz/subagents/wizz-exec-opus.md +12 -0
- package/src/modules/wizz/subagents/wizz-exec-review.md +11 -0
- package/src/modules/wizz/subagents/wizz-exec-sonnet.md +12 -0
- package/src/skills-lib/launch-readiness/SKILL.md +94 -0
- package/src/skills-lib/launch-readiness/references/01-tecnico-build.md +26 -0
- package/src/skills-lib/launch-readiness/references/02-seguranca.md +26 -0
- package/src/skills-lib/launch-readiness/references/03-seo-descoberta.md +27 -0
- package/src/skills-lib/launch-readiness/references/04-analytics-medicao.md +25 -0
- package/src/skills-lib/launch-readiness/references/05-conteudo-prova-social.md +25 -0
- package/src/skills-lib/launch-readiness/references/06-legal-lgpd.md +25 -0
- package/src/skills-lib/launch-readiness/references/07-infra-deploy-rollback.md +26 -0
- package/src/skills-lib/launch-readiness/references/08-fusao-priorizacao.md +33 -0
- package/src/skills-lib/launch-readiness/references/09-persistencia-project-context.md +48 -0
- package/src/skills-lib/site-launch-kit/SKILL.md +1 -1
- package/src/skills-lib/taste-skill/SKILL.md +4 -2
- package/src/skills-lib/{taste-redesign → taste-skill}/references/design-audit.md +30 -41
- package/src/skills-lib/taste-skill/references/redesign-protocol.md +2 -2
- package/src/skills-lib/taste-skill/references/upgrade-techniques.md +33 -0
- package/src/skills-lib/wizz-offer-forge/SKILL.md +3 -2
- package/src/skills-lib/wizz-router/SKILL.md +7 -1
- package/src/skills-lib/wizz-router/references/routing-table-flat.md +3 -2
- package/tools/fetch-assets.mjs +3 -2
- package/tools/installer/commands/trace-report.js +248 -4
- package/tools/installer/modules/official-modules.js +5 -0
- package/wizz-modules.yaml +3 -3
- package/src/skills-lib/taste-redesign/SKILL.md +0 -42
- package/src/skills-lib/taste-redesign/references/upgrade-techniques.md +0 -31
|
@@ -1,74 +1,64 @@
|
|
|
1
|
-
|
|
1
|
+
> taste-skill reference file. Loaded on demand from the SKILL.md index.
|
|
2
|
+
> Cross-references like "Section N" map to sibling files via the index table in ../SKILL.md.
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
## 11.G REDESIGN AUDIT CHECKLIST (detail)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Full checklist for the Audit Before Touching step (Section 11.B). Scan the project against every category below and list every match found, feeding the "Patterns to retire" list in 11.B. Where a finding is already governed by an always-on directive elsewhere in this skill, the item below points to that section instead of repeating the fix, so there is one source of truth for the actual rule.
|
|
6
7
|
|
|
7
8
|
### Typography
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- **Browser default fonts or Inter everywhere.** Replace with a font that has character. Good options: `Geist`, `Outfit`, `Cabinet Grotesk`, `Satoshi`. For editorial/creative projects, pair a serif header with a sans-serif body.
|
|
10
|
+
- **Browser default fonts or Inter everywhere.** Replace per the approved font list and pairings in Section 4.1.
|
|
12
11
|
- **Headlines lack presence.** Increase size for display text, tighten letter-spacing, reduce line-height. Headlines should feel heavy and intentional.
|
|
13
|
-
- **Body text too wide.**
|
|
12
|
+
- **Body text too wide.** Cap paragraph width per Section 4.1 (`max-w-[65ch]`) and increase line-height for readability.
|
|
14
13
|
- **Only Regular (400) and Bold (700) weights used.** Introduce Medium (500) and SemiBold (600) for more subtle hierarchy.
|
|
15
14
|
- **Numbers in proportional font.** Use a monospace font or enable tabular figures (`font-variant-numeric: tabular-nums`) for data-heavy interfaces.
|
|
16
15
|
- **Missing letter-spacing adjustments.** Use negative tracking for large headers, positive tracking for small caps or labels.
|
|
17
|
-
- **All-caps subheaders everywhere.** Try lowercase italics, sentence case, or small-caps instead.
|
|
16
|
+
- **All-caps subheaders everywhere.** Try lowercase italics, sentence case, or small-caps instead. (Distinct from the eyebrow-frequency rule in Section 4.7: this is about styling, that is about how often an eyebrow appears at all.)
|
|
18
17
|
- **Orphaned words.** Single words sitting alone on the last line. Fix with `text-wrap: balance` or `text-wrap: pretty`.
|
|
19
18
|
|
|
20
19
|
### Color and Surfaces
|
|
21
20
|
|
|
22
|
-
- **Pure `#000000` background
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **Purple/blue "AI gradient" aesthetic.** This is the most common AI design fingerprint. Replace with neutral bases and a single, considered accent.
|
|
27
|
-
- **Generic `box-shadow`.** Tint shadows to match the background hue. Use colored shadows (e.g., dark blue shadow on a blue background) instead of pure black at low opacity.
|
|
28
|
-
- **Flat design with zero texture.** Add subtle noise, grain, or micro-patterns to backgrounds. Pure flat vectors feel sterile.
|
|
21
|
+
- **Pure `#000000` background or oversaturated / multi-accent colors.** Governed by the Lila Rule and saturation cap in Section 4.2, and the Section 9.A bans. Flag any instance found on the existing site.
|
|
22
|
+
- **Mixing warm and cool grays.** Governed by Section 4.2 ("one palette per project"). Flag any inconsistency found.
|
|
23
|
+
- **Generic `box-shadow`.** Governed by Section 4.4 (tint shadows to the background hue). Flag any pure-black, untinted shadow found.
|
|
24
|
+
- **Flat design with zero texture.** Add subtle noise, grain, or micro-patterns to backgrounds to break digital flatness. Apply per the DOM-cost rule in Section 6.E (fixed, `pointer-events-none` layer only, never on scrolling containers).
|
|
29
25
|
- **Perfectly even gradients.** Break the uniformity with radial gradients, noise overlays, or mesh gradients instead of standard linear 45-degree fades.
|
|
30
26
|
- **Inconsistent lighting direction.** Audit all shadows to ensure they suggest a single, consistent light source.
|
|
31
|
-
- **Random dark
|
|
32
|
-
- **Empty, flat sections with no visual depth.** Sections that are just text on a plain background feel unfinished. Add
|
|
27
|
+
- **Random dark section in an otherwise light page (or vice versa).** Governed by the Page Theme Lock in Section 4.11. Flag it as a redesign finding; fix by committing to one theme for the whole page.
|
|
28
|
+
- **Empty, flat sections with no visual depth.** Sections that are just text on a plain background feel unfinished. Add background imagery, a pattern, or an ambient gradient, sourced per the priority order in Section 4.8.
|
|
33
29
|
|
|
34
30
|
### Layout
|
|
35
31
|
|
|
36
|
-
- **Everything centered and symmetrical.**
|
|
37
|
-
- **Three equal card columns as feature row.**
|
|
38
|
-
- **Using `height: 100vh` for full-screen sections.** Replace with `min-height: 100dvh` to prevent layout jumping on mobile browsers (iOS Safari viewport bug).
|
|
32
|
+
- **Everything centered and symmetrical.** Governed by the anti-center-bias rule in Section 4.3. Flag it as a finding on redesigns; the override there still applies for editorial/manifesto briefs.
|
|
33
|
+
- **Three equal card columns as a feature row.** Banned outright per Section 9.C. Replace with a 2-column zig-zag, asymmetric grid, or horizontal scroll.
|
|
34
|
+
- **Using `height: 100vh` for full-screen sections.** Replace with `min-height: 100dvh` to prevent layout jumping on mobile browsers (iOS Safari viewport bug). See the viewport-stability check in the pre-flight matrix (Section 14).
|
|
39
35
|
- **Complex flexbox percentage math.** Replace with CSS Grid for reliable multi-column structures.
|
|
40
|
-
- **No max-width container.** Add a container constraint (around 1200-1440px) with auto margins so content
|
|
36
|
+
- **No max-width container.** Add a container constraint (around 1200-1440px) with auto margins so content does not stretch edge-to-edge on wide screens.
|
|
41
37
|
- **Cards of equal height forced by flexbox.** Allow variable heights or use masonry when content varies in length.
|
|
42
|
-
- **Uniform border-radius on everything.**
|
|
38
|
+
- **Uniform border-radius on everything, with no documented rule.** Section 4.4's Shape Consistency Lock allows variation only when there is a documented rule (e.g. "buttons full-pill, cards 16px, inputs 8px") followed everywhere. An existing site with radius applied at random, with no rule at all, is the audit finding here.
|
|
43
39
|
- **No overlap or depth.** Elements sit flat next to each other. Use negative margins to create layering and visual depth.
|
|
44
|
-
- **Symmetrical vertical padding.** Top and bottom padding are always identical. Adjust optically
|
|
40
|
+
- **Symmetrical vertical padding.** Top and bottom padding are always identical. Adjust optically; bottom padding often needs to be slightly larger.
|
|
45
41
|
- **Dashboard always has a left sidebar.** Try top navigation, a floating command menu, or a collapsible panel instead.
|
|
46
42
|
- **Missing whitespace.** Double the spacing. Let the design breathe. Dense layouts work for data dashboards, not for marketing pages.
|
|
47
43
|
- **Buttons not bottom-aligned in card groups.** When cards have different content lengths, CTAs end up at random heights. Pin buttons to the bottom of each card so they form a clean horizontal line regardless of content above.
|
|
48
44
|
- **Feature lists starting at different vertical positions.** In pricing tables or comparison cards, the list of features should start at the same Y position across all columns. Use consistent spacing above the list or fixed-height title/price blocks.
|
|
49
45
|
- **Inconsistent vertical rhythm in side-by-side elements.** When placing cards, columns, or panels next to each other, align shared elements (titles, descriptions, prices, buttons) across all items. Misaligned baselines make the layout look broken.
|
|
50
|
-
- **Mathematical alignment that looks optically wrong.** Centering by the math
|
|
46
|
+
- **Mathematical alignment that looks optically wrong.** Centering by the math does not always look centered to the eye. Icons next to text, play buttons in circles, or text in buttons often need 1-2px optical adjustments to feel right.
|
|
51
47
|
|
|
52
48
|
### Interactivity and States
|
|
53
49
|
|
|
54
|
-
- **No hover states
|
|
55
|
-
- **No
|
|
50
|
+
- **No hover states, no active/pressed feedback, no loading or empty states.** Governed by Section 4.5 (Interactive UI States: skeletal loaders, composed empty states, `-translate-y-[1px]` / `scale-[0.98]` on press). Flag every missing state found on the existing site as a redesign fix.
|
|
51
|
+
- **No error states, or errors handled with `window.alert()`.** Add clear, inline error messages for forms per Section 4.5. `window.alert()` specifically is banned; it is a jarring, unstyled browser dialog.
|
|
56
52
|
- **Instant transitions with zero duration.** Add smooth transitions (200-300ms) to all interactive elements.
|
|
57
53
|
- **Missing focus ring.** Ensure visible focus indicators for keyboard navigation. This is an accessibility requirement, not optional.
|
|
58
|
-
- **No loading states.** Replace generic circular spinners with skeleton loaders that match the layout shape.
|
|
59
|
-
- **No empty states.** An empty dashboard showing nothing is a missed opportunity. Design a composed "getting started" view.
|
|
60
|
-
- **No error states.** Add clear, inline error messages for forms. Do not use `window.alert()`.
|
|
61
54
|
- **Dead links.** Buttons that link to `#`. Either link to real destinations or visually disable them.
|
|
62
55
|
- **No indication of current page in navigation.** Style the active nav link differently so users know where they are.
|
|
63
56
|
- **Scroll jumping.** Anchor clicks jump instantly. Add `scroll-behavior: smooth`.
|
|
64
|
-
- **Animations using `top`, `left`, `width`, `height`.**
|
|
57
|
+
- **Animations using `top`, `left`, `width`, `height`.** Governed by Section 6.A: animate only `transform` and `opacity`.
|
|
65
58
|
|
|
66
59
|
### Content
|
|
67
60
|
|
|
68
|
-
- **Generic names
|
|
69
|
-
- **Fake round numbers like `99.99%`, `50%`, `$100.00`.** Use organic, messy data: `47.2%`, `$99.00`, `+1 (312) 847-1928`.
|
|
70
|
-
- **Placeholder company names like "Acme Corp", "Nexus", "SmartFlow".** Invent contextual, believable brand names.
|
|
71
|
-
- **AI copywriting cliches.** Never use "Elevate", "Seamless", "Unleash", "Next-Gen", "Game-changer", "Delve", "Tapestry", or "In the world of...". Write plain, specific language.
|
|
61
|
+
- **Generic names, fake-perfect numbers, placeholder brand names, AI copywriting cliches.** Governed by Section 9.D. Flag every instance found on the existing site; do not repeat the banned-word list here, see that section.
|
|
72
62
|
- **Exclamation marks in success messages.** Remove them. Be confident, not loud.
|
|
73
63
|
- **"Oops!" error messages.** Be direct: "Connection failed. Please try again."
|
|
74
64
|
- **Passive voice.** Use active voice: "We couldn't save your changes" instead of "Mistakes were made."
|
|
@@ -79,20 +69,20 @@ Check for these problems and fix them:
|
|
|
79
69
|
|
|
80
70
|
### Component Patterns
|
|
81
71
|
|
|
82
|
-
- **Generic card look (border + shadow + white background)
|
|
72
|
+
- **Generic card look (border + shadow + white background) with no elevation purpose.** Governed by Section 4.4: use cards only when elevation communicates hierarchy.
|
|
83
73
|
- **Always one filled button + one ghost button.** Add text links or tertiary styles to reduce visual noise.
|
|
84
74
|
- **Pill-shaped "New" and "Beta" badges.** Try square badges, flags, or plain text labels.
|
|
85
75
|
- **Accordion FAQ sections.** Use a side-by-side list, searchable help, or inline progressive disclosure.
|
|
86
|
-
- **3-card carousel testimonials with dots.** Replace with a masonry wall, embedded social posts, or a single rotating quote.
|
|
76
|
+
- **3-card carousel testimonials with dots.** Replace with a masonry wall, embedded social posts, or a single rotating quote. See Section 4.10 for quote length and attribution rules once the format is fixed.
|
|
87
77
|
- **Pricing table with 3 towers.** Highlight the recommended tier with color and emphasis, not just extra height.
|
|
88
78
|
- **Modals for everything.** Use inline editing, slide-over panels, or expandable sections instead of popups for simple actions.
|
|
89
79
|
- **Avatar circles exclusively.** Try squircles or rounded squares for a less generic look.
|
|
90
|
-
- **Light/dark toggle always a sun/moon switch.** Use a dropdown, system preference detection, or integrate it into settings.
|
|
80
|
+
- **Light/dark toggle always a sun/moon switch.** Use a dropdown, system preference detection, or integrate it into settings. See Section 8.C for when a manual toggle is warranted at all.
|
|
91
81
|
- **Footer link farm with 4 columns.** Simplify. Focus on main navigational paths and legally required links.
|
|
92
82
|
|
|
93
83
|
### Iconography
|
|
94
84
|
|
|
95
|
-
- **Lucide or Feather icons exclusively.**
|
|
85
|
+
- **Lucide or Feather icons exclusively.** Governed by Section 9.E: use Phosphor, HugeIcons, Radix, or Tabler instead.
|
|
96
86
|
- **Rocketship for "Launch", shield for "Security".** Replace cliche metaphors with less obvious icons (bolt, fingerprint, spark, vault).
|
|
97
87
|
- **Inconsistent stroke widths across icons.** Audit all icons and standardize to one stroke weight.
|
|
98
88
|
- **Missing favicon.** Always include a branded favicon.
|
|
@@ -104,12 +94,12 @@ Check for these problems and fix them:
|
|
|
104
94
|
- **Inline styles mixed with CSS classes.** Move all styling to the project's styling system.
|
|
105
95
|
- **Hardcoded pixel widths.** Use relative units (`%`, `rem`, `em`, `max-width`) for flexible layouts.
|
|
106
96
|
- **Missing alt text on images.** Describe image content for screen readers. Never leave `alt=""` or `alt="image"` on meaningful images.
|
|
107
|
-
- **Arbitrary z-index values like `9999`.**
|
|
97
|
+
- **Arbitrary z-index values like `9999`.** Governed by Section 6.F: establish a documented z-index scale instead.
|
|
108
98
|
- **Commented-out dead code.** Remove all debug artifacts before shipping.
|
|
109
99
|
- **Import hallucinations.** Check that every import actually exists in `package.json` or the project dependencies.
|
|
110
100
|
- **Missing meta tags.** Add proper `<title>`, `description`, `og:image`, and social sharing meta tags.
|
|
111
101
|
|
|
112
|
-
### Strategic Omissions (
|
|
102
|
+
### Strategic Omissions (what AI typically forgets)
|
|
113
103
|
|
|
114
104
|
- **No legal links.** Add privacy policy and terms of service links in the footer.
|
|
115
105
|
- **No "back" navigation.** Dead ends in user flows. Every page needs a way back.
|
|
@@ -117,4 +107,3 @@ Check for these problems and fix them:
|
|
|
117
107
|
- **No form validation.** Add client-side validation for emails, required fields, and format checks.
|
|
118
108
|
- **No "skip to content" link.** Essential for keyboard users. Add a hidden skip-link.
|
|
119
109
|
- **No cookie consent.** If required by jurisdiction, add a compliant consent banner.
|
|
120
|
-
|
|
@@ -18,7 +18,7 @@ Document the current state before proposing changes:
|
|
|
18
18
|
* **Information architecture** - page tree, primary nav, key conversion paths.
|
|
19
19
|
* **Content blocks** - what exists, what's doing work, what's filler.
|
|
20
20
|
* **Patterns to preserve** - signature interactions, recognisable hero, copy voice.
|
|
21
|
-
* **Patterns to retire** - AI-slop tells, broken layouts, dead links, generic stock imagery, perf traps.
|
|
21
|
+
* **Patterns to retire** - AI-slop tells, broken layouts, dead links, generic stock imagery, perf traps. Run the full checklist in [design-audit.md](design-audit.md) (Section 11.G) against the project and list every match here.
|
|
22
22
|
* **Dial reading of the existing site** - infer current `DESIGN_VARIANCE` / `MOTION_INTENSITY` / `VISUAL_DENSITY`. That's your starting point, not the baseline.
|
|
23
23
|
* **SEO baseline** - current ranking pages, meta titles, structured data, OG cards. **SEO migration is the #1 redesign risk.**
|
|
24
24
|
|
|
@@ -30,7 +30,7 @@ Document the current state before proposing changes:
|
|
|
30
30
|
* **Respect existing analytics events.** Do not rename buttons, form fields, section IDs that downstream tracking depends on.
|
|
31
31
|
|
|
32
32
|
### 11.D Modernisation Levers (priority order)
|
|
33
|
-
Apply in order - stop when the brief is satisfied
|
|
33
|
+
Apply in order - stop when the brief is satisfied. Concrete techniques for each lever live in [upgrade-techniques.md](upgrade-techniques.md) (Section 11.H).
|
|
34
34
|
1. **Typography refresh** - biggest visual lift per unit of risk.
|
|
35
35
|
2. **Spacing & rhythm** - increase section padding, fix vertical rhythm.
|
|
36
36
|
3. **Color recalibration** - desaturate, unify neutrals, keep brand accent.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
> taste-skill reference file. Loaded on demand from the SKILL.md index.
|
|
2
|
+
> Cross-references like "Section N" map to sibling files via the index table in ../SKILL.md.
|
|
3
|
+
|
|
4
|
+
## 11.H MODERNISATION TECHNIQUES (detail)
|
|
5
|
+
|
|
6
|
+
High-impact techniques for the Modernisation Levers in Section 11.D, once the audit checklist (Section 11.G) has identified which categories need work. Grouped by Typography, Layout, and Motion/Surface. Where a technique already has a canonical skeleton or named pattern elsewhere in this skill, this file points there instead of restating it, so there is one implementation to maintain.
|
|
7
|
+
|
|
8
|
+
### Typography Upgrades
|
|
9
|
+
|
|
10
|
+
- **Variable font animation.** Interpolate weight or width on scroll or hover for text that feels alive.
|
|
11
|
+
- **Outlined-to-fill transitions.** Text starts as a stroke outline and fills with color on scroll entry or interaction. Named pattern: "Gradient Stroke Animation" in Section 10.
|
|
12
|
+
- **Text mask reveals.** Large typography acting as a window to video or animated imagery behind it. Named pattern: "Text Mask Reveal" in Section 10; use that vocabulary entry when scoping the work.
|
|
13
|
+
|
|
14
|
+
### Layout Upgrades
|
|
15
|
+
|
|
16
|
+
- **Broken grid / asymmetry.** Elements that deliberately ignore column structure: overlapping, bleeding off-screen, or offset with calculated randomness. Reach for this beyond the baseline anti-center-bias rule in Section 4.3 when the brief wants a stronger break from the grid.
|
|
17
|
+
- **Whitespace maximization.** Aggressive use of negative space to force focus on a single element.
|
|
18
|
+
- **Parallax card stacks.** Sections that stick and physically stack over each other during scroll. Implement with the canonical Sticky-Stack skeleton in Section 5.A; named pattern "Sticky Scroll Stack" in Section 10.
|
|
19
|
+
- **Split-screen scroll.** Two halves of the screen sliding in opposite directions. Named pattern "Split-Screen Scroll" in Section 10.
|
|
20
|
+
|
|
21
|
+
### Motion Upgrades
|
|
22
|
+
|
|
23
|
+
- **Smooth scroll with inertia.** Decouple scrolling from browser defaults for a heavier, cinematic feel.
|
|
24
|
+
- **Staggered entry.** Elements cascade in with slight delays, combining Y-axis translation with opacity fade. Never mount everything at once. Implement with the Scroll-Reveal Stagger skeleton in Section 5.C, or `staggerChildren` per Section 5.D.
|
|
25
|
+
- **Spring physics.** Replace linear easing with spring-based motion for a natural, weighty feel on all interactive elements. Parameters and when to use them: Section 5 (Perpetual Micro-Interactions).
|
|
26
|
+
- **Scroll-driven reveals.** Content entering through expanding masks, wipes, or draw-on SVG paths tied to scroll progress. Distinct from the simple enter-on-scroll stagger in Section 5.C: this is for a deliberate reveal choreography, not a generic list-item fade-in.
|
|
27
|
+
|
|
28
|
+
### Surface Upgrades
|
|
29
|
+
|
|
30
|
+
- **True glassmorphism.** Go beyond `backdrop-filter: blur`. Full technique (1px inner border, inset shadow, reduced-transparency fallback) and the honest Apple Liquid Glass distinction live in Section 5 (Liquid Glass / Glassmorphism) and design-systems.md Appendix C.
|
|
31
|
+
- **Spotlight borders.** Card borders that illuminate dynamically under the cursor. Named pattern "Spotlight Border Card" in Section 10.
|
|
32
|
+
- **Grain and noise overlays.** A fixed, `pointer-events-none` overlay with subtle noise to break digital flatness. Apply per the DOM-cost rule in Section 6.E: fixed layer only, never on a scrolling container.
|
|
33
|
+
- **Colored, tinted shadows.** Shadows that carry the hue of the background rather than using generic black. Full rule in Section 4.4.
|
|
@@ -49,8 +49,9 @@ Formule a Promessa Primária em 1 frase de alto impacto:
|
|
|
49
49
|
Consulte `references/empilhamento-valor.md`:
|
|
50
50
|
- **Produto Principal:** O caminho mais rápido e direto ao resultado.
|
|
51
51
|
- **Bônus 1 (Velocidade):** Templates, atalhos, checklists prontos que encurtam a execução.
|
|
52
|
-
- **Bônus 2 (
|
|
53
|
-
- **Bônus 3 (
|
|
52
|
+
- **Bônus 2 (Quebra de Objeção):** Elimina a maior desculpa para não comprar.
|
|
53
|
+
- **Bônus 3 (Blindagem / Segurança):** Como evitar o erro mais comum ou o que fazer em caso de imprevisto.
|
|
54
|
+
- **Bônus 4 (Próximo Nível):** O que fazer depois de atingir o primeiro marco.
|
|
54
55
|
- **Order Bump Estratégico:** Complemento impulsivo de alta margem (30-50% de take rate).
|
|
55
56
|
|
|
56
57
|
### Passo 4 — Ancoragem de Preço & Garantia Reversa
|
|
@@ -10,7 +10,7 @@ description: "OBRIGATÓRIO: invoque ANTES de agir em qualquer pedido não-trivia
|
|
|
10
10
|
|
|
11
11
|
Invoque esta skill ANTES de agir em pedidos não-triviais (feature, bug, design, marketing, SEO, infra, refactor, audit, review, integração, configuração — amplo OU específico).
|
|
12
12
|
|
|
13
|
-
**Exceção única:** edições de 1 linha (typo, rename) e conversa pura.
|
|
13
|
+
**Exceção única:** edições de 1 linha (typo, rename) e conversa pura. **Critério objetivo (TRIVIALITY GATE):** pedido que toca ≤1 arquivo, ~≤10 linhas, sem comportamento novo, mudança de tipo conhecido → executa direto, sem acionar router/maestro.
|
|
14
14
|
|
|
15
15
|
**Fora do Plan Mode:** liste candidatas via `AskUserQuestion` e aguarde confirmação ANTES de disparar. Nunca auto-dispare fora do Plan Mode.
|
|
16
16
|
**Dentro do Plan Mode:** auto-dispare todas as relevantes para enriquecer o plano.
|
|
@@ -24,6 +24,8 @@ Você é o **Diretor / porta de entrada** — não o orquestrador (esse é o `wi
|
|
|
24
24
|
|
|
25
25
|
## Triagem e delegação (o coração do Diretor)
|
|
26
26
|
|
|
27
|
+
**Estágio do projeto (fail-open):** `grep -m1 '^stage:' {project-root}/**/project-context.md` (ex: `_wizz-output/project-context.md`, path configurável via `output_folder`). Se achar `prototype`/`mvp`, prefira solução leve e não recomende observabilidade/infra de produção; `production`, gates de qualidade valem integralmente. Sem arquivo: siga sem mencionar estágio.
|
|
28
|
+
|
|
27
29
|
Descubra o contexto: **existe `{project-root}/_wizz/`?**
|
|
28
30
|
|
|
29
31
|
### A) Dentro de projeto Wizz — você DELEGA, nunca executa
|
|
@@ -42,6 +44,8 @@ Avalie a **Área**: quantas áreas o pedido toca (design, dev, copy, seo, growth
|
|
|
42
44
|
|
|
43
45
|
> Um agente de área só cobre a área dele. 2+ áreas exigem coordenação = trabalho do maestro; a cláusula de área decide sozinha, sem somar com mais nada.
|
|
44
46
|
|
|
47
|
+
**Descoberta de capacidade (índice, não atalho de delegação):** a [tabela de roteamento flat](references/routing-table-flat.md) também pode ser consultada aqui, dentro de projeto Wizz, quando o pedido não nomeia a capacidade certa (ex.: "quero um carrossel" → índice aponta `canvas-design`). Ela só serve pra achar o nome da capacidade; a entrega continua pelo dispatch normal acima (agente da área / maestro) — nunca dispare a skill direto a partir da tabela dentro de projeto Wizz.
|
|
48
|
+
|
|
45
49
|
**Exemplos calibrados de borda** (do dataset de evals, `evals/routing/dataset.json`):
|
|
46
50
|
|
|
47
51
|
- *Trivial → direto (sem router):* `t07` ("trocar 'envie' por 'enviar' na linha 42"): edição de 1 linha.
|
|
@@ -55,6 +59,8 @@ Ao delegar (pro maestro ou pro agente de área), declare o brief no formato do [
|
|
|
55
59
|
|
|
56
60
|
Não há agentes wizz nem maestro. Você é a porta de descoberta global. Fluxo: analise a intenção (pode ter várias dimensões) → mapeie candidatas pela **[tabela de roteamento](references/routing-table-flat.md)** → fora do Plan Mode, apresente via `AskUserQuestion` e confirme → dispare as aprovadas via `Skill` (em paralelo quando independentes). Se nada cobrir, use o protocolo de **skill/MCP faltante** (no fim da mesma tabela).
|
|
57
61
|
|
|
62
|
+
**Ao encerrar o modo flat**, emita 1 linha máquina-legível de decision-trace — telemetria de decisão coletada por hook — no formato exato: `🧭 {"rota":"flat:<skill>","sel":["id",...],"desc":[["id_descartado","motivo≤6 palavras"]],"gate":"n/a","repetiria":true}`
|
|
63
|
+
|
|
58
64
|
## Modo Auditoria 360°
|
|
59
65
|
|
|
60
66
|
Ao detectar "auditoria completa / revisa tudo / 360 / análise geral", siga **[references/auditoria-360.md](references/auditoria-360.md)**.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tabela de Roteamento — Modo Flat
|
|
2
2
|
|
|
3
|
-
Use esta tabela **
|
|
3
|
+
Use esta tabela pra mapear skills/CLIs/MCPs direto **fora de projeto Wizz** (sem `_wizz/`) — aí o router dispara a skill sozinho. **Dentro de projeto Wizz** ela também pode ser consultada como ÍNDICE DE CAPACIDADES, pra descobrir uma capacidade relevante que o usuário não nomeou (ex.: "quero um carrossel" → `canvas-design`); mas a delegação continua sendo feita pelo dispatch normal do SKILL.md (agente da área / maestro) — a tabela nunca dispara a skill direto dentro de projeto Wizz.
|
|
4
4
|
|
|
5
5
|
**Verificação de existência:** antes de oferecer qualquer skill, confirme que ela existe no ambiente (catálogo de skills da sessão ou `ls ~/.claude/skills`); se não existir, não ofereça: use o protocolo de skill faltante (`find-skills`).
|
|
6
6
|
|
|
@@ -16,6 +16,7 @@ Use esta tabela **só fora de projeto Wizz** (sem `_wizz/`), quando o router map
|
|
|
16
16
|
| Dependências, packages, vulnerabilidades, npm audit | `database-and-deps` | 2 |
|
|
17
17
|
| Segurança, XSS, CSRF, SQLi, IDOR, OWASP, rate limit, CORS, clickjacking, PII na resposta, enumeração de usuário, headers | `web-security` + `auth-and-secrets` | 1 |
|
|
18
18
|
| Auditoria/pentest de segurança do app inteiro, "auditar segurança", "pentest", "encontrar vulnerabilidades", varredura antes de release | `security-audit-pentest` | 1 |
|
|
19
|
+
| Auditoria de prontidão pra lançamento, "tá pronto pra lançar?", checklist de release amplo (técnico, segurança, SEO, analytics, conteúdo, legal, infra), "o que falta antes de ir pra produção" | `launch-readiness` | 1 |
|
|
19
20
|
| Desktop, Electron, contextIsolation, code signing | `desktop-security` | 2 |
|
|
20
21
|
|
|
21
22
|
## Área Técnica — Código e Qualidade
|
|
@@ -77,7 +78,7 @@ Use esta tabela **só fora de projeto Wizz** (sem `_wizz/`), quando o router map
|
|
|
77
78
|
| Copywriting, copy, persuasão, texto de venda | `copywriting` + `humanizer` | 1 |
|
|
78
79
|
| Pesquisa de público de oferta, VoC, matriz de ângulos, léxico de infoproduto | `pesquisa-de-publico-do-piva` | 1 |
|
|
79
80
|
| Forjar oferta, criar oferta irresistível, mecanismo único, bônus, garantia | `wizz-offer-forge` + `pricing-strategy` | 1 |
|
|
80
|
-
| Pesquisa de mercado, inteligência competitiva | `deep-research` | 2 |
|
|
81
|
+
| Pesquisa de mercado, inteligência competitiva | `deep-research` (plugin externo — só se instalado) | 2 |
|
|
81
82
|
|
|
82
83
|
## Contexto e Memória
|
|
83
84
|
|
package/tools/fetch-assets.mjs
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
// Por que existe: `huashu-design/assets/**/*.mp3` (~30MB) e
|
|
5
5
|
// `canvas-design/canvas-fonts/**/*.ttf` (~5.5MB) inflavam o pacote npm em
|
|
6
6
|
// ~73%, mas só são necessários no primeiro uso real de export de vídeo
|
|
7
|
-
// (BGM/SFX) ou de uma variante de fonte específica.
|
|
8
|
-
//
|
|
7
|
+
// (BGM/SFX) ou de uma variante de fonte específica. Fonte de verdade dos BGM
|
|
8
|
+
// é o GitHub Release assets-v1 (fora do git e do tarball desde o P2 da
|
|
9
|
+
// auditoria 360°); os SFX pequenos e as fontes seguem no git. Este script baixa o
|
|
9
10
|
// bundle certo, no lugar certo, verificando sha256 (mesmo espírito do pin
|
|
10
11
|
// com checksum do rtk — nunca extrai um bundle adulterado).
|
|
11
12
|
//
|
|
@@ -11,13 +11,137 @@
|
|
|
11
11
|
|
|
12
12
|
const os = require('node:os');
|
|
13
13
|
const path = require('node:path');
|
|
14
|
+
const yaml = require('yaml');
|
|
14
15
|
const fs = require('../fs-native');
|
|
15
16
|
const prompts = require('../prompts');
|
|
17
|
+
const { getProjectRoot } = require('../project-root');
|
|
16
18
|
|
|
17
19
|
function getTraceFile() {
|
|
18
20
|
return process.env.WIZZ_TRACE_FILE || path.join(os.homedir(), '.claude', 'wizz-trace.jsonl');
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
// `--coverage` (P2 da auditoria 360°, "evals de descoberta"): cruza o
|
|
24
|
+
// catálogo de skills do skills-registry.yaml (fonte única, lido em runtime
|
|
25
|
+
// e nunca hardcoded aqui) contra os marcadores de decisão (`type:
|
|
26
|
+
// "decision"`, escritos por tools/hooks/wizz-decision-trace.js) já
|
|
27
|
+
// agregados no mesmo JSONL. Mede subutilização de roteamento: uma skill
|
|
28
|
+
// pode estar SELECIONADA (`sel`), DESCARTADA COM MOTIVO (`desc`, correto:
|
|
29
|
+
// foi considerada e explicitamente preterida) ou NUNCA CONSIDERADA (não
|
|
30
|
+
// aparece em nenhum dos dois arrays de nenhum trace): esta última é a
|
|
31
|
+
// falha de roteamento silenciosa que o item da auditoria pede pra medir.
|
|
32
|
+
function getRegistryFile() {
|
|
33
|
+
return path.join(getProjectRoot(), 'skills-registry.yaml');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Lê e parseia skills-registry.yaml, devolvendo o catálogo de ids de
|
|
37
|
+
// skills em ordem alfabética estável (mesma lista independente da ordem em
|
|
38
|
+
// que as áreas/skills aparecem no YAML). Escopo deliberado: só as skills
|
|
39
|
+
// `areas.*.skills[]` e as cross-cutting `utility[]` (graphify, find-skills,
|
|
40
|
+
// enhance-prompt, wizz-router; também são skills de verdade em
|
|
41
|
+
// src/skills-lib/). CLIs/MCPs/squads ficam de fora: `sel`/`desc` no
|
|
42
|
+
// marcador de decisão podem citar agentes ou skills (ver encerramento.md),
|
|
43
|
+
// mas este comando mede especificamente subutilização de SKILL, não de
|
|
44
|
+
// ferramenta/squad. Lança em vez de devolver `null` em erro: quem chama
|
|
45
|
+
// decide como reportar (fail-clear, não fail-silent: ao contrário do
|
|
46
|
+
// trace, o catálogo é a fonte de verdade e um erro aqui é um bug real).
|
|
47
|
+
function collectSkillCatalog(registryFile) {
|
|
48
|
+
const raw = fs.readFileSync(registryFile, 'utf8');
|
|
49
|
+
const registry = yaml.parse(raw);
|
|
50
|
+
const ids = new Set();
|
|
51
|
+
for (const area of Object.values(registry.areas || {})) {
|
|
52
|
+
for (const skill of area.skills || []) {
|
|
53
|
+
if (skill && typeof skill.id === 'string') ids.add(skill.id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const item of registry.utility || []) {
|
|
57
|
+
if (item && typeof item.id === 'string') ids.add(item.id);
|
|
58
|
+
}
|
|
59
|
+
return [...ids].sort();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Agrega os traces `type: "decision"` já parseados contra o catálogo.
|
|
63
|
+
// Função pura (mesmo espírito de `aggregate`/`aggregateLadder`), testável
|
|
64
|
+
// sem tocar em disco. `catalogIds` já deve vir ordenado (saída de
|
|
65
|
+
// `collectSkillCatalog`): a ordem de `neverConsidered` deriva dela, então
|
|
66
|
+
// a saída é estável entre execuções.
|
|
67
|
+
//
|
|
68
|
+
// Ids de `sel`/`desc` que não pertencem ao catálogo (ex.: agente
|
|
69
|
+
// "wizz-designer" em vez de skill) são ignorados aqui, não contados como
|
|
70
|
+
// erro: o marcador aceita os dois tipos (encerramento.md), este comando só
|
|
71
|
+
// mede a fatia de skills.
|
|
72
|
+
//
|
|
73
|
+
// Categorização mutuamente exclusiva por skill (soma sempre = catalogTotal):
|
|
74
|
+
// selecionada (apareceu em algum `sel`) > descartada-só (apareceu só em
|
|
75
|
+
// `desc`, nunca em `sel`) > nunca considerada (nenhum dos dois). Se uma
|
|
76
|
+
// skill foi selecionada numa decisão e descartada noutra, conta como
|
|
77
|
+
// selecionada: "foi de fato usada ao menos uma vez" pesa mais que "também
|
|
78
|
+
// foi preterida uma vez" para o proposito de subutilização.
|
|
79
|
+
function aggregateCoverage(entries, catalogIds) {
|
|
80
|
+
const catalogSet = new Set(catalogIds);
|
|
81
|
+
const selected = new Set();
|
|
82
|
+
const discarded = new Set();
|
|
83
|
+
let decisionCount = 0;
|
|
84
|
+
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
if (!entry || entry.type !== 'decision') continue;
|
|
87
|
+
const decision = entry.decision;
|
|
88
|
+
if (!decision || typeof decision !== 'object') continue;
|
|
89
|
+
decisionCount++;
|
|
90
|
+
|
|
91
|
+
if (Array.isArray(decision.sel)) {
|
|
92
|
+
for (const id of decision.sel) {
|
|
93
|
+
if (typeof id === 'string' && catalogSet.has(id)) selected.add(id);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(decision.desc)) {
|
|
97
|
+
for (const pair of decision.desc) {
|
|
98
|
+
if (Array.isArray(pair) && typeof pair[0] === 'string' && catalogSet.has(pair[0])) {
|
|
99
|
+
discarded.add(pair[0]);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const discardedOnly = [];
|
|
106
|
+
const neverConsidered = [];
|
|
107
|
+
for (const id of catalogIds) {
|
|
108
|
+
if (selected.has(id)) continue;
|
|
109
|
+
if (discarded.has(id)) discardedOnly.push(id);
|
|
110
|
+
else neverConsidered.push(id);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
catalogTotal: catalogIds.length,
|
|
115
|
+
decisionCount,
|
|
116
|
+
selectedCount: selected.size,
|
|
117
|
+
discardedOnlyCount: discardedOnly.length,
|
|
118
|
+
neverConsidered,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function formatCoverageSummary(stats, registryFile) {
|
|
123
|
+
const consideredCount = stats.catalogTotal - stats.neverConsidered.length;
|
|
124
|
+
const lines = [
|
|
125
|
+
`Catálogo: ${stats.catalogTotal} skills (${registryFile})`,
|
|
126
|
+
`Traces de decisão: ${stats.decisionCount}`,
|
|
127
|
+
`Selecionadas (sel): ${stats.selectedCount} (${pct(stats.selectedCount, stats.catalogTotal)})`,
|
|
128
|
+
`Descartadas c/ motivo: ${stats.discardedOnlyCount} (${pct(stats.discardedOnlyCount, stats.catalogTotal)})`,
|
|
129
|
+
`Nunca consideradas: ${stats.neverConsidered.length} (${pct(stats.neverConsidered.length, stats.catalogTotal)})`,
|
|
130
|
+
`Cobertura do catálogo: ${pct(consideredCount, stats.catalogTotal)}`,
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
if (stats.decisionCount === 0) {
|
|
134
|
+
lines.push('', '(nenhum trace de decisão encontrado; rode com WIZZ_TRACE=1 e feche pedidos roteados pra gerar dados)');
|
|
135
|
+
} else if (stats.neverConsidered.length === 0) {
|
|
136
|
+
lines.push('', 'Nunca consideradas: nenhuma, catálogo 100% coberto.');
|
|
137
|
+
} else {
|
|
138
|
+
lines.push('', 'Nunca consideradas:');
|
|
139
|
+
for (const id of stats.neverConsidered) lines.push(` ${id}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return lines.join('\n');
|
|
143
|
+
}
|
|
144
|
+
|
|
21
145
|
// Faz o parse de 1 linha JSONL. Retorna `null` (em vez de lançar) para
|
|
22
146
|
// linhas corrompidas — fail-open, mesmo espírito do resto do framework: o
|
|
23
147
|
// trace nunca pode quebrar quem o lê.
|
|
@@ -31,14 +155,24 @@ function parseLine(line) {
|
|
|
31
155
|
|
|
32
156
|
// Agrega as entradas já parseadas em contadores/período. Função pura, sem
|
|
33
157
|
// I/O, para ser testável isoladamente do disco.
|
|
158
|
+
//
|
|
159
|
+
// Linhas tipadas (`type: "decision"` do marcador 🧭 e `type: "ladder"` da
|
|
160
|
+
// escada de modelos, ambas escritas por tools/hooks/wizz-decision-trace.js)
|
|
161
|
+
// são IGNORADAS aqui: são outra granularidade de evento (o fecho de um
|
|
162
|
+
// pedido, não o roteamento em si) e contá-las junto de trivial/mode poluiria
|
|
163
|
+
// as contagens. `type: "ladder"` alimenta só `aggregateLadder`, abaixo.
|
|
34
164
|
function aggregate(entries) {
|
|
35
165
|
const byMode = { wizz: 0, flat: 0, null: 0 };
|
|
166
|
+
let total = 0;
|
|
36
167
|
let trivialCount = 0;
|
|
37
168
|
let warningsCount = 0;
|
|
38
169
|
let firstTs = null;
|
|
39
170
|
let lastTs = null;
|
|
40
171
|
|
|
41
172
|
for (const entry of entries) {
|
|
173
|
+
if (entry.type === 'decision' || entry.type === 'ladder') continue;
|
|
174
|
+
total++;
|
|
175
|
+
|
|
42
176
|
if (entry.isTrivial) {
|
|
43
177
|
trivialCount++;
|
|
44
178
|
} else {
|
|
@@ -54,9 +188,9 @@ function aggregate(entries) {
|
|
|
54
188
|
}
|
|
55
189
|
|
|
56
190
|
return {
|
|
57
|
-
total
|
|
191
|
+
total,
|
|
58
192
|
trivialCount,
|
|
59
|
-
routedCount:
|
|
193
|
+
routedCount: total - trivialCount,
|
|
60
194
|
byMode,
|
|
61
195
|
warningsCount,
|
|
62
196
|
firstTs,
|
|
@@ -64,6 +198,53 @@ function aggregate(entries) {
|
|
|
64
198
|
};
|
|
65
199
|
}
|
|
66
200
|
|
|
201
|
+
// Bucket de rota pra agregação da escada de modelos: agrupa qualquer
|
|
202
|
+
// "agent:*" (designer, copy, seo, etc.) numa única chave — o que importa
|
|
203
|
+
// pra aderência é "foi delegado a um agente de área", não qual área
|
|
204
|
+
// especificamente. `maestro` e `flat` ficam como buckets próprios; qualquer
|
|
205
|
+
// outro valor (ou ausência) cai em `outro`.
|
|
206
|
+
function ladderBucket(rota) {
|
|
207
|
+
if (typeof rota !== 'string' || rota.length === 0) return 'outro';
|
|
208
|
+
if (rota.startsWith('agent:')) return 'agent:*';
|
|
209
|
+
if (rota === 'maestro') return 'maestro';
|
|
210
|
+
if (rota === 'flat') return 'flat';
|
|
211
|
+
return 'outro';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Agrega as linhas `type: "ladder"` (uma por pedido roteado que fechou com
|
|
215
|
+
// marcador de decisão — ver wizz-decision-trace.js) em aderência à escada
|
|
216
|
+
// de modelos: quantos pedidos invocaram algum subagente wizz-exec-*,
|
|
217
|
+
// quebrado por rota. Função pura, mesmo espírito de `aggregate`.
|
|
218
|
+
function aggregateLadder(entries) {
|
|
219
|
+
const byRoute = {};
|
|
220
|
+
|
|
221
|
+
const bump = (bucket, invoked) => {
|
|
222
|
+
if (!byRoute[bucket]) byRoute[bucket] = { total: 0, withExec: 0 };
|
|
223
|
+
byRoute[bucket].total++;
|
|
224
|
+
if (invoked) byRoute[bucket].withExec++;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
let total = 0;
|
|
228
|
+
let withExec = 0;
|
|
229
|
+
|
|
230
|
+
for (const entry of entries) {
|
|
231
|
+
if (!entry || entry.type !== 'ladder') continue;
|
|
232
|
+
total++;
|
|
233
|
+
const invoked = Array.isArray(entry.execs) && entry.execs.length > 0;
|
|
234
|
+
if (invoked) withExec++;
|
|
235
|
+
bump(ladderBucket(entry.rota), invoked);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return { total, withExec, byRoute };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Percentual formatado, protegido contra divisão por zero (mostra "—" em
|
|
242
|
+
// vez de NaN%/Infinity% quando o denominador é 0).
|
|
243
|
+
function pct(part, total) {
|
|
244
|
+
if (!total) return '—';
|
|
245
|
+
return `${Math.round((part / total) * 100)}%`;
|
|
246
|
+
}
|
|
247
|
+
|
|
67
248
|
function formatSummary(stats, traceFile) {
|
|
68
249
|
const lines = [
|
|
69
250
|
`Arquivo: ${traceFile}`,
|
|
@@ -82,10 +263,34 @@ function formatSummary(stats, traceFile) {
|
|
|
82
263
|
return lines.join('\n');
|
|
83
264
|
}
|
|
84
265
|
|
|
266
|
+
// Ordem de exibição fixa das rotas na segunda caixa — independente da ordem
|
|
267
|
+
// em que apareceram no arquivo, pra saída estável entre execuções.
|
|
268
|
+
const ROUTE_DISPLAY_ORDER = ['agent:*', 'maestro', 'flat', 'outro'];
|
|
269
|
+
|
|
270
|
+
function formatLadderSummary(ladderStats) {
|
|
271
|
+
const lines = [
|
|
272
|
+
`Pedidos roteados com dado de escada: ${ladderStats.total}`,
|
|
273
|
+
`Invocaram algum wizz-exec-*: ${ladderStats.withExec} (${pct(ladderStats.withExec, ladderStats.total)})`,
|
|
274
|
+
'Por rota:',
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
const routes = ROUTE_DISPLAY_ORDER.filter((route) => ladderStats.byRoute[route]);
|
|
278
|
+
if (routes.length === 0) {
|
|
279
|
+
lines.push(' (sem dados)');
|
|
280
|
+
} else {
|
|
281
|
+
for (const route of routes) {
|
|
282
|
+
const bucket = ladderStats.byRoute[route];
|
|
283
|
+
lines.push(` ${route.padEnd(8)} ${bucket.withExec}/${bucket.total} (${pct(bucket.withExec, bucket.total)})`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return lines.join('\n');
|
|
288
|
+
}
|
|
289
|
+
|
|
85
290
|
module.exports = {
|
|
86
291
|
command: 'trace-report',
|
|
87
292
|
description: 'Resume o arquivo local de trace do roteamento (WIZZ_TRACE)',
|
|
88
|
-
options: [],
|
|
293
|
+
options: [['--coverage', 'Cruza o catálogo de skills do registry contra os traces: mede skills nunca consideradas no roteamento']],
|
|
89
294
|
action: async (options) => {
|
|
90
295
|
try {
|
|
91
296
|
const traceFile = getTraceFile();
|
|
@@ -112,10 +317,37 @@ module.exports = {
|
|
|
112
317
|
}
|
|
113
318
|
}
|
|
114
319
|
|
|
320
|
+
// `--coverage` é um modo alternativo, não aditivo: troca as 2 caixas
|
|
321
|
+
// base (contagem trivial/mode e escada de modelos) por 1 caixa focada
|
|
322
|
+
// em subutilização de skills. Motivo: são leituras diferentes do mesmo
|
|
323
|
+
// JSONL (roteamento agregado vs catálogo x descoberta): misturar as
|
|
324
|
+
// 3 caixas por padrão poluiria a saída sem ganho pro caso de uso de
|
|
325
|
+
// cada flag.
|
|
326
|
+
if (options.coverage) {
|
|
327
|
+
const registryFile = getRegistryFile();
|
|
328
|
+
let catalogIds;
|
|
329
|
+
try {
|
|
330
|
+
catalogIds = collectSkillCatalog(registryFile);
|
|
331
|
+
} catch (error) {
|
|
332
|
+
await prompts.log.error(`Não foi possível ler o catálogo de skills: ${error.message}`);
|
|
333
|
+
await prompts.log.message(`Esperado em: ${registryFile}`);
|
|
334
|
+
process.exit(1);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const coverageStats = aggregateCoverage(entries, catalogIds);
|
|
339
|
+
await prompts.box(formatCoverageSummary(coverageStats, registryFile), 'Cobertura do Catálogo de Skills');
|
|
340
|
+
process.exit(0);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
115
344
|
const stats = { ...aggregate(entries), corruptedCount };
|
|
116
345
|
|
|
117
346
|
await prompts.box(formatSummary(stats, traceFile), 'Wizz Trace Report');
|
|
118
347
|
|
|
348
|
+
const ladderStats = aggregateLadder(entries);
|
|
349
|
+
await prompts.box(formatLadderSummary(ladderStats), 'Aderência à Escada de Modelos');
|
|
350
|
+
|
|
119
351
|
process.exit(0);
|
|
120
352
|
} catch (error) {
|
|
121
353
|
await prompts.log.error(`Trace report failed: ${error.message}`);
|
|
@@ -127,5 +359,17 @@ module.exports = {
|
|
|
127
359
|
},
|
|
128
360
|
// Exportado só para teste unitário direto da agregação, sem precisar
|
|
129
361
|
// spawnar o processo pra cada caso de borda.
|
|
130
|
-
_internal: {
|
|
362
|
+
_internal: {
|
|
363
|
+
aggregate,
|
|
364
|
+
parseLine,
|
|
365
|
+
formatSummary,
|
|
366
|
+
aggregateLadder,
|
|
367
|
+
ladderBucket,
|
|
368
|
+
formatLadderSummary,
|
|
369
|
+
pct,
|
|
370
|
+
collectSkillCatalog,
|
|
371
|
+
aggregateCoverage,
|
|
372
|
+
formatCoverageSummary,
|
|
373
|
+
getRegistryFile,
|
|
374
|
+
},
|
|
131
375
|
};
|
|
@@ -292,6 +292,11 @@ class OfficialModules {
|
|
|
292
292
|
* @param {Object} options.logger - Logger instance for output
|
|
293
293
|
*/
|
|
294
294
|
async install(moduleName, wizzDir, fileTrackingCallback = null, options = {}) {
|
|
295
|
+
// Aliases (ex.: bauto → bmad-loop) chegam crus via --modules e via
|
|
296
|
+
// moduleIds de instalações antigas; sem normalizar aqui, o cache de
|
|
297
|
+
// getPluginResolution, o targetPath e o manifest usariam o código legado.
|
|
298
|
+
moduleName = await this.externalModuleManager.resolveCanonicalCode(moduleName);
|
|
299
|
+
|
|
295
300
|
// Check if this module has a plugin resolution (custom marketplace install)
|
|
296
301
|
const { CustomModuleManager } = require('./custom-module-manager');
|
|
297
302
|
const customMgr = new CustomModuleManager();
|