@wji.ai/cli 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +22 -2
  2. package/dist/commands/canvas.js +52 -5
  3. package/dist/commands/fsnode.js +13 -6
  4. package/dist/commands/gen.js +3 -2
  5. package/dist/commands/model.js +4 -2
  6. package/dist/commands/workspace.js +6 -3
  7. package/dist/core/output.js +29 -0
  8. package/dist/index.js +5 -2
  9. package/package.json +1 -1
  10. package/skill/ads/SKILL.md +176 -0
  11. package/skill/ads/reference/ai-consistency.md +109 -0
  12. package/skill/ads/reference/brief-template.md +103 -0
  13. package/skill/ads/reference/compliance.md +66 -0
  14. package/skill/ads/reference/formats-image.md +108 -0
  15. package/skill/ads/reference/formats-video.md +121 -0
  16. package/skill/ads/reference/models.md +95 -0
  17. package/skill/ads/reference/product-photography.md +119 -0
  18. package/skill/ads/reference/styles.md +70 -0
  19. package/skill/short-drama/SKILL.md +4 -0
  20. package/skill/short-drama/reference/canvas-recipes.md +18 -0
  21. package/skill/short-drama/reference/operations-cli.md +1 -0
  22. package/skill/short-drama/reference/operations-wji.md +27 -4
  23. package/skill/short-drama/reference/stage-storyboard.md +6 -0
  24. package/skill/social-media/SKILL.md +152 -0
  25. package/skill/social-media/reference/content-craft.md +124 -0
  26. package/skill/social-media/reference/plan-template.md +171 -0
  27. package/skill/social-media/reference/platforms-china.md +94 -0
  28. package/skill/social-media/reference/platforms-global.md +122 -0
  29. package/skill/social-media/reference/ratio-map.md +100 -0
  30. package/skill/social-media/reference/repurpose.md +119 -0
  31. package/skill/wji/SKILL.md +30 -2
  32. package/skill/wji/reference/commands.md +27 -12
