wizz-method 2.16.0 → 2.17.1
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/THIRD-PARTY-NOTICES.md +6 -0
- package/package.json +1 -1
- package/skills-registry.yaml +18 -6
- package/src/modules/wizz/_shared/model-ladder.md +7 -5
- package/src/modules/wizz/_shared/video-pipeline.md +1 -0
- package/src/modules/wizz/subagents/codex/wizz-exec-mechanical.toml +2 -2
- package/src/modules/wizz/subagents/codex/wizz-exec-review.toml +2 -2
- package/src/modules/wizz/subagents/codex/wizz-exec-standard.toml +2 -2
- package/src/modules/wizz/subagents/codex/wizz-exec-strong.toml +2 -2
- package/src/modules/wizz/subagents/spec.yaml +7 -4
- package/src/skills-lib/wizz-router/references/routing-table-flat.md +1 -0
- package/src/skills-lib/wizz-video-styles/SKILL.md +66 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/CREDITS.md +54 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/LIBRARIES.md +31 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/kit.json +182 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/acoustic-lifestyle.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/cinematic-tense.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/classical-light.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/corporate-light.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/lofi-chill.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/meme-beat.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/piano-editorial.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/music/tech-pulse.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/boom-impact.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/click-mouse.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/ding-notify.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/glitch-short.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/ka-ching.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/pop-bubble.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/record-scratch.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/riser-short.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/swoosh-text.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/typing-short.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/whoosh-fast.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/audio/sfx/whoosh-soft.mp3 +0 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/EditorialReel.tsx +111 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/README.md +77 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/captions.tsx +56 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/example-words.json +285 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/primitives.tsx +241 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/scenes.tsx +113 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/theme.ts +68 -0
- package/src/skills-lib/wizz-video-styles/assets/remotion/editorial/timeline.ts +65 -0
- package/src/skills-lib/wizz-video-styles/data/recipes.json +341 -0
- package/src/skills-lib/wizz-video-styles/data/references.json +3397 -0
- package/src/skills-lib/wizz-video-styles/data/styles.json +726 -0
- package/src/skills-lib/wizz-video-styles/references/audio.md +54 -0
- package/src/skills-lib/wizz-video-styles/references/measured-patterns.md +38 -0
- package/src/skills-lib/wizz-video-styles/references/research-method.md +33 -0
- package/src/skills-lib/wizz-video-styles/references/style-picker.md +51 -0
- package/src/skills-lib/wizz-video-styles/references/styles/camera-no-setup.md +60 -0
- package/src/skills-lib/wizz-video-styles/references/styles/desafio-numero.md +60 -0
- package/src/skills-lib/wizz-video-styles/references/styles/esquete.md +57 -0
- package/src/skills-lib/wizz-video-styles/references/styles/experimento.md +56 -0
- package/src/skills-lib/wizz-video-styles/references/styles/explicador-animado.md +62 -0
- package/src/skills-lib/wizz-video-styles/references/styles/macro-asmr.md +61 -0
- package/src/skills-lib/wizz-video-styles/references/styles/meme-rapido.md +65 -0
- package/src/skills-lib/wizz-video-styles/references/styles/motion-editorial.md +69 -0
- package/src/skills-lib/wizz-video-styles/references/styles/podcast-clip.md +61 -0
- package/src/skills-lib/wizz-video-styles/references/styles/pov-vlog.md +57 -0
- package/src/skills-lib/wizz-video-styles/references/styles/quadro-branco.md +60 -0
- package/src/skills-lib/wizz-video-styles/references/styles/talking-head-cards.md +62 -0
- package/src/skills-lib/wizz-video-styles/references/styles/talking-head-legenda.md +62 -0
- package/src/skills-lib/wizz-video-styles/references/styles/tour.md +59 -0
- package/src/skills-lib/wizz-video-styles/scripts/analyze.sh +66 -0
- package/src/skills-lib/wizz-video-styles/scripts/build_catalog.py +128 -0
- package/tools/installer/core/project-instructions.js +2 -1
- package/tools/installer/core/subagent-models.js +112 -0
- package/tools/installer/ide/_config-driven.js +8 -3
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Motion editorial (Greg Isenberg)
|
|
2
|
+
|
|
3
|
+
Measured on 3 shorts (en) in: dev / AI / build in public (EN).
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 829,395 · median 642,459 |
|
|
10
|
+
| Cuts per 10 s | min 1.2 · median 1.71 · max 1.95 |
|
|
11
|
+
| Median scene length | 4.1 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 3 / 0 / 0 |
|
|
13
|
+
| Cuts with a sound effect on them | 3/23 (13%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
Only a voice track. No one on camera required (a short face insert is optional). App or product screens as screenshots.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Explaining a system, a workflow, a tool or a framework; tech, SaaS, AI, productivity, finance apps, B2B. Calm authority, saves and comments.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Light warm background (cream, sand, light grey) with a faint square grid and a soft vignette.
|
|
30
|
+
- One object at a time in the centre: dark rounded cards with deep soft shadows, pill-shaped inputs, file chips, a phone card holding a real screenshot.
|
|
31
|
+
- An accent shape in one warm colour (orange, copper) that recurs: rays, a ring, a starburst.
|
|
32
|
+
- Dashed connectors drawing between chips; text typed inside pills.
|
|
33
|
+
|
|
34
|
+
**Palette:** Background #EEE7DA, ink #1A1A1A, card #1C1916 → #2A2521, card text #DFD8C6, one accent (#B5541C / #C9622A / #E39A6C). Swap the accent for the brand colour; keep the light background.
|
|
35
|
+
|
|
36
|
+
**Typography:** Serif italic display for headlines and pill text (Playfair Display italic 600/700); sans for small UI; mono for code.
|
|
37
|
+
|
|
38
|
+
**Motion**
|
|
39
|
+
|
|
40
|
+
- Each scene enters with a spring (scale 0.94 → 1, rise 70 px) and leaves rising and fading; scenes overlap ~0.1 s, so there is no hard cut.
|
|
41
|
+
- Slow camera push of 3 to 4 % across a scene.
|
|
42
|
+
- Objects transform into the next object (pill becomes card, card becomes phone) instead of cutting.
|
|
43
|
+
- Counters tick up to real numbers; typing in pills; connectors draw in.
|
|
44
|
+
|
|
45
|
+
**Captions:** Small or none. If used: one line of 2 to 4 words, sans bold ~50 px, ink colour on the light background, active word in the accent. Headline in serif italic, two-tone (ink + accent), only at key moments.
|
|
46
|
+
|
|
47
|
+
**Hook (0 to 3 s):** A serif headline of the claim with one object animating in under it (0 to 3 s). A real number works well.
|
|
48
|
+
|
|
49
|
+
**CTA:** The CTA word typed in a pill with the accent shape lighting up; one line of serif below.
|
|
50
|
+
|
|
51
|
+
**Music:** Continuous bed, calm (piano, ambient, soft electronic), around 0.2 of the voice level with fade in/out.
|
|
52
|
+
|
|
53
|
+
**SFX:** Rare: a soft whoosh on the 2 or 3 biggest transformations, at most ~1 per 10 s. Light typing under one typed pill. Nothing on every scene.
|
|
54
|
+
|
|
55
|
+
## Do not
|
|
56
|
+
|
|
57
|
+
- Full-screen browser screen recordings (they can come out stretched); use real screenshots inside a phone card.
|
|
58
|
+
- Giant outlined captions; they fight the editorial look.
|
|
59
|
+
- A sound on every scene change; pops, dings and impacts in sequence.
|
|
60
|
+
|
|
61
|
+
## Watch before editing
|
|
62
|
+
|
|
63
|
+
- [Greg Isenberg](https://www.youtube.com/shorts/ovLAIhbk3ek) · 829,395 views
|
|
64
|
+
- [Greg Isenberg](https://www.youtube.com/shorts/yJK5GueSHmU) · 642,459 views
|
|
65
|
+
- [Greg Isenberg](https://www.youtube.com/shorts/5G9PAIUs5Pk) · 458,691 views
|
|
66
|
+
|
|
67
|
+
## Template
|
|
68
|
+
|
|
69
|
+
`assets/remotion/editorial/` (Remotion). Copy it into the project's `src/`, set the theme and the scenes; see its README.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Podcast or interview clip
|
|
2
|
+
|
|
3
|
+
Measured on 12 shorts (en, pt) in: dev / AI / build in public (EN), personal finance / investing, product / SaaS / marketing / business / law, health / fitness / nutrition.
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 9,846,107 · median 216,533 |
|
|
10
|
+
| Cuts per 10 s | min 0.0 · median 1.91 · max 4.42 |
|
|
11
|
+
| Median scene length | 3.5 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 0 / 6 / 6 |
|
|
13
|
+
| Cuts with a sound effect on them | 7/124 (6%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
A recorded conversation or talk with at least one good camera; a second angle helps.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Finance, health, business, mindset; any expert talking. Reuses long-form content.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Two cameras alternating speakers in a dark studio; channel badge in a corner.
|
|
30
|
+
- Variants: letterbox with a title bar on top; tier list or ranking being filled over the clip; reaction picture-in-picture; black background with the clip in a window and tools stacking (Starter Story).
|
|
31
|
+
|
|
32
|
+
**Palette:** Studio darks; captions white with yellow/red keywords; title bar white with black text.
|
|
33
|
+
|
|
34
|
+
**Typography:** Condensed bold uppercase captions; plain bold sans titles.
|
|
35
|
+
|
|
36
|
+
**Motion**
|
|
37
|
+
|
|
38
|
+
- Cuts follow the speaker; inserts of the thing being discussed (product, card, chart) full frame for 1 to 2 s.
|
|
39
|
+
|
|
40
|
+
**Captions:** Word by word, large, uppercase, white with outline, keyword in yellow or red, lower-centre.
|
|
41
|
+
|
|
42
|
+
**Hook (0 to 3 s):** Start mid-sentence on the strongest line, or with the title/ranking on screen.
|
|
43
|
+
|
|
44
|
+
**CTA:** Spoken or a title card; often none (the clip ends on the punchline).
|
|
45
|
+
|
|
46
|
+
**Music:** None or faint.
|
|
47
|
+
|
|
48
|
+
**SFX:** Almost none on cuts.
|
|
49
|
+
|
|
50
|
+
## Do not
|
|
51
|
+
|
|
52
|
+
- Starting with greetings or context.
|
|
53
|
+
- Clips that need the long episode to make sense.
|
|
54
|
+
|
|
55
|
+
## Watch before editing
|
|
56
|
+
|
|
57
|
+
- [Doctor Mike](https://www.youtube.com/shorts/cnyqT48dyjE) · 9,846,107 views
|
|
58
|
+
- [Graham Stephan](https://www.youtube.com/shorts/K7UvJQsjMOM) · 1,238,146 views
|
|
59
|
+
- [Theo - t3․gg](https://www.youtube.com/shorts/vgdpLKxS8dY) · 476,638 views
|
|
60
|
+
- [Graham Stephan](https://www.youtube.com/shorts/V1hW3DH69pw) · 371,080 views
|
|
61
|
+
- [Alex Hormozi](https://www.youtube.com/shorts/57_uoyn15_w) · 332,850 views
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# POV vlog (Drew Binsky)
|
|
2
|
+
|
|
3
|
+
Measured on 3 shorts (en, pt) in: food / recipes / lifestyle / travel, beauty / fashion / local services (clinic, salon, architecture, real estate).
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 8,726,757 · median 1,394,792 |
|
|
10
|
+
| Cuts per 10 s | min 0.39 · median 2.71 · max 6.38 |
|
|
11
|
+
| Median scene length | 3.27 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 2 / 1 / 0 |
|
|
13
|
+
| Cuts with a sound effect on them | 2/56 (4%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
Handheld footage of a place or experience, wide lens, the creator's voice.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Travel, experiences, behind the scenes, 'a day at'.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Wide-angle phone footage, quick cuts, a selfie at the end; emphasis word in red.
|
|
30
|
+
|
|
31
|
+
**Palette:** The place; captions white with shadow; red emphasis.
|
|
32
|
+
|
|
33
|
+
**Typography:** Bold sans with black outline.
|
|
34
|
+
|
|
35
|
+
**Motion**
|
|
36
|
+
|
|
37
|
+
- Quick cuts (median ~2.7 per 10 s, up to ~6.4); question-mark stickers; movement in every shot.
|
|
38
|
+
|
|
39
|
+
**Captions:** 1 to 3 words, white bold, lower-centre, emphasis in red.
|
|
40
|
+
|
|
41
|
+
**Hook (0 to 3 s):** The most striking shot of the place plus a curiosity title in 0 to 1 s.
|
|
42
|
+
|
|
43
|
+
**CTA:** Selfie to camera at the end.
|
|
44
|
+
|
|
45
|
+
**Music:** Continuous or faint bed.
|
|
46
|
+
|
|
47
|
+
**SFX:** Almost none on cuts.
|
|
48
|
+
|
|
49
|
+
## Do not
|
|
50
|
+
|
|
51
|
+
- Static shots; this style is movement.
|
|
52
|
+
|
|
53
|
+
## Watch before editing
|
|
54
|
+
|
|
55
|
+
- [Drew Binsky](https://www.youtube.com/shorts/d9w9tME0aEY) · 8,726,757 views
|
|
56
|
+
- [Mari Maria](https://www.youtube.com/shorts/BuQbDL9F9eY) · 1,394,792 views
|
|
57
|
+
- [Cata e Davi](https://www.youtube.com/shorts/kdC1VJtz0EY) · 624,507 views
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Whiteboard or hand drawing
|
|
2
|
+
|
|
3
|
+
Measured on 5 shorts (en, pt) in: dev / AI / build in public (EN), dev / AI / tech business (BR), product / SaaS / marketing / business / law, health / fitness / nutrition.
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 4,438,595 · median 608,820 |
|
|
10
|
+
| Cuts per 10 s | min 0.0 · median 1.31 · max 1.96 |
|
|
11
|
+
| Median scene length | 6.12 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 2 / 1 / 2 |
|
|
13
|
+
| Cuts with a sound effect on them | 0/28 (0%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
A board, a notebook or a drawing app, and someone explaining. Face optional.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Concepts, frameworks, health explanations, programming ideas. Long single takes are acceptable here.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Hand drawing in a notebook with highlighters (Filipe Deschamps), a board in one take (Dayan Siebra), white lines drawn on black (ThePrimeagen), a flip chart behind the speaker (Codie Sanchez).
|
|
30
|
+
- A fixed question or title box at the top for the whole video.
|
|
31
|
+
|
|
32
|
+
**Palette:** Paper white or board black; one neon highlighter; ink colours of the markers.
|
|
33
|
+
|
|
34
|
+
**Typography:** Handwriting for the content; plain sans in a white box for the fixed title.
|
|
35
|
+
|
|
36
|
+
**Motion**
|
|
37
|
+
|
|
38
|
+
- Drawing appears progressively; few cuts; long takes (a median scene of several seconds).
|
|
39
|
+
|
|
40
|
+
**Captions:** Often none beyond the drawing; when present, small and plain.
|
|
41
|
+
|
|
42
|
+
**Hook (0 to 3 s):** The provocative question fixed on screen from frame one.
|
|
43
|
+
|
|
44
|
+
**CTA:** Spoken; sometimes the drawing ends on the CTA.
|
|
45
|
+
|
|
46
|
+
**Music:** Mixed; often none.
|
|
47
|
+
|
|
48
|
+
**SFX:** None measured on cuts.
|
|
49
|
+
|
|
50
|
+
## Do not
|
|
51
|
+
|
|
52
|
+
- Drawing that the viewer cannot read on a phone (write big).
|
|
53
|
+
|
|
54
|
+
## Watch before editing
|
|
55
|
+
|
|
56
|
+
- [ThePrimeagen](https://www.youtube.com/shorts/_ebVsYQou8A) · 4,438,595 views
|
|
57
|
+
- [Filipe Deschamps](https://www.youtube.com/shorts/wydSHobAaZQ) · 1,142,498 views
|
|
58
|
+
- [Dayan Siebra](https://www.youtube.com/shorts/V4v1hg69XRI) · 608,820 views
|
|
59
|
+
- [Filipe Deschamps](https://www.youtube.com/shorts/MLDH_t3Rpms) · 335,545 views
|
|
60
|
+
- [Codie Sanchez](https://www.youtube.com/shorts/cLfZgtGNNx4) · 145,271 views
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Talking head with cards and b-roll
|
|
2
|
+
|
|
3
|
+
Measured on 13 shorts (en, pt) in: dev / AI / build in public (EN), dev / AI / tech business (BR), personal finance / investing, product / SaaS / marketing / business / law, health / fitness / nutrition, beauty / fashion / local services (clinic, salon, architecture, real estate), education / science / comedy.
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 2,181,318 · median 431,649 |
|
|
10
|
+
| Cuts per 10 s | min 0.0 · median 0.45 · max 5.31 |
|
|
11
|
+
| Median scene length | 9.47 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 5 / 6 / 2 |
|
|
13
|
+
| Cuts with a sound effect on them | 20/174 (11%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
A person on camera plus things to show: news headlines, article screenshots, charts, product shots, stock b-roll.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
News and commentary (finance, tech, science), explainers with evidence, any niche that needs proof on screen.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Face in selfie or studio; cards slide over the frame: headline screenshots with highlighter, numbered section titles, charts, stickers.
|
|
30
|
+
- Variants: split screen (archive images on top, presenter below), face in a bubble over full-screen b-roll.
|
|
31
|
+
|
|
32
|
+
**Palette:** Neutral room; white cards; highlighter yellow; one alert colour (red) for numbers and arrows.
|
|
33
|
+
|
|
34
|
+
**Typography:** Condensed bold uppercase for section titles; medium sans for captions (yellow with outline on BR channels).
|
|
35
|
+
|
|
36
|
+
**Motion**
|
|
37
|
+
|
|
38
|
+
- Cards enter over the face rather than cutting away; cuts mostly when the topic changes.
|
|
39
|
+
- Face bubble stays on from after the hook to the CTA when b-roll is full screen.
|
|
40
|
+
|
|
41
|
+
**Captions:** Lower-centre, yellow or white with keyword emphasis; section number big at the top when the piece is a list.
|
|
42
|
+
|
|
43
|
+
**Hook (0 to 3 s):** A thumbnail-like card in the first frames ('THIS BANK WILL BE NEXT?') with a red arrow or the key number.
|
|
44
|
+
|
|
45
|
+
**CTA:** Back to the face full screen, no card on top.
|
|
46
|
+
|
|
47
|
+
**Music:** Faint bed in most; continuous in the faster ones.
|
|
48
|
+
|
|
49
|
+
**SFX:** A soft whoosh or paper sound when a card enters, on a minority of cards.
|
|
50
|
+
|
|
51
|
+
## Do not
|
|
52
|
+
|
|
53
|
+
- Cards covering the face for long stretches.
|
|
54
|
+
- Unreadable article screenshots (crop to the line that matters and highlight it).
|
|
55
|
+
|
|
56
|
+
## Watch before editing
|
|
57
|
+
|
|
58
|
+
- [Manual do Mundo](https://www.youtube.com/shorts/q1DLHGpLSss) · 2,181,318 views
|
|
59
|
+
- [Katia Haranaka](https://www.youtube.com/shorts/1NEVJoOAzcE) · 1,960,278 views
|
|
60
|
+
- [Bruno Perini - Você MAIS Rico](https://www.youtube.com/shorts/xZYgNVefQsQ) · 1,159,863 views
|
|
61
|
+
- [NetworkChuck](https://www.youtube.com/shorts/lO961HRQn5Q) · 815,553 views
|
|
62
|
+
- [Bruno Perini - Você MAIS Rico](https://www.youtube.com/shorts/s5cwz0SeU5I) · 720,508 views
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Talking head with highlighted captions
|
|
2
|
+
|
|
3
|
+
Measured on 21 shorts (en, pt) in: dev / AI / build in public (EN), dev / AI / tech business (BR), personal finance / investing, product / SaaS / marketing / business / law, beauty / fashion / local services (clinic, salon, architecture, real estate), education / science / comedy.
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 9,809,160 · median 382,506 |
|
|
10
|
+
| Cuts per 10 s | min 0.0 · median 0.92 · max 5.69 |
|
|
11
|
+
| Median scene length | 7.42 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 0 / 6 / 15 |
|
|
13
|
+
| Cuts with a sound effect on them | 17/188 (9%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
A person on camera talking (selfie, studio, stream, stage). Nothing else.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Opinion, news, advice, reaction, review, beauty talk; every niche in the set has it. Reach comes from the content, not the edit.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- One framing (selfie or studio), sometimes a second angle; jump cuts remove pauses.
|
|
30
|
+
- A headline box (white or black) in the first seconds; captions word by word.
|
|
31
|
+
|
|
32
|
+
**Palette:** Whatever the room is; captions white with outline, one accent for the keyword (yellow is the BR default; red, green or purple elsewhere).
|
|
33
|
+
|
|
34
|
+
**Typography:** Bold sans uppercase for captions; condensed bold for the headline box; some finance/BR channels use a white serif.
|
|
35
|
+
|
|
36
|
+
**Motion**
|
|
37
|
+
|
|
38
|
+
- Few cuts (median ~1 per 10 s); punch-in zooms on emphasis; occasional reaction insert.
|
|
39
|
+
|
|
40
|
+
**Captions:** Word by word or 1 to 3 words, bold, lower-centre (above the platform UI), keyword in the accent colour.
|
|
41
|
+
|
|
42
|
+
**Hook (0 to 3 s):** The headline box with the claim or question in the first frame, spoken at the same time.
|
|
43
|
+
|
|
44
|
+
**CTA:** Spoken to camera; caption repeats the keyword.
|
|
45
|
+
|
|
46
|
+
**Music:** None or faint in most; the voice carries it.
|
|
47
|
+
|
|
48
|
+
**SFX:** Rare; an occasional pop on a caption keyword.
|
|
49
|
+
|
|
50
|
+
## Do not
|
|
51
|
+
|
|
52
|
+
- Leaving pauses and 'uhs' in.
|
|
53
|
+
- Captions under the like/comment buttons.
|
|
54
|
+
- Music that competes with the voice.
|
|
55
|
+
|
|
56
|
+
## Watch before editing
|
|
57
|
+
|
|
58
|
+
- [Thiago Concer](https://www.youtube.com/shorts/-xP6HufvUOk) · 9,809,160 views
|
|
59
|
+
- [ThePrimeagen](https://www.youtube.com/shorts/M-VU0fLjIUU) · 5,401,385 views
|
|
60
|
+
- [rodrigo vizu](https://www.youtube.com/shorts/zcXXksbFwIQ) · 3,759,620 views
|
|
61
|
+
- [Felipe Neto](https://www.youtube.com/shorts/7U4hRvg0vXw) · 1,660,932 views
|
|
62
|
+
- [Mari Maria](https://www.youtube.com/shorts/rNJNJBpz1P8) · 1,419,599 views
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Walkthrough or tour (Enes Yilmazer, Ryan Serhant)
|
|
2
|
+
|
|
3
|
+
Measured on 3 shorts (en, pt) in: food / recipes / lifestyle / travel, beauty / fashion / local services (clinic, salon, architecture, real estate).
|
|
4
|
+
|
|
5
|
+
## Measured
|
|
6
|
+
|
|
7
|
+
| Metric | Value |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Reach (views) | max 1,051,145 · median 370,693 |
|
|
10
|
+
| Cuts per 10 s | min 0.4 · median 2.88 · max 4.47 |
|
|
11
|
+
| Median scene length | 2.1 s |
|
|
12
|
+
| Music bed (continuous / faint / none) | 0 / 1 / 2 |
|
|
13
|
+
| Cuts with a sound effect on them | 8/90 (9%) |
|
|
14
|
+
|
|
15
|
+
Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).
|
|
16
|
+
|
|
17
|
+
## Material it needs
|
|
18
|
+
|
|
19
|
+
A place to walk through (property, studio, store) and someone guiding.
|
|
20
|
+
|
|
21
|
+
## When it fits
|
|
22
|
+
|
|
23
|
+
Real estate, architecture, travel destinations, venues, clinics, stores; local services.
|
|
24
|
+
|
|
25
|
+
## Recipe
|
|
26
|
+
|
|
27
|
+
**Look**
|
|
28
|
+
|
|
29
|
+
- Walking through the space facing the camera; a seated close; an insert of a phone/app when relevant; or one long take of the agent talking with a title box.
|
|
30
|
+
|
|
31
|
+
**Palette:** The space; captions white; brand red for logos.
|
|
32
|
+
|
|
33
|
+
**Typography:** Plain or condensed sans; title in a white box at the start.
|
|
34
|
+
|
|
35
|
+
**Motion**
|
|
36
|
+
|
|
37
|
+
- Walking tours cut every ~2 s (median scene 2.1 s) between rooms or spots; the single-take agent talk is the slow variant.
|
|
38
|
+
- The walk itself is the motion; no graphic transitions.
|
|
39
|
+
|
|
40
|
+
**Captions:** 1 or 2 words, white, centre or middle third.
|
|
41
|
+
|
|
42
|
+
**Hook (0 to 3 s):** The most impressive room first, or the quote of the claim in a title box.
|
|
43
|
+
|
|
44
|
+
**CTA:** Spoken; contact on screen.
|
|
45
|
+
|
|
46
|
+
**Music:** None measured.
|
|
47
|
+
|
|
48
|
+
**SFX:** None measured on cuts.
|
|
49
|
+
|
|
50
|
+
## Do not
|
|
51
|
+
|
|
52
|
+
- Graphic transitions between rooms; cut on the walk.
|
|
53
|
+
- Measured reach is modest (hundreds of thousands to ~1M), not tens of millions.
|
|
54
|
+
|
|
55
|
+
## Watch before editing
|
|
56
|
+
|
|
57
|
+
- [Viaje Por Conta](https://www.youtube.com/shorts/3mmhzj4y_78) · 1,051,145 views
|
|
58
|
+
- [Enes Yilmazer](https://www.youtube.com/shorts/FQYtkO9SpmU) · 370,693 views
|
|
59
|
+
- [Ryan Serhant](https://www.youtube.com/shorts/fX7uB6IobEk) · 150,846 views
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Measures one public YouTube short: download (720p), cuts (scene detection),
|
|
3
|
+
# audio (music bed, SFX type heuristic, loudness) and a 16-frame contact sheet.
|
|
4
|
+
# Usage: analyze.sh <youtube_id> <out_dir> → <out_dir>/<id>.json + <id>-sheet.png
|
|
5
|
+
# The .mp4 is deleted at the end; read the contact sheet before describing the look.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
[ $# -eq 2 ] || { echo "uso: analyze.sh <youtube_id> <out_dir>" >&2; exit 2; }
|
|
8
|
+
id="$1"; out="$2"
|
|
9
|
+
[[ "$id" =~ ^[A-Za-z0-9_-]{11}$ ]] || { echo "id inválido: $id" >&2; exit 2; }
|
|
10
|
+
mkdir -p "$out"; cd "$out"
|
|
11
|
+
f="./$id" # prefixo ./ : ID que começa com hífen não vira opção do ffmpeg
|
|
12
|
+
trap 'rm -f "$f.wav" "$f.mp4"' EXIT
|
|
13
|
+
# Python with librosa + numpy: set VIDEO_STYLES_PY to a venv python, or python3 must have them.
|
|
14
|
+
PY="${VIDEO_STYLES_PY:-python3}"
|
|
15
|
+
"$PY" -c "import librosa, numpy" 2>/dev/null || { echo "precisa de librosa e numpy: pip install librosa numpy (ou VIDEO_STYLES_PY=/caminho/do/python)" >&2; exit 2; }
|
|
16
|
+
for bin in yt-dlp ffmpeg ffprobe; do command -v "$bin" >/dev/null || { echo "falta $bin no PATH" >&2; exit 2; }; done
|
|
17
|
+
url="https://www.youtube.com/shorts/$id"
|
|
18
|
+
fmt="bv*[height<=1280][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b"
|
|
19
|
+
# When YouTube answers "confirm you're not a bot", the android player client usually still works (no cookies used).
|
|
20
|
+
[ -f "$f.mp4" ] || yt-dlp -q --no-warnings -f "$fmt" --merge-output-format mp4 -o "$f.mp4" "$url" \
|
|
21
|
+
|| yt-dlp -q --no-warnings --extractor-args "youtube:player_client=android" -f "$fmt" --merge-output-format mp4 -o "$f.mp4" "$url"
|
|
22
|
+
meta_fmt="%(view_count)s|%(like_count)s|%(channel)s|%(upload_date)s|%(title)s"
|
|
23
|
+
yt-dlp -q --no-warnings --skip-download --print "$meta_fmt" "$url" > "$f.meta" \
|
|
24
|
+
|| yt-dlp -q --no-warnings --skip-download --extractor-args "youtube:player_client=android" --print "$meta_fmt" "$url" > "$f.meta" \
|
|
25
|
+
|| echo "NA|NA|NA|NA|NA" > "$f.meta"
|
|
26
|
+
ffmpeg -nostats -i "$f.mp4" -vf "select='gt(scene,0.28)',showinfo" -an -f null - 2>&1 | grep -o "pts_time:[0-9.]*" | cut -d: -f2 > "$f.cuts" || true
|
|
27
|
+
ffmpeg -loglevel error -y -i "$f.mp4" -ac 1 -ar 22050 "$f.wav"
|
|
28
|
+
# Video without audio: ebur128 prints no "I:" line; grep would abort under pipefail. Record "NA" instead.
|
|
29
|
+
lufs=$(ffmpeg -i "$f.mp4" -af ebur128 -f null - 2>&1 | grep -E "^\s+I:" | tail -1 | awk '{print $2}' || true)
|
|
30
|
+
[ -n "$lufs" ] || lufs="NA"
|
|
31
|
+
d=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f.mp4")
|
|
32
|
+
step=$(python3 -c "print(max(1.0, $d/16))")
|
|
33
|
+
ffmpeg -loglevel error -y -i "$f.mp4" -vf "fps=1/$step,scale=200:-1,tile=8x2" -frames:v 1 "$f-sheet.png"
|
|
34
|
+
"$PY" - "$id" "$lufs" <<'PY'
|
|
35
|
+
import librosa, numpy as np, json, sys
|
|
36
|
+
id, lufs = sys.argv[1], sys.argv[2]
|
|
37
|
+
y, sr = librosa.load(f"{id}.wav", sr=22050); dur = len(y)/sr
|
|
38
|
+
cuts = [float(x) for x in open(f"{id}.cuts").read().split()]
|
|
39
|
+
H, P = librosa.effects.hpss(y, margin=2.0)
|
|
40
|
+
hop = 256
|
|
41
|
+
r = librosa.feature.rms(y=y, hop_length=hop)[0]; rh = librosa.feature.rms(y=H, hop_length=hop)[0]; rp = librosa.feature.rms(y=P, hop_length=hop)[0]
|
|
42
|
+
S = np.abs(librosa.stft(y, hop_length=hop)); f = librosa.fft_frequencies(sr=sr)
|
|
43
|
+
low = S[f < 150].sum(0)/(S.sum(0)+1e-9); cent = librosa.feature.spectral_centroid(S=S, sr=sr)[0]; flat = librosa.feature.spectral_flatness(S=S)[0]
|
|
44
|
+
tfr = librosa.frames_to_time(np.arange(len(r)), sr=sr, hop_length=hop)
|
|
45
|
+
on = librosa.onset.onset_detect(onset_envelope=librosa.onset.onset_strength(y=P, sr=sr, hop_length=hop), sr=sr, hop_length=hop, delta=0.3)
|
|
46
|
+
thr = np.percentile(rp, 80); kinds = {"pop_click":0, "whoosh":0, "impact_low":0}
|
|
47
|
+
events = []
|
|
48
|
+
for o in on:
|
|
49
|
+
seg = slice(o, min(o+60, len(rp))); e = rp[seg]; pk = e.max()
|
|
50
|
+
if pk < thr: continue
|
|
51
|
+
n = (e > pk*0.3).sum()*hop/sr; k = None
|
|
52
|
+
if low[seg].mean() > 0.30 and n > 0.12: k = "impact_low"
|
|
53
|
+
elif n < 0.09 and cent[seg].max() > 3000: k = "pop_click"
|
|
54
|
+
elif n >= 0.15 and flat[seg].mean() > 0.04: k = "whoosh"
|
|
55
|
+
if k: kinds[k] += 1; events.append([round(float(tfr[o]),2), k])
|
|
56
|
+
on_cut = sum(1 for c in cuts if any(abs(t-c) < 0.15 for t,_ in events))
|
|
57
|
+
shots = np.diff([0]+cuts+[dur]) if dur else np.array([0])
|
|
58
|
+
bed = float(np.percentile(rh,15)/(np.percentile(rh,95)+1e-9))
|
|
59
|
+
meta = open(f"{id}.meta").read().strip().split("|", 4)
|
|
60
|
+
json.dump({"id": id, "url": f"https://www.youtube.com/shorts/{id}", "views": meta[0], "likes": meta[1], "channel": meta[2], "upload_date": meta[3], "title": meta[4],
|
|
61
|
+
"duration_s": round(dur,1), "cuts": len(cuts), "cuts_per_10s": round(len(cuts)/dur*10,2), "shot_median_s": round(float(np.median(shots)),2), "shot_mean_s": round(float(shots.mean()),2),
|
|
62
|
+
"music_bed_ratio": round(bed,3), "music_bed_guess": "continua" if bed > 0.13 else ("fraca" if bed > 0.07 else "sem"),
|
|
63
|
+
"sfx_counts": kinds, "sfx_per_10s": round(sum(kinds.values())/dur*10,2), "sfx_on_cuts": f"{on_cut}/{len(cuts)}", "sfx_events": events[:40],
|
|
64
|
+
"integrated_lufs": lufs, "note": "sfx/música por heurística (HPSS+onsets); não identifica o NOME do efeito"}, open(f"{id}.json","w"), ensure_ascii=False, indent=1)
|
|
65
|
+
print(f"{id} ok")
|
|
66
|
+
PY
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Rebuild the catalogue from its data.
|
|
2
|
+
|
|
3
|
+
data/references.json (every measured short, each with a `style`) +
|
|
4
|
+
data/recipes.json (the qualitative recipe of each style)
|
|
5
|
+
→ data/styles.json (per-style numbers) and references/styles/<style>.md.
|
|
6
|
+
|
|
7
|
+
Run after adding references (see references/research-method.md):
|
|
8
|
+
python3 scripts/build_catalog.py
|
|
9
|
+
Stdlib only. A style with a recipe but no measured reference is refused:
|
|
10
|
+
the catalogue never shows a style it cannot back with a measurement.
|
|
11
|
+
"""
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import statistics as st
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
18
|
+
DATA = os.path.join(ROOT, "data")
|
|
19
|
+
CARDS = os.path.join(ROOT, "references", "styles")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def num(value):
|
|
23
|
+
try:
|
|
24
|
+
return float(value)
|
|
25
|
+
except (TypeError, ValueError):
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def views(ref):
|
|
30
|
+
return int(ref["views"]) if str(ref.get("views", "")).isdigit() else 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def aggregate(refs):
|
|
34
|
+
by_style = {}
|
|
35
|
+
for ref in refs:
|
|
36
|
+
by_style.setdefault(ref["style"], []).append(ref)
|
|
37
|
+
out = {}
|
|
38
|
+
for style, lst in by_style.items():
|
|
39
|
+
cuts = [c for c in (num(r["ritmo"]["cuts_per_10s"]) for r in lst) if c is not None]
|
|
40
|
+
shots = [s for s in (num(r["ritmo"]["shot_median_s"]) for r in lst) if s is not None]
|
|
41
|
+
music = [r["musica"]["guess"] for r in lst]
|
|
42
|
+
on_cuts = [tuple(map(int, r["sfx"]["on_cuts"].split("/"))) for r in lst if "/" in str(r["sfx"].get("on_cuts", ""))]
|
|
43
|
+
reach = sorted((views(r) for r in lst), reverse=True)
|
|
44
|
+
ranked = sorted(lst, key=views, reverse=True)
|
|
45
|
+
out[style] = {
|
|
46
|
+
"n": len(lst),
|
|
47
|
+
"nichos": sorted({r["nicho"] for r in lst}),
|
|
48
|
+
"langs": sorted({(r.get("idioma") or "")[:2] for r in lst if r.get("idioma")}),
|
|
49
|
+
"views_max": reach[0],
|
|
50
|
+
"views_median": int(st.median(reach)),
|
|
51
|
+
"cuts_per_10s": [round(min(cuts), 2), round(st.median(cuts), 2), round(max(cuts), 2)],
|
|
52
|
+
"shot_median_s": round(st.median(shots), 2),
|
|
53
|
+
"music": {k: music.count(k) for k in ("continua", "fraca", "sem")},
|
|
54
|
+
"sfx_on_cuts": [sum(a for a, _ in on_cuts), sum(b for _, b in on_cuts)],
|
|
55
|
+
"top": [{"channel": r["channel"], "views": r["views"], "url": r["url"]} for r in ranked[:5]],
|
|
56
|
+
}
|
|
57
|
+
return out
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def card(key, recipe, stats, niches):
|
|
61
|
+
c = stats["cuts_per_10s"]
|
|
62
|
+
m = stats["music"]
|
|
63
|
+
hit, total = stats["sfx_on_cuts"]
|
|
64
|
+
pct = f"{hit}/{total} ({round(100 * hit / total)}%)" if total else "0/0"
|
|
65
|
+
where = ", ".join(niches[n] for n in stats["nichos"])
|
|
66
|
+
lines = [
|
|
67
|
+
f"# {recipe['title']}", "",
|
|
68
|
+
f"Measured on {stats['n']} shorts ({', '.join(stats['langs'])}) in: {where}.", "",
|
|
69
|
+
"## Measured", "",
|
|
70
|
+
"| Metric | Value |", "|---|---|",
|
|
71
|
+
f"| Reach (views) | max {stats['views_max']:,} · median {stats['views_median']:,} |",
|
|
72
|
+
f"| Cuts per 10 s | min {c[0]} · median {c[1]} · max {c[2]} |",
|
|
73
|
+
f"| Median scene length | {stats['shot_median_s']} s |",
|
|
74
|
+
f"| Music bed (continuous / faint / none) | {m['continua']} / {m['fraca']} / {m['sem']} |",
|
|
75
|
+
f"| Cuts with a sound effect on them | {pct} |", "",
|
|
76
|
+
"Cuts come from scene detection (it undercounts overlays and cards); music and SFX from an audio "
|
|
77
|
+
"heuristic that classifies type, never names the sound ([../research-method.md](../research-method.md)).", "",
|
|
78
|
+
"## Material it needs", "", recipe["needs"], "",
|
|
79
|
+
"## When it fits", "", recipe["fits"], "",
|
|
80
|
+
"## Recipe", "",
|
|
81
|
+
"**Look**", "", *[f"- {x}" for x in recipe["look"]], "",
|
|
82
|
+
f"**Palette:** {recipe['palette']}", "",
|
|
83
|
+
f"**Typography:** {recipe['type']}", "",
|
|
84
|
+
"**Motion**", "", *[f"- {x}" for x in recipe["motion"]], "",
|
|
85
|
+
f"**Captions:** {recipe['captions']}", "",
|
|
86
|
+
f"**Hook (0 to 3 s):** {recipe['hook']}", "",
|
|
87
|
+
f"**CTA:** {recipe['cta']}", "",
|
|
88
|
+
f"**Music:** {recipe['music']}", "",
|
|
89
|
+
f"**SFX:** {recipe['sfx']}", "",
|
|
90
|
+
"## Do not", "", *[f"- {x}" for x in recipe["dont"]], "",
|
|
91
|
+
"## Watch before editing", "",
|
|
92
|
+
*[f"- [{t['channel']}]({t['url']}) · {views(t):,} views" for t in stats["top"]], "",
|
|
93
|
+
]
|
|
94
|
+
if recipe.get("template"):
|
|
95
|
+
lines += ["## Template", "",
|
|
96
|
+
f"`{recipe['template']}` (Remotion). Copy it into the project's `src/`, set the theme and the scenes; see its README.", ""]
|
|
97
|
+
return "\n".join(lines)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def main():
|
|
101
|
+
with open(os.path.join(DATA, "references.json"), encoding="utf-8") as fh:
|
|
102
|
+
refs = json.load(fh)
|
|
103
|
+
with open(os.path.join(DATA, "recipes.json"), encoding="utf-8") as fh:
|
|
104
|
+
recipes = json.load(fh)
|
|
105
|
+
no_views = [r.get("id", "?") for r in refs if not str(r.get("views", "")).isdigit()]
|
|
106
|
+
if no_views:
|
|
107
|
+
sys.exit(f"references without numeric views (fix the data before building): {no_views}")
|
|
108
|
+
bad_niche = sorted({r["nicho"] for r in refs} - set(recipes["niches"]))
|
|
109
|
+
if bad_niche:
|
|
110
|
+
sys.exit(f"references with a niche missing from recipes.json niches: {bad_niche}")
|
|
111
|
+
unknown = sorted({r["style"] for r in refs} - set(recipes["styles"]))
|
|
112
|
+
if unknown:
|
|
113
|
+
sys.exit(f"references with a style that has no recipe: {unknown}")
|
|
114
|
+
stats = aggregate(refs)
|
|
115
|
+
unbacked = sorted(set(recipes["styles"]) - set(stats))
|
|
116
|
+
if unbacked:
|
|
117
|
+
sys.exit(f"recipes with no measured reference: {unbacked}")
|
|
118
|
+
with open(os.path.join(DATA, "styles.json"), "w", encoding="utf-8") as fh:
|
|
119
|
+
json.dump(stats, fh, ensure_ascii=False, indent=1)
|
|
120
|
+
os.makedirs(CARDS, exist_ok=True)
|
|
121
|
+
for key, recipe in recipes["styles"].items():
|
|
122
|
+
with open(os.path.join(CARDS, f"{key}.md"), "w", encoding="utf-8") as fh:
|
|
123
|
+
fh.write(card(key, recipe, stats[key], recipes["niches"]))
|
|
124
|
+
print(f"{len(refs)} references, {len(stats)} styles, cards in references/styles/")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
@@ -22,8 +22,9 @@ const INSTRUCTION_FILES = ['CLAUDE.md', 'AGENTS.md'];
|
|
|
22
22
|
// claude-haiku-4-5 continua atual (não há Haiku mais novo em 2026-09-30).
|
|
23
23
|
// `claude-(opus|sonnet)-5` sem sufixo foi trocado por 5-5; o lookahead evita
|
|
24
24
|
// casar o próprio `-5-5`.
|
|
25
|
+
// A família GPT 5.x (Codex) saiu da escada em 2026-10-05: a família GPT-6 assumiu.
|
|
25
26
|
const RETIRED_MODEL_RE =
|
|
26
|
-
/\bclaude-(?:instant|2|3|3-5|3-7)(?:-[a-z0-9]+)*\b|\bclaude-(?:opus|sonnet)-4(?:-\d+)?\b|\bclaude-(?:opus|sonnet)-5\b(?!-)/gi;
|
|
27
|
+
/\bclaude-(?:instant|2|3|3-5|3-7)(?:-[a-z0-9]+)*\b|\bclaude-(?:opus|sonnet)-4(?:-\d+)?\b|\bclaude-(?:opus|sonnet)-5\b(?!-)|\bgpt-5(?:\.\d+)?(?:-[a-z]+)*\b/gi;
|
|
27
28
|
|
|
28
29
|
const LEGACY_RULES = [
|
|
29
30
|
{ id: 'gsd', re: /\bGSD\b|get-shit-done|\/gsd[:-]/, why: 'GSD foi substituído pelas fases e checkpoints do Wizz Method' },
|