@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wji.ai/cli",
3
- "version": "0.8.1",
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": ">=20"
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`**. Do not start Stage 1 without the first two.
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
- Generate the dashboard whenever the user wants to review the project, and refresh it after a
165
- stage or episode is locked:
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
- The output is one static HTML file: production totals and gate health, brief and guideline,
175
- episode directory, character bibles, scene / prop sheets, scripts, cut timing and storyboard
176
- plans. It does not call WJI and costs no credits. Every character, scene, prop and storyboard
177
- slot keeps an image placeholder until a picture or video is bound. A bound value may be a WJI
178
- server URL (`https://…` image or video) or a local file: set `image.url` / `video.url`, or
179
- `wji.assets.sheet|headshot|keyframe|video`, to that URL or to a path relative to the project
180
- (or an absolute path). Files whose name contains the entity or asset id are also picked up from
181
- `{project}/assets`, `{project}/output`, the project tree, or `--assets <dir>`. A video URL or
182
- `.mp4` / `.webm` / `.mov` file renders as a player; if the address fails to load, the
183
- placeholder stays. Open `dashboard.html` in a browser. Do not paste the HTML into a dataset or
184
- upload it as an asset.
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** to throw out of focus. All three are gated and all three go into the
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
- shoot past a foreground, and stay within the preset's stop (T2.8; T2 for `sweet-romance` and `costume-idol`, which
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, edit them into a locked cut (picture lock),
381
- `wji asset upload` it and bind `wji.assets.edit`. `prompt score E0N [--fps 24]` prints the planned
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), mix the sections under the edit at their offsets, upload and bind `wji.assets.mix`.
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.)