@wji.ai/cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/commands/canvas.js +91 -12
- package/dist/commands/fsnode.js +30 -1
- package/dist/commands/gen.js +4 -19
- package/dist/commands/workspace.js +6 -2
- package/dist/index.js +4 -1
- package/package.json +1 -1
- package/skill/short-drama/SKILL.md +305 -0
- package/skill/short-drama/examples/night-shift/episodes/E01.json +1883 -0
- package/skill/short-drama/examples/night-shift/project.json +774 -0
- package/skill/short-drama/reference/canvas-recipes.md +199 -0
- package/skill/short-drama/reference/craft-motion.md +116 -0
- package/skill/short-drama/reference/craft-shots.md +177 -0
- package/skill/short-drama/reference/craft-story.md +188 -0
- package/skill/short-drama/reference/dialogue-craft.md +120 -0
- package/skill/short-drama/reference/schema.md +435 -0
- package/skill/short-drama/reference/stage-art.md +56 -0
- package/skill/short-drama/reference/stage-characters.md +206 -0
- package/skill/short-drama/reference/stage-outline.md +103 -0
- package/skill/short-drama/reference/stage-script.md +113 -0
- package/skill/short-drama/reference/stage-storyboard.md +465 -0
- package/skill/short-drama/reference/workspace-layout.md +118 -0
- package/skill/short-drama/scripts/selftest.mjs +1411 -0
- package/skill/short-drama/scripts/short-drama.mjs +3371 -0
- package/skill/wji/SKILL.md +97 -22
- package/skill/wji/reference/canvas-recipes.md +16 -2
- package/skill/wji/reference/commands.md +15 -6
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: short-drama
|
|
3
|
+
description: Produce an AI short drama (短劇) on the WJI platform end to end — write it the way a commercial 短剧 is written (创作简报, 创作指引, 人物圣经, 分集目录 with 爽点 and 钩子, the 15-second hook and 30-second turns, 谈话+行动, the right 语体), adapt a story or novel into an outline, character / scene / prop bibles, per-episode scripts and storyboards, then generate the sheets, keyframes and video clips through the `wji` CLI, with data stored as workspace datasets and the work laid out on canvases (characters, scenes, one per episode). Every stage is gated by `scripts/short-drama.mjs validate`. Use whenever a task mentions short drama, 短劇 / 短剧, 分集 / 分镜 / 剧本 for AI video, or producing a serialised video story on WJI. Works together with the `wji` skill.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Short drama on WJI
|
|
7
|
+
|
|
8
|
+
Five stages, one project directory, one workspace. The **model writes the design fields**; the
|
|
9
|
+
**script checks them** (`validate`), derives what can be derived (`seed`, `prompt`) and keeps the
|
|
10
|
+
local ↔ WJI bindings (`manifest`, `bind`). Nothing is generated until its stage is green.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
outline ──▶ characters ──▶ art ──▶ script (per episode) ──▶ storyboard (per episode)
|
|
14
|
+
│ │ │ │ │
|
|
15
|
+
story/ character/ location/ story/ shot/E01/ datasets
|
|
16
|
+
dataset datasets + prop/ screenplay + E01 canvas: keyframes → video
|
|
17
|
+
`characters` datasets + dataset
|
|
18
|
+
canvas `scenes` canvas
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`{baseDir}` = this directory. Script: `node {baseDir}/scripts/short-drama.mjs <cmd> …` (zero
|
|
22
|
+
dependencies). Read `{baseDir}/reference/schema.md` before writing any JSON and
|
|
23
|
+
`{baseDir}/reference/workspace-layout.md` before touching WJI. The `wji` skill governs every CLI
|
|
24
|
+
call (auth, confirmations, spending policy, model choice) — this skill only says what to build.
|
|
25
|
+
|
|
26
|
+
**How the drama is written** comes from `{baseDir}/reference/craft-story.md` (the 短剧 method:
|
|
27
|
+
brief, three phases, 分集目录, 爽点 / 钩子 libraries, the episode formula, the character bible) and
|
|
28
|
+
`{baseDir}/reference/dialogue-craft.md` (lines as action, 语体 rules, the polish pass). Read the
|
|
29
|
+
first before stage 1 and the second before stage 4. The gates encode what those two can check.
|
|
30
|
+
|
|
31
|
+
**Re-read the guideline.** The 创作指引 (`render guideline`) is the drama's top rule document.
|
|
32
|
+
Print it before writing any character, any episode and any storyboard, and print the speakers'
|
|
33
|
+
`render character` before writing their lines — a script that drifts from the guideline is wrong
|
|
34
|
+
even when every gate is green. When the user changes a core requirement (genre, register, length,
|
|
35
|
+
ending), change the guideline first, then the episodes.
|
|
36
|
+
|
|
37
|
+
## Before anything else
|
|
38
|
+
|
|
39
|
+
1. **Preflight WJI**: `wji auth whoami --json`, the version check from the `wji` skill,
|
|
40
|
+
`wji profile wallet` (a drama is many generations — know the balance).
|
|
41
|
+
2. **Scan the message for `-auto`** (spending waiver, see the `wji` skill). Without it: one image
|
|
42
|
+
runs, video and batches ask first.
|
|
43
|
+
3. **Ask the parameters once**, in one message: episodes × minutes per episode, genre, adapt
|
|
44
|
+
mode (原创 / 忠实 / 抽核 / 借壳), the 语体 (`register`: 粤语 / 大陆普通话 / 台湾国语 / 港式普通话 /
|
|
45
|
+
古装 / 年代 / 英文美式 / 英文英式 — it decides how the lines are written and the accent the video
|
|
46
|
+
model speaks), ratio (default 9:16). Offer the defaults you will use unless
|
|
47
|
+
told otherwise: `video: h3` (MiniMax H3 ref), `style: realistic`, **`references: sheets`** (no
|
|
48
|
+
storyboard images) and **`videoDuration: auto`**. Do not start Stage 1 without the first two.
|
|
49
|
+
|
|
50
|
+
**The video mode decides how the plot is cut up.** A segment is one video generation, so its
|
|
51
|
+
length is whatever the provider accepts — and that differs by a factor of two:
|
|
52
|
+
|
|
53
|
+
| `--video` | model | segment | images | voices | auto duration | prompt |
|
|
54
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
55
|
+
| `h3` | `minimax-h3-ref` | **5–15 s** | 9 | 3 | ✗ — always `fixed` | English, keyframe-pinned |
|
|
56
|
+
| `seedance` | `seedance-2.5-ref` | **4–30 s** | 30 | 10 | ✓ | English, `@imageN` |
|
|
57
|
+
| `seedance2` | `seedance-2.0-ref` | **4–15 s** | 9 | 3 | ✓ | English, `@imageN` |
|
|
58
|
+
| `seedance2fast` | `seedance-2.0-fast-ref` | **4–15 s** | 9 | 3 | ✓ | English, `@imageN` |
|
|
59
|
+
| `wan` | `wan-3.0-ref` | **2–30 s** | 10 | 5 | ✓ | Chinese prose, **speaks the dialogue itself** |
|
|
60
|
+
|
|
61
|
+
All five take **whole seconds only**, and each has its own resolution tiers (h3: 480P / 768P /
|
|
62
|
+
2K / 4K — note there is no 720P; the Seedance pair is lowercase; wan: 480P / 720P / 1080P).
|
|
63
|
+
`validate` checks the spelling against the model. Pick the mode **before** the storyboard: the
|
|
64
|
+
same 90-second episode is 7 generations on a 15 s model and 3 on a 30 s one, and
|
|
65
|
+
`seed storyboard` computes that split for you. With `wan`, set `speechAccent` (e.g.
|
|
66
|
+
台湾口音国语) because the model speaks the lines.
|
|
67
|
+
|
|
68
|
+
**Style**: `photoreal` for a live-action drama, `realistic` for semi-realistic painterly,
|
|
69
|
+
`ghibli` for hand-painted anime. **References** (default `sheets`): the video node references
|
|
70
|
+
the character/scene sheets directly and no storyboard images are generated — fewer images to
|
|
71
|
+
pay for and approve, and continuity comes from the sheets. Choose `keyframes` (one generated
|
|
72
|
+
image per cut) only when a shot has to be composed exactly; h3 needs it for its keyframe-pinned
|
|
73
|
+
prompt. **Duration** (default `auto`): the model matches the clip to the prompt; `fixed` sends
|
|
74
|
+
`-d` = Σ cuts and is forced on models without an auto duration.
|
|
75
|
+
|
|
76
|
+
**The camera package** is `params.camera` — body, lens family and working stop, default
|
|
77
|
+
`ARRI ALEXA Mini LF` / `Zeiss Supreme Prime` / `T1.5`. Every shot prompt names it verbatim, so
|
|
78
|
+
the drama looks shot on one rig; a cut can override the focal and the stop. A look the user asks
|
|
79
|
+
for on top of that (大光圈, 背景虛化, 前景模糊…) goes in `lookPhrase`.
|
|
80
|
+
4. **Locate or create the project directory** (the user's choice, else next to the source):
|
|
81
|
+
```bash
|
|
82
|
+
node {baseDir}/scripts/short-drama.mjs init <dir> --title "<title>" --episodes N --minutes M --genre "<genre>" --register 台湾国语 [--adapt 抽核] [--ratio 9:16] [--video h3|seedance|seedance2|seedance2fast|wan] [--resolution 480P|…] [--accent "台湾口音国语"] [--style photoreal|realistic|ghibli] [--references sheets|keyframes] [--duration auto|fixed] [--look "<lens phrase>"] [--lang zh]
|
|
83
|
+
# params.camera (body / lens / aperture) is edited in project.json
|
|
84
|
+
```
|
|
85
|
+
An existing `project.json` means a resumed run: `validate` and `manifest` tell you where it stands.
|
|
86
|
+
5. **Workspace**: reuse the one bound in `project.json`; otherwise create it and bind the ids
|
|
87
|
+
(`wji ws create "<title>" -r <ratio>` → `wji ws use` → find the semantic
|
|
88
|
+
folders → `bind`). Details in `reference/workspace-layout.md`.
|
|
89
|
+
|
|
90
|
+
## The loop every stage follows
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
write JSON → validate --stage <stage> → fix until green → render → sync datasets → build canvas → generate → bind ids
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **Validate before spending.** `validate` exits 1 with the failing gates; fix each one, re-run.
|
|
97
|
+
Never generate from a red stage.
|
|
98
|
+
- **Sync = publish.** `render` produces the markdown for the dataset's `content.content`; the
|
|
99
|
+
entity JSON goes to `metadata.shortDrama`; prompts to `image_prompt` / `video_prompt` /
|
|
100
|
+
`audio_prompt` (a character's voice brief). Use
|
|
101
|
+
`wji fs set --merge …` (never `--content`), `--add-images` (never `--images` on an existing node).
|
|
102
|
+
- **Bind immediately.** Every id `wji` returns goes into `project.json` / `episodes/E<nn>.json`
|
|
103
|
+
with `bind` before the next command. `manifest` lists what is still unbound; run it before creating
|
|
104
|
+
anything so a resumed run never duplicates.
|
|
105
|
+
- **Look at what you generated.** `wji asset download <id> -o <dir>` and open the image before
|
|
106
|
+
approving a sheet or moving to the next segment. The reference-repo lesson: one wrong sheet
|
|
107
|
+
corrupts every shot after it.
|
|
108
|
+
|
|
109
|
+
## Stage 1 — Outline
|
|
110
|
+
|
|
111
|
+
Read `{baseDir}/reference/stage-outline.md`.
|
|
112
|
+
|
|
113
|
+
1. **Brief first**: `outline.brief` — the six judgements (logline, audience, 爽点 engine, main
|
|
114
|
+
hook, the pressures on both sides, emotional line, promise). If the user gave one line, ask
|
|
115
|
+
the focusing questions; do not invent a genre.
|
|
116
|
+
2. **Skeleton**: `outline.core/keep/cut/merge/risks`, `characters[]` (id/name/tier/role/arc/from),
|
|
117
|
+
`scenes[]` (id/name/primary/reusePlan), `props[]` (id/name/function/beatIds), `beats[]`,
|
|
118
|
+
`outline.structure` (golden / escalation / climax with episode ranges) and `outline.guideline`
|
|
119
|
+
(tone, intensity, dialogue style, visual style, limits, ≥ 3 forbidden, 3–5 priorities).
|
|
120
|
+
`validate --stage outline` will still fail on `episodes` — that is expected at this point; read
|
|
121
|
+
the other gates.
|
|
122
|
+
3. **Sign-off ⛔**: show the user the brief, what was cut, who was merged, where the major beats
|
|
123
|
+
land (`cutNote` / `mergeNote`) and the guideline's priorities. Do not write episode synopses
|
|
124
|
+
before they agree — a wrong skeleton wastes every downstream stage.
|
|
125
|
+
4. **Episodes** in batches of ≤10 — design before prose: `function` / `task` / `change` /
|
|
126
|
+
`satisfaction` / `hookType` (the 分集目录; episode 1 grabs, 2 proves the 爽点, 3 widens the line,
|
|
127
|
+
the finale settles), then `synopsis` / `hook` / `suspense` / ids / `crowdPlan` / `warnings`;
|
|
128
|
+
`validate --stage outline` until green.
|
|
129
|
+
5. Sync: `render outline` → `story/` dataset (type `outline`, `viewMode=content`), bind
|
|
130
|
+
`wji.outlineDatasetId`; `render guideline` → its own `story/` dataset `<title> 创作指引`
|
|
131
|
+
(type `outline`), bind `wji.guidelineDatasetId`.
|
|
132
|
+
|
|
133
|
+
## Stage 2 — Characters
|
|
134
|
+
|
|
135
|
+
Read `{baseDir}/reference/stage-characters.md`.
|
|
136
|
+
|
|
137
|
+
1. Fill `oneLiner`, `profile` (with the 关系网 in `relationships`: surface / real / power / secret),
|
|
138
|
+
**`bible`** (剧情功能, 一句话人物钩子, Want vs Need, 核心误信, 核心矛盾, 受压反应, `speech` — and for leads
|
|
139
|
+
the wound, past choices, forbidden / mustFace and the arc; `craft-story.md` §7), `identityEn`,
|
|
140
|
+
`image` (portrait prompt, negative, 16:9 sheet prompt, tags) and `voice` for every character;
|
|
141
|
+
`validate --stage characters`. Two of those exist purely so a video prompt can talk about the
|
|
142
|
+
person: **`identityEn`** is the name-free way to refer to them (`the woman in her mid thirties
|
|
143
|
+
in headphones`) and **`voice.videoDirection`** is one English clause on how they speak, pasted
|
|
144
|
+
beside every line they say in every clip — written from `bible.speech`.
|
|
145
|
+
2. Sync each character to a `character/` dataset (description = oneLiner, content = `render
|
|
146
|
+
character C01`, `image_prompt` = the sheet prompt, `audio_prompt` = `prompt voice C01`,
|
|
147
|
+
metadata = the JSON).
|
|
148
|
+
3. `characters` canvas (`wji canvas create characters` once): per character a title node, a
|
|
149
|
+
**headshot** image node (1:1, portrait prompt), a **sheet** image node (16:9, `--from` the headshot,
|
|
150
|
+
sheet prompt prefixed with `@image1 is the face to match`), and a **voice** audio node
|
|
151
|
+
(`seed-audio-1.0`, `--from` the headshot — the model reads the face and invents a voice for it;
|
|
152
|
+
the composed prompt asks for a dry voice, because the same model also makes rooms, scores and
|
|
153
|
+
sound effects — that is what its stage-5 soundtrack nodes are for;
|
|
154
|
+
`prompt voice C01` composes the text: a parenthetical carrying age, identity, personality,
|
|
155
|
+
timbre, pitch, pace, accent and emotion, then the acted line).
|
|
156
|
+
Recipes in `reference/canvas-recipes.md`.
|
|
157
|
+
4. Generate headshots first (single images run without asking; a batch of them is a batch — quote
|
|
158
|
+
the total), inspect, then sheets and voices from the approved headshots. Listen to each voice.
|
|
159
|
+
Attach all three assets — the asset list takes audio too:
|
|
160
|
+
`fs set <dataset> --add-images <headshot> <sheet> <voice> --icon <headshot> --set primaryAudio=<voice>`; bind node and asset ids.
|
|
161
|
+
|
|
162
|
+
## Stage 3 — Art (scenes + props)
|
|
163
|
+
|
|
164
|
+
Read `{baseDir}/reference/stage-art.md`.
|
|
165
|
+
|
|
166
|
+
1. Scenes: `summary`, 3–5 `anchors`, `lighting` states derived from the episodes the scene appears
|
|
167
|
+
in, empty-scene `image.*`; variants via `variantOf` + `changes`. Props (only narrative ones):
|
|
168
|
+
`scale`, `anchors`, `states`, white-background `image.*`. `validate --stage art`.
|
|
169
|
+
2. Sync to `location/` and `prop/` datasets; `scenes` canvas: one sheet node per scene / prop
|
|
170
|
+
(16:9), variant and state nodes `--from` the parent sheet. Generate, inspect (no people in a
|
|
171
|
+
scene, no hands on a prop, one space across all panels), attach as `icon`, bind.
|
|
172
|
+
|
|
173
|
+
## Stage 4 — Script (per episode, batches of ≤3)
|
|
174
|
+
|
|
175
|
+
Read `{baseDir}/reference/stage-script.md`.
|
|
176
|
+
|
|
177
|
+
1. `render guideline` and the speakers' `render character` first. Then `seed script --ep N`
|
|
178
|
+
writes `episodes/E0N.json` with target seconds, hook/cliff, claimed beats, the episode design
|
|
179
|
+
(`function` / `task` / `change` / `hookType`, `satisfactionBeat` to set) and a `seedNote`
|
|
180
|
+
(synopsis, the 爽点 to realise, register, guideline priorities, every speaker's `bible.speech`,
|
|
181
|
+
ids, previous cliff, budget). Fill `scenes[].flow` — action beats and line beats alternating,
|
|
182
|
+
**common actions only**, hook image inside the first 3 beats and by 15 s, a `turn: true` beat
|
|
183
|
+
at least every 30 s, the 爽点 on an action (`satisfactionBeat`), cliff as the last beat; lines
|
|
184
|
+
in the register, from each speaker's `speech` (`dialogue-craft.md`). Delete `seedNote` when done.
|
|
185
|
+
2. `validate --stage script --ep N` — duration math, line length, speakers, hook window, the
|
|
186
|
+
rhythm, the design, filmability, upstream ids; the register gate only advises. Over budget: cut
|
|
187
|
+
actions first; under: add conflict, not small talk. When dialogue is the weakness, run the
|
|
188
|
+
polish pass: `render dialogue --ep N` → fill the 逐句校对表 → apply → re-validate.
|
|
189
|
+
3. Sync: `render script --ep N` (the 短剧 episode format with the 创作自检 table) → `story/` dataset
|
|
190
|
+
`E0N 剧本` (type `screenplay`, `viewMode=content`); bind `wji.screenplayDatasetId` with `--ep N`.
|
|
191
|
+
|
|
192
|
+
## Stage 5 — Storyboard (per episode)
|
|
193
|
+
|
|
194
|
+
Read `{baseDir}/reference/stage-storyboard.md`.
|
|
195
|
+
|
|
196
|
+
Every cut is a set-up, so besides its beats and framing it carries the **lens** (`focal`, or let the
|
|
197
|
+
shot size pick it), the **key light relative to the camera** (`light.direction` from the vocabulary
|
|
198
|
+
plus `light.note` saying what it picks out, what fills the shadow side and how it changes over the
|
|
199
|
+
cut) and the **foreground** to throw out of focus. All three are gated and all three go into the
|
|
200
|
+
prompt, alongside the camera package and each speaker's delivery.
|
|
201
|
+
|
|
202
|
+
**And every cut is a shot with a job** — read `{baseDir}/reference/craft-shots.md` and
|
|
203
|
+
`{baseDir}/reference/craft-motion.md` before the first storyboard. In both reference modes a cut
|
|
204
|
+
carries its `purpose` (kind + what changes), its three framing axes (`angle`, `height`, `axisSide`
|
|
205
|
+
against the segment's declared `axis`), its `start` / `end` boundaries (positions, facing, gaze,
|
|
206
|
+
hands, held props per person — the next cut and the next segment begin where these end), its
|
|
207
|
+
`motion` (cue → one visible action → landing) and `cameraNote` (a lock-off says what still moves, a
|
|
208
|
+
move says why and where it ends); the segment carries its `sound` (ambience chained across the
|
|
209
|
+
scene, sfx per cut, music intent) and the 爽点 / cliff scenes a `visualPlan`. `frame` stays the
|
|
210
|
+
frozen start instant. `prompt segment` composes all of it into the prompt, and the prompt is
|
|
211
|
+
delivery text: no ids, files or notes, subtitles off, the other person's lips closed while one
|
|
212
|
+
speaks (H3), everyone bound by `@imageK` in their own shot (sheets).
|
|
213
|
+
|
|
214
|
+
**Everything the node references is addressed by its label, everywhere it applies.** WJI numbers
|
|
215
|
+
connected references per type, each series from 1: `@image1…` the sheets or keyframes, `@video1…`
|
|
216
|
+
the previous clip when `params.videoReferences: previous` is on (continuity of grade and camera
|
|
217
|
+
language — opt-in), `@audio1…` the voice samples of whoever speaks. The legend says what each one
|
|
218
|
+
is, and then each label is used where it belongs — `@imageK` in the shot that anchors on it,
|
|
219
|
+
`@videoK` in the sentence saying what to carry over, and **every line a character speaks names
|
|
220
|
+
their `@audioN`**, at each line rather than once in the legend, because the model picks a voice per
|
|
221
|
+
line. All of it is gated. `prompt segment` prints the references in the exact order the video node
|
|
222
|
+
must be connected: pictures, then clips, then voices.
|
|
223
|
+
|
|
224
|
+
1. `seed storyboard --ep N` adds `storyboard.plan`, `storyboard.seedScenes` (every beat with its
|
|
225
|
+
computed seconds, an axis hint per scene) and `storyboard.visualPlans` (the worksheet for the
|
|
226
|
+
爽点 scene and the cliff scene — fill it before cutting them). **Follow the plan**: it reads the chosen model's duration range and says how
|
|
227
|
+
many segments each scene needs and how long each should be — the split follows the model, not
|
|
228
|
+
the story's own rhythm, because a segment is one generation and cannot outlast what the provider
|
|
229
|
+
accepts. Then cut the episode into those **segments** (one scene each,
|
|
230
|
+
`minSegmentSeconds`–`maxSegmentSeconds`, whole seconds) of **cuts** (2–5 s, claiming consecutive
|
|
231
|
+
beats). Per cut: `purpose`, `angle` / `height` / `axisSide`, `start` (first cut) and `end`,
|
|
232
|
+
`motion`, `cameraNote`, light / foreground / `background`, then the `frame` (the start instant);
|
|
233
|
+
per segment `axis` and `sound`. Then the segment `prompt` — take the skeleton from
|
|
234
|
+
`prompt <project> segment E0N-01` and fill in the descriptions. Delete `seedScenes` and `plan`
|
|
235
|
+
when done. `validate --stage storyboard --ep N` (the advisory `storyboard-advice` only notes).
|
|
236
|
+
2. Sync: shot folder `shot/E0N`, one `shot` dataset per segment (`video_prompt` = the prompt,
|
|
237
|
+
content = `render segment E0N-01` — the 分镜 with one `### SHOT k` block per cut).
|
|
238
|
+
3. `E0N` canvas (`wji canvas create E0N`): display nodes for every sheet the episode uses
|
|
239
|
+
(`canvas add image --asset …`, keyed in `wji.displayNodes`). Then, in the default `sheets` mode,
|
|
240
|
+
the video node per segment straight from those display nodes (`--from` them in the order
|
|
241
|
+
`prompt segment` prints the legend — the order is the legend, so a reconnect must redo the whole
|
|
242
|
+
set). With `references: keyframes`, first a keyframe node per cut (`--from` the display nodes,
|
|
243
|
+
ratio = `params.ratio`), then the video node `--from` the keyframes in cut order.
|
|
244
|
+
Either way the video node takes the mode's model, `--resolution params.videoResolution`,
|
|
245
|
+
`--prompt-file`, and `-d` = Σ cut seconds **only in `fixed` duration mode** — in `auto` leave
|
|
246
|
+
`-d` off and let the model match the clip to the prompt.
|
|
247
|
+
4. In `sheets` mode go straight to generating the clips. With `keyframes`, **generate the first
|
|
248
|
+
segment's keyframes only**, download, check: same world as the scene sheet, same faces as the
|
|
249
|
+
character sheets, the right shot size, nobody extra in frame. Regenerate what is off, then
|
|
250
|
+
continue segment by segment. Keyframes for one segment are a batch (quote the total); each video
|
|
251
|
+
is a video (ask, or `-auto`). Stay under the queue cap (`wji` skill *Limits*): submit up to the
|
|
252
|
+
cap, `wji history get <id> --wait`, continue.
|
|
253
|
+
5. **Soundtrack node** per segment (`params.audioTrack`, default `bed`): `prompt audio E0N-01`
|
|
254
|
+
derives a Seed Audio prompt from `segment.sound` — timecoded `[start s:end s]` ambience, sfx on
|
|
255
|
+
their cuts, music that enters / swells / ducks / falls silent at the cues you wrote on
|
|
256
|
+
`sound.music.cues` — and `canvas add audio -m seed-audio-1.0 --prompt-file …` makes it (~0.15
|
|
257
|
+
credits a minute, no `--from`; `--full` adds the lines in the connected `@Audio1..3` voices).
|
|
258
|
+
Seed Audio is the voice-sample model, but it is an audio-scene generator: one prompt is a whole
|
|
259
|
+
track. Attach the asset to the shot dataset; bind `wji.nodes.track` / `wji.assets.track`.
|
|
260
|
+
6. After each clip: `fs set <shot dataset> --add-images <keyframes…> <track> --set primaryVideo=<clip>`;
|
|
261
|
+
bind asset ids. `manifest --ep N` must come back clean before you call the episode done.
|
|
262
|
+
|
|
263
|
+
- **A failed generation is not always a bad prompt.** `wan-3.0-ref` rejections from DashScope's
|
|
264
|
+
content filter (`DataInspectionFailed`) charge nothing and are partly random — retry the same node
|
|
265
|
+
8–12 times, then **shorten** the prompt (that, not rewording, is what clears a stuck one).
|
|
266
|
+
|
|
267
|
+
## Reporting
|
|
268
|
+
|
|
269
|
+
One line per stage when you stop: what exists (counts), what was generated and the credits
|
|
270
|
+
actually charged (the `credits` line of each result, not the estimate), what `manifest` still
|
|
271
|
+
lists, and any gate you had to fix. If a generation failed, say which and why — never resubmit a
|
|
272
|
+
node whose status is `generating`.
|
|
273
|
+
|
|
274
|
+
## Rules specific to this skill
|
|
275
|
+
|
|
276
|
+
- **The user signs off the brief + outline skeleton and the first segment's keyframes.**
|
|
277
|
+
Everything else runs on the `wji` spending table.
|
|
278
|
+
- **The guideline outranks a good idea.** A single episode's idea that conflicts with
|
|
279
|
+
`outline.guideline` is either dropped or the guideline is changed with the user first.
|
|
280
|
+
- **Ids are stable.** Never renumber `C01` / `S01` / `P01` / `B01` / `E01-01` after a dataset or node
|
|
281
|
+
is bound; add new ids at the end.
|
|
282
|
+
- **Prompts never carry names.** Faces come from the sheet references; `validate` rejects a name
|
|
283
|
+
or alias in any English prompt.
|
|
284
|
+
- **The voice sample is a reference, not a deliverable.** 3–5 s, acted, generated from the
|
|
285
|
+
headshot; it connects to later video nodes as `@audio1` to hold the timbre the way the sheet
|
|
286
|
+
holds the face.
|
|
287
|
+
- **In `wan` mode the dialogue audio also comes from the video model** — the video model speaks the lines from the segment
|
|
288
|
+
prompt's 音频 line. Fill the `voice` fields anyway; they are the register, and the gate wants them.
|
|
289
|
+
- **One style for the whole drama** (`params.style`). Changing it later means regenerating every
|
|
290
|
+
sheet — say so before doing it.
|
|
291
|
+
- **Keyframes at `params.ratio`, sheets at 16:9.** A 9:16 drama still gets landscape sheets.
|
|
292
|
+
- **Don't fight a gate by loosening `params`** unless the user asks; the thresholds encode
|
|
293
|
+
production limits (H3 15 s, 2–5 s attention span, one breath per line).
|
|
294
|
+
|
|
295
|
+
## Self-test
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
node {baseDir}/scripts/selftest.mjs # no model calls, every gate has a breaking case
|
|
299
|
+
node {baseDir}/scripts/short-drama.mjs validate {baseDir}/examples/night-shift
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`examples/night-shift` — 《夜班便利店》, 3 × 1 min, three characters, two scenes, one prop, episode 1
|
|
303
|
+
scripted and storyboarded in H3 mode — passes every gate (the register gate is advisory and clean)
|
|
304
|
+
and is the reference for the shape of every field, the brief, the guideline and the bibles
|
|
305
|
+
included.
|