@wji.ai/cli 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -9
- package/skill/short-drama/SKILL.md +44 -23
- package/skill/short-drama/dashboard.html +863 -0
- package/skill/short-drama/examples/night-shift/episodes/E01.json +1 -1
- package/skill/short-drama/examples/night-shift/project.json +5 -4
- package/skill/short-drama/reference/canvas-recipes.md +1 -1
- package/skill/short-drama/reference/cinematography-low-key.md +5 -6
- package/skill/short-drama/reference/cinematography.md +1 -1
- package/skill/short-drama/reference/craft-motion.md +21 -1
- package/skill/short-drama/reference/craft-shots.md +24 -0
- package/skill/short-drama/reference/edit-tools.md +65 -0
- package/skill/short-drama/reference/mix-over-video.md +5 -1
- package/skill/short-drama/reference/operations-cli.md +3 -3
- package/skill/short-drama/reference/schema.md +18 -10
- package/skill/short-drama/reference/stage-characters.md +26 -16
- package/skill/short-drama/reference/stage-storyboard.md +34 -7
- package/skill/short-drama/reference/workspace-layout.md +1 -1
- package/skill/short-drama/scripts/selftest.mjs +440 -33
- package/skill/short-drama/scripts/short-drama.mjs +644 -107
- package/skill/short-drama/scripts/short-drama-dashboard.mjs +0 -459
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wji.ai/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Command line interface for the WJI AI platform",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "WJI AI",
|
|
@@ -28,18 +28,19 @@
|
|
|
28
28
|
"README.md"
|
|
29
29
|
],
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
31
|
+
"node": ">=22.23.4"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup && chmod +x dist/index.js",
|
|
35
|
+
"dev": "tsup --watch",
|
|
36
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
37
|
+
"start": "node dist/index.js",
|
|
38
|
+
"prepublishOnly": "pnpm run build"
|
|
32
39
|
},
|
|
33
40
|
"dependencies": {
|
|
34
41
|
"commander": "^12.1.0"
|
|
35
42
|
},
|
|
36
43
|
"publishConfig": {
|
|
37
44
|
"access": "public"
|
|
38
|
-
},
|
|
39
|
-
"scripts": {
|
|
40
|
-
"build": "tsup && chmod +x dist/index.js",
|
|
41
|
-
"dev": "tsup --watch",
|
|
42
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
43
|
-
"start": "node dist/index.js"
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|
|
@@ -59,7 +59,11 @@ ending), change the guideline first, then the episodes.
|
|
|
59
59
|
古装 / 年代 / 英文美式 / 英文英式 — it decides how the lines are written and the accent the video
|
|
60
60
|
model speaks), ratio (default 9:16 for short, 16:9 for medium and movie). Offer the defaults you will use unless
|
|
61
61
|
told otherwise: `video: h3` (MiniMax H3 ref), `style: realistic`, **`references: sheets`** (no
|
|
62
|
-
storyboard images) and **`videoDuration: auto`**.
|
|
62
|
+
storyboard images) and **`videoDuration: auto`**. That message is a gate. If the user left
|
|
63
|
+
something out — no video model, no episode count, no genre, no 语体 — ask for it, or name the
|
|
64
|
+
default you would use, in the same message. Do not `init`, and do not start Stage 1, until they
|
|
65
|
+
confirm the set. A default is a proposal, not a decision. A resumed `project.json` that already
|
|
66
|
+
has these params is not asked again unless a required field is empty.
|
|
63
67
|
|
|
64
68
|
**The video mode decides how the plot is cut up.** A segment is one video generation, so its
|
|
65
69
|
length is whatever the provider accepts — and that differs by a factor of two:
|
|
@@ -132,7 +136,9 @@ ending), change the guideline first, then the episodes.
|
|
|
132
136
|
`params.violence` is `blood` (default) or `implied`.
|
|
133
137
|
4. **Locate or create the project directory** (the user's choice, else next to the source):
|
|
134
138
|
```bash
|
|
135
|
-
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>"] [--cinematography low-key|sweet-romance|period-nostalgia|costume-idol|costume-dark|scifi-hard|scifi-soft|none] [--action gun-fu|hk-kungfu|wuxia-fantasy|historical-realist|bullet-time|superhero|street-brawl|car-chase|none] [--violence blood|implied] [--grammar drama|action|faceslap|comedy] [--comedy slapstick|deadpan|romcom|none] [--composition standard|art-first] [--story revenge,sweet,…] [--market mainland|overseas] [--format short|medium|movie] [--lang zh]
|
|
139
|
+
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>"] [--cinematography low-key|sweet-romance|period-nostalgia|costume-idol|costume-dark|scifi-hard|scifi-soft|none] [--action gun-fu|hk-kungfu|wuxia-fantasy|historical-realist|bullet-time|superhero|street-brawl|car-chase|none] [--violence blood|implied] [--grammar drama|action|faceslap|comedy] [--comedy slapstick|deadpan|romcom|none] [--composition standard|art-first] [--story revenge,sweet,…] [--market mainland|overseas] [--format short|medium|movie] [--lang zh] [--image-lang en|zh]
|
|
140
|
+
# --image-lang zh: character / scene / prop image prompts in Chinese (the default is English)
|
|
141
|
+
# --foreground low|medium|high: how often cuts shoot past a foreground (default medium; high for 唯美 / 美感优先)
|
|
136
142
|
# params.camera (body / lens / aperture) is edited in project.json
|
|
137
143
|
```
|
|
138
144
|
An existing `project.json` means a resumed run: `validate` and `manifest` tell you where it stands.
|
|
@@ -161,27 +167,33 @@ write JSON → validate --stage <stage> → fix until green → render → sync
|
|
|
161
167
|
|
|
162
168
|
## Production dashboard
|
|
163
169
|
|
|
164
|
-
|
|
165
|
-
|
|
170
|
+
The dashboard is one static file, `{baseDir}/dashboard.html`. It does not bake `project.json`,
|
|
171
|
+
and it does not download images. **Every project keeps its own copy in the same folder as
|
|
172
|
+
`project.json`.** `init` copies it. On any later session, if that file is missing, copy it
|
|
173
|
+
again — do not overwrite a copy that is already there:
|
|
166
174
|
|
|
167
175
|
```bash
|
|
168
176
|
node {baseDir}/scripts/short-drama.mjs dashboard {project}
|
|
169
|
-
# custom location, and a folder of downloaded WJI images:
|
|
170
|
-
node {baseDir}/scripts/short-drama.mjs dashboard {project} \
|
|
171
|
-
--output {project}/dashboard.html --assets {project}/assets --force
|
|
172
177
|
```
|
|
173
178
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
`
|
|
180
|
-
|
|
181
|
-
`
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
179
|
+
That command checks `{project}/dashboard.html`. Missing → copy. Already there → leave it
|
|
180
|
+
(`--force` replaces it with the skill's current page). Open the copy through a local static
|
|
181
|
+
server so it can `fetch` `./project.json` and `episodes/E01.json`. Refreshing re-reads the JSON.
|
|
182
|
+
|
|
183
|
+
Pictures and videos stay as asset ids on `wji.assets.sheet|headshot|keyframe|poster|video`
|
|
184
|
+
(and `lighting:` / `state:` keys). The page asks `POST /assets/check-status` for those ids
|
|
185
|
+
and uses the returned `url` — the same file address as `GET /assets/list/:id` (`wji asset get`).
|
|
186
|
+
Paste the bearer from `wji auth token` once; the browser then loads the CDN url. Do not run
|
|
187
|
+
`wji asset download` for the dashboard. An `https` url already stored on `image.url` /
|
|
188
|
+
`video.url` is used as-is. A relative file that is already in the chosen folder is shown from
|
|
189
|
+
that file. Anything else stays a placeholder. Video urls render as a player.
|
|
190
|
+
|
|
191
|
+
The left nav scrolls the page itself (the section links call `scrollTo` on the content column).
|
|
192
|
+
Bound WJI ids become links to `https://app.wji.ai/app/workspace/<workspaceId>`:
|
|
193
|
+
a canvas is `?app=InfiniteCanvas&canvas=<id>` (and `&node=<id>` when a node is bound);
|
|
194
|
+
a dataset is `?app=Dataset&dataset=<id>`.
|
|
195
|
+
|
|
196
|
+
Do not paste the HTML into a dataset or upload it as an asset.
|
|
185
197
|
|
|
186
198
|
## Stage 1 — Outline
|
|
187
199
|
|
|
@@ -286,14 +298,20 @@ Read `{baseDir}/reference/stage-storyboard.md`.
|
|
|
286
298
|
Every cut is a set-up, so besides its beats and framing it carries the **lens** (`focal`, or let the
|
|
287
299
|
shot size pick it), the **key light relative to the camera** (`light.direction` from the vocabulary
|
|
288
300
|
plus `light.note` saying what it picks out, what fills the shadow side and how it changes over the
|
|
289
|
-
cut) and the **foreground**
|
|
301
|
+
cut) and the **foreground** if the story gives one a reason (`params.foregroundLevel`: `low` / `medium` / `high`). All three are gated and all three go into the
|
|
290
302
|
prompt, alongside the camera package and each speaker's delivery.
|
|
291
303
|
|
|
304
|
+
**Everyone on screen is alive** (gate `idle-motion`, sheets mode): a model freezes whoever the prompt gives no
|
|
305
|
+
motion. In a cut with two or more visible people, all but the one carrying the action get a small
|
|
306
|
+
motion in `idle` (`"still"` when keeping still is the performance). See `craft-motion.md`.
|
|
307
|
+
|
|
308
|
+
**Two people talking** (gate `two-person-framing`, sheets mode): a two-shot once, then over-the-shoulder (`ots`) for the exchange, a clean single for the punchline. A single names only its person; every look states a screen direction (`eyeline`); the sides stay locked. See `reference/craft-shots.md`.
|
|
309
|
+
|
|
292
310
|
**Every cut is lit and composed in the preset's look.** Read the preset's guide
|
|
293
311
|
(`{baseDir}/reference/cinematography-<preset>.md`) before the first storyboard. Name the source
|
|
294
312
|
in `light.source`, stage the person against it, and choose the camera side that gives the
|
|
295
313
|
preset's preferred direction (the table in `cinematography.md`). Compose as the guide says,
|
|
296
|
-
|
|
314
|
+
and stay within the preset's stop (T2.8; T2 for `sweet-romance` and `costume-idol`, which
|
|
297
315
|
start on a T1.3 package and name their bokeh; T4 for `period-nostalgia`). Both costume presets (`costume-idol`, `costume-dark`) also need a 全景 / 大全景 with negative
|
|
298
316
|
space in every segment.
|
|
299
317
|
For `sweet-romance` and `costume-idol`, shoot the 甜宠 set pieces (心动对视, 回眸, 共伞…) as
|
|
@@ -377,8 +395,10 @@ must be connected: pictures, then clips, then voices.
|
|
|
377
395
|
spotting notes for the score.
|
|
378
396
|
6. After each clip: `fs set <shot dataset> [--add-images <keyframes…>] --set primaryVideo=<clip>`;
|
|
379
397
|
bind asset ids.
|
|
380
|
-
7. **Score the edited episode.** When every clip is in,
|
|
381
|
-
`
|
|
398
|
+
7. **Score the edited episode.** When every clip is in, cut them to picture lock as in
|
|
399
|
+
`reference/edit-tools.md`: FilmCraft (`filmcraft-cli`), timeline kept at `edits/E0N.fcproj`,
|
|
400
|
+
or ffmpeg when that CLI is not installed. `wji asset upload` the export and bind
|
|
401
|
+
`wji.assets.edit`. `prompt score E0N [--fps 24]` prints the planned
|
|
382
402
|
spotting sheet — SMPTE rows for the scene beds, every line (where the music ducks), each
|
|
383
403
|
segment's music cues at episode time, the `post` sound design, the sfx already in the clips, the
|
|
384
404
|
hook / turns / 爽点 / cliff (起承转合) and the ≤120 s Seed Audio sections. Conform it to the edit's
|
|
@@ -386,7 +406,8 @@ must be connected: pictures, then clips, then voices.
|
|
|
386
406
|
`reference/bgm-sfx.md`, loudness and terms in `reference/film-mixing-guideline.md`): BGM, BGE /
|
|
387
407
|
ambience and sound design only — never what the clips already carry. One `canvas add audio -n
|
|
388
408
|
"E0N score K" -m seed-audio-1.0 --prompt-file …` per section (~0.15 credits a minute — quote
|
|
389
|
-
first),
|
|
409
|
+
first), lay the sections under the edit with SoundCraft, or ffmpeg when `soundcraft-cli` is
|
|
410
|
+
missing (`reference/edit-tools.md`), upload and bind `wji.assets.mix`.
|
|
390
411
|
`manifest --ep N` must come back clean before you call the episode done. (`audioTrack: bed` /
|
|
391
412
|
`full` instead make a Seed Audio node per segment from `prompt audio E0N-01` and put the music in
|
|
392
413
|
the clip.)
|