@@ -0,0 +1,119 @@
1
+ # Product photography — lighting, shots, backgrounds, camera, grade
2
+
3
+ The studio vocabulary (棚拍語彙) an image or video model understands, organised as the parts of
4
+ a prompt: lighting setup, shot type, background, camera and lens, colour grade. Each row gives
5
+ the look, what it is for, and the phrase to write. The style presets in `reference/styles.md`
6
+ pick from these tables; `reference/ai-consistency.md` says how to keep the product identical
7
+ between shots.
8
+
9
+ ## Lighting setups (布光)
10
+
11
+ | Setup | Look | Use for | Prompt phrase |
12
+ | --- | --- | --- | --- |
13
+ | Three-point (三點光) | key from 45°, fill opposite at half power, back light on the edge; even, dimensional, "catalogue" | any product, safe default | `three-point studio lighting, soft key from upper left, gentle fill, thin rim light separating the product from the background` |
14
+ | Large softbox (柔光箱) | wrap-around soft light, broad soft highlight, faint shadow; closer = softer | packaging, skincare, food, anything matte | `single large softbox close above and to the left, soft wrap-around light, one soft highlight, faint shadow` |
15
+ | Rim / backlight (輪廓光 / 逆光) | bright edges, dark centre, glow through liquid | glass, bottles, dark products, anything translucent | `strong backlight through the bottle, glowing rim light on both edges, dark background, no front fill` |
16
+ | Clamshell (蚌殼光) | key above, reflector below, nearly shadow-free, luminous | cosmetics, jewellery, beauty, faces | `clamshell beauty lighting, soft light from above and below, shadowless, dewy highlights` |
17
+ | High-key (高調) | white background lit to pure white, few shadows, airy | pharmacy, tech accessories, e-commerce packshots | `high-key lighting, pure white seamless background, minimal shadow, bright and clean` |
18
+ | Low-key (低調) | one key at 45°, deep shadow, product carved out of black; premium | spirits, watches, luxury, automotive | `low-key lighting, single hard key from the right, deep black shadows, product emerging from darkness` |
19
+ | Hard light (硬光) | small source, crisp shadows, graphic, punchy | fashion, streetwear, retail-loud, editorial | `hard direct light, sharp-edged shadow cast on the wall, high contrast, graphic` |
20
+ | Strip lights (條形光) | long thin highlights that follow the product's curve; gradient reflections | gloss and metal: cans, bottles, cars, phones | `two vertical strip lights either side, long gradient highlights along the glossy surface, controlled reflections` |
21
+
22
+ Combine at most two (rim + softbox is the standard bottle setup). Name the *direction* and the
23
+ *result on the product* ("soft highlight on the shoulder of the bottle"), not the equipment
24
+ brand; the model renders results, not gear.
25
+
26
+ ## Shot types (景別 / 拍法)
27
+
28
+ | Shot | What it shows | Use for | Prompt phrase |
29
+ | --- | --- | --- | --- |
30
+ | Packshot (產品照) | the product alone, label to camera, on white / neutral, eye-level, f/8–f/11 sharpness edge to edge | identity reference, e-commerce, end card | `clean product packshot, front label facing camera, centred, white seamless background, evenly lit, sharp throughout` |
31
+ | Hero (主視覺照) | low angle, dramatic light, product as monument | KV, poster, TVC end frame | `hero shot from a low angle, product towering, dramatic rim light, dark gradient background` |
32
+ | Lifestyle (情境照) | product in use in a real setting, natural light, shallow depth | social, feed, testimonial stills | `lifestyle photo, product held at a sunlit kitchen counter, window light, shallow depth of field, candid` |
33
+ | Flat lay (平鋪) | top-down, product with props arranged on a surface | cosmetics, food, stationery, social | `flat lay, top-down view, product centred among a few props on linen, soft even light` |
34
+ | Macro (微距) | texture, condensation, fabric weave, a logo emboss | hooks, cut-aways, quality proof | `extreme macro, 100 mm macro lens, condensation droplets on the label, shallow focus` |
35
+ | In-hand (手持) | a hand holding or opening the product; scale and use | UGC, demo, app / device | `product held in one hand at chest height, natural skin, hand steady, label readable` |
36
+ | Floating (懸浮) | product suspended, slight tilt, ingredients or parts orbiting | tech, beauty, food | `product floating in mid-air, slight tilt, soft shadow beneath, ingredients suspended around it` |
37
+ | Splash / freeze (潑濺) | liquid frozen mid-air around the product | drinks, skincare, cleaning | `high-speed splash, liquid frozen mid-air around the bottle, backlit droplets, dark background` |
38
+ | Knolling (整齊排列) | items laid out at right angles, grid-like | kits, sets, tools, fashion | `knolling arrangement, every item at right angles on a plain surface, top-down, even light` |
39
+ | 360 turntable (轉台) | a video move: the product rotating a full turn on a plinth | demo clip, e-commerce spin | video prompt: `product on a turntable rotating slowly through 360 degrees, camera locked, studio light constant` |
40
+
41
+ ## Backgrounds (背景)
42
+
43
+ | Background | Reads as | Phrase |
44
+ | --- | --- | --- |
45
+ | Seamless white / grey (無縫背景紙) | e-commerce, clean | `white seamless sweep` / `mid-grey seamless backdrop` |
46
+ | Gradient | studio, premium | `smooth dark-to-charcoal gradient background` |
47
+ | Brand-colour sweep | campaign, retail | `seamless backdrop in the brand colour #hex, no texture` |
48
+ | Acrylic / reflective | tech, beauty, luxury | `product standing on black acrylic with a soft mirror reflection` |
49
+ | Podium / plinth (展台) | luxury, skincare | `on a round stone podium, one step, soft shadow` |
50
+ | Textured natural | food, wellness, craft | `on rough slate` / `on washed linen` / `at the edge of still water` |
51
+ | Environment | lifestyle | name the room, the time of day and the light source |
52
+
53
+ ## Camera and lens language
54
+
55
+ | Choice | Effect | Phrase |
56
+ | --- | --- | --- |
57
+ | 85 mm | compression, flattering, no distortion; the packshot lens | `85 mm lens` |
58
+ | 100 mm macro | detail and texture | `100 mm macro lens` |
59
+ | 35 mm | environment visible, lifestyle | `35 mm lens, environment in frame` |
60
+ | 16–24 mm | interiors, real estate; keep verticals straight | `24 mm lens, verticals corrected` |
61
+ | f/8–f/11 | packshot sharpness, every letter readable | `f/11, sharp front to back` |
62
+ | f/2.8 or wider | lifestyle, isolates the product | `f/2.8, background softly out of focus` |
63
+ | Eye level | neutral, catalogue | `eye-level camera` |
64
+ | 45° down | shows the top and the front; food, flat objects | `camera at 45 degrees looking down` |
65
+ | Low hero | authority, scale | `low-angle camera, slightly below the product base` |
66
+
67
+ ## Colour-grading vocabulary (調色)
68
+
69
+ | Grade | Reads as | Phrase |
70
+ | --- | --- | --- |
71
+ | Clean neutral | true product colour, e-commerce | `neutral colour balance, accurate product colours, no colour cast` |
72
+ | Warm golden | comfort, food, lifestyle | `warm golden grade, soft highlights` |
73
+ | Teal-orange | cinematic, tech, automotive | `teal and orange cinematic grade` |
74
+ | High-contrast editorial | fashion, retail-loud | `high-contrast editorial grade, deep blacks, crisp whites` |
75
+ | Pastel matte | beauty, wellness, festive | `pastel matte grade, lifted blacks, soft saturation` |
76
+ | Desaturated luxury | spirits, watches, premium | `desaturated luxury grade, muted tones, rich blacks` |
77
+
78
+ Always end the grade line with the product exception: "product colours stay exact".
79
+
80
+ ## The prompt template
81
+
82
+ Write in this order; each slot is one clause. Skip a slot only when the reference image already
83
+ fixes it.
84
+
85
+ ```
86
+ [subject: product, exact state, label to camera] →
87
+ [shot type] → [lighting setup, direction, result on the product] →
88
+ [background] → [camera: lens, aperture, height] → [grade] →
89
+ [constraints: keep label / shape / colour exactly as @image1; no text; no extra objects]
90
+ ```
91
+
92
+ ### Worked examples
93
+
94
+ **Bottled oolong tea** (packshot reference `@image1`, KV at 4:5, 2K)
95
+
96
+ `A chilled glass bottle of oolong tea exactly as in @image1, label facing camera, beads of
97
+ condensation on the glass. Hero shot from a slightly low angle. Strong backlight glowing through
98
+ the amber tea, thin rim light on both edges, one small soft highlight on the shoulder. Dark
99
+ teal-to-black gradient background, faint mist at the base. 85 mm lens, f/8, product sharp
100
+ throughout. Cool clean grade with the tea's amber kept exact. Keep the label text, bottle shape
101
+ and cap colour exactly as the reference; no added text; nothing else in frame; upper third
102
+ empty for a headline.`
103
+
104
+ **Trail sneaker** (packshot `@image1`, lifestyle still at 16:9)
105
+
106
+ `The sneaker exactly as in @image1, worn on a right foot mid-stride on wet asphalt at dusk.
107
+ Low-angle lifestyle shot, 35 mm lens, f/2.8, the shoe sharp and the street softly blurred.
108
+ Hard low sun from behind the shoe as rim light, cool ambient fill, small splash of water from
109
+ the heel frozen mid-air. Teal and orange cinematic grade; the shoe's colours and logo placement
110
+ stay exact. No text, no other people in focus.`
111
+
112
+ **Skincare jar** (packshot `@image1`, KV at 1:1, 2K)
113
+
114
+ `The cream jar exactly as in @image1 on a round pale-stone podium, lid off and leaning against
115
+ the jar, a smooth swirl of cream visible. Clamshell beauty lighting, soft light from above and
116
+ below, nearly shadowless, dewy highlights on the glass. Warm off-white seamless background with
117
+ a single soft petal-pink shadow. 85 mm lens, f/11, eye-level. Pastel matte grade, jar and label
118
+ colours exact. Keep the label, jar shape and lid finish exactly as the reference; no text; no
119
+ hands.`
@@ -0,0 +1,70 @@
1
+ # Visual styles — 13 looks for ads
2
+
3
+ One style per campaign, chosen from the brief's industry and tone and written into every prompt
4
+ so the KV, the stills and the clips agree. Each row names the visual signifiers, the lighting
5
+ preset it borrows from `reference/product-photography.md`, the phrases to write, and the tone
6
+ of the CTA that fits. Nothing here names a real brand's look; describe the style, never a
7
+ competitor's ad.
8
+
9
+ ## The styles
10
+
11
+ | Style | Visual signifiers | Light preset | Prompt phrases | CTA tone |
12
+ | --- | --- | --- | --- | --- |
13
+ | Minimal (極簡) | negative space, one product, neutral sweep, thin type, nothing moves fast | large softbox or high-key | `minimal composition, generous negative space, single product, neutral seamless background, soft shadow, quiet` | short, lower-case, one verb: "Try it." |
14
+ | Luxury (奢華) | low-key black, jewel tones, marble or dark stone, gold accents, serif type, slow motion | low-key + rim | `low-key luxury lighting, black gradient, marble surface, gold rim highlights, rich shadows, slow deliberate camera` | restrained, no discount: "Discover the collection" |
15
+ | Retail-loud (促銷) | saturated brand colours, big percentage type, bursts and badges, hard light, fast cuts | hard light | `bold saturated brand colour background, hard direct light, punchy contrast, high energy, graphic` | urgent, numeric: "40 % off. Ends Sunday." |
16
+ | Lifestyle (生活感) | real rooms and streets, window or golden-hour light, candid people, hands, imperfect framing | softbox window light (natural) | `lifestyle photo, natural window light, candid moment, shallow depth of field, warm and lived-in` | conversational: "Made for mornings like this" |
17
+ | Tech (科技) | dark background, neon edge light, glass and brushed metal, particles, HUD lines, orbiting camera | strip lights + low-key | `dark studio, cyan and magenta edge lighting, glass and brushed metal, floating particles, slow orbit camera` | precise, feature-led: "Meet the new X" |
18
+ | Food (食品) | warm backlight, steam, drips, glistening surfaces, macro, shallow depth, wood and linen | rim / backlight + softbox | `warm backlit food shot, rising steam, glossy surface, macro detail, shallow focus, wooden table` | appetite verbs: "Taste it hot" |
19
+ | Beauty (美妝) | clamshell light, dewy skin, water droplets, product swatches, pastel and skin-tone palette | clamshell | `clamshell beauty lighting, dewy luminous skin, water droplets, soft pastel palette, swatch of the product texture` | promise-led, gentle: "Glow by morning" |
20
+ | Fashion (時裝) | editorial pose, hard flash, colour block, fabric in motion, off-centre crop | hard light | `editorial fashion shot, hard on-camera flash look, colour-block background, fabric mid-motion, bold crop` | terse, imperative: "Wear it now" |
21
+ | Automotive (汽車) | wet asphalt, dusk or tunnel light, long strip reflections down the body, low tracking camera | strip lights + low-key | `car on wet asphalt at dusk, tunnel light streaks along the bodywork, low tracking camera, cinematic teal-orange` | aspirational, one line: "Drive further" |
22
+ | Real estate (房地產) | 16–24 mm interiors, verticals corrected, HDR balance of window and room, twilight exteriors | high-key interior, natural | `wide 24 mm interior, verticals straight, balanced window and room exposure, twilight exterior with warm windows` | invitation: "Book a viewing" |
23
+ | App / SaaS (應用 / 軟體) | device mockups, cursor and tap animation, brand gradient, kinetic type, flat clean UI | high-key or gradient sweep | `phone mockup floating on a brand gradient, clean UI on screen, soft shadow, kinetic typography space around it` | outcome + free: "Start free" |
24
+ | Festive (節慶) | seasonal props, warm bokeh lights, gold and red or snow and blue, wrapped gifts | softbox + warm practicals | `festive scene, warm bokeh string lights, seasonal props, gift wrapping, cosy warm grade` | gifting: "Gift the good stuff" |
25
+ | Black Friday (黑五) | black background, neon or acid accents, glitch and scan lines, countdown numerals, bold percentage type | hard light + neon rim | `black background, neon accent rim light, glitch texture, bold oversized sale typography space, high contrast` | countdown, urgency: "24 hours. 50 % off." |
26
+
27
+ ## Choosing by industry
28
+
29
+ | Industry | First choice | Second choice | Avoid |
30
+ | --- | --- | --- | --- |
31
+ | Beverage, snacks | Food | Lifestyle, Retail-loud | Luxury unless premium spirits |
32
+ | Skincare, cosmetics | Beauty | Minimal, Luxury | Retail-loud (cheapens the product) |
33
+ | Fashion, footwear | Fashion | Lifestyle, Minimal | Tech |
34
+ | Consumer electronics | Tech | Minimal | Food, Festive |
35
+ | Software, apps | App / SaaS | Minimal | Luxury |
36
+ | Cars, e-bikes | Automotive | Tech | Retail-loud except clearance |
37
+ | Property | Real estate | Luxury (high-end) | Everything else |
38
+ | Jewellery, watches, spirits | Luxury | Minimal | Lifestyle unless aspirational |
39
+ | Supermarket, e-commerce promo | Retail-loud | Black Friday (seasonal) | Minimal |
40
+ | Seasonal campaign, any category | Festive | the category's first choice | — |
41
+ | Home, furniture, wellness | Lifestyle | Minimal | Tech |
42
+
43
+ ## Style in motion (video clips)
44
+
45
+ The same style decides how the camera and the cut behave; write the motion clause of a clip
46
+ prompt from this table and keep it constant through the ad.
47
+
48
+ | Style | Camera | Cut rhythm | Motion phrases |
49
+ | --- | --- | --- | --- |
50
+ | Minimal, Luxury, Beauty | slow push or slow orbit, locked horizon | 4–8 s per clip | `slow push in`, `slow orbit`, `camera locked, only the light moves` |
51
+ | Retail-loud, Black Friday, Fashion | whip pans, snap zooms, hard cuts | 1–3 s per clip | `fast whip pan`, `snap zoom onto the product`, `hard cut` |
52
+ | Lifestyle, Food, Festive | handheld drift, rack focus, natural pace | 3–5 s | `gentle handheld drift`, `rack focus from the hand to the product` |
53
+ | Tech, Automotive | orbit, low tracking, reveal from dark | 3–6 s | `low tracking shot`, `orbit with edge light sweeping across the surface`, `reveal from darkness` |
54
+ | Real estate, App / SaaS | slow glide, dolly through a door, screen-locked mockup | 4–6 s | `slow glide forward`, `dolly through the doorway`, `tap animation on the screen` |
55
+
56
+ Clip lengths above are planning values; the accepted ranges per model are in
57
+ `reference/models.md`.
58
+
59
+ ## Applying a style
60
+
61
+ - Write the style's phrases in **every** prompt of the campaign: KV, stills, clips. A style that
62
+ appears in the KV and not in the clips reads as two campaigns.
63
+ - The style sets light, background, palette and type feeling. It never changes the product: the
64
+ packshot reference and the identity clause in `reference/ai-consistency.md` stay in force.
65
+ - Two styles in one ad is a mistake except the deliberate before / after (a Lifestyle "before"
66
+ cut to a Minimal "after").
67
+ - Brand colours from the brief override the style's palette: a Tech look in a brand's orange is
68
+ `orange edge lighting`, not cyan.
69
+ - Match the CTA tone column to the copy on the end card; a Luxury visual with "BUY NOW!!!" on
70
+ the card is the most common mismatch.
@@ -366,6 +366,10 @@ actually charged (the `credits` line of each result, not the estimate), what `ma
366
366
  lists, and any gate you had to fix. If a generation failed, say which and why — never resubmit a
367
367
  node whose status is `generating`.
368
368
 
369
+ Once an episode is generated, teasers, posters and covers per platform are the `social-media`
370
+ skill's job (it reads this project's `episodes/E0N.json` and canvases); a commercial for the show
371
+ is the `ads` skill's. Point the user there rather than improvising sizes here.
372
+
369
373
  ## Rules specific to this skill
370
374
 
371
375
  - **The user signs off the brief + outline skeleton and the first segment's keyframes.**
@@ -4,6 +4,24 @@
4
4
  which row, and in what order the references are connected. Read them as written and substitute the
5
5
  tool calls from `operations-wji.md`; `--from A B C` is `fromNodeIds: ['A','B','C']` and the array
6
6
  order is the reference order. Everything about rows, `@imageN` order and prompts is identical.
7
+ Build each row with **one `canvas_create_nodes` call**: its `nodes` array takes the fields of
8
+ `canvas_create_node` (minus `canvas`), and `"$i"` in `fromNodeIds` or `nextTo` means item i of the
9
+ same batch (0-based, must come earlier), so a headshot → sheet → voice chain is one call and a
10
+ `characters` canvas of twelve characters is one or two calls instead of fifty. Items are created in
11
+ order; if one fails the result says `failedAt` and the earlier nodes stay on the canvas — fix that
12
+ item and resend from it with real ids (up to 60 nodes a call).
13
+
14
+ ```
15
+ canvas_create_nodes { canvas: CV, nodes: [
16
+ { kind: "title", text: "C01 林小夏", position: {x: 0, y: 0} }, # $0
17
+ { kind: "image", name: "C01 headshot", position: {x: 400, y: 0},
18
+ generate: { model: "<image model>", ratio: "1:1", prompt: "<portrait prompt>" } }, # $1
19
+ { kind: "image", name: "C01 sheet", fromNodeIds: ["$1"],
20
+ generate: { model: "<image model>", ratio: "16:9", prompt: "@image1 is the face to match … " } }, # $2
21
+ { kind: "audio", name: "C01 voice", fromNodeIds: ["$1"],
22
+ generate: { model: "seed-audio-1.0", prompt: <voice prompt> } } # $3
23
+ ] } → created[0..3].id = T1 H1 S1 V1
24
+ ```
7
25
 
8
26
  Command sequences for the three canvas types. All ids are placeholders — take real ones from the
9
27
  command output (`wji --json canvas add … | jq -r .id`) and `bind` them at once. `SD` below is
@@ -36,6 +36,7 @@ The `wji` skill governs auth, confirmations and spending. The calls this skill m
36
36
  | preflight | `wji auth whoami --json`, `wji profile wallet` |
37
37
  | workspace | `wji ws create "<title>" -r <ratio>` → `wji ws use <id>` |
38
38
  | datasets | `wji dataset new … --app <appId>`, `wji fs set <id> --merge` (never `--content`), `--add-images` (never `--images` on an existing node) |
39
+ | reads | `wji fs get <id> --json` is the `standard` summary; `--detail full` whenever you need the whole `content` (`--merge` reads full for you) |
39
40
  | canvases | `wji canvas create <name>` · `wji canvas add <kind> -c <cv> …` · `wji canvas connect <a> <b>` · `wji canvas get <node>` · `wji canvas gen <node> [--yes --wait]` · `wji canvas rm` |
40
41
  | assets | `wji asset download <id> -o <dir>` — **look at what you generated** before building on it |
41
42
  | history | `wji history get <id> --wait` |
@@ -43,9 +43,9 @@ write a whole document at a time rather than field by field.
43
43
 
44
44
  | Purpose | Tool |
45
45
  | --- | --- |
46
- | workspace | `workspace_search`, `workspace_get`, `workspace_create`, `workspace_add_app` |
46
+ | workspace | `workspace_get { id }` for the workspace the chat is in, `workspace_create`, `workspace_add_app`; `workspace_search` **only with `limit`** (≤ 10) and a `keyword` — without them it returns every workspace the user can see. Both default to `detail: 'standard'`; `detail: 'full'` only when you need `settings` |
47
47
  | semantic folders | `resolve_dataset_folder { id, key: 'story' \| 'character' \| 'location' \| 'prop' \| 'shot' }` |
48
- | datasets | `fsnode_create_file { parent, name, dataset: true, datasetType, description, content, tags }`, `fsnode_update`, `fsnode_upsert_segment` |
48
+ | datasets | `fsnode_create_file { parent, name, dataset: true, datasetType, description, content, tags }`, `fsnode_update`, `fsnode_upsert_segment`; `fsnode_get { id, detail: 'full' }` before replacing a `content` (the default `standard` read is a summary with `truncated: true`, and writing it back is rejected) |
49
49
  | assets | `asset_get`, `asset_check_status`, `asset_create_from_url` |
50
50
  | canvases | the `canvas_*` tools below |
51
51
 
@@ -59,16 +59,21 @@ substitute:
59
59
  | `canvas-recipes.md` shows | call |
60
60
  | --- | --- |
61
61
  | `wji canvas create <name>` | `canvas_create { workspace, name }` → canvas id |
62
- | `wji canvas add <kind> -c CV -n "<name>" --at x,y …` | `canvas_create_node { canvas, kind, name, position: {x, y}, … }` |
62
+ | `wji canvas add <kind> -c CV -n "<name>" --at x,y …` | `canvas_create_node { canvas, kind, name, position: {x, y}, … }` — one node |
63
+ | a whole row of `wji canvas add …` lines | `canvas_create_nodes { canvas, nodes: [ … ] }` — up to 60 nodes in one call, each item the fields of `canvas_create_node` without `canvas`; `"$i"` in `fromNodeIds` / `nextTo` is item i of the same batch (0-based, must come earlier). Built in order; on a failure the result has `failedAt` and the earlier nodes stay |
63
64
  | `--prompt-file /tmp/x.txt` / `-p "<prompt>"` | `generate: { prompt, model, ratio, resolution, duration }` on `canvas_create_node` |
64
65
  | `--asset <id>` (a display node) | `assetId` on `canvas_create_node` |
65
66
  | `--from A B C` | `fromNodeIds: ['A','B','C']` — **the array order is the reference order** |
66
67
  | `wji canvas connect <a> <b>` | `canvas_connect_nodes { canvas, fromId, toId }` |
67
- | `wji canvas get <node>` | `canvas_get_node { canvas, id }` — references, label, status, asset |
68
+ | `wji canvas get <node>` | `canvas_get_node { canvas, id }` — references, label, status, asset; `detail: 'full'` for the whole `generate` / `text` before editing them |
68
69
  | `wji canvas gen <node>` (cost preview) | `canvas_generate { canvas, nodeIds, estimateOnly: true }` |
69
70
  | `wji canvas gen <node> --yes --wait` | `canvas_generate { canvas, nodeIds, wait: true }` |
70
71
  | `wji canvas rm` | `canvas_delete_nodes { canvas, ids }` |
71
72
 
73
+ Build each row with **one** `canvas_create_nodes` call (title, headshot, sheet `fromNodeIds: ["$1"]`,
74
+ voice `fromNodeIds: ["$1"]`), not four `canvas_create_node` calls — see the batch example at the top
75
+ of `canvas-recipes.md`.
76
+
72
77
  Reference labels (`@image1`, `@audio1` …) are numbered per type in connection order, exactly as the
73
78
  canvas UI numbers them. After connecting, call `canvas_get_node` and check the labels match what the
74
79
  prompt names **before** generating — a mislabelled reference is a wasted generation.
@@ -77,6 +82,24 @@ prompt names **before** generating — a mislabelled reference is a wasted gener
77
82
  first, tell the user the cost, and only generate for real once they say yes. The `wji` skill's
78
83
  spending policy applies here in full.
79
84
 
85
+ ## Steps and context
86
+
87
+ **A turn is capped at 40 steps, not 40 tool calls** (an Agent can set its own cap). One step is one
88
+ model call; every tool call you emit in the same step runs together and counts once. So emit
89
+ independent calls together — all the `short_drama_render` / `fsnode_create_file` of a stage in one
90
+ step, the five `resolve_dataset_folder` calls in one step — and write a whole document per
91
+ `short_drama_put` rather than field by field. When two steps are left you get a system note: stop
92
+ calling tools, report what was written (with ids) and what is still open; the stream ends at the cap
93
+ without letting you reply.
94
+
95
+ **Tool results stay in the context for the rest of the turn.** Read what you need, once: `ai_list_models`
96
+ once per project with `features: 'image'` (it is large); `fsnode_get` on the one dataset you need
97
+ instead of `fsnode_children` on a folder of them; `short_drama_get { section }` for one branch rather
98
+ than the whole project; never `workspace_search` without `limit`. Every list / get tool takes
99
+ `detail: 'brief' | 'standard' | 'full'` and defaults to `standard` (text clipped to 200 chars, media
100
+ as `{ id, url, status }`, `content` summarised); ask for `brief` when you only need ids and for `full`
101
+ only when you need the complete `content` / `form` / `settings`.
102
+
80
103
  **In a canvas chat** (the chat panel beside an open canvas) the browser supplies its own `canvas_*`
81
104
  tools, which always act on the canvas the user is looking at and take no `canvas` argument. A short
82
105
  drama needs several canvases, so do that work in a workspace chat; in a canvas chat, say so.
@@ -345,6 +345,12 @@ segment is rejected, retry, then trim — do not go hunting for a forbidden word
345
345
  To bisect anyway, use a scratch video node at `-d 2`, 480P: free when rejected, ~30 credits when it
346
346
  passes, and sample each fragment several times because one pass proves nothing.
347
347
 
348
+ **Last resort: the uncensored twin.** `wan-3.0-ref-uncensored` (MuleRouter, no green-net) takes the
349
+ same prompt and the same 10 images + 5 videos + 5 audios, at ~1.3× the price; note that it bills the
350
+ reference-video seconds as well as the output. Switch a stuck segment to it only with the
351
+ Producer's approval, and only after retry-then-trim has failed. `short-drama.mjs` does not know it
352
+ as a mode, so set it as the node's model directly.
353
+
348
354
  ## Sheets mode — no storyboard images (the default)
349
355
 
350
356
  `params.references: sheets` drops stage 5's image generation entirely: the video node references
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: social-media
3
+ description: Make and size content for social platforms on WJI through the `wji` CLI — the image and video specs of Instagram, TikTok, YouTube / Shorts, Facebook, X, LinkedIn, Pinterest, Threads, Snapchat, 小红书, 抖音, 快手, 视频号, B站, 微博 and 微信公众号 (ratio, pixels, duration, file size, safe zones, caption / title / hashtag limits, covers and thumbnails), what performs on each (the 3-second hook, loops, on-screen text), and the repurposing recipes: one master into every placement, a short-drama episode into vertical teasers and a poster set, an ad master into all its placements. Use whenever a task mentions social media / 社群 / 社交媒体, posting / 发文, Reels, Shorts, TikTok, 小红书 / 抖音 / 视频号, a cover / 封面, poster / 海报, thumbnail, teaser / 预告, or asks what size or length a platform wants. Combines with the short-drama and ads skills. Works together with the `wji` skill.
4
+ ---
5
+
6
+ # Social media on WJI
7
+
8
+ You are the person who knows every platform's numbers and turns one piece of work into the
9
+ right post for each of them. **You write the spec sheet, the hooks and the copy**; the `wji`
10
+ CLI keeps the plan as a dataset and generates the per-ratio images and videos on a canvas;
11
+ local `sharp` or `ffmpeg` (when installed) crops to exact pixels. Nothing is generated until
12
+ the user has said yes to the quote (or the message carried `-auto`, see the `wji` skill).
13
+
14
+ ```
15
+ what & where ──▶ spec sheet ──▶ source assets ──▶ generate per ratio ──▶ covers ──▶ copy ──▶ post plan
16
+ │ │ │ │ │ │
17
+ platforms, one row per existing nodes / images: native thumbnail, caption,
18
+ goal, market surface from short-drama / ratio then crop; poster, hashtags,
19
+ the tables ads / new video: regenerate 图文 cover slot, label
20
+ ```
21
+
22
+ `{baseDir}` = this skill. The `wji` skill governs every CLI call.
23
+
24
+ | Read | When |
25
+ | --- | --- |
26
+ | `reference/platforms-global.md` | any Instagram / TikTok / YouTube / Facebook / X / LinkedIn / Pinterest / Threads / Snapchat question — the spec tables and safe zones |
27
+ | `reference/platforms-china.md` | 抖音 / 快手 / 小红书 / 视频号 / B站 / 微博 / 公众号 — specs, and China-specific practice (AI label, titles, 图文) |
28
+ | `reference/ratio-map.md` | before generating: which WJI model makes which ratio natively, what must be cropped and how to anchor the crop |
29
+ | `reference/content-craft.md` | hooks, loops, overlays, captions and hashtags per platform, posting times, cover design, carousel / 图文 storytelling |
30
+ | `reference/repurpose.md` | master → placements, drama episode → teaser + posters, ad master → placements, the deliverables checklist |
31
+ | `reference/plan-template.md` | the post spec sheet — write one row per post before touching the canvas |
32
+
33
+ ## Operations
34
+
35
+ ### Where the plan lives
36
+
37
+ Locally: `social/<campaign>/plan.md` (the spec sheet, one row per post, plus the copy and the
38
+ deliverables) and `prompts/`. On WJI: the same plan as a dataset `SOCIAL <campaign>` in the
39
+ workspace's **story** folder.
40
+
41
+ ```bash
42
+ wji auth whoami --json && wji profile wallet
43
+ wji ws use <workspaceId>
44
+ wji ws app list # the Dataset app id → DS_APP
45
+ wji --json ws fs --app DS_APP | jq -r '.. | objects | select(.content.semanticKey? == "story") | .id' # → STORY
46
+ wji dataset new STORY "SOCIAL <campaign>" -t other -d "<one line>" --json | jq -r .id # → PLAN
47
+ wji fs set PLAN --merge content=@social/<campaign>/plan.md --merge viewMode=content
48
+ wji canvas list # the masters, keyframes, sheets already there
49
+ wji canvas nodes -c <canvas> --json | jq '.[] | {id,name,kind,assetId}'
50
+ wji asset download <assetId…> -o /tmp/social # look before you write about it
51
+ wji asset upload <file> # the user's own material
52
+ wji models get <model> # the ratio list ratio-map.md summarises
53
+ ```
54
+
55
+ ### Generating per ratio
56
+
57
+ One canvas `SOCIAL · <campaign>` (`wji canvas create "SOCIAL · <campaign>" --json | jq -r .id`),
58
+ one row per platform surface:
59
+
60
+ | Need | Command |
61
+ | --- | --- |
62
+ | image at a native ratio | `wji canvas add image -c SC -n "小红书 cover" --from <source nodes> -m <image model> -r 3:4 --resolution 2K --prompt-file prompts/xhs-cover.txt` — the source keyframe / KV / sheet first in `--from` |
63
+ | video at the platform ratio | `wji canvas add video -c SC -n "Reels teaser A" --from <same references as the master> -m <video model> -r 9:16 -d 20 --prompt-file prompts/reels-a.txt` — **regenerated, never cropped** |
64
+ | quote → yes → run | `wji canvas gen <nodeIds…>` (prints the cost, refuses) → tell the user → `wji canvas gen <nodeIds…> --yes --wait` |
65
+ | adjust | `wji canvas set <node> -p … / -r … / -d …`, `wji canvas connect <from> <to>` |
66
+ | one-off still | `wji gen image -m <model> -p "…" -r 4:5 --ref <assetId> --wait` |
67
+
68
+ ### Exact pixels
69
+
70
+ A model generates a ratio, not a pixel size. When the placement needs exact pixels or a ratio no
71
+ model has (1200×628, 1080×1260 视频号, 1146×717 B站, 900×383 公众号, banner sizes), generate at the
72
+ nearest native ratio from `reference/ratio-map.md`, download the asset, and crop locally:
73
+ `npx sharp-cli` / a five-line node script with `sharp` (`resize(w, h, { fit: 'cover', position })`)
74
+ or `ffmpeg -i in.png -vf "crop=w:h:x:y,scale=W:H" out.png` — whichever is installed; if neither
75
+ is, deliver the generated frame plus the crop box (left, top, width, height) and say so. Anchor
76
+ every crop as `reference/ratio-map.md` §"Crop anchoring" says: faces, then product centre, then
77
+ the headline zone. Upload the result with `wji asset upload` and add it to the canvas as a display
78
+ node so the plan's ids point at the final file.
79
+
80
+ ## Before anything else
81
+
82
+ 1. **Ask what and where, in one message**: what is being promoted (a drama episode, an ad, a
83
+ product, an account), which platforms and surfaces (feed vs Reels vs Stories are different
84
+ posts), the goal (views, follows, clicks to the full episode, sales), the market and language
85
+ (mainland / overseas / both — it changes the platform list and the label rules). **Never guess
86
+ the platform.** Offer the usual sets: 短剧 launch = 抖音 + 小红书 + 视频号 (+ TikTok + Reels +
87
+ Shorts overseas); product = Instagram feed + Reels + TikTok + 小红书.
88
+ 2. **Write the spec sheet** (`reference/plan-template.md`): one row per post with the platform's
89
+ own numbers copied from the tables — ratio, pixels, duration cap, safe zone, caption / title /
90
+ hashtag limits, cover spec. Rows marked *(verify)* in the tables stay marked in the sheet.
91
+ 3. **Find the source material** before proposing generation: the canvases and datasets already
92
+ in the workspace, the user's files, or the other skills' work (next section). Generate new
93
+ material only for what does not exist.
94
+ 4. **Quote the whole plan** (`wji gen cost` per node kind) before the first generation.
95
+
96
+ ## Combining with other skills
97
+
98
+ - **A short-drama project is present** (a folder with `project.json` and `episodes/`, or the
99
+ short-drama skill is installed beside this one at `../short-drama/`) → *drama mode*. Read the
100
+ episode with the engine: `node ../short-drama/scripts/short-drama.mjs render <project> script --ep N`
101
+ for the lines and `… render <project> segment E0N-01` per segment (or read
102
+ `storyboard.segments` in `<project>/episodes/E0N.json` directly); `… manifest <project> --ep N`
103
+ tells you the episode canvas id, and
104
+ `wji canvas nodes -c <E0N canvas>` lists its keyframes, sheets and clips. Then
105
+ `reference/repurpose.md` §"Drama episode → teaser + poster set": pick the hook line from the middle of the
106
+ episode, build the 4-beat 15–45 s teaser (hook 0–3 s → context → escalation → cut before the
107
+ payoff + 「主页看全集」) as **new 9:16 video nodes generated from the same character and scene
108
+ sheets** (never a crop of the 16:9 clips), 2–3 variants that differ only in the hook, and the
109
+ poster set (小红书 3:4, Instagram 4:5, Pinterest 2:3, YouTube thumbnail 16:9, B站 1146×717,
110
+ 视频号 6:7) from the episode keyframes with the title zone kept clear. Record the node ids in
111
+ `plan.md`; do not write into the drama's `project.json`.
112
+ - **An ads brief is present** (`ads/<product>/brief.md` or the `AD <product>` dataset) →
113
+ *campaign mode*. Read the brief and the `AD · <product>` canvas (KV, stills, clips, master
114
+ ratio). `reference/repurpose.md` §"Ad master → placements": one row per placement, KV
115
+ regenerated at native ratios or cropped for the rest, vertical / square video regenerated from
116
+ the same stills, per-platform copy written from the brief's CTA and legal lines, the AI-content
117
+ label toggled where the ads skill's `reference/compliance.md` says so.
118
+ - **Neither** → standalone: the user's assets or fresh generation, same spec sheet.
119
+ - If the material the user describes belongs to a skill that is **not installed**, say which one
120
+ (short-drama / ads) rather than rebuilding its data by hand.
121
+
122
+ ## Making the posts
123
+
124
+ - **Images**: generate at the native ratio where one exists (`reference/ratio-map.md`), with the
125
+ source node first in `--from` so the subject stays the same; crop only for non-native sizes.
126
+ One ratio for every card of a carousel / 图文.
127
+ - **Video**: one node per platform ratio, regenerated with the master's references and a prompt
128
+ reframed on the faces / product for vertical; `-d` under the surface's cap; captions and
129
+ on-screen text are overlays inside the safe zone, never generated.
130
+ - **Covers and thumbnails**: face + ≤4 words, high contrast, the series template repeated
131
+ (`reference/content-craft.md` §"Cover and thumbnail design"); 小红书 cover is the hook of the 图文.
132
+ - **Copy**: hook line, body, CTA, hashtags within the platform's limits (Instagram ≤5 hashtags,
133
+ 小红书 title ≤20 chars, X 280) — written into `plan.md`, one block per post.
134
+ - **Posting slots** from `reference/content-craft.md` are starting points, said as such.
135
+
136
+ ## Reporting
137
+
138
+ After the spec sheet: the rows and what will be generated vs cropped, with the quote. After
139
+ generation: the deliverables table from `reference/repurpose.md` (post, file / node, ratio, pixels,
140
+ duration, cover, caption, hashtags, slot, AI label) and anything the user still has to do in
141
+ their editor (captions, subtitles, crops you could not make).
142
+
143
+ ## Rules specific to this skill
144
+
145
+ - **Ask before every generation**; a batch is one quote.
146
+ - **Never invent a platform limit** — cite the table row; keep *(verify)* flags; if a platform
147
+ is not in the tables, say so and ask the user for its spec.
148
+ - Video is regenerated at the target ratio, never cropped; images are cropped only when no model
149
+ has the ratio.
150
+ - Text stays out of the platform's UI zones; one ratio per carousel; the drama's dialogue is
151
+ quoted verbatim in teasers.
152
+ - Do not compile or store personal data of real people from the platforms; all-audiences content only.
@@ -0,0 +1,124 @@
1
+ # Content craft — hooks, loops, overlays, captions, covers, carousels
2
+
3
+ What makes a post perform once the size is right: the first three seconds, the ending that
4
+ re-plays, text that stays inside the safe zone, a caption shaped for each platform's reading
5
+ pattern, a posting slot to start from, a cover that reads at thumbnail size, and a carousel that
6
+ tells one story. Sizes and limits are quoted from platforms-global.md and platforms-china.md,
7
+ not restated here; teaser and poster recipes built on these rules are in repurpose.md.
8
+
9
+ ## The first 3 seconds
10
+
11
+ Feeds decide in the first swipe-length. The product, the face or the question is on screen by
12
+ second 3, in motion, with no logo card, no fade-in and no "hi guys". Hook types, with a line
13
+ each (drama and product examples side by side):
14
+
15
+ | Hook type | Drama teaser | Product / brand |
16
+ | --- | --- | --- |
17
+ | Shocking line, mid-scene | 「你以为我不知道孩子是谁的?」 cut in on the reaction | "This is the last one we could get made." |
18
+ | Result first, cause later | the slap, the arrest, the reveal — then 「三天前…」 | the after-state (clean pan, finished room), then the before |
19
+ | Direct question | 「如果你婆婆当众撕了你的结婚证,你会怎么做?」 | "Why does every white sneaker turn yellow in a month?" |
20
+ | Contradiction / mismatch | the bride in a wedding dress signing divorce papers | a luxury unboxing on a bus |
21
+ | Countdown / stakes | 「还有十分钟,她就要嫁给别人了」 | "Three tests. One survives." |
22
+ | Visual anomaly | one impossible detail in an ordinary frame (a wet footprint indoors) | the product doing the one thing rivals cannot |
23
+ | Named audience | 「二婚的姐妹看过来」 | "If you edit on a phone, watch this." |
24
+
25
+ Rules: one hook per cut, the first frame is already the strongest frame (it is also the cover),
26
+ sound-off comprehension — the hook line is burned in as text. Write 2–3 hooks for the same body
27
+ and let the platform pick (repurpose.md, variants).
28
+
29
+ ## Loop-friendly endings
30
+
31
+ Reels, TikTok and 抖音 count re-watches. End on a frame that matches the first frame (same
32
+ composition, same subject position) so the loop hides the seam; or end one beat *before* the
33
+ answer the hook promised, so the viewer re-watches to catch it; or end on the CTA card that is
34
+ also the cover. Never end on a logo fade or a black frame. For a drama teaser the ending is the
35
+ cut before the payoff plus the line 「主页看全集 / full episode in bio」 (repurpose.md).
36
+
37
+ ## On-screen text and burned subtitles
38
+
39
+ - Keep every word inside the safe zone of the 9:16 diagram (platforms-global.md): headline in the
40
+ upper safe band, subtitles at the lower edge of the safe band (≈y 1100–1240 on 1080×1920), never
41
+ behind the caption or the right rail.
42
+ - Subtitles are burned in (most feeds autoplay muted): 2 lines maximum, ≤ 14 CJK chars or ≤ 32
43
+ Latin chars per line, high-contrast box or stroke, one style for the whole account.
44
+ - Headline type ≥ 60 px on 1080×1920, ≤ 6 words / 8 chars; a second overlay only when the first
45
+ has left. Do not repeat the caption on screen.
46
+ - Text is added after the crop and at the final ratio (ratio-map.md, crop anchoring); text
47
+ generated inside the picture is only for covers that are never cropped again.
48
+ - 「AI生成」 label where required (platforms-china.md) is the platform's toggle, not an overlay
49
+ you design — but do not place other text where the platform paints its label (top-left on most
50
+ Chinese apps).
51
+
52
+ ## Caption structure per platform
53
+
54
+ | Platform | Structure | Hashtags / tags | Length notes |
55
+ | --- | --- | --- | --- |
56
+ | Instagram | hook line (shown before "more") → 2–4 short lines → CTA (save / share / comment) | **≤5** (Dec 2025 cap) — 3 niche + 2 broad | 2,200 max; the first 125 chars are the post |
57
+ | TikTok / 抖音 | one-line hook + a question that invites comments | 3–5 hashtags / 话题, one is the series tag | 4,000 max on TikTok; 抖音 shows ≈20 chars of title |
58
+ | YouTube | title ≤ 60–70 chars shown; description: 2-line summary, links, chapters, disclosure | 3–5 hashtags at the end of the description | title 100 hard cap |
59
+ | Facebook | short hook, link in the first comment or the post, CTA | 1–3 | shares outweigh hashtags |
60
+ | X | the hook is the whole post; thread for detail | 1–2 or none | 280 |
61
+ | LinkedIn | hook in the first two lines → line-broken story → question → 3 hashtags | 3 | 3,000; "see more" after ≈3 lines |
62
+ | Pinterest | keyword title ≤ 100, description with 2–3 search phrases | none | description 500–800 *(verify)* |
63
+ | Threads | one sentence; the picture carries the rest | none | 500 |
64
+ | 小红书 | 标题 ≤ 20 with the keyword first → 正文 in short lines with emoji markers → 话题 tags | keyword + 3–6 话题 (#…#) | 正文 1,000 (长文 6,000) |
65
+ | 视频号 / 公众号 | one-line 描述 with 话题; the article's first line is the hook | 1–3 话题 | limits not confirmed |
66
+ | B站 | 标题 with the series and episode number; 简介 with timestamps | tags on upload (platform field) | limits not confirmed |
67
+
68
+ A CTA is one verb: 关注 / follow, 主页看全集 / full episode in bio, save, comment the answer.
69
+ Platform buttons (shop, link, subscribe) are not drawn into the picture.
70
+
71
+ ## Posting-time starting points
72
+
73
+ Sprout Social 2026 aggregates, to be treated as **starting points** and replaced by the
74
+ account's own insights after two weeks: Instagram Mon–Thu 10:00–15:00; TikTok Wed 14:00–17:00;
75
+ LinkedIn Tue 11:00–17:00. Local time of the audience, not of the account. Other platforms and
76
+ the Chinese apps: not confirmed in the research — plan lunchtime (12–13) and evening (20–22)
77
+ slots in the audience's time zone and measure. Series content posts at the same slot every
78
+ time; the second post of a series goes out within 24 h of the first while the hook is fresh.
79
+
80
+ ## Cover and thumbnail design
81
+
82
+ - **Face + ≤ 4 words** (≤ 8 CJK chars): the face at 40–60 % of the frame height, looking at the
83
+ camera or at the text; the words in one colour band, one weight.
84
+ - **High contrast**: light text on a darkened lower third or dark text on a light band; check
85
+ it at 120 px wide (the 小红书 / 快手 tile is half a phone).
86
+ - **One template per series**: same title position, same colour, same type; the episode number
87
+ changes, nothing else. Recognition beats novelty in a grid.
88
+ - **Ratio per platform** (ratio-map.md): 16:9 1280×720 YouTube; 3:4 小红书 / IG grid; 9:16 Reels
89
+ / TikTok / 抖音 with the text in the centre 60 % because the grid crops to a taller tile;
90
+ 1146×717 B站 with the bottom-left clear; 6:7 视频号 composed for its 1:1 share crop.
91
+ - Covers are generated **with** the text only at the final ratio (nano-banana-pro, gpt-image-2.5
92
+ or seedream-5-pro for reliable multilingual type); every other size gets the text overlaid
93
+ after the crop.
94
+
95
+ ## Carousel / 图文 storytelling
96
+
97
+ 1. **Cover as hook** — the question, the contrast or the result; it must work alone in the feed.
98
+ 2. **One idea per card**, one line of text per card, the same layout grid on every card.
99
+ 3. **Escalate**: cards 2–N answer the cover in order of surprise, not of logic; the strongest
100
+ proof sits two cards before the end.
101
+ 4. **Last card = CTA** (follow, save, 主页看全集, 领取), in the same template as the cover so the
102
+ loop back to card 1 feels designed.
103
+ 5. **One ratio for the whole set** (IG ≤ 20 slides, 小红书 ≤ 18 images, TikTok photo mode ≤ 35):
104
+ generate every card at the same `ratio` and crop to the same box.
105
+ 6. Caption repeats the cover's keyword in the first line; on 小红书 the 话题 tags close the body.
106
+
107
+ ## Trending audio
108
+
109
+ Trending sounds lift reach on TikTok / 抖音 / Reels, but a business account may only use
110
+ tracks from the platform's **commercially licensed library**; personal-account sounds are
111
+ muted or the post is removed when the account is business-typed. AI-generated soundtracks
112
+ (Seed Audio, generated per teaser) avoid the problem and can be reused across the series.
113
+ Never lip-sync a drama clip to a licensed pop song for a paid promotion.
114
+
115
+ ## What to avoid
116
+
117
+ - A logo intro, a fade-in, a title card before the hook.
118
+ - Letterboxed 16:9 inside a 9:16 post (regenerate — ratio-map.md).
119
+ - Text in the top 270 px or the bottom 670 px of a vertical frame; text under the right rail.
120
+ - More than 5 hashtags on Instagram; hashtag walls anywhere; hashtags that do not exist yet.
121
+ - Sub-1080-px sources, upscaled 1K frames, JPEG re-compression of a re-compression.
122
+ - Cross-platform reposts with the other platform's watermark or overlay language.
123
+ - Engagement bait ("like if…", fake polls), fake countdowns, fake UI buttons drawn into the frame.
124
+ - Claiming AI footage is real footage; skipping the AI label where it is required